如何从图像中获取前5种最常用的RGB颜色?

时间:2012-07-29 20:22:48

标签: c#

我需要一个方向来执行此操作。我正在迭代所有像素并通过GetPixel()方法获取值。接下来我该怎么办?

4 个答案:

答案 0 :(得分:5)

这是一个获取所有像素的辅助方法:

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

如果您只需要颜色(没有计数器):

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);
    }
}

顺便说一句,这里是使用计数器选择前5种最常用的颜色:

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);
    }
}

答案 1 :(得分:2)

Dictionary<Color, int>中汇总它们,您可以在其中保留每种颜色的计数。迭代完所有后,提取按值(计数)排序的前5位。

性能较差但更简单的解决方案是:

(from c in allColors
group c by c into g
order by g.Count() descending
select g.Key).Take(5)

答案 2 :(得分:1)

我不会为您编写代码,但会对您的需求进行一般性描述:

  1. 保存每种颜色及其出现次数的数据结构
  2. 对于每个像素,如果数据结构中存在颜色,请递增数字 2.a如果颜色不存在,请加上计数1
  3. 完成所有像素后,按计数对结构进行排序并获得前5名

答案 3 :(得分:0)

创建一个这样的字典:

Dictionary<Color, int> dictColors = new Dictionary<Color, int>();

然后在迭代每个像素时,执行此操作

Color color =GetPixel(x,y);
if(!dictColors.Contains(color) )
{
dictColors.Add(color,0);
}
else
{
dictColors[color]++;
}

then take first five:
 var top5 = dictColors.Take(5);