# k means image segmentation based on intensity and spatial

32 views (last 30 days)
Mohammad Al Nagdawi on 11 Feb 2017
Commented: Image Analyst on 11 Feb 2017
In the below code can segment image based on color and spatial. how can I convert it to work with intensity instead of color?
function Ikm = Km2(I,K)
%%color + spatial (option: K (Number of Clusters))
I = im2double(I);
[x,y] = meshgrid(1:size(I,2),1:size(I,1)); % Spatial Features
L = [y(:)/max(y(:)),x(:)/max(x(:))];
C = reshape(I,size(I,1)*size(I,2),3); % Color Features
F = [C,L]; % Color & Spatial Features
%%Kmeans Segmentation
CENTS = F( ceil(rand(K,1)*size(F,1)) ,:); % Cluster Centers
DAL = zeros(size(F,1),K+2); % Distances and Labels
KMI = 10; % K-means Iteration
for n = 1:KMI
for i = 1:size(F,1)
for j = 1:K
DAL(i,j) = norm(F(i,:) - CENTS(j,:));
end
[Distance CN] = min(DAL(i,1:K)); % 1:K are Distance from Cluster Centers 1:K
DAL(i,K+1) = CN; % K+1 is Cluster Label
DAL(i,K+2) = Distance; % K+2 is Minimum Distance
end
for i = 1:K
A = (DAL(:,K+1) == i); % Cluster K Points
CENTS(i,:) = mean(F(A,:)); % New Cluster Centers
if sum(isnan(CENTS(:))) ~= 0 % If CENTS(i,:) Is Nan Then Replace It With Random Point
NC = find(isnan(CENTS(:,1)) == 1); % Find Nan Centers
for Ind = 1:size(NC,1)
CENTS(NC(Ind),:) = F(randi(size(F,1)),:);
end
end
end
end
X = zeros(size(F));
for i = 1:K
idx = find(DAL(:,K+1) == i);
X(idx,:) = repmat(CENTS(i,:),size(idx,1),1);
end
Ikm = reshape(X(:,1:3),size(I,1),size(I,2),3);
end

#### 1 Comment

Image Analyst on 11 Feb 2017
You forgot to attach the image.

Walter Roberson on 11 Feb 2017
Right after the first line, add
I = repmat( rgb2gray(I), 1, 1, 3);
That will make the code take grayscale intensity of the color image, and then copies the intensities to all three planes (making a gray RGB image). The code should work from there.
There are more efficient ways of doing this, but they require more code changes. If you are going to do extensive code changes then the best approach would be to just call the MATLAB kmeans() routine.

Mohammad Al Nagdawi on 11 Feb 2017
"If you are going to do extensive code changes then the best approach would be to just call the MATLAB kmeans() routine." I compare with a different type of classification to find best for multimodal image registration.
If we use this way will lose any important information from the output image? because the output image will feed to similarity measurement function.
last question, I know how to get the same result from kmean but how I do this with SOM??
Walter Roberson on 11 Feb 2017
"If we use this way will lose any important information from the output image?"
r = uint8([177 171 165 159 152 146 140 134 128 122 116 110 104 98 91 85;176 170 164 158 152 146 140 134 128 122 115 109 103 97 91 85;176 170 164 158 152 146 139 133 127 121 115 109 103 97 91 85;176 170 164 157 151 145 139 133 127 121 115 109 102 96 90 84;175 169 163 157 151 145 139 133 127 120 114 108 102 96 90 84;175 169 163 157 151 144 138 132 126 120 114 108 102 96 90 83;175 168 162 156 150 144 138 132 126 120 114 107 101 95 89 83;174 168 162 156 150 144 138 131 125 119 113 107 101 95 89 83;174 168 162 156 149 143 137 131 125 119 113 107 101 94 88 82;173 167 161 155 149 143 137 131 125 119 112 106 100 94 88 82;173 167 161 155 149 143 136 130 124 118 112 106 100 94 88 82;173 167 160 154 148 142 136 130 124 118 112 106 99 93 87 81;172 166 160 154 148 142 136 130 123 117 111 105 99 93 87 81;172 166 160 154 147 141 135 129 123 117 111 105 99 93 86 80;172 165 159 153 147 141 135 129 123 117 110 104 98 92 86 80;171 165 159 153 147 141 135 128 122 116 110 104 98 92 86 80]);
g = 128 * ones(16, 16, 'uint8');
b = uint8([0 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240;1 17 33 49 65 81 97 113 129 145 161 177 193 209 225 241;2 18 34 50 66 82 98 114 130 146 162 178 194 210 226 242;3 19 35 51 67 83 99 115 131 147 163 179 195 211 227 243;4 20 36 52 68 84 100 116 132 148 164 180 196 212 228 244;5 21 37 53 69 85 101 117 133 149 165 181 197 213 229 245;6 22 38 54 70 86 102 118 134 150 166 182 198 214 230 246;7 23 39 55 71 87 103 119 135 151 167 183 199 215 231 247;8 24 40 56 72 88 104 120 136 152 168 184 200 216 232 248;9 25 41 57 73 89 105 121 137 153 169 185 201 217 233 249;10 26 42 58 74 90 106 122 138 154 170 186 202 218 234 250;11 27 43 59 75 91 107 123 139 155 171 187 203 219 235 251;12 28 44 60 76 92 108 124 140 156 172 188 204 220 236 252;13 29 45 61 77 93 109 125 141 157 173 189 205 221 237 253;14 30 46 62 78 94 110 126 142 158 174 190 206 222 238 254;15 31 47 63 79 95 111 127 143 159 175 191 207 223 239 255]);
M = cat(3, r, g, b);
image(M)
Have a look at this image. This image is constant brightness, 128 in every position -- rgb2gray(M) is all 128. Would you lose any important information if you converted this image to intensity?
"I compare with a different type of classification to find best for multimodal image registration."
No point in being inefficient. Use the built-in routines when they exist.
"how I do this with SOM??"
Sorry, I do not know how to use SOM.