圖像分割是一種圖像處理方法, 它是指將一副圖像分割成若干個互不相交的區域;
圖像分割實質就是像素的聚類;
圖像分割可以分為兩類:基於邊緣的分割,基於區域的分割,
聚類就是基於區域的分割;
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