首页 文章

比较RGB颜色,使色差比强度和更重要

提问于
浏览
1

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

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

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

image description

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

但我想提高GUI的精度_1452566知道如何正确比较颜色总和以获得一些真正的色差 .

所以想象你有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) 之间的差异?

2 回答

  • 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/

  • 1

    use dot product

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

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

    performance

    每个通道使用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] additional info

    标准化颜色是单位 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位...对于整数 <0,255> |col|=255 也可以〜右移8位 . 对于非标准化颜色,您需要除以需要 sqrt 和除法的 |col| ,但 dc 系数在 <0,1> 范围内,所以如果您使用 dc^2 ,您只需更改对您不重要的系数的线性度 |col|^2 sqrt 用法已过时,因为 |col|^2=sqrt(r*r+g*g+b*b)^2=(r*r+g*g+b*b) .

    为了更好地加速,您应该在完成任务之前将整个图像转换为标准化颜色 . 如果编码正确,它应该在 10+ ms 左右,用于常见的桌面分辨率

    [Notes]

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

相关问题