流程:
读图片(512, 512, 3)–>下采样,降低维度(256, 256, 3)–>将通道展平,data = (65536, 3)–>归一化
–>设置类别Class_num=3
–>初始阶段,取样本前三个,作为是三个类别的初始中心像素
–>计算所有样本点与3类中心坐标的距离,将类别分配距离中心坐标最小的哪一类
–>求各类样本的均值,更新中心坐标,重复迭代,直到分布不在改变
求出各类的平均像素,令各类别的像素均等于平均像素,显示出来。
python程序实现
import tensorflow as tf import numpy as np import cv2 import matplotlib.pyplot as plt from sklearn.cluster import KMeans #%%数据读取归一化 img = cv2.imread(r"pepper.bmp") #转换为RGB通道 img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) plt.imshow(img) plt.axis("off") plt.show() #进行下采样,降低维度 img1 = cv2.pyrDown(img) plt.imshow(img1) plt.axis("off") plt.show() ##通道展平[R,G,B] data = img1.reshape((-1,3)) #数据归一化 data = data/255.0 #%%定义聚类 class C_means(): def __init__(self): self.data = None self.label = None self.center = None self.Class_number = None #self.distacen = None def fit(self,data,Class_number): self.data = data self.Class_number = Class_number self.center = [data[i] for i in range(Class_number)] #求欧式距离 def eucldist_vectorized(self,coords1, coords2): return np.sqrt(np.sum((coords1 - coords2)**2)) #计算中心坐标 def compute_center(self): self.center = np.array([np.mean(self.data[self.label==i,:],axis = 0) for i in range(self.Class_number)]) #归类 def classify(self): label = [] for i in self.data: distance = [self.eucldist_vectorized(i,j) for j in self.center] index = np.argmin(distance) #将类别归类 label.append(index) self.label = np.array(label) def predict(self): flag = True quenu = [1,43,100,10,3] while flag: self.classify() self.compute_center() quenu.append(self.label) quenu.pop(0) if np.sum(quenu[0]) == np.sum(quenu[-1]): flag = False return self.center,self.label #%% 测试 cnn = C_means() cnn.fit(data,Class_number = 3) center,label = cnn.predict() #%% 划分类,绘图 for j,i in enumerate(label): if i == 0: data[j] = center[0] if i == 1: data[j] = center[1] if i == 2: data[j] = center[2] result = data.reshape((img1.shape)) plt.imshow(result) plt.axis("off") plt.show()
结果