LoginSignup
7
9

More than 3 years have passed since last update.

画像のドミナントカラーをk-meansクラスタリングで抽出

Posted at

ドミナントカラー(dominant color)とは、配色全体を支配するような色相のことです。 --Google

5色抽出して、割合で円グラフを描きます。


input.jpg
out.png
input.jpg
out.png
input.jpg
out.png

使うパッケージ

$ pip install opencv-python
$ pip install scikit-learn
$ pip install matplotlib

画像を読み込む

画像をk-meansクラスタリングできるデータにするため、RGBのリストにする

import cv2
import itertools

image = cv2.imread('./input.jpg')
rgbs = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
rgb_list = list(itertools.chain(*rgbs.tolist()))

k-means

抽出する色の数=クラスタの数
ここでは5の例:

from sklearn.cluster import KMeans

clusters = KMeans(n_clusters=5).fit(rgb_list)

クラスタのセンターがドミナントカラー

colors = clusters.cluster_centers_
print(colors)
[[ 25.29093216 119.84721127 142.13737995]
 [223.23362209 201.96734673 193.59849205]
 [176.3426999  108.01350558 118.93074255]
 [  8.36396613  14.71480369  27.54413049]
 [ 98.95068783  32.240443    48.93265647]]
#rgb

各クラスタの割合を計算

import numpy as np

def cluster_percents(labels):
    total = len(labels)
    percents = []
    for i in set(labels):
        percent = (np.count_nonzero(labels == i) / total) * 100
        percents.append(round(percent, 2))
    return percents
percents = cluster_percents(clusters.labels_)
print(percents)
[9.16, 9.6, 11.51, 48.37, 21.35]
#%

円グラフを描く

matplotlibのcolorが0~1にスケールされたRGBしか受け付けないためスケールする。

import matplotlib.pyplot as plt

colors = clusters.cluster_centers_ / 255
colors = colors.tolist()

円グラフを綺麗に見せるため割合を大から小にソートする。

percents = cluster_percents(clusters.labels_)
tup = zip(colors, percents)
sorted_tup = sorted(tup, key=lambda n: n[1], reverse=True)
sorted_colors = [c for c,p in sorted_tup]
sorted_percents = [p for c,p in sorted_tup]

円グラフを描く

plt.pie(sorted_percents, colors=sorted_colors, counterclock=False, startangle=90)
plt.show()
7
9
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
7
9