根据@ SO的建议,我已经编制了一组库存图像的平均颜色 r,g,b = image.convert(“RGB”)。resize((1,1),Image.ANTIALIAS).getpixel((0,0))
现在,我想向用户展示一个色轮,并对我的目录进行搜索,以找到与所选颜色最匹配的图像。
我已经阅读了这里发布的几个问题,建议“找到两种颜色之间的距离”,并参考Flickr Hacks一书。
Flickr Hack距离算法似乎基本上是:
diffr = checkImage.r - search_r
diffg = checkImage.g - search_g
diffb = checkImage.b - search_b
距离=(diffr * diffr + diffg * diffg + diffb * diffb)
如果距离<阈值然后匹配。
此方法需要我计算搜索颜色与每个图像的颜色指纹之间的距离。我想知道是否有办法以某种方式根据所选颜色(中心点)和预定阈值(或搜索半径)指定“搜索区域”。然后构造一个类似SQL的查询,以返回属于该区域的所有图像。
这可能吗?
BTW,我正在使用PIL和相关库在Python中实现它。
感谢您的帮助SO!
SR
答案 0 :(得分:4)
Color difference (Delta E) - 两种颜色之间的差异或距离是颜色科学中感兴趣的指标。
您可以找到Python
代码here
请注意,在计算RGB
之前,您需要将Lab
转换为Delta E
。
其他信息:
答案 1 :(得分:3)
通过对每个组件进行比较而不是平方来查找距离,可以显着节省计算量。
if abs(check.r - search.r) < threshold and
abs(check.g - search.g) < threshold and
abs(check.b - search.b) < threshold
将此与缓存表相结合可能足以满足您的需求。
答案 2 :(得分:1)
如果是我,我会更喜欢并将搜索缓存在辅助表格中,例如:
CREATE TABLE `image_search` (
`id` int not null auto_increment,
`image_id` int not null,
`r` tinyint not null,
`g` tinyint not null,
`b` tinyint not null,
`distance` tinyint not null,
`hit` bool not null,
PRIMARY KEY (`id`),
UNIQUE KEY `image_id_by_rgb_by_distance` (`image_id`,`r`,`g`,`b`,`distance`),
KEY `image_id_by_rgb_by_distance_by_hit` (`image_id`,`r`,`g`,`b`,`distance`,`hit`),
);
从中拉出来找到你的比赛,比如
SELECT `image_id`
FROM `image_search`
WHERE `r` = $r
AND `g` = $g
AND `b` = $b
AND `distance` = $distance
AND `hit` = 1
如果没有结果,请执行
SELECT `image_id`
FROM `image_search`
WHERE `r` = $r
AND `g` = $g
AND `b` = $b
AND `distance` = $distance
如果 没有结果,则运行图像目录进行比较,并将每个结果(正面或负面)存储在表格中。
然后,当它没有缓存结果时,它只会很慢。如果您的用户界面鼓励用户选择某些有用的预设颜色,您可以对其进行预先计算并提供更多帮助。
当您将图像添加到目录中时,预先计算所有先前执行的搜索的奖励积分。
答案 3 :(得分:0)
我们可以将颜色看作三维空间中的一个点。现在每个图像将位于由其平均颜色定义的空间中的点。用户正在三维空间中选择一个点,并且您希望找到最接近该点的图像。
这并不简单,但是比你或我更聪明的人做了很多工作(Don Knuth称之为'邮局问题')。像往常一样,一个好的起点是at Wikipedia。