diff --git a/Homework_9/ImageSegmentation.py b/Homework_9/ImageSegmentation.py new file mode 100644 index 0000000..a8a4359 --- /dev/null +++ b/Homework_9/ImageSegmentation.py @@ -0,0 +1,44 @@ +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +from MeanShift import MeanShift +from KMeans import K_Means +from SpectralClustering import Spectral +import numpy + +def segmentation(img, method): + #Image to Nomalized vector + size = img.shape + data = numpy.zeros(shape=(size[2]+1, size[0]*size[1])) + label = numpy.zeros(shape=(data.shape[1])) + result = numpy.zeros(shape=(img.shape)) + + for row in range(size[0]): + for col in range(size[1]): + #Normalize pixel position 0.0~1.0 + data[0][row*size[1]+col] = float(row) / float(size[0]-1) + data[1][row*size[1]+col] = float(col) / float(size[1]-1) + for color in range(size[2]-1): + data[color+2][row*size[1]+col] = img[row][col][color] + + #clustring - input : ndarray(colum vector) + if method == "MEAN-SHIFT": + label = MeanShift(data, 0.4) #radius 0.4 + elif method == "K-MEANS": + label = K_Means(data, 8) #8 cluster + elif method == "SPECTRAL": + label = Spectral(data, 8) s #8 cluster + + #clustring result to image + for row in range(size[0]): + for col in range(size[1]): + result[row][col][0] = float(label[row*size[1]+col] * 29 % 100) / 100.0 + result[row][col][1] = float(label[row*size[1]+col] * 13 % 100) / 100.0 + result[row][col][2] = float(label[row*size[1]+col] * 37 % 100) / 100.0 + result[row][col][3] = 1.0 + + plt.imsave("result.png", result) + plt.imshow(result) + plt.show() + + + return 0 diff --git a/Homework_9/KMeans.py b/Homework_9/KMeans.py new file mode 100644 index 0000000..0005d22 --- /dev/null +++ b/Homework_9/KMeans.py @@ -0,0 +1,48 @@ +import numpy +import random +import copy + +def K_Means(data, nClass): + label = numpy.zeros(shape=(data.shape[1])) + prvLabel = numpy.zeros(shape=(data.shape[1])) + nLabel = numpy.zeros(shape=(nClass)) + CovPos = numpy.zeros(shape=(data.shape[0], nClass)) + tCov = numpy.zeros(shape=(data.shape[0], nClass)) + + + #init random point + tsize = tCov.shape + for row in range(tsize[0]): + for col in range(tsize[1]): + tCov[row][col] = random.random() + + #Loop until convergence + while 1: + CovPos = copy.copy(tCov) + tCov[:] = 0.0 + nLabel[:] = 0.0 + + for i in range(data.shape[1]): + Mindist = 9999.0 + for j in range(nClass): + sub = CovPos[:,j] - data[:,i] + dist = numpy.dot(sub, sub) + + if Mindist > dist: + Mindist = dist + label[i] = j + + tCov[:,label[i]] += data[:,i] + nLabel[label[i]] += 1 + + if label.all() == prvLabel.all(): + break + + for i in range(tCov.shape[1]): + if nLabel[i] != 0: + tCov[:,i] /= nLabel[i] + prvLabel = label[:] + + label[:] += 1 + + return label diff --git a/Homework_9/MeanShift.py b/Homework_9/MeanShift.py new file mode 100644 index 0000000..0880f40 --- /dev/null +++ b/Homework_9/MeanShift.py @@ -0,0 +1,58 @@ +import numpy +import copy + +def MeanShift(data, rad): + label = numpy.zeros(shape=(data.shape[1])) + CovPos = numpy.zeros(shape=(data.shape)) + Idx = [] + prevIdx = [] + + rad = rad*rad + + #Mean-shift algorithm + for n in range(data.shape[1]): + #Initialize convergence point + CovPos[:,n] = copy.copy(data[:,n]) + del Idx[:] + del prevIdx[:] + + while 1: + prevIdx = copy.copy(Idx[:]) + del Idx[:] + + for i in range(data.shape[1]): + #euclidean distance calculation + sub = CovPos[:,n] - data[:,i] + dist = numpy.dot(sub, sub) + + if dist <= rad: + Idx.append(i) + + #convergence check + if prevIdx == Idx: + break + if len(Idx) == 0: + break + + #Center search + CovPos[:,n] = 0.0 + for j in range(len(Idx)): + CovPos[:,n] += data[:, Idx[j]] + CovPos[:,n] /= float(len(Idx)) + + #Merge Converge Point + cCount = 1 + for n in range(len(label)): + if label[n] == 0: + label[n] = cCount + for i in range(len(label)): + if label[i] != 0: + continue + #euclidean distance calculation + sub = CovPos[:,n] - CovPos[:,i] + dist = numpy.sqrt(numpy.dot(sub, sub)) + if dist <= 0.01: + label[i] = cCount + cCount+=1 + + return label diff --git a/Homework_9/Result_KMeans.png b/Homework_9/Result_KMeans.png new file mode 100644 index 0000000..2d6fd03 Binary files /dev/null and b/Homework_9/Result_KMeans.png differ diff --git a/Homework_9/Result_MeanShift.png b/Homework_9/Result_MeanShift.png new file mode 100644 index 0000000..ad0e84d Binary files /dev/null and b/Homework_9/Result_MeanShift.png differ diff --git a/Homework_9/Result_Spectral.png b/Homework_9/Result_Spectral.png new file mode 100644 index 0000000..08f3aa0 Binary files /dev/null and b/Homework_9/Result_Spectral.png differ diff --git a/Homework_9/SegmentationTest.py b/Homework_9/SegmentationTest.py new file mode 100644 index 0000000..3f2c07e --- /dev/null +++ b/Homework_9/SegmentationTest.py @@ -0,0 +1,14 @@ +from ImageSegmentation import segmentation +import matplotlib.pyplot as plt +import matplotlib.image as mpimg + +Img = mpimg.imread("sample2.png") + +#K-Means segmentation +segmentation(Img, "K-MEANS") + +#Spectral segmentation +segmentation(Img, "SPECTRAL") + +#Mean shift segmentation +segmentation(Img, "MEAN-SHIFT") diff --git a/Homework_9/SpectralClustering.py b/Homework_9/SpectralClustering.py new file mode 100644 index 0000000..4194291 --- /dev/null +++ b/Homework_9/SpectralClustering.py @@ -0,0 +1,48 @@ +import numpy +import math +from scipy import linalg as LA + +def Spectral(data, nClass): + label = numpy.zeros(shape=(data.shape[1])) + sigma = 1.0 + + #Affinity, D, Dinv matrix calculation + sigma = sigma * sigma + W = numpy.zeros(shape=(data.shape[1], data.shape[1])) + D = numpy.zeros(shape=(W.shape)) + invD = numpy.zeros(shape=(W.shape)) + for i in range(W.shape[0]): + for j in range(W.shape[1]): + dist = data[:,i] - data[:,j] + dist = numpy.dot(dist,dist) + W[i][j] = numpy.exp(-dist / (2.0*sigma)) + + D[i][i] += W[i][j] + invD[i][i] = numpy.sqrt(1.0/D[i][i]) + print(i) + + #ndarray to matrix + W = numpy.matrix(numpy.array(W)) + D = numpy.matrix(numpy.array(D)) + invD = numpy.matrix(numpy.array(invD)) + + #Calculate D^(-0.5)*(D-W)*D^(-0.5) + T = invD*(D-W)*D + + #eigen vector & eigen value + val, vec = LA.eigh(T) + + #Calculate label + y = invD*vec + #for i in range(data.shape[1]): + # for j in range(nClass-1): + # if y[i, j+1] > 0: + # label[j] += numpy.power(2,j) + + for i in range(nClass-1): + for j in range(data.shape[1]): + if y[j,i+1] > 0: #check row vector or col vector + label[j] += numpy.power(2,i) + + + return label diff --git a/Homework_9/sample.png b/Homework_9/sample.png new file mode 100644 index 0000000..a6fdd0b Binary files /dev/null and b/Homework_9/sample.png differ diff --git a/Homework_9/sample2.png b/Homework_9/sample2.png new file mode 100644 index 0000000..d284f2e Binary files /dev/null and b/Homework_9/sample2.png differ