k-means实现图像颜色分割及压缩

from sklearn.datasets import make_blobs#多
from sklearn.cluster import KMeans
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.image import imread


#ladybug.png

image = imread('strawberry.jpg')
##image.shape#三个参数不行,不满足kmeansAPI输入要求

X = image.reshape(-1,3)#-1,代表前两个参数相乘#分为三列#三维变二维?
##X.shape#多
print('读取图片完成')

##kmeans = KMeans(n_clusters = 8,random_state=42).fit(X)#8簇,随机种子42?fit啥意思?#fit使用X作为训练数据拟合模型,这步训练慢,因为图像数据大
print('完成')

##kmeans.cluster_centers_#每个簇的中心位置,训练后
print('完成')

##segmented_img = kmeans.cluster_centers_[kmeans.labels_].reshape(image.shape)#图像分割#图像中心点#标签?#图像中心点的一个标签#reshape还原成一个三维的,
print('完成')

segmented_imgs = []#列表
n_colors = (10,8,6,4,2)#几种不同的像素点
for n_cluster in n_colors: #从5color循环,遍历k值,很慢执行5次
    kmeans = KMeans(n_clusters = n_cluster,random_state=42).fit(X)#借鉴上面kmeans算法#fit使用X作为训练数据拟合模型
    segmented_img = kmeans.cluster_centers_[kmeans.labels_]#上面,这一步先把结果拿到手
    segmented_imgs.append(segmented_img.reshape(image.shape))#上面,reshape操作,恢复三维图像,#.append操作将,后面的数据添加到列表中
    print('完成')
    
plt.figure(figsize=(12,8))#tang10,5#moon12,8#?子图,尺寸变小?宽高
plt.subplot(231)#原始图像
##plt.imshow(image)#报错,得加.astype(np.uint8)
plt.imshow(image.astype('uint8'))#为什么有的图片反而不用uint8
plt.title('Original image')#标题

for idx,n_clusters in enumerate(n_colors):#枚举enumerate,能得到索引,?的个数,#for循环,每一次迭代的结果
    plt.subplot(232+idx)#idx从0开始?
    plt.imshow(segmented_imgs[idx])#显示#索引
    plt.imshow(segmented_imgs[idx].astype('uint8'))
    ##plt.title('{}colors'.format(n_clusters))#标题
    print('完成')
# plt.savefig('result.png')#保存图片
plt.show()
print('总完成')

原始图像k-means实现图像颜色分割及压缩_第1张图片

 10颜色聚类k-means实现图像颜色分割及压缩_第2张图片

图片中各类颜色的占比情况k-means实现图像颜色分割及压缩_第3张图片

 

 8颜色聚类k-means实现图像颜色分割及压缩_第4张图片k-means实现图像颜色分割及压缩_第5张图片

 

6颜色聚类k-means实现图像颜色分割及压缩_第6张图片k-means实现图像颜色分割及压缩_第7张图片 

 

4颜色聚类k-means实现图像颜色分割及压缩_第8张图片k-means实现图像颜色分割及压缩_第9张图片 

 

2颜色聚类k-means实现图像颜色分割及压缩_第10张图片k-means实现图像颜色分割及压缩_第11张图片 

 

饼状图显示颜色占比情况

#分类颜色程序,需要手动输入K值
import numpy as np
import cv2 as cv

img_rgb = cv.imread(r"C:\Users\wsl\Desktop\k-means\kmeans-py\strawberry.jpg")
img_bgr = cv.cvtColor(img_rgb, cv.COLOR_RGB2BGR)
Z = img_bgr.reshape((-1,3))

# convert to np.float32
Z = np.float32(Z)

# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 2##############################################################################################################
############################################################代表k不同时,需要更换的参数
ret,label,center=cv.kmeans(Z,K,None,criteria,10,cv.KMEANS_RANDOM_CENTERS)

# Now convert back into uint8, and make original image
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img_bgr.shape))
print("完成")

#显示源头分类完的3通道颜色数据组,进行频率统计
img2= res2
a = img2.reshape((-1,3))
a = np.array(a)

uniques, counts = np.unique(a, return_counts=True, axis=0)

print([(unique, count) for unique, count in zip(uniques, counts)])
print(counts)#只打印出现的频率
print(uniques)
#绘制颜色出现频率的饼状图

# 绘制育龄妇女的受教育程度分布饼图
import matplotlib.pyplot as plt
 
# ********** Begin *********#
#总数据
#Num = 1501817+4506185
Num = Sum
#单个数据
#data = [1501817,4506185]
data = counts
#数据标签
#labels = ['(101,145,213)', '(253,253,254)']
#labels = [uniques[0], uniques[1],uniques[2],uniques[3],uniques[4], uniques[5],uniques[6], uniques[7],uniques[8], uniques[9]]
labels = [uniques[0], uniques[1]]
#####################################################################################################################################3
#各区域颜色
#colors = [(213/255, 145/255, 101/255),(254/255, 253/255, 253/255)]
#数组同除
Uniques = np.array(uniques)/255#归一,255变为1

#列表变元组
a0=tuple(Uniques[0])
a1=tuple(Uniques[1])
#a2=tuple(Uniques[2])
#a3=tuple(Uniques[3])
#a4=tuple(Uniques[4])
#a5=tuple(Uniques[5])
#a6=tuple(Uniques[6])
#a7=tuple(Uniques[7])
#a8=tuple(Uniques[8])
#a9=tuple(Uniques[9])
########################################################################################################################################
#colors = [Uniques[0],Uniques[1],Uniques[2],Uniques[3],Uniques[4],Uniques[5],Uniques[6],Uniques[7],Uniques[8],Uniques[9]]
#colors = [a0,a1,a2,a3,a4,a5,a6,a7,a8,a9]
colors = [a0,a1]
#########################################################################################################################################
#背景色,防止白色看不见
fig = plt.figure(1, facecolor='#EAEAEF', figsize=(10, 8))

#数据计算处理
#sizes = [data[0]/Num*100,data[1]/Num*100,data[2]/Num*100,data[3]/Num*100,data[4]/Num*100,data[5]/Num*100,data[6]/Num*100,data[7]/Num*100,data[8]/Num*100,data[9]/Num*100]
sizes = [data[0]/Num*100,data[1]/Num*100]
#############################################################################################################################################
#设置突出模块偏移值
#expodes = (0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.1)##################################################################################
expodes = (0.01,0.1)
#设置绘图属性并绘图
patches,p_text = plt.pie(sizes,explode=expodes,labels=labels,shadow=True,colors=colors)
## 用于显示为一个长宽相等的饼图

#改变字体大小
for t in p_text:
    t.set_size(10)
    
plt.axis('equal')
#保存并显示
#plt.savefig('fig10.png')##################################################################################################################
plt.savefig('fig2.png')
plt.show()
# ********** End **********#

你可能感兴趣的:(kmeans,python)