Start_python’s diary

ふたり暮らし

アラフィフ夫婦のフリーランスプラン

配列データをExcelに書き込む (クロスステッチデータを作る 第4回)

本日の課題と目標
cv2.kmeans関数の戻り値2であるラベル番号を調べる
Excelにラベルデータを書き込む


はじめに
前回の続きで、作成したExcelファイルにラベルデータを書き込んでいきます。これが出来れば、ほぼクロスステッチ用データの完成です。


プログラム

# -*- coding: utf-8 -*-
import cv2
import numpy as np
import openpyxl
from openpyxl.styles.borders import Border, Side
from openpyxl.styles import Font

# 減色処理
def sub_color(src, K):
    # 画面サイズを確認
    size_y,size_x,zzz = src.shape

    # 次元数を1落とす
    Z = src.reshape((-1,3))
    # float32型に変換
    Z = np.float32(Z)
    # 基準の定義
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
    # K-means法で減色
    ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
    # UINT8に変換
    center = np.uint8(center)
    res = center[label.flatten()]

    # Excelファイルを作成
    book = openpyxl.Workbook()
    # シートの指定
    sheet = book.active
    # 罫線(外枠)を設定
    border = Border(top=Side(style='thin'), 
                    bottom=Side(style='thin'), 
                    left=Side(style='thin'),
                    right=Side(style='thin'))
    # 罫線とフォント
    for i in range(size_y):
        for j in range(size_x):
            # 罫線を引く
            sheet.cell(row=i + 1 ,column=j + 1).border = border
            # 文字の大きさを変更
            sheet.cell(row=i + 1 ,column=j + 1).font = Font(size=7)
    # セルの幅・高さを変更
    # 行の高さを変更
    for i in range(size_y):
        sheet.row_dimensions[i + 1].height = 12
    # 列の幅を変更
    for j in range(size_x):
        # openpyxl.utils.get_column_letterを使って列「1」を 列「A」に変換
        sheet.column_dimensions[openpyxl.utils.get_column_letter(j + 1)].width = 2

    # ラベルデータの書き込み
    n = 0
    for i in range(size_y):
        for j in range(size_x):
            sheet.cell(row=i + 1,column=j + 1).value = int(label[n])
            n = n + 1

    # ブックの保存
    book.save('テスト.xlsx')
    
    # 配列の次元数と入力画像と同じに戻す
    return res.reshape((src.shape))


def main():
    # 入力画像とスクリーントーン画像を取得
    img = cv2.imread("input.jpg")
    # 減色処理(三値化)
    dst = sub_color(img, K=12)
    # 結果を出力
    cv2.imwrite("output.jpg", dst)


if __name__ == '__main__':
    main()

f:id:Start_python:20191102201328j:plain


解説
ラベルデータの情報を調べました。

label.shape

shapeから画像のサイズ(幅、高さ)を取得できる。
カラー画像の場合は行(高さ) x 列(幅) x 色(3)の三次元のndarrayとなる。shapeは(行(高さ), 列(幅), 色(3))のタプルとなる。
注意: sizeの時とは、高さと幅の順が逆になります。

ラベルデータは二次元配列でした。


書き込み用メソッド
sheet.cell(セル番号).value


参考サイト

虹のフリーイラストはこちらでお借りしました。


保存ファイル
lesson24.py


文責:Luke