【问题标题】:Compare RGB colors so that color difference is more significant then intensity sum比较 RGB 颜色,使颜色差异比强度总和更显着
【发布时间】:2015-03-31 22:45:33
【问题描述】:

在图像分析过程中比较颜色时,您很快就会发现您可以只使用灰度图像。为什么?因为通常你会这样做:

double average = (color.r+color.g+color.b)/3;

基于grascale的平均颜色,我做了一个算法,在屏幕上找到对象时实际上是相当令人满意的(我使用了整个桌面,但是,这已经足够了):

按平均颜色搜索耗时 67 毫秒,而按精确像素匹配(蓝框)搜索耗时 1.255 ! (前者在找到第一个匹配后立即终止,而平均颜色算法循环整个图像)。

但我想提高 GUI 的精度。在 GUI 中,红色按钮看起来就像蓝色按钮,可能匹配错误。这就是我实现颜色敏感积分图像的原因。现在我发现我不知道如何正确比较颜色总和以获得一些真实色差。

假设您有 2 个包含 3 个元素的数组。

//Summed colors on the image you're looking for
double sumOnSearchedImage[3];
//Summed colors on currently checked rectangle (in some loop we'll not bother with here)
double sumOnBigImage[3];

数组中的每个数字分别代表红色、蓝色和绿色的总和(不是平均值)。您如何比较这些以使rgb(0, 255, 255)rgb(255,255,255) 之间的差异大于 rgb(170,170,170)rgb(255,255,255) 之间的差异?

【问题讨论】:

  • 鉴于颜色存在于 r、g 和 b 形成三个轴的 3 维空间中,您是否考虑过计算从一种颜色到另一种颜色的向量,然后比较向量的长度/方向而不是每个轴上差异的总和?
  • 我在想也许使用像小波这样的变换可能会大大提高速度和准确性,你为什么要使用简单的 rgb 格式?!
  • @AliAmiri 我是一个简单的学习者。您必须从 something 开始。

标签: java algorithm image-processing colors


【解决方案1】:

使用点积

dc=cos(ang)=dot(col1,col2);
dc=r1*r2+g1*g2+b1*b2

对于标准化的 RGB 颜色(单位向量),这为您提供dc=<0,1> 范围内的系数,其中0 表示颜色之间的 90 度角(最大可能差异),1 表示相同颜色(不是强度)

性能

每个通道使用 8 位 ... 所以范围是 <0,255> 以避免 FPU 使用。您可以通过以下方式避免 sqrt 用于非标准化颜色:

dc=(r1*r2+g1*g2+b1*b2)^2/(|col1|^2*|col2|^2)
|col|^2=r*r+g*g+b*b

[edit1] 附加信息

标准化颜色是单位 3D 向量

如果您将其转换为 8 位范围,如 255*(r,g,b),那么您将获得每个通道范围 8 位,因此您可以将每个颜色通道作为整数或定点小数处理。对于定点,你只需要改变乘法和除法,其余的操作都是一样的:

add=a+b
sub=a-b
mul=(a*b)>>8
div=((a<<8)/b)>>8

当您使用标准化颜色时,则使用|col|=1,因此您不需要sqrt 也不需要除法。对于定点,只需右移 8 位...对于整数 &lt;0,255&gt; |col|=255,这也可以通过 ~ 右移 8 位来完成。对于非标准化颜色,您需要除以|col|,这需要sqrt 和除法,但dc 系数在&lt;0,1&gt; 范围内,因此如果您使用dc^2,您只需更改系数的线性度,这对您来说并不重要对于|col|^2sqrt 的用法已过时,因为|col|^2=sqrt(r*r+g*g+b*b)^2=(r*r+g*g+b*b)

为了提高速度,您应该在执行任务之前将整个图像转换为标准化颜色。如果编码正确,对于常见的桌面分辨率,它应该在 10+ ms 左右

[备注]

还有其他更适合您的色彩空间,例如 HSV

【讨论】:

  • 感谢您的回答!您能否详细解释一下您的性能说明,特别是第一个?
【解决方案2】:

在度量空间中,rgb(0,255,255) 和 rgb(255,255,255) 之间的距离已经远远大于 rgb(170,170,170) 和 rgb(255,255,255) 之间的距离。

为了速度,不要使用距离本身,而是使用它们的平方。

|(0, 255, 255), (255,255,255)|^2 = 255^2 = 9*85^2
|(170,170,170), (255,255,255)|^2 = 3*85^2

顺便说一句,不要惊讶地发现灰度视觉就足够了。好的设计使设计师能够使事物 a) 清晰可见 b) 至少以某种方式对大约 18% 的人可见,因为只有这么多人在看颜色方面存在问题。 http://www.colour-blindness.com/general/prevalence/

【讨论】:

  • 所以基本上我所做的就是将我的结果平方(最初是abs(color1-color2))?
  • 是的。只需将其乘以自己。计算距离非常昂贵。但是比较它们很便宜,因为你不需要使用 sqrt()。
  • 好的。有趣的是,我也在考虑同样的方法——但从未意识到它是在比较距离。你知道,当我需要对结果进行非线性分析时,我使用sqrt(较小的结果更显着)或^2(更大的结果更显着)。但在这种情况下,我害怕在计算中抛出一些随机函数。感谢您解释这一点。
猜你喜欢
  • 2018-01-20
  • 2016-03-31
  • 2011-04-27
  • 2011-10-19
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 2013-09-23
  • 2011-02-23
相关资源
最近更新 更多