如何按颜色范围选择
本文关键字:选择 范围 颜色 何按 | 更新日期: 2023-09-27 18:35:58
在我的应用程序中,我加载了一张图片,我希望能够检测到相似的颜色。因此,如果我选择一种颜色,我希望应用程序能够找到具有相同(或几乎相同)颜色的所有像素。这是我为一个检测系统编写的,该系统在鼠标单击点和位图末尾之间沿垂直方向查看。
for (int y = mouseY; y < m_bitmap.Height; y++)
{
Color pixel = m_bitmap.GetPixel(mouseX, y);
//check if there is another color
if ((pixel.R > curcolor.R + treshold || pixel.R < curcolor.R - treshold) ||
(pixel.G > curcolor.G + treshold || pixel.G < curcolor.G - treshold) ||
(pixel.B > curcolor.B + treshold || pixel.B < curcolor.B - treshold))
{ //YESSSSS!
if ((y - ytop > minheight)&&(curcolor != Color.White)) //no white, at least 15px height
{
colorlayers.Add(new ColorLayer(curcolor, y - 1, ytop));
}
curcolor = pixel;
ytop = y;
}
}
这是最好的方法吗?不知何故,它看起来对淡黄色不太好。
RGB 是一个 3D 空间。
一个颜色在各个方向上都远在阈值上与原来的颜色不太相似(根据数字相似的东西可能与人类的眼睛不太相似)。
我会使用 HSL(例如)进行检查,其中色调值作为有限的 1D 范围,例如:
for (int y = mouseY; y < m_bitmap.Height; y++)
{
Color pixel = m_bitmap.GetPixel(mouseX, y);
if (Math.Abs(color.GetHue() - curcolor.GetHue()) <= threshold)
{
// ...
}
}
此外,请注意,以这种方式使用位图(GetPixel()
非常慢,看看这篇文章,看看一个 - 更快的替代方案)。
看看 Paint.NET 中的魔杖工具是如何工作的可能会很有趣。
这是他们比较 2 种颜色的方式:
private static bool CheckColor(ColorBgra a, ColorBgra b, int tolerance)
{
int sum = 0;
int diff;
diff = a.R - b.R;
sum += (1 + diff * diff) * a.A / 256;
diff = a.G - b.G;
sum += (1 + diff * diff) * a.A / 256;
diff = a.B - b.B;
sum += (1 + diff * diff) * a.A / 256;
diff = a.A - b.A;
sum += diff * diff;
return (sum <= tolerance * tolerance * 4);
}
源
黄色带来问题的原因可能是RGB不是一个感知均匀的色彩空间。这意味着,给定色彩空间中两点/颜色之间的距离,对该颜色距离/差异的感知通常不会相同。
也就是说,您可能希望使用另一个颜色空间,例如 Adriano 建议的 HSL,或者可能是 Lab。
如果你想坚持RGB,我建议计算欧几里得距离,像这样(我认为更简单):
float distance = Math.sqrt((pixel.R-curcolor.R)^2 + (pixel.G-curcolor.G)^2 + (pixel.B-curcolor.B)^2);
if(distance < threshold)
{
// Do what you have to.
}