K-means聚類算法之程序實現-3維像素級分割

最近看了k-means算法,網上這個算法很多都是用來分割二維圖片的,所以想嘗試用這個算法做一下三維圖片的分割。
那麼我們先來介紹一下二維圖片的分割:
原理是這樣的,我們把二維圖片中的每一個像素點的值作爲一個特徵值,如果是彩色圖片,那麼一個像素點就可以由3個特徵值組成,因爲有三個顏色通道。

代碼:

from scipy.cluster.vq import *
from scipy.misc import imresize
from pylab import *
from PIL import Image
import pdb
steps = 40 # image is divided in steps*steps region   

infile = 'E:\dataset\ORI_dataset\ADNI-slice3\cMCI\\278_brain\\46_278_brain.jpg'

im = array(Image.open(infile))

dx = int(im.shape[0] / steps)

dy = int(im.shape[1] / steps)

# compute color features for each region

features = []
#pdb.set_trace()

for x in range(steps):

    for y in range(steps):
        R = mean(im[x * dx:(x + 1) * dx, y * dy:(y + 1) * dy])   #彩色圖片進行三次
        #R = mean(im[x * dx:(x + 1) * dx, y * dy:(y + 1) * dy, 0])        
        #G = mean(im[x * dx:(x + 1) * dx, y * dy:(y + 1) * dy, 1])        
        #B = mean(im[x * dx:(x + 1) * dx, y * dy:(y + 1) * dy, 2])        
        #features.append([R, G, B])
        features.append(R)

features = array(features, 'f') # make into array

# cluster

centroids, variance = kmeans(features, 2)

code, distance = vq(features, centroids)

# create image with cluster labels

codeim = code.reshape(steps, steps)

codeim = imresize(codeim, im.shape[:2], 'nearest')

figure()

ax1 = subplot(121)

ax1.set_title('Image')

axis('off')

imshow(im)

ax2 = subplot(122)

ax2.set_title('Image after clustering')

axis('off')

imshow(codeim)

show()

結果:
在這裏插入圖片描述

我們的重點是對三維磁共振圖片進行分割,那麼其實原理和二維的差不多,也是將圖片中的像素值作爲特徵值進行劃分。

from scipy.cluster.vq import *
from scipy.misc import imresize
from pylab import *
from PIL import Image
import pdb
import nibabel as nib
from skimage import transform
steps = 182 # image is divided in steps*steps region

infile = 'E:\dataset\ORI_dataset\ADNI-teacher\AD\AD_001.nii\\AD_001.nii'
img=nib.load(infile)
ref_affine = img.affine
img=img.get_data()

img= np.array(img) / 1
#img= transform.resize(img, (32, 40, 32), mode='constant')
dx = int(img.shape[0] / steps)

dy = int(img.shape[2] / steps)
# compute color features for each region

#len(img.shape[1])
all=[]
#pdb.set_trace()

features = []
for i in range(218):
    im= img[:, i, :]  # 取出一張圖像

    dic2 = []

    for a in im:
        dic1 = []
        for b in a:
            aa=int(b)
            dic1.append(aa)
        dic2.append(dic1)
    im=np.array(dic2)
    for x in range(steps):
        for y in range(steps):
            R = im[x ,y]

            features.append([R])

features = array(features, 'f') # make into array

# cluster

centroids, variance = kmeans(features, 2)

code, distance = vq(features, centroids)

# create image with cluster labels
codeim = code.reshape(218,steps,steps)
#codeim = codeim.reshape(steps,40,steps)
heng5 = nib.Nifti1Image(codeim , ref_affine)
nib.save(heng5,  'E:\dataset\ORI_dataset\ADNI-teacher\AD\AD_001.nii\\112.nii')

一定要注意像素點重新分配的位置,因爲我的圖片是(182,218,182),我的像素點讀取相當於是用(182,182)大小的圖片進行了218次堆疊,每次先遍歷一張圖片,一共遍歷218次,所以最後reshape回來就是(218,182,182)。如果你的reshape是(182,218,182),那麼結果就三維展示會是這樣:
在這裏插入圖片描述

正確結果:右邊爲原始圖像,左邊爲分割之後的圖像,只是這時候像素點位置出現變化。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章