利用K-Means進(jìn)行圖像分割

使用K—Means進(jìn)行圖像分割

一、需要用到的庫:

sklearn.cluster中的kmeans、PIL中的image、skimage中的color、PIL中的image

PIL是圖像處理標(biāo)準(zhǔn)庫,用image得到圖像的像素值和尺寸大小,依據(jù)尺寸,可以得到各個(gè)點(diǎn)的RGB值(三通道值),還可以利用image內(nèi)的函數(shù)保存圖片。利用PIL庫可以對(duì)圖像進(jìn)行讀寫

<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之間。

為了加速聚類的收斂,可以對(duì)通道值進(jìn)行規(guī)范化。

三、進(jìn)行聚類

Fit_predict進(jìn)行kmeans

四、將聚類結(jié)果可視化

將聚類表示轉(zhuǎn)換為不同顏色的矩陣,可以手動(dòng)對(duì)各個(gè)聚類標(biāo)識(shí)規(guī)定顏色,比如得到各個(gè)聚類中心的RGB通道來代表這一類的RGB通道值,下圖舉了三個(gè)例子,表示第0、1、2類的通道值

五、總的代碼

<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 聚類

kmeans =KMeans(n_clusters=16)

label = kmeans.fit_predict(img)#因?yàn)閒it和predict傳入的數(shù)據(jù)是一樣的,所以可以直接寫在一起,直接得到聚類結(jié)果

# 將圖像聚類結(jié)果,轉(zhuǎn)化成圖像尺寸的矩陣

label = label.reshape([width, height])

# 創(chuàng)建個(gè)新圖像 img,用來保存圖像聚類壓縮后的結(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è)類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>

得到的圖片如下所示:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容