-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKmeans-segmentation.py
66 lines (57 loc) · 2.3 KB
/
Kmeans-segmentation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import numpy as np
import cv2
def distEclud(vecA, vecB):
return np.linalg.norm(vecA-vecB)
def randCent(dataSet, k):
n = np.shape(dataSet)[1]
centroids = np.mat(np.zeros((k,n)))#create centroid mat
for j in range(n):#create random cluster centers, within bounds of each dimension
minJ = min(dataSet[:,j])
rangeJ = float(max(dataSet[:,j]) - minJ)
centroids[:,j] = np.mat(minJ + rangeJ * np.random.rand(k,1))
return centroids
# dataSet have k center point
# disMeas the distance, we use eclud
# createCent,the initial center point
def kMeans(dataSet, k, length,width,distMeas=distEclud, createCent=randCent):
m = np.shape(dataSet)[0] #num of sample
new_arr=(np.zeros((length,width,3)))
clusterAssment = np.mat(np.zeros((m,2))) #m*2 matrix
centroids = createCent(dataSet, k) #initial k centers
clusterChanged = True
round=0
while clusterChanged: # while center still changes
clusterChanged = False
for i in range(m):
minDist = np.inf;
minIndex = -1
for j in range(k): # find nearest mass center
distJI = distMeas(centroids[j, :], dataSet[i, :])
if distJI < minDist:
minDist = distJI;
minIndex = j
if clusterAssment[i, 0] != minIndex: clusterChanged = True
# the first column is the center while the second column is the distance
clusterAssment[i, :] = minIndex, minDist ** 2
# change the mass center
for cent in range(k):
ptsInClust = dataSet[np.nonzero(clusterAssment[:, 0].A == cent)[0]]
centroids[cent, :] = np.mean(ptsInClust, axis=0)
round=round+1
#return the new image
for i in range(length):
for j in range(width):
# print(clusterAssment[i*width+j,0],np.int(clusterAssment[i*width+j,0]))
new_arr[i,j,:]=centroids[np.int(clusterAssment[i*width+j,0]),:]
return centroids, clusterAssment,new_arr
img = cv2.imread('star.ppm')
length=img.shape[0]
width=img.shape[1]
Z = np.mat(img.reshape((-1,3)))
Z = np.float32(Z)
K = 3
center,ret,img2=kMeans (Z,K,length,width)
cv2.imwrite("after.png", img2)
#cv2.imshow('img2',img2)
#cv2.waitKey(0)
#cv2.destroyAllWindows()