k-mean cluster classifies pixel randomly. I wrote this code to repeat clustering until both images meet proper cluster.

 while 1
  idx_fix = kmeans(double(fix(:)),4);
  idx_float = kmeans(double(float(:)),4);
  idx_fix = reshape(idx_fix,size(fix));
  idx_float  = reshape(idx_float,size(float));
  f1 = idx_fix(127,303);
  f2 = idx_float(114,205);
  if (f1 == f2)
      if (f1 == f2)%when these pixles same that mean this is my target classification.
  mat1 = uint8(255*mat2gray(idx_fix));
  mat2 = uint8(255*mat2gray(idx_float));
  disp(['mat1 = ' num2str(mat1(127,303))]);
  disp(['mat2 = ' num2str(mat2(114,205))]);% the value still correct after coversion.
  imshow(mat1); title('Fix image class');
  hold on
  hold off;
  imshow(mat2); title('Float image class');
  hold on
  hold off;


enter image description here

The output image is not as expected. I point the compared pixel by a red circle, however, the area around those circles should have the same color... why this happened?

The original images -> https://1drv.ms/f/s!Al4zZ4gTzuGXhOtUnqo7Oiui1HMpSg

  • 2
    $\begingroup$ it's not clear what you want to do and exactly what is your problem. what are your original images? why do you want to cluster them? what should the red dot denote? what is your expected result? can you provide us the original images? $\endgroup$ Jan 5, 2017 at 6:34
  • $\begingroup$ I want to cluster these images to find a correlation between multimodal images before registration. the red circle donates the same area between those images (i.e tumor). the expected result is same tumor color because the k-mean value cluster is same but you can see the color is diff ... why?! $\endgroup$ Jan 5, 2017 at 7:21
  • $\begingroup$ So, it is more a visualization than the clustering problem. Unfortunately, I cant run the code to see what's wrong, because wtih the supplied original images, my kmeans-clustering does not converge to 4 clusters. How do you create the fix and float variables? $\endgroup$ Jan 5, 2017 at 7:50
  • $\begingroup$ Acctuly the original images is so big but I add to the same place - please check it again. for this code I use slice #165 for both images. also, I upload my full code I hope this will help. Thanks for your collaboration. $\endgroup$ Jan 5, 2017 at 8:06
  • $\begingroup$ still with the code, it wont give me the output you show here. Most of the time, the clustering fails, since the images are not multi-modal. I suppose the problem with your visualization might be different min/max of mat1 and mat2, such that MAtlab scales the colors differently. $\endgroup$ Jan 5, 2017 at 8:21

1 Answer 1


Frankly speaking I did not quite understand your question, but let me write my comments to this kind of problems. This is the signal processing forum not only MatLab, so I will not discuss the code. All calculations I did in Mathematica.

First of all you cluster pixel intensity, meaning that you clustering 1D array and spatial correlation don't make sense and it is better to deal with the image histogram.

First let me plot your image histogram.

Image histogram

As you can see the left spike corresponds to the background. It is not a big problem, but it's better to eliminate the background from the clustering problem.

Using various filters I create the mask for your image,

enter image description here

and check that the mask is correct.

enter image description here

Let's plot the image histogram without the background (please note, I plot the smoothed histogram).

enter image description here

Now you can start clustering of your histogram. If you know a priory the number of clusters, you can do Kmean clustering, for example. Kmean simply finds the local minimum of the variation of your data from clusters. You may have many local minimums and you have to vary initial conditions to find the global one.

Let me give you a simple example.

Let's consider a mixture of 4 Gaussian distributions

enter image description here

where mean values are {10, 15, 25, 35}, standard deviations are {1, 1, 1, 1} and amplitudes {1/4, 1/4, 1/4, 1/4}. You can write the problem of clustering of the mixture on two cluster as minimization problem of function of two variables (because you know the distribution analytically). You can plot this function

enter image description here

where the x-variable corresponds to the boundary between the first and the second classes, and y-variable between the second and the third classes.

As you can see on the plot, there are two minimums, where the top-right minimum is the global one. Let's plot these minimums on the mixture PDF

enter image description here

