图像分割是一种图像处理方法, 它是指将一副图像分割成若干个互不相交的区域;
图像分割实质就是像素的聚类;
图像分割可以分为两类:基于边缘的分割,基于区域的分割,
聚类就是基于区域的分割;
KMeans 实现图像分割
KMeans 分割图像实质上是对像素的聚类,每个类有个代表像素,把原始像素替换成该类别对应的代表像素即完成分割;
每个类别对应一个分割区域,每个区域是个单通道图;
示例
import numpy as np from sklearn.cluster import KMeans from PIL import Image ### 原始像素 img = Image.open('e://55.jpg') print(img.size) np_img = np.array(img) print(np_img) print(np_img.shape) ### 聚类的数据预处理 np_flatten = np_img.flatten() ### 拉成一维 np_flatten = np_flatten[:, np.newaxis] ### kmeans 要求 二维 np_flatten_std = np_flatten / 256. ### 归一化 # print(np_flatten_std) ### 聚类 所有像素点 km = KMeans(n_clusters=3, random_state=0).fit(np_flatten_std) print(km.labels_) print(km.cluster_centers_) reshape_label = np.reshape(km.labels_, np_img.shape) centers = km.cluster_centers_ ### 新建图像以查看分割效果 img1 = Image.new('L', img.size, color=255) ### 分割区域1 img1.show() img2 = Image.new('L', img.size, color=255) ### 分割区域2 img3 = Image.new('L', img.size, color=255) ### 分割区域3 img4_np = np.zeros(np_img.shape) ### 分割区域的合成 x, y ,z = np_img.shape for yv in range(y): for xv in range(x): ### 把 类别对应的代表像素 添加到图像中的对应位置 img1.putpixel((yv, xv), int(centers[reshape_label[xv, yv, 0]] * 256.)) img2.putpixel((yv, xv), int(centers[reshape_label[xv, yv, 1]] * 256.)) img3.putpixel((yv, xv), int(centers[reshape_label[xv, yv, 2]] * 256.)) img4_np[xv, yv, 0] = int(centers[reshape_label[xv, yv, 0]] * 256.) img4_np[xv, yv, 1] = int(centers[reshape_label[xv, yv, 1]] * 256.) img4_np[xv, yv, 2] = int(centers[reshape_label[xv, yv, 2]] * 256.) print(img4_np) print(img4_np.shape) ### 显示 # img1.show() # img2.show() # img3.show() ### 保存 img1.save('img1.png') img2.save('img2.png') img3.save('img3.png') img4 = Image.fromarray(img4_np.astype(np.uint8)) ### L (8-bit pixels, black and white) img4.save('img4.png')
下面依次为:原图、区域1、区域2、区域3、分割后的合成图
参考资料:
https://blog.csdn.net/xxuffei/article/details/90180408
来源:https://www.cnblogs.com/yanshw/p/12394629.html