LoginSignup
10
10

More than 5 years have passed since last update.

Coursera Machine Learningの課題をPythonで: ex7-1 (K-meansクラスタリングで画像圧縮)

Posted at

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色に減色されているのがわかります。

ex7-1.png
ex7-2.png

全コード

全コードはこちらになります。短いですね。

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++でスクラッチ実装しましたが、数百行のプログラムにはなっていたような...
ライブラリが整備されて、いい時代ですね。

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10