where red lines show the global minimum and green lines the local one. Even for such a simple problem Kmean may converge to the local solution, and you should do the best to be sure that the method converges the global one.

If you have 1D data, finding the global minimum can be done by a simple brute-force. You can split the histogram on all possible classes, calculate the variation and find the global solution. I took your histogram and brute-force it to separate on three classes. Please, find the result below

enter image description here

where the best combination is

{{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}}

and the histogram is

intensity={0., 0.0204082, 0.0408163, 0.0612245, 0.0816327, 0.102041, 0.122449, 0.142857, 0.163265, 0.183673, 0.204082, 0.22449, 0.244898, 0.265306, 0.285714, 0.306122, 0.326531, 0.346939, 0.367347, 0.387755, 0.408163, 0.428571, 0.44898, 0.469388, 0.489796, 0.510204, 0.530612, 0.55102, 0.571429, 0.591837, 0.612245, 0.632653, 0.653061, 0.673469, 0.693878, 0.714286, 0.734694, 0.755102, 0.77551, 0.795918, 0.836735, 0.857143, 0.897959, 0.938776, 0.959184}

bins={0.00766421, 0.0344291, 0.0280162, 0.0230938, 0.0201404, 0.0210605, 0.0252008, 0.0263049, 0.0271238, 0.0306568, 0.0330398, 0.0265901, 0.0287339, 0.0391123, 0.0618841, 0.0936635, 0.091078, 0.0935254, 0.120474, 0.0829354, 0.0292859, 0.0114089, 0.00848308, 0.00669813, 0.00557564, 0.0050144, 0.00423234, 0.00348708, 0.00262221, 0.00204256, 0.00185855, 0.0012237, 0.000901672, 0.000726858, 0.000634851, 0.000414033, 0.000266821, 0.000184015, 0.0000736059, 0.0000828066, 9.20073*10^-6, 9.20073*10^-6, 9.20073*10^-6, 9.20073*10^-6, 0.0000184015}

If you don't know the number of classes, you may use clustering which can detect it (DBSCAN, Mean shift, Hierarchical clustering, variational Gaussian mixture algorithm, spectral clustering algorithm just to mention a few). For your data the best looking result gives variational Gaussian mixture algorithm, at lest it gives 3 clusters. Other method gives more than 10 clusters or less than two. Please find below result of clustering with the variational Gaussian mixture algorithm.

enter image description here

For my view, the result is still not good enough. If you histogram is the mixture of highly-overlapped distributions, this type of clustering may fail. In this scenario clustering of the histogram in scale-plane may help. I use idea from the paper, with my modifications. The basic of the idea tells that you take your histogram, convolve it with the Gaussian kernel increasing the scale parameter (the standard deviation) and track all local minimums of the histogram (local minimums of the function). Then, you may find that some minimums survive longer than others and survivors minimums are the clusters boundary. You can find the plot which shows the positions of minimums depending on the scale parameters in the convolution for your histogram

enter image description here

Then, using Kmean clustering, you can separate long lines from the short ones (you can find details in the paper). The separation gives

enter image description here

And finally it shows, that there are three minimums, where the right minimum looks like the boundary artifact. These minimums are the boundaries of your classes. Please, find the plot the boundaries

enter image description here

which looks reasonably good. Please note I slightly modified the method from the paper, if you need more details, just let me now.

  • 1
    $\begingroup$ First of all you cluster pixel intensity, meaning that you clustering 1D array and spatial correlation don't make sense and it is better to deal with the image histogram I refer to matlab documentation and found the k-mean use the intensity and position to cluster the image. $\endgroup$ Jan 7, 2017 at 4:40
  • $\begingroup$ Looks like he is using 1D intensity data. In his code it is written kmeans(double(fix(:)),4) $\endgroup$ Jan 7, 2017 at 4:44
  • $\begingroup$ after converting 2D array to vector the index still there and we can return it back using reshape. $\endgroup$ Jan 7, 2017 at 4:58
  • $\begingroup$ Thank you for your comment. It would be nice to clarify it with the author of the question. $\endgroup$ Jan 7, 2017 at 5:10
  • $\begingroup$ I am the author $\endgroup$ Jan 7, 2017 at 5:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.