# 提取主色

## 2. KMeans 自适应

• 对输入图片进行缩放，缩小图片大小
• 使用`MiniBatchKMeans`代替``Kmeans`
• 计算轮廓系数时进行采样计算

## 3. 整体过程及代码

1. 读取图片，并缩小
2. 将RGB转为HSV进行聚类，找到最好的K值
3. 利用最好的K值再次聚类，得到最终结果并转回RGB
4. 可视化提取的主色块
``````import time
from functools import wraps
import matplotlib.pyplot as plt
import numpy as np
from skimage.color import rgb2hsv, hsv2rgb
from skimage import transform
from sklearn.cluster import MiniBatchKMeans
from sklearn.metrics import silhouette_score

# calculating time
def time_it(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
print(f"Spend time:{

time.time() - start} s")
return result

return wrapper

@time_it
def get_best_k(src):
K_list = [i for i in range(2, 8)]
scores = []
for i in K_list:
mbk = MiniBatchKMeans(n_clusters=i, random_state=0)
scores.append(silhouette_score(src, mbk.fit_predict(src), sample_size=int(src.shape[0] / 128)))
index = scores.index(max(scores))
best_k = K_list[index]
print(f'best_k:', best_k)
return best_k

def get_main_Color(src):
# to_HSV
img = rgb2hsv(src)
h, w, d = img.shape
img = np.reshape(img, (h * w, d))
k = get_best_k(img)
bk = MiniBatchKMeans(n_clusters=k, random_state=0)
bk.fit(img)
result = bk.cluster_centers_
# to_RGB
maincolor = hsv2rgb(result) * 255
return maincolor

def maincolor_show(maincolor):
N = len(maincolor)
img = np.zeros((300, 100 * N, 3), np.uint8)

for i in range(N):
img[:, 100 * i:100 * (i + 1)] = [maincolor[i]]
plt.imshow(img)
plt.axis('off')
plt.show()

def main():
plt.imshow(src)
plt.axis('off')
plt.show()

src = transform.rescale(src, [0.4, 0.4, 1])
maincolor = get_main_Color(src)
print(maincolor)
# visualization
maincolor_show(maincolor)

if __name__ == '__main__':
main()

``````