kmeans做简单的图像分割

kmeans做简单的图像分割

kmeans做简单的图像分割_第1张图片

包的使用

import numpy as np
import matplotlib.pyplot as plt

因为这道题目相对的比较简单,就使用和numpy 和matplotlib 这两个库进行代码的浮现

第一步对图像进行处理

归一化,按照像素作为输入还是3*3窗函数对某一坐标周围的9个点做平均或者最大值和最小值求平均这三种方式对我们的图像进行预处理作为真正的输入。

def preprocess(image,way = 1):  #way 作为一个额外的输入代表不同的预处理方式
    image = (image - np.min(image))/(np.max(image)-np.min(image)) # 归一化
    if way == 1:  #3*3*平均值
        image_new = np.zeros(image.shape)
        image_new[[0,-1],:] = image[[0,-1],:]
        image_new[:,[0,-1]] = image[:,[0,-1]]
        for i in range(1,image.shape[0]-1):
            for j in range(1,image.shape[1]-1):
                image_new[i,j] = np.average(image[i-1:i+2,j-1:j+2])
        return image_new
    elif way == 2:  # 3*3窗的最大值与最小值平均
        image_new = np.zeros(image.shape)
        image_new[[0,-1],:] = image[[0,-1],:]
        image_new[:,[0,-1]] = image[:,[0,-1]]
        for i in range(1,image.shape[0]-1):
            for j in range(1,image.shape[1]-1):
                image_new[i,j] = (np.max(image[i-1:i+2,j-1:j+2]) + np.min(image[i-1:i+2,j-1:j+2]))/2
        return image_new
    else :  #
        return image

第二步相似性计算

简单来说就是用两个像素值之间差的绝对值作为相似性的度量,若某一个坐标的像素值与kmeans中的一个代表向量绝对差越小则说明他们越相似的。
由于本题中是像素级别的,并没有涉及到民科夫斯基距离这些可度量距离的概念。

def dist(val1,val2):
    return np.abs(val1-val2)

结果展示

image = np.average(plt.imread('iamge.png',format = None)[:,:,0:3],axis = 2)
(a,b) = image.shape
image = preprocess(image,way =1)
k0 = np.max(image)
k1 = np.min(image)
theta = 1
count = 0
while theta > 0.00001:
    class1 = np.array([[1 if dist(k0,image[i,j])>dist(k1,image[i,j]) else 0 for j in range(b)] for i in range(a)])
    k0_new = np.average(image[class1==0])
    k1_new = np.average(image[class1==1])
    theta = (k0-k0_new)**2 + (k1 - k1_new)**2
    k0 = k0_new
    k1 = k1_new
    count += 1
    
plt.subplot(121)
plt.imshow(image,cmap ='gray')
plt.axis('off')
plt.title('original')    
plt.subplot(122)
plt.imshow(class1,cmap ='gray')
plt.axis('off')
plt.title('kmeans') 
plt.show()

kmeans算法的伪代码

1:确定需要分类的个数K
2:随机选取k个聚类中心
3:遍历数据集中的所有元素,并将其划分到这K个聚类中心代表下的区域里
4:对分别属于这K个聚类区域的里面的元素向量进行求平均得到新的K个聚类中心
5:判断新生成的聚类中心和老的k个中心是否满足循环结束条件(一般来说就是他们变化很小就可以,说明聚类中心收敛到稳定了),不满足返回步骤**3**
6:算法结束

学习重点

可以尝试去学习和证明kmeans算法的收敛性。

你可能感兴趣的:(机器学习,python,kmeans算法)