「世界初、来店不要のフルオーダーメイド靴」のプレスリリースを行いました。

14-8. k-meansで画像の階調を下げる

やること

k-meansというクラスタリング手法を用いて画像の階調を落としてみます。後半にパンケーキのお店当てクイズもついていますので、パンケーキ好きは挑戦してみてください。

参考にさせていただいたサイト

k-means法については説明が面倒 こちらの動画が分かりやすいです。

アルゴリズムがデータを分ける様子を可視化した【K-means】【クラスタリング】

こちらも同様に分かりやすい。

404 Not Found

こちらは sklearn.cluster.KMeans の使い方です。

scikit-learn でクラスタ分析 (K-means 法) – Python でデータサイエンス

実行環境

WinPython3.6をおすすめしています。

WinPython - Browse /WinPython_3.6/3.6.7.0 at SourceForge.net
Portable Scientific Python 2/3 32/64bit Distribution for Windows

Google Colaboratoryが利用可能です。

Google Colaboratory

コード

sklearn.cluster.KMeans のおかげでクラスタリングは数行で終わります。丁寧にコメントを入れてもこの程度です。

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans


#============================
# パラメータ
#============================
#画像
file = 'hoge.jpg'

#何色に落とすか
n_clusters = 5


#============================
# 前処理
#============================
#画像読み込み
img = Image.open(file).convert('RGB'); img.close

#画像をたて200pxにリサイズする
w, h = int(img.size[0] * 200 / img.size[1]), 200
img_resize = img.resize((w, h), Image.BICUBIC)

#表示
print('img_resize')
plt.imshow(img_resize)
plt.show()

#(-1, 3)次元の配列に変形、-1は適当に判断してくれる
img_array = np.array(img_resize).reshape(-1, 3)
print('img_array.shape\n{}'.format(img_array.shape))


#============================
# k-means
#============================
#k-meansのオブジェクト
km = KMeans(n_clusters=n_clusters)

#計算を実行
km.fit(img_array)

#各クラスタの重心
km_centers = km.cluster_centers_
print('km_centers\n{}'.format(km_centers))

#計算結果に応じてクラスタリング(クラスタ番号の配列が返ってくる)
km_predict = km.predict(img_array)
print('km_predict.shape\n{}'.format(km_predict.shape))


#============================
# 後処理
#============================
#クラスタ番号を2次元に戻す
img_predict = km_predict.reshape(h, w)
print('img_predict.shape\n{}'.format(img_predict.shape))

#表示
print('img_predict')
plt.imshow(img_predict)
plt.show()

#クラスタ番号をクラスタ重心に置き換える、(h, w, 3)次元になる
img_final = np.empty((h, w, 3), dtype=int)
for i in range(n_clusters):
    img_final[img_predict==i] = km_centers[i]
print('img_final.shape\n{}'.format(img_final.shape))

#表示
print('img_final')
plt.imshow(img_final)
plt.show()

5階調のときの出力です。

img_resize

img_array.shape
(59800, 3)
km_centers
[[ 30.12513446  41.97968208  19.47579778]
 [219.39103917 214.34248182 198.82237861]
 [173.46803045  66.32949572  10.8       ]
 [204.4928753  167.28275437  77.73619348]
 [ 99.0330566  106.72875472  47.45916981]]
km_predict.shape
(59800,)
img_predict.shape
(200, 299)
img_predict

img_final.shape
(200, 299, 3)
img_final

画像をリサイズして、(たて, よこ, RGB) という3次元情報だったものを (一列, RGB) すなわち img_array.shape=(59800, 3) に伸ばします。これを k-means にかけます。km_predict はクラスタ番号が並んだ配列です。km_centers は各クラスタの重心で、これがRBGの色になります。km_predict を (たて, よこ) の2次元に戻してやって、各要素に重心RGBを入れてやると、(たて, よこ, RGB) の出力画像となります。

こちらの写真を入力しました。どこのお店で撮ったものでしょうか?(難易度★★★☆☆)

20階調。ペイント感があっていいですね。

10階調。まだいけます。

5階調。このあたりがギリギリでしょうか。

ちなみにこちらはPowerPointのアート効果>カットアウト(影の数=3)です。5~10階調くらいに相当しそうです。

クイズ

私がこれまでに撮ったパンケーキコレクションの一部です。それぞれどこのお店でしょうか。左は元画像、右は10階調です。

クイズ1(難易度★☆☆☆☆)
パンケーキ好きの登竜門です。

クイズ2(難易度★☆☆☆☆)
威力(がありすぎて昼食に食べると午後の)業務(が)妨害(される)

クイズ3(難易度★★★☆☆)
どのパンケーキにもハチミツとメープルシロップがついてきます。

クイズ4(難易度★★★☆☆)
バターソースがポイントです。

答え

サンプル画像 サンドッグイン神戸屋(全国)食べ放題実施店は限られています

クイズ1 FLIPPER’S(全国)かんたん

クイズ2 38mitsubachi(仙台)画像に写ってる…

クイズ3 花きゃべつ(自由が丘)食事系パンケーキも豊富

クイズ4 Clinton St. Baking Company(Newyork)

タイトルとURLをコピーしました