 <p>The reason why you are getting different results is the fact that your colour segmentation algorithm uses <a href="http://en.wikipedia.org/wiki/K-means_clustering" rel="nofollow"><em>k</em>-means clustering</a>. I'm going to assume you don't know what this is as someone familiar in how it works would instantly tell you that this is why you're getting different results every time. In fact, the different results you are getting after you run this code each time are a natural consequence to <em>k</em>-means clustering, and I'll explain why. </p> <p>How it works is that for some data that you have, you want to group them into <em>k</em> groups. You initially choose <em>k</em> random points in your data, and these will have labels from <code>1,2,...,k</code>. These are what we call the <strong>centroids</strong>. Then, you determine how close the rest of the data are to each of these points. You then group those points so that whichever points are closest to any of these <em>k</em> points, you assign those points to belong to that particular group (<code>1,2,...,k</code>). After, for all of the points for each group, you update the <strong>centroids</strong>, which actually is defined as the representative point for each group. For each group, you compute the average of all of the points in each of the <em>k</em> groups. These become the <strong>new</strong> centroids for the next iteration. In the next iteration, you determine how close each point in your data is to <strong>each of the centroids</strong>. You keep iterating and repeating this behaviour until the centroids don't move anymore, or they move very little.</p> <p>How this applies to the above code is that you are taking the image and you want to represent the image using only <em>k</em> possible colours. Each of these possible colours would thus be a centroid. Once you find which cluster each pixel belongs to, you would replace the pixel's colour with the centroid of the cluster that pixel belongs to. Therefore, for each colour pixel in your image, you want to decide which out of the <em>k</em> possible colours this pixel would be best represented with. The reason why this is a colour segmentation is because you are <strong>segmenting</strong> the image to belong to only <em>k</em> possible colours. This, in a more general sense, is what is called <strong>unsupervised segmentation</strong>.</p> <p>Now, back to <em>k</em>-means. How you choose the initial centroids is the reason why you are getting different results. You are calling <em>k</em>-means in the default way, which automatically determines which initial points the algorithm will choose from. Because of this, you are <strong>not guaranteed</strong> to generate the same initial points each time you call the algorithm. If you want to <strong>repeat</strong> the same segmentation no matter how many times you call <code>kmeans</code>, you will need to <strong>specify the initial points yourself</strong>. As such, you would need to modify the <em>k</em>-means call so that it looks like this:</p> <pre><code>[cluster_idx, cluster_center] = kmeans(ab,nColors,'distance','sqEuclidean', ... 'Replicates', 3, 'start', seeds); </code></pre> <p>Note that the call is the same, but we have added two additional parameters to the <em>k</em>-means call. The flag <code>start</code> means that you are specifying the initial points, and <code>seeds</code> is a <code>k x p</code> array where <em>k</em> is how many groups you want. In this case, this is the same as <code>nColors</code>, which is 3. <code>p</code> is the dimension of your data. Because of the way you are transforming and reshaping your data, this is going to be 2. As such, you are ultimately specifying a <code>3 x 2</code> matrix. However, you have a <code>Replicate</code> flag there. This means that the <em>k</em>-means algorithm will run a certain number of times specified by you, and it will output the segmentation that has the least amount of error. As such, we will repeat the <code>kmeans</code> calls for as many times as specified with this flag. The above structure of <code>seeds</code> will no longer be <code>k x p</code> but <code>k x p x n</code>, where <code>n</code> is the number of times you want to run the segmentation. This is now a 3D matrix, where each 2D slice determines the initial points for each run of the algorithm. Keep this in mind for later.</p> <p>How you choose these points is up to you. However, if you want to randomly choose these and not leave it up to you, but want to reproduce the same results every time you call this function, you should set the <a href="http://www.mathworks.com/help/matlab/ref/rng.html" rel="nofollow">random seed generator</a> to be a known number, like <code>123</code>. That way, when you generate random points, it will always generate the same sequence of points, and is thus reproducible. Therefore, I would add this to your code before calling <code>kmeans</code>.</p> <pre><code>rng(123); %// Set seed for reproducibility numReplicates = 3; ind = randperm(size(ab,1), numReplicates*nColors); %// Randomly choose nColors colours from data %// We are also repeating the experiment numReplicates times %// Make a 3D matrix where each slice denotes the initial centres for each iteration seeds = permute(reshape(ab(ind,:).', [2 nColors numReplicates]), [2 1 3]); %// Now call kmeans [cluster_idx, cluster_center] = kmeans(ab,nColors,'distance','sqEuclidean', ... 'Replicates', numReplicates, 'start', seeds); </code></pre> <p>Bear in mind that you specified the <code>Replicates</code> flag, and we want to repeat this algorithm a certain number of times. This is <code>3</code>. Therefore, what we need to do is specify initial points for <strong>each run of the algorithm</strong>. Because we are going to have 3 clusters of points, and we are going to run this algorithm 3 times, we need 9 initial points (or <code>nColors * numReplicates</code>) in total. Each set of initial points has to be a <strong>slice</strong> in a 3D array, which is why you see that complicated statement just before the <code>kmeans</code> call.</p> <p>I made the number of replicates as a variable so that you can change this and to your heart's content and it'll still work. The complicated statement with <a href="http://www.mathworks.com/help/matlab/ref/permute.html" rel="nofollow"><code>permute</code></a> and <a href="http://www.mathworks.com/help/matlab/ref/reshape.html" rel="nofollow"><code>reshape</code></a> allows us to create this 3D matrix of points very easily.</p> <p>Bear in mind that the call to <a href="http://www.mathworks.com/help/matlab/ref/randperm.html" rel="nofollow"><code>randperm</code></a> in MATLAB only accepted the second parameter as of recently. If the above call to <code>randperm</code> doesn't work, do this instead:</p> <pre><code>rng(123); %// Set seed for reproducibility numReplicates = 3; ind = randperm(size(ab,1)); %// Randomly choose nColors colours from data ind = ind(1:numReplicates*nColors); %// We are also repeating the experiment numReplicates times %// Make a 3D matrix where each slice denotes the initial centres for each iteration seeds = permute(reshape(ab(ind,:).', [2 nColors numReplicates]), [2 1 3]); %// Now call kmeans [cluster_idx, cluster_center] = kmeans(ab,nColors,'distance','sqEuclidean', ... 'Replicates', numReplicates, 'start', seeds); </code></pre> <hr> <p>Now with the above code, you should be able to generate the same colour segmentation results every time.</p> <p>Good luck!</p>