├── code ├── GMM.py └── fuzzy_c_means.py ├── data ├── assignmentSegmentBrain.mat └── assignmentSegmentBrainGmmEmMrf.mat ├── report ├── GMMs.pdf └── fuzzy.pdf └── results ├── GMMs ├── q2_figure7_1.png ├── q2_figure7_10.png ├── q2_figure7_2.png ├── q2_figure7_3.png ├── q2_figure7_4.png ├── q2_figure7_5.png ├── q2_figure7_6.png ├── q2_figure7_7.png ├── q2_figure7_8.png └── q2_figure7_9.png └── fuzzy ├── q1_figure4_1.png ├── q1_figure4_2.png ├── q1_figure6_1.png ├── q1_figure6_2.png ├── q1_figure6_3.png ├── q1_figure6_4.png ├── q1_figure7_1.png ├── q1_figure8_1.png ├── q1_figure9_1.png ├── q1_figure9_2.png └── q1_figure9_3.png /code/GMM.py: -------------------------------------------------------------------------------- 1 | #%% 2 | #Libraries 3 | import numpy as np 4 | import h5py 5 | import matplotlib.pyplot as plt 6 | from math import sqrt, pi 7 | from sklearn.cluster import KMeans 8 | 9 | #%% 10 | #Read 11 | f = h5py.File('../data/assignmentSegmentBrainGmmEmMrf.mat','r') 12 | list(f.keys()) 13 | imageData = f.get('imageData') 14 | imageMask = f.get('imageMask') 15 | imageData = np.array(imageData) 16 | imageData = imageData.T 17 | imageMask = np.array(imageMask) 18 | imageMask = imageMask.T 19 | 20 | #%% 21 | #GMM With EM 22 | def label_priors(input_label,old_labels,beta,map_left, 23 | map_right,map_top,map_bottom,mask): 24 | img = input_label 25 | if len(input_label)==1: 26 | img = input_label*np.ones((old_labels.shape)) 27 | top = ((img-np.roll(old_labels,[1,1], [0,1]))*map_top)!=0 28 | bottom = ((img-np.roll(old_labels,[-1,1], [0,1]))*map_bottom)!=0 29 | left = ((img-np.roll(old_labels,[1,2], [0,1]))*map_left)!=0 30 | right = ((img-np.roll(old_labels,[-1,2], [0,1]))*map_right)!=0 31 | return np.exp(-((top+bottom+left+right)*beta))*mask 32 | 33 | def memberships( y,means,sigmas,old_labels,mask,prior_val): 34 | K = means.shape[0] 35 | likelihood = np.zeros((y.shape[0], y.shape[1], 3)) 36 | prior = np.zeros((y.shape[0], y.shape[1], 3)) 37 | for i in range(K): 38 | likelihood[:,:,i] = ((1/(sigmas[i,0]*sqrt(2*pi)))*np.exp(-(y-means[i,0])**2/(2*sigmas[i,0]**2)))*mask 39 | prior[:,:,i] = prior_val(np.array([i]),old_labels) 40 | norm = np.sum(prior,2) 41 | for i in range(K): 42 | prior[:,:,i] /=norm 43 | membership = likelihood*prior 44 | norm = np.sum(membership,2) 45 | for i in range(K): 46 | membership[:,:,i] /= norm 47 | 48 | temp = np.zeros((old_labels.shape)) 49 | for i in range(K): 50 | temp = membership[:,:,i] 51 | temp[mask==0] = 0 52 | membership[:,:,i] = temp 53 | 54 | return membership 55 | 56 | def gaussian_paprameters(y, mem, maps ): 57 | means = np.zeros((mem.shape[2],1)) 58 | sigmas = np.zeros((mem.shape[2],1)) 59 | for i in range(mem.shape[2]): 60 | den = np.sum(mem[:, :, i]) 61 | means[i,0] = np.sum(mem[:, :, i]*y)/den 62 | sigmas[i,0] = np.sqrt(np.sum(mem[:,:,i]*((y-means[i,0])**2)*maps)/den) 63 | 64 | return means, sigmas 65 | 66 | def posterior_val(old_labels, y, means,sigmas, maps, prior_val): 67 | likelihood = np.zeros((old_labels.shape)) 68 | for i in range(len(means)): 69 | indeold_labels = np.where(old_labels==i) 70 | likelihood[indeold_labels] = (1/(sigmas[i,0]*sqrt(2*pi)))*np.exp(-(y[indeold_labels]-means[i,0])**2/(2*(sigmas[i,0]**2))) 71 | prior = prior_val(old_labels,old_labels) 72 | return likelihood*prior*maps 73 | 74 | def segmentation( old_labels,y,means,sigmas,iters,mask,prior_val): 75 | for i in range(iters): 76 | oldLogPosterior = np.sum(np.log(posterior_val(old_labels,y,means,sigmas,mask,prior_val)[mask!=0])) 77 | print('%d : Initial log posterior = %f\n'%(i,oldLogPosterior)) 78 | membership = memberships(y,means,sigmas,old_labels,mask,prior_val) 79 | new_labels = np.argmax(membership,2) 80 | new_labels = new_labels*mask 81 | posterior = posterior_val(new_labels,y,means,sigmas,mask,prior_val) 82 | newLogPosterior = np.sum(np.log(posterior[mask!=0])) 83 | print('%d : Final log posterior = %f\n'%(i,newLogPosterior)) 84 | 85 | if newLogPosterior0] 118 | masked_img = np.reshape(masked_img, (masked_img.shape[0], 1)) 119 | kmeans = KMeans(n_clusters = K).fit(masked_img) 120 | initial_labels = kmeans.labels_ 121 | means_init = kmeans.cluster_centers_ 122 | label_map = np.zeros((imageData.shape)) 123 | label_map[imageMask>0] = initial_labels 124 | 125 | 126 | #%% 127 | #Variance 128 | sigmas_init = np.zeros((K,1)) 129 | for i in range(K): 130 | clusterVals = masked_img[initial_labels==i] 131 | sigmas_init[i] = np.linalg.norm(clusterVals - means_init[i])/sqrt(len(clusterVals)) 132 | 133 | #%% 134 | #Segmentation 135 | initial_labels = label_map 136 | print('Modified ICM with beta = %f \n'%(beta1)) 137 | labels1,means1,sigmas1,iters1 = segmentation(initial_labels,imageData,means_init, 138 | sigmas_init,20,imageMask,prior1) 139 | 140 | print('Modified ICM with beta = %f \n'%(beta2)) 141 | labels2,means2,sigmas2,iters2 = segmentation(initial_labels,imageData,means_init, 142 | sigmas_init,20,imageMask,prior2) 143 | 144 | #%% 145 | #Images 146 | plt.figure() 147 | plt.imshow(imageData, cmap=plt.cm.gray) 148 | plt.title('Corrupted image') 149 | 150 | plt.figure() 151 | plt.imshow(initial_labels, extent=[0, 1, 0, 1]) 152 | plt.title('Initial estimate for the label image') 153 | 154 | 155 | plt.figure() 156 | plt.imshow(labels1, extent=[0, 1, 0, 1]) 157 | plt.title('Optimal label image estimate for beta = 2.0') 158 | 159 | plt.figure() 160 | plt.imshow(labels2, extent=[0, 1, 0, 1]) 161 | plt.title('Optimal label image estimate for beta = 0') 162 | 163 | #Beta = 2.0 164 | for i in range(K): 165 | seg = np.zeros((imageData.shape)) 166 | seg[labels1==i] = imageData[labels1==i] 167 | plt.figure() 168 | plt.imshow(seg, cmap=plt.cm.gray) 169 | plt.title('Optimal class membership image estimate %d for beta = 2.0'%(i+1)) 170 | 171 | #Beta =0 172 | for i in range(K): 173 | seg = np.zeros((imageData.shape)) 174 | seg[labels2==i] = imageData[labels2==i] 175 | plt.figure() 176 | plt.imshow(seg, cmap=plt.cm.gray) 177 | plt.title('Optimal class membership image estimate %d for beta = 0'%(i+1)) 178 | 179 | #%% 180 | #Optimal Estimates 181 | print('Initial class means are (%f, %f, %f)'%(means_init[0,0],means_init[1,0],means_init[2,0])) 182 | print('For beta = 2.0, optimal class means are (%f, %f, %f)'%(means1[0,0],means1[1,0],means1[2,0])) 183 | print('For beta = 0, optimal class means are (%f, %f, %f)'%(means2[0,0],means2[1,0],means2[2,0])) 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /code/fuzzy_c_means.py: -------------------------------------------------------------------------------- 1 | #%% 2 | #Libraries 3 | import numpy as np 4 | import h5py 5 | import matplotlib.pyplot as plt 6 | from scipy.ndimage.filters import convolve 7 | from sklearn.cluster import KMeans 8 | 9 | #%% 10 | #Gausian Filtere and 2D Convolution 11 | def gauss2D(shape=(3,3),sigma=0.5): 12 | m,n = [(ss-1.)/2. for ss in shape] 13 | y,x = np.ogrid[-m:m+1,-n:n+1] 14 | h = np.exp( -(x*x + y*y) / (2.*sigma*sigma) ) 15 | h[ h < np.finfo(h.dtype).eps*h.max() ] = 0 16 | sumh = h.sum() 17 | if sumh != 0: 18 | h /= sumh 19 | return h 20 | 21 | 22 | def conv2D(x,y,mode='same'): 23 | if not(mode == 'same'): 24 | raise Exception("Mode not supported") 25 | if (len(x.shape) < len(y.shape)): 26 | dim = x.shape 27 | for i in range(len(x.shape),len(y.shape)): 28 | dim = (1,) + dim 29 | x = x.reshape(dim) 30 | elif (len(y.shape) < len(x.shape)): 31 | dim = y.shape 32 | for i in range(len(y.shape),len(x.shape)): 33 | dim = (1,) + dim 34 | y = y.reshape(dim) 35 | origin = () 36 | for i in range(len(x.shape)): 37 | if ( (x.shape[i] - y.shape[i]) % 2 == 0 and 38 | x.shape[i] > 1 and 39 | y.shape[i] > 1): 40 | origin = origin + (-1,) 41 | else: 42 | origin = origin + (0,) 43 | z = convolve(x,y, mode='constant', origin=origin) 44 | return z 45 | 46 | 47 | #%% 48 | #Modified Fuzzy C-Means 49 | def biasField(w, y, u, c, k, q): 50 | s = y.shape 51 | sum_num = np.zeros((s)) 52 | sum_den = np.zeros((s)) 53 | for i in range(k): 54 | sum_num += (u[:, :, i]**q)*c[i] 55 | sum_den += (u[:, :, i]**q)*(c[i]**2) 56 | num = conv2D(y*sum_num, w, 'same') 57 | den = conv2D(sum_den, w, 'same') 58 | return num/den 59 | 60 | 61 | def cmeans(u, y, w, b, q, k): 62 | sum_num = conv2D(b, w, 'same') 63 | sum_den = conv2D(b**2, w, 'same') 64 | cmeans = np.zeros((k,1)) 65 | for i in range(k): 66 | cmeans[i] = np.sum((u[:, :, i]**q)*y*sum_num)/np.sum((u[:, :, i]**q)*sum_den) 67 | return cmeans 68 | 69 | 70 | def membership(w, y, c, b, imageMask, k, q): 71 | s = y.shape 72 | u = np.zeros((s[0], s[1], k)) 73 | d = np.zeros((s[0], s[1], k)) 74 | sum_mask = np.sum(w) 75 | t1 = conv2D(b,w,'same') 76 | t2 = conv2D(b**2,w,'same') 77 | for i in range(k): 78 | d[:, :, i] = (y**2)*sum_mask - 2*c[i]*y*t1 + (c[i]**2)*t2 79 | d[d<0] = 0 80 | u = np.divide(1,d)**(1/(q-1)) 81 | sum_u = np.nansum(u, 2) 82 | for i in range(k): 83 | u_new = u[:, :, i] 84 | u_new = u_new/sum_u 85 | u_new[np.where(imageMask == 0)] = 0 86 | u[:, :, i] = u_new 87 | return np.nan_to_num(u) 88 | 89 | 90 | def objFun(y, w, c, b, u, q, k): 91 | s = y.shape 92 | d = np.zeros((s[0], s[1], k)) 93 | sum_mask = np.sum(w) 94 | a1 = conv2D(b, w, 'same') 95 | a2 = conv2D(b**2, w, 'same') 96 | a3 = np.zeros((s)) 97 | for i in range(k): 98 | d[:, :, i] = (y**2)*sum_mask - 2*c[i]*y*a1 + (c[i]**2)*a2 99 | for i in range(k): 100 | a3 += (u[:, :, i]**q)*d[:, :, i] 101 | return np.sum(conv2D(w, a3, 'same')) 102 | 103 | #%% 104 | # Class Memberships are initialized by kmeans 105 | f = h5py.File('../data/assignmentSegmentBrain.mat','r') 106 | #list(f.keys()) 107 | imageData = f.get('imageData') 108 | imageMask = f.get('imageMask') 109 | imageData = np.array(imageData) 110 | imageData = imageData.T 111 | imageMask = np.array(imageMask) 112 | imageMask = imageMask.T 113 | s = imageData.shape 114 | 115 | #Plot Of Original Image and ImageMaks 116 | plt.imshow(imageData, cmap=plt.cm.gray) 117 | plt.title('Original Image') 118 | plt.figure() 119 | 120 | plt.imshow(imageMask, cmap=plt.cm.gray) 121 | plt.title('Image Mask') 122 | plt.figure() 123 | #%% 124 | #Ititialized with simple k-means 125 | k = 3 126 | img = imageData[imageMask > 0] 127 | #plt.imshow(img) 128 | img = np.reshape(img, (21282,1)) 129 | kmeans = KMeans(n_clusters=k).fit(img) 130 | labels = kmeans.cluster_centers_ 131 | 132 | u0 = np.zeros((s[0], s[1], k)) 133 | for i in range(s[0]): 134 | for j in range(s[1]): 135 | if(imageMask[i, j] > 0): 136 | t = np.ones((k,1))*imageData[i, j] 137 | index = np.argmin(abs(t - labels)) 138 | u0[i, j, index] = 1 139 | 140 | #Parameters Used 141 | q = 2.2 142 | b0 = np.ones((s))*imageMask 143 | window = 5; 144 | w = gauss2D((10, 10)) 145 | maxIter = 30 146 | J = np.zeros((maxIter, 1)) 147 | 148 | 149 | #Modified Fuzzy C-Means 150 | y = imageData*imageMask 151 | u = u0 152 | c = labels 153 | b = b0 154 | for i in range(maxIter): 155 | u = membership(w, y, c, b, imageMask, k, q) 156 | c = cmeans(u, imageData, w, b, q, k) 157 | b = biasField(w, imageData, u, c, k, q) 158 | b[np.where(imageMask == 0)] = 0 159 | J[i] = objFun(imageData, w, c, b, u, q, k) 160 | print(J[i]) 161 | 162 | print('Initial Estimate of cluster centers is : ', kmeans.cluster_centers_) 163 | print('Optimal Estimate of cluster centers is : ', c) 164 | 165 | #%% 166 | #Plot of segmented brain sections 167 | plt.imshow(u[:, :, 0], cmap=plt.cm.gray) 168 | plt.title('Optimal Cluster 1') 169 | plt.figure() 170 | 171 | plt.imshow(u[:, :, 1], cmap=plt.cm.gray) 172 | plt.title('Optimal Cluster 2') 173 | plt.figure() 174 | 175 | plt.imshow(u[:, :, 2], cmap=plt.cm.gray) 176 | plt.title('Optimal Cluster 3') 177 | 178 | plt.figure() 179 | plt.imshow(b, cmap=plt.cm.gray) 180 | plt.title('Bias Field') 181 | 182 | #%% 183 | #Bias Removed Image 184 | nb = np.zeros((s)); 185 | for i in range(k): 186 | nb += u[:,:,i]*c[i] 187 | nb = nb*imageMask 188 | 189 | plt.figure() 190 | plt.imshow(nb, cmap='gray') 191 | plt.title('Bias-removed image') 192 | 193 | #%% 194 | #Recidual Image 195 | eecidual = imageData - nb*b 196 | plt.figure() 197 | plt.imshow(eecidual, cmap=plt.cm.gray) 198 | plt.title('Recidual image') 199 | 200 | #%% 201 | #neighborhodd mask 202 | plt.figure() 203 | plt.imshow(w, extent=[0, 1, 0, 1]) 204 | plt.title('Neighborhodd mask') 205 | 206 | #%% 207 | #Segmentation based on kmeans 208 | plt.imshow(u0[:, :, 0], cmap=plt.cm.gray) 209 | plt.title('Kmeans Cluster 1') 210 | plt.figure() 211 | 212 | plt.imshow(u0[:, :, 1], cmap=plt.cm.gray) 213 | plt.title('Kmeans Cluster 2') 214 | plt.figure() 215 | 216 | plt.imshow(u0[:, :, 2], cmap=plt.cm.gray) 217 | plt.title('Kmeans Cluster 3') 218 | 219 | 220 | -------------------------------------------------------------------------------- /data/assignmentSegmentBrain.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/data/assignmentSegmentBrain.mat -------------------------------------------------------------------------------- /data/assignmentSegmentBrainGmmEmMrf.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/data/assignmentSegmentBrainGmmEmMrf.mat -------------------------------------------------------------------------------- /report/GMMs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/report/GMMs.pdf -------------------------------------------------------------------------------- /report/fuzzy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/report/fuzzy.pdf -------------------------------------------------------------------------------- /results/GMMs/q2_figure7_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/GMMs/q2_figure7_1.png -------------------------------------------------------------------------------- /results/GMMs/q2_figure7_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/GMMs/q2_figure7_10.png -------------------------------------------------------------------------------- /results/GMMs/q2_figure7_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/GMMs/q2_figure7_2.png -------------------------------------------------------------------------------- /results/GMMs/q2_figure7_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/GMMs/q2_figure7_3.png -------------------------------------------------------------------------------- /results/GMMs/q2_figure7_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/GMMs/q2_figure7_4.png -------------------------------------------------------------------------------- /results/GMMs/q2_figure7_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/GMMs/q2_figure7_5.png -------------------------------------------------------------------------------- /results/GMMs/q2_figure7_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/GMMs/q2_figure7_6.png -------------------------------------------------------------------------------- /results/GMMs/q2_figure7_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/GMMs/q2_figure7_7.png -------------------------------------------------------------------------------- /results/GMMs/q2_figure7_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/GMMs/q2_figure7_8.png -------------------------------------------------------------------------------- /results/GMMs/q2_figure7_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/GMMs/q2_figure7_9.png -------------------------------------------------------------------------------- /results/fuzzy/q1_figure4_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/fuzzy/q1_figure4_1.png -------------------------------------------------------------------------------- /results/fuzzy/q1_figure4_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/fuzzy/q1_figure4_2.png -------------------------------------------------------------------------------- /results/fuzzy/q1_figure6_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/fuzzy/q1_figure6_1.png -------------------------------------------------------------------------------- /results/fuzzy/q1_figure6_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/fuzzy/q1_figure6_2.png -------------------------------------------------------------------------------- /results/fuzzy/q1_figure6_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/fuzzy/q1_figure6_3.png -------------------------------------------------------------------------------- /results/fuzzy/q1_figure6_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/fuzzy/q1_figure6_4.png -------------------------------------------------------------------------------- /results/fuzzy/q1_figure7_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/fuzzy/q1_figure7_1.png -------------------------------------------------------------------------------- /results/fuzzy/q1_figure8_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/fuzzy/q1_figure8_1.png -------------------------------------------------------------------------------- /results/fuzzy/q1_figure9_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/fuzzy/q1_figure9_1.png -------------------------------------------------------------------------------- /results/fuzzy/q1_figure9_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/fuzzy/q1_figure9_2.png -------------------------------------------------------------------------------- /results/fuzzy/q1_figure9_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaido975/Image-Segmentation/53a21c3bfba13fb5dedada46352baa95c58463a4/results/fuzzy/q1_figure9_3.png --------------------------------------------------------------------------------