Advertisement

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('总完成')
    
  
    
    
    
    

原始图像

10颜色聚类

图片中各类颜色的占比情况

8颜色聚类

6颜色聚类

4颜色聚类

2颜色聚类

饼状图显示颜色占比情况

复制代码
 #分类颜色程序,需要手动输入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 **********#
    
    
    
    

全部评论 (0)

还没有任何评论哟~