Pythonでいろいろやってみる

Pythonを使った画像処理や機械学習などの簡単なプログラムを載せています。

K-means(K平均法)で花の写真を色でクラスタリングする

K-Meansクラスタリングは、与えられたデータを自動的に分類するアルゴリズムであるクラスタリングの一種で、クラスタの平均を用い、与えられたクラスタ数k個に分類する手法です。(Wikipedia >> k平均法)
cv2.kmeans()を用いるとK-Meansクラスタリングが簡単に実装できます。
様々な色の花の写真を色に応じてクラスタリングします。写真全体のBGR各チャンネルの比率を特徴量として(特徴量3つ)、クラスタリングを行い、それぞれのクラスタ別にフォルダを作り画像ファイルを移動します。

関連記事

K-Meansクラスタリングによる画像の減色

環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 5.6.0
  • Python 3.7.0
  • OpenCV 4.0.0
準備

画像ファイルはフリー写真素材ぱくたそから花の写真25枚をダウンロードさせていただき、jupyter notebookファイル(***.ipynb)と同じディレクトリに、'flowers'ディレクトリを作成しそこに保存しました。

コード
import os  
import cv2
import numpy as np

# 画像ファイルのあるフォルダの相対パス
dir_path = 'flowers/'  
# フォルダ内のファイルのリスト生成
files = os.listdir(dir_path)
# jpgファイルのリスト生成
files_jpg = [s for s in files if '.jpg' in s]

list_all =[]
for i in files_jpg:  # ファイル数だけ繰り返す
    img = cv2.imread(dir_path+i)  # 画像の読み出し
    #BGR各チャンネルの輝度をすべての輝度の合計で規格化しリスト化 
    bgr_sum = np.sum(img ,axis = (0,1))
    b_ratio,g_ratio,r_ratio = bgr_sum/np.sum(bgr_sum)        
    bgr_list = [b_ratio,g_ratio,r_ratio]
    list_all.append(bgr_list)

# リストをndarrayに変換
list_all_n = np.array(list_all)
# リストをfloat32に変換
list_all_n = np.float32(list_all_n)
# 計算終了条件の設定。指定された精度(1.0)か指定された回数(10)計算したら終了
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# クラスター数
K = 4
# K-Meansクラスタリングの実施
ret,label,center=cv2.kmeans(list_all_n,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)

# ラベル別ディレクトリ作成
for i in range(K):
    new_dir_path =dir_path+str(i) 
    os.mkdir(new_dir_path)

# クラスタリング結果に応じたディレクトリに画像ファイルを移動
for file_name,dir_name in zip(files_jpg,label):
    original_file_name = dir_path+file_name
    new_file_name = dir_path+str(int(dir_name))+'/'+file_name
    os.rename(original_file_name,new_file_name)
実行結果

label0に分類された画像はピンクや紫の花が多いようです。
f:id:T_A_T:20190625232739p:plain
label1には青い花が分類されました
f:id:T_A_T:20190625232755p:plain
label2には赤い花が分類されました
f:id:T_A_T:20190625232806p:plain
label3には黄色い花が分類されました
f:id:T_A_T:20190625232824p:plain
それなりに分類されましたが、黄色い花がlabel0に分類されるなど人間が分類する場合とは合わなそうな結果が見られます。今回用いた特徴量は写真全体のBGRチャンネル比を用いているため花以外の背景の色も加味されるためそこは改善の余地がありそうです。

以下のサイトを参考にさせていただきました

OpenCV >> K-Means Clustering in OpenCV
OpenCV-Python Tutorials 1 documentation >> OpenCVのK-Meansクラスタリング

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村