Python - 查找相似颜色的最佳方法
我写了一个函数,可以在图片中找到某种颜色,并返回它的坐标 x 和 y。现在我需要添加一个新功能,让我可以根据给定的容差来找到颜色。这应该很简单吧?
下面是找到图片中颜色并返回 x 和 y 的代码:
def FindColorIn(r,g,b, xmin, xmax, ymin, ymax):
image = ImageGrab.grab()
for x in range(xmin, xmax):
for y in range(ymin,ymax):
px = image.getpixel((x, y))
if px[0] == r and px[1] == g and px[2] == b:
return x, y
def FindColor(r,g,b):
image = ImageGrab.grab()
size = image.size
pos = FindColorIn(r,g,b, 1, size[0], 1, size[1])
return pos
结果:
根据回答,比较两种颜色的常用方法是使用欧几里得距离或切比雪夫距离。
我决定主要使用(平方)欧几里得距离,并尝试多种不同的颜色空间,比如 LAB、deltaE(LCH)、XYZ、HSL 和 RGB。在我的代码中,大多数颜色空间使用平方欧几里得距离来计算颜色之间的差异。
例如,在 LAB、RGB 和 XYZ 中,简单的平方欧几里得距离就能解决问题:
if ((X-X1)^2 + (Y-Y1)^2 + (Z-Z1)^2) <= (Tol^2) then
...
LCH 和 HSL 稍微复杂一些,因为它们有圆柱形的色调,但通过一些数学运算可以解决这个问题,然后在这里也使用平方欧几里得距离。
在大多数情况下,我为每个通道添加了“单独的参数”来设置容差(使用一个全局容差,以及替代的“修正值” HueTol := Tolerance * hueMod
或 LightTol := Tolerance * LightMod
)。
看起来基于 XYZ 的颜色空间(如 LAB 和 LCH)在我的许多场景中表现最好。虽然 HSL 在某些情况下也能产生很好的结果,而且从 RGB 转换过来也更便宜,不过 RGB 也很不错,能满足我大部分的需求。
10 个回答
不要用这个:
if px[0] == r and px[1] == g and px[2] == b:
试试这个:
if max(map(lambda a,b: abs(a-b), px, (r,g,b))) < tolerance:
这里的 tolerance
是你能接受的颜色通道之间的最大差异。
它的做法是从你想要的颜色值中减去每个通道的值,然后取绝对值,最后找出这些绝对值中的最大值。
这里有一个经过优化的Python
版本,是根据Bruno的回答改编的:
def ColorDistance(rgb1,rgb2):
'''d = {} distance between two colors(3)'''
rm = 0.5*(rgb1[0]+rgb2[0])
d = sum((2+rm,4,3-rm)*(rgb1-rgb2)**2)**0.5
return d
用法:
>>> import numpy
>>> rgb1 = numpy.array([1,1,0])
>>> rgb2 = numpy.array([0,0,0])
>>> ColorDistance(rgb1,rgb2)
2.5495097567963922
计算RGB颜色之间的距离,让人眼能理解的方式,并不是简单地计算这两个RGB向量之间的欧几里得距离。
这里有一篇有趣的文章,讲得很详细:http://www.compuphase.com/cmetric.htm
下面是用C语言实现的一个例子:
typedef struct {
unsigned char r, g, b;
} RGB;
double ColourDistance(RGB e1, RGB e2)
{
long rmean = ( (long)e1.r + (long)e2.r ) / 2;
long r = (long)e1.r - (long)e2.r;
long g = (long)e1.g - (long)e2.g;
long b = (long)e1.b - (long)e2.b;
return sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8));
}
把这个例子转到Python应该不会太难。
补充:
另外,正如这个回答所建议的,你可以使用HLS和HSV。colorsys
模块似乎有一些函数可以将RGB转换。它的文档中也链接了这些页面,值得一读,以理解为什么RGB的欧几里得距离并不太适用:
- http://www.poynton.com/ColorFAQ.html
- http://www.cambridgeincolour.com/tutorials/color-space-conversion.htm
补充 2:
根据这个回答,这个库可能会很有用:http://code.google.com/p/python-colormath/