使用K—Means進(jìn)行圖像分割
一、需要用到的庫(kù):
sklearn.cluster中的kmeans关顷、PIL中的image糊秆、skimage中的color、PIL中的image
PIL是圖像處理標(biāo)準(zhǔn)庫(kù)议双,用image得到圖像的像素值和尺寸大小痘番,依據(jù)尺寸,可以得到各個(gè)點(diǎn)的RGB值(三通道值)平痰,還可以利用image內(nèi)的函數(shù)保存圖片汞舱。利用PIL庫(kù)可以對(duì)圖像進(jìn)行讀寫(xiě)
<pre>import PIL.Image as image
# 得到圖像的像素值
img = image.open(f)
# 得到圖像尺寸
width, height = img.size</pre>
二、準(zhǔn)備階段
加載數(shù)據(jù)—獲取圖像信息【包括圖像像素?cái)?shù)據(jù)宗雇、圖像的尺寸和通道數(shù)】—對(duì)圖像每個(gè)通道的數(shù)據(jù)進(jìn)行數(shù)據(jù)規(guī)范化
jpg格式的圖像具有三個(gè)通道(R昂芜,G,B)赔蒲,也就是一個(gè)像素點(diǎn)具有3個(gè)特征值泌神,特征值的范圍在0-255之間。
為了加速聚類(lèi)的收斂舞虱,可以對(duì)通道值進(jìn)行規(guī)范化欢际。
三、進(jìn)行聚類(lèi)
Fit_predict進(jìn)行kmeans
四矾兜、將聚類(lèi)結(jié)果可視化
將聚類(lèi)表示轉(zhuǎn)換為不同顏色的矩陣损趋,可以手動(dòng)對(duì)各個(gè)聚類(lèi)標(biāo)識(shí)規(guī)定顏色,比如得到各個(gè)聚類(lèi)中心的RGB通道來(lái)代表這一類(lèi)的RGB通道值椅寺,下圖舉了三個(gè)例子舶沿,表示第0、1配并、2類(lèi)的通道值
五、總的代碼
<pre>
import numpy as np
import PIL.Image as image
from sklearn.cluster import KMeans
from sklearn import preprocessing
# 加載圖像高镐,并對(duì)數(shù)據(jù)進(jìn)行規(guī)范化
def load_data(filePath):
? ? # 讀文件
? ? f = open(filePath,'rb')
? ? data = []
? ? # 得到圖像的像素值
? ? img = image.open(f)
? ? # 得到圖像尺寸
? ? width, height = img.size
? ? for x in range(width):
? ? ? ? for y in range(height):
? ? ? ? ? ? # 得到點(diǎn) (x,y) 的三個(gè)通道值
? ? ? ? ? ? c1, c2, c3 = img.getpixel((x, y))
? ? ? ? ? ? data.append([(c1+1)/256.0, (c2+1)/256.0, (c3+1)/256.0])
? ? f.close()
? ? return np.mat(data), width, height
# 加載圖像溉旋,得到規(guī)范化的結(jié)果 imgData,以及圖像尺寸
img, width, height = load_data(r'C:\users\dell\Desktop\weixin.jpg')
# 用 K-Means 對(duì)圖像進(jìn)行 16 聚類(lèi)
kmeans =KMeans(n_clusters=16)
label = kmeans.fit_predict(img)#因?yàn)閒it和predict傳入的數(shù)據(jù)是一樣的嫉髓,所以可以直接寫(xiě)在一起观腊,直接得到聚類(lèi)結(jié)果
# 將圖像聚類(lèi)結(jié)果邑闲,轉(zhuǎn)化成圖像尺寸的矩陣
label = label.reshape([width, height])
# 創(chuàng)建個(gè)新圖像 img,用來(lái)保存圖像聚類(lèi)壓縮后的結(jié)果
img=image.new('RGB', (width, height))
for x in range(width):
? ? for y in range(height):
? ? ? ? c1 = kmeans.cluster_centers_[label[x, y], 0]
? ? ? ? c2 = kmeans.cluster_centers_[label[x, y], 1]
? ? ? ? c3 = kmeans.cluster_centers_[label[x, y], 2]
? ? ? ? #c1,c2,c3代表了每個(gè)類(lèi)RGB通道的數(shù)值
? ? ? ? img.putpixel((x, y), (int(c1*256)-1, int(c2*256)-1, int(c3*256)-1))
? ? ? ? # #用 putpixel 函數(shù)對(duì)新圖像的點(diǎn)進(jìn)行RGB的設(shè)置梧油,因?yàn)榍懊鎸?duì)通道值進(jìn)行了規(guī)范化苫耸,控制在了0-1,但是通道值要在0-255的時(shí)候才會(huì)顯示出顏色儡陨,所以這邊*256恢復(fù)到0-255的范圍
img.save(r'C:\users\dell\Desktop\weixin_new.jpg')
<\pre>
得到的圖片如下所示: