Python学习—利用Kmeans聚类算法进行主颜色提取
目录
颜色是一张图像最具代表性的特征,那么如何去对一张图像进行主颜色提取呢?这是今天所要解决的问题。
通过查阅相关资料发现,最常使用的主颜色提取方法是利用Kmeans聚类的方法进行颜色提取。
思路:使用k-means算法对图像像素点进行聚类,中心点即为图片主体色彩。
颜色提取方法流程:
1、导入pyrhon需要的相关库
from skimage import io
from sklearn.cluster import KMeans
import numpy as np
import cv2
2、原图像
3、读取图像并进行数据类型转换
img=cv2.imread("E:\\car\\2.jpg")
# 转换数据维度
img_ori_shape = img.shape
img1 = img.reshape((img_ori_shape[0] * img_ori_shape[1], img_ori_shape[2]))
img_shape = img1.shape
# 获取图片色彩层数
n_channels = img_shape[1]
print(img_ori_shape)
print(img_shape)
数据转换结果:
(754, 500, 3)
(377000, 3)
4、构造Kmeans聚类器
k=10
estimator = KMeans(n_clusters=k, max_iter=4000, init='k-means++', n_init=50) # 构造聚类器
estimator.fit(img1) # 聚类
k-means算法
K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。
k-means算法特点在于:同一聚类的簇内的对象相似度较高;而不同聚类的簇内的对象相似度较小。
参数:
n_clusters:整形,缺省值=8 【生成的聚类数,即产生的质心(centroids)数。】
max_iter:整形,缺省值=300
执行一次k-means算法所进行的最大迭代数。
用不同的质心初始化值运行算法的次数,最终解是在inertia意义下选出的最优结果。
init:有三个可选值:’k-means++’, ‘random’,或者传递一个ndarray向量。
此参数指定初始化方法,默认值为 ‘k-means++’。
(1)‘k-means++’ 用一种特殊的方法选定初始质心从而能加速迭代过程的收敛
(2)‘random’ 随机从训练数据中选取初始质心。
(3)如果传递的是一个ndarray,则应该形如 (n_clusters, n_features) 并给出初始质心。
n_init:整形,缺省值=10
5、获取聚类中心
centroids = estimator.cluster_centers_ # 获取聚类中心
6、主颜色数据可视化
result = []
result_width = 200
result_height_per_center = 80
for center_index in range(k):
result.append(np.full((result_width * result_height_per_center, n_channels), centroids[center_index], dtype=int))
result = np.array(result)
result = result.reshape((result_height_per_center * k, result_width, n_channels))
主颜色RGB值
[[ 19.82205991 149.7690272 211.49931195]
[214.7921876 225.59464734 232.63928502]
[ 27.94646364 30.19337169 38.60147449]
[137.8024557 143.75987211 169.59865311]
[247.01430781 248.36793259 247.67733138]
[ 59.12095428 80.34021664 151.25188991]
[177.2187077 187.48049797 209.521568 ]
[ 76.69247648 76.76323896 74.26908308]
[ 80.64346774 228.37937817 241.31598457]
[222.01081434 198.77818711 189.82191984]]
主颜色:
代码展示:
from skimage import io
from sklearn.cluster import KMeans
import numpy as np
import warnings
import cv2
#聚类个数
k = 10
img=cv2.imread("E:\\car\\2.jpg")
# 转换数据维度
img_ori_shape = img.shape
img1 = img.reshape((img_ori_shape[0] * img_ori_shape[1], img_ori_shape[2]))
img_shape = img1.shape
# 获取图片色彩层数
n_channels = img_shape[1]
estimator = KMeans(n_clusters=k, max_iter=4000, init='k-means++', n_init=50) # 构造聚类器
estimator.fit(img1) # 聚类
centroids = estimator.cluster_centers_ # 获取聚类中心
# 使用算法跑出的中心点,生成一个矩阵,为数据可视化做准备
result = []
result_width = 200
result_height_per_center = 80
for center_index in range(k):
result.append(np.full((result_width * result_height_per_center, n_channels), centroids[center_index], dtype=int))
result = np.array(result)
result = result.reshape((result_height_per_center * k, result_width, n_channels))
# 保存图片
io.imsave('E:\\car\\' + 'result.bmp', result)
print(centroids)
原图
主色RGB值
[[209.48521825 195.61594055 71.92092171]
[ 52.48426043 96.02463706 20.59607313]
[ 8.99264171 74.41625716 200.81015865]
[189.51310268 7.27714641 6.92790465]
[ 22.64248968 211.86446047 198.96500448]]
主色结果
鸣谢:
https://blog.csdn.net/github_39261590/article/details/76910689