CourseraのMachine LearningのMatlab/Octaveプログラミング課題をPythonで実装していくシリーズ。
今回は教師なし学習の最初の課題、K平均クラスタリングをやります。
はじめに:課題の内容
元画像(.png)は、RGBそれぞれ256階調で、1677万色のもの。この色情報を、K平均クラスタリングによって16のクラスタに分類し、16色の画像にするのが課題です。
PILライブラリのインストール
画像処理にはpillowというライブラリを使うのでインストールしておきましょう。
pip install pillow
pillowのドキュメントはこちら。
コードの最初:ライブラリをインポート
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
最初に画像を読み込み
画像データの読み込みにはPIL.Image.open()
を使い、128 x 128 x 3 の3次元のnumpy arrayに読み込みます。これを、reshape(128*128, 3)
して、クラスタリングに渡せる形の 16384 x 3 の2次元行列に変換(flatten)します。
img = np.array(Image.open('bird_small.png')) # imgは128x128x3 の3次元行列
img_flat = img.reshape(128*128,3)/255 # 16384x3 の2次元行列に変換
クラスタリングを実施
クラスタリングは、KMeans.fit(data)
一発でできます。KMeansのパラメータでn_clusters=16
と、16個のクラスタに分けるよう指定します。
model = KMeans(n_clusters=16).fit(img_flat)
結果の表示
クラスタリングの結果、各ピクセルがどのクラスタに分類されたかは model.labels_
(0-15の数字)、各クラスタの重心の値はmodel.cluster_centers_
(16x3行列) に格納されています。
これを使って、各ピクセルの値をクラスタの重心で置き換えた行列は、model.cluster_centers_[model.labels_]
として作成することができます(16384 x 3 の2次元行列)。これを、画像で表示できる形の 128 x 128 x 3 の3次元行列に戻すため、reshape(128, 128, 3)
します。
img_comp = model.cluster_centers_[model.labels_].reshape(128,128,3)
plt.imshow(img_comp)
元画像と結果の画像はこちら。16色に減色されているのがわかります。
全コード
全コードはこちらになります。短いですね。
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
img = np.array(Image.open('bird_small.png')) # imgは128x128x3 の3次元行列
img_flat = img.reshape(128*128,3)/255 # 16384x3 の2次元行列に変換
model = KMeans(n_clusters=16).fit(img_flat)
img_comp = model.cluster_centers_[model.labels_].reshape(128,128,3)
plt.imshow(img_comp)
おわりに
10ウン年前に画像処理を研究する学生だった頃にK平均クラスタリングをC++でスクラッチ実装しましたが、数百行のプログラムにはなっていたような...
ライブラリが整備されて、いい時代ですね。