在任何丰富的图像中,您的大多数颜色都可能在某种程度上是独一无二的。随之而来的是,获取不同的颜色可能无法帮助您实现目标。
我建议检查图像中每个像素的 HSV 值。我将为您提供无数在线示例,这些示例将图像检索为 HSV 值数组。
使用您的 HSV 值,您可以通过创建一个包含 256 个色调计数的整数数组来计算突出色调的集群,计算图像数据中的色调直方图。您可以通过查找具有高计数和的 4-6 个连续色调的集群来确定突出的色调。
在挑选了几个突出的色调之后,将这些色调的像素细分为另一个测量饱和度的直方图,并挑选出突出的集群,等等。
粗略的例子
下面的代码尝试帮助识别突出的色调。很可能还有其他很棒的方法可以做到这一点;但是,这可能会提供一些想法。
首先,我将所有图像颜色作为对象数组获取Color
,如下所示:
private static Color[] GetImageData(Image image)
{
using (var b = new Bitmap(image))
{
var bd = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
byte[] arr = new byte[bd.Width * bd.Height * 3];
Color[] colors = new Color[bd.Width * bd.Height];
Marshal.Copy(bd.Scan0, arr, 0, arr.Length);
b.UnlockBits(bd);
for (int i = 0; i < colors.Length; i++)
{
var start = i*3;
colors[i] = Color.FromArgb(arr[start], arr[start + 1], arr[start + 2]);
}
return colors;
}
}
您可能会考虑验证我在Color.FromArgb
方法调用中以正确的顺序获得了 RGB 的顺序。
接下来,我隐藏了一个用于转换为 HSV 的实用方法。在我的示例中,我将只使用色调,但这里有一个完整的转换示例:
private static void ColorToHSV(Color color, out int hue, out int saturation, out int value)
{
int max = Math.Max(color.R, Math.Max(color.G, color.B));
int min = Math.Min(color.R, Math.Min(color.G, color.B));
hue = (int)(color.GetHue() * 256f / 360f);
saturation = (max == 0) ? 0 : (int)(1d - (1d * min / max));
value = (int)(max / 255d);
}
最后,我构建了色调直方图,定义了一个色调宽度(比如 9 种色调),在其中将计数聚合在一起,然后将计数报告给控制台。
private static void ProcessImage(Color[] imagecolors)
{
var hues = new int[256];
var hueclusters = new int[256];
int hue, saturation, value;
// build hue histogram.
foreach (var color in imagecolors) {
ColorToHSV(color, out hue, out saturation, out value);
hues[hue]++;
}
// calculate counts for clusters of colors.
for (int i = 0; i < 256; i++) {
int huecluster = 0;
for (int count = 0, j = i; count < 9; count++, j++) {
huecluster += hues[j % 256];
}
hueclusters[(i + 5) % 256] = huecluster;
}
// Print clusters on the console
for (int i = 0; i < 256; i++) {
Console.WriteLine("Hue {0}, Score {1}.", i, hueclusters[i]);
}
}
我没有尝试过滤到要选择的色调。您可能需要考虑一些启发式方法,而不是盲目地选择如此多的计数,因为您可能想要选择在色谱上有些分离的色调。我没有时间进一步探讨这个问题,但我希望这能提供一些关于你可以考虑的策略的见解。