A efficient way of getting the percentage of each color in kmeans clustering example

101 views
Skip to first unread message

jfcote....@gmail.com

unread,
Mar 5, 2013, 9:55:57 AM3/5/13
to accor...@googlegroups.com
Hi!

I'm using the code from the kmeans example about clustering the color in a picture. In my case, I always create 3 clusters.

After it's done, I would like to know 2 things
1) Color (In BGR or RGB format)
2) Percentage (or at least, how many pixel have this color in the final picture)

Since I always have 3 colors, I need this information 3 times.

I have coded something but it's taking a lot of time to perform because I need to go through the double array of all color, increment count, etc...

Is there anything in the Accord.NET framework that could help me with this? Basically, a function that count the number of time a specific color is there?

Thanks!

César

unread,
Mar 5, 2013, 4:46:46 PM3/5/13
to accor...@googlegroups.com
Hi there!

Hmmm... Can I ask how you are currently computing the counts? Iterating the image and counting is actually supposed to be quite fast!

By the way, you can also use AForge's ImageStatistics to compute the color histogram for an image. The color histogram is exactly this; the number of times a color occurs within an image. Hope it can be useful to you!

Best regards,
Cesar

jfcote....@gmail.com

unread,
Mar 6, 2013, 8:40:53 AM3/6/13
to accor...@googlegroups.com
Hi Cesar,

I've checked for the histogram but the problem is that it create an histogram for each channel. What I want to know is the complete color (3 channels).

Another question related to that. I'm comparing your kmeans to the kmeans in opencv. In openCV, I always get the same result at the end. But with your kmeans, even with the same parameter, the 3 colors can be quite different between 2 calls at the end. Is there a way to always get the same result or is it that the algorithm itself is not deterministic?

Ok, let's go back to the way I get the 3 colors at the end. This code go at the end, after the "ApplyInPlace" call:

for (int i = 0; i < pixels.Count(); i++)
{
Bgr couleur = new Bgr(pixels[i][2], pixels[i][1], pixels[i][0]);

int nCount = (from c in _listCouleur
where c.Color.Blue == couleur.Blue &&
c.Color.Green == couleur.Green &&
c.Color.Red == couleur.Red
select c.Color).Count();

if (nCount == 0)
_listCouleur.Add(new ColorPercentage(couleur, 1));
else
{
//Si ça existe déja, on update son nombre de fois
ColorPercentage couleurP = (from c in _listCouleur
where c.Color.Blue == couleur.Blue &&
c.Color.Green == couleur.Green &&
c.Color.Red == couleur.Red
select c).First();
couleurP.Percentage++;
}
}

foreach (ColorPercentage p in _listCouleur)
{
p.Percentage = (p.Percentage / (_image.Rows * _image.Cols)) * 100;
}

_listCouleur = _listCouleur.OrderByDescending(p => p.Percentage).ToList();


César

unread,
Mar 6, 2013, 4:33:12 PM3/6/13
to accor...@googlegroups.com
Hi there!

Hmm but do you mean you would like to count the number of times a specific color (RGB) occurs within the image, after you have performed the k-means? It is, you would like to know how many times one of the key colors detected by kmeans had been substituted in the image after the ApplyInPlace?

If that is the case, you can use the Proportions property of the KMeansCluster class. For example, if your KMeans object is named kmeans, you can use KMeans.Clusters[colorIndex].Proportion to get the proportion of pixels replaced by the clusterIndex cluster color. Just multiply this value by the number of pixels and you can get the total number of pixels you asked (it is, if I understood your question correctly!)

Regarding the different values, the algorithm is really non-deterministic. You can try to get slight more stable results if you pass true to the useSeeding parameter in the Randomize method before you compute the model. 

Hope it helps!

Best regards,
Cesar

jfcote....@gmail.com

unread,
Mar 8, 2013, 8:38:09 AM3/8/13
to accor...@googlegroups.com
Wow! Worked like a charm!!!

Thank you so much!

Reply all
Reply to author
Forward
0 new messages