Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the top 5 most used RGB colors from an image?

Tags:

c#

I need a direction to perform this. I am iterating through all the pixels and getting the value through GetPixel() method. What should I do next?

like image 730
fresky Avatar asked Jul 29 '12 20:07

fresky


2 Answers

Here is a helper method to get all pixels:

public static IEnumerable<Color> GetPixels(Bitmap bitmap)
{
    for (int x = 0; x < bitmap.Width; x++)
    {
        for (int y = 0; y < bitmap.Height; y++)
        {
            Color pixel = bitmap.GetPixel(x, y);
            yield return pixel;
        }
    }
}

If you just need the colors (without the counters):

using (var bitmap = new Bitmap(@"..."))
{
    var mostUsedColors =
        GetPixels(bitmap)
            .GroupBy(color => color)
            .OrderByDescending(grp => grp.Count())
            .Select(grp => grp.Key)
            .Take(5);
    foreach (var color in mostUsedColors)
    {
        Console.WriteLine("Color {0}", color);
    }
}

By the way, here is the selection of top 5 most used colors with the counters:

using (var bitmap = new Bitmap(@"..."))
{
    var colorsWithCount =
        GetPixels(bitmap)
            .GroupBy(color => color)
            .Select(grp =>
                new
                    {
                        Color = grp.Key,
                        Count = grp.Count()
                    })
            .OrderByDescending(x => x.Count)
            .Take(5);

    foreach (var colorWithCount in colorsWithCount)
    {
        Console.WriteLine("Color {0}, count: {1}",
            colorWithCount.Color, colorWithCount.Count);
    }
}
like image 117
Sergey Vyacheslavovich Brunov Avatar answered Sep 21 '22 10:09

Sergey Vyacheslavovich Brunov


Aggregate them in a Dictionary<Color, int> where you keep the count for each color. After you have iterated over all of them, extract the top 5 ordered by Value (count).

A less well performing but simpler solution is this:

(from c in allColors
group c by c into g
order by g.Count() descending
select g.Key).Take(5)
like image 43
usr Avatar answered Sep 24 '22 10:09

usr