7

根据@ 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
distance = (diffr * diffr + diffg * diffg + diffb * diffb)
如果距离 < 阈值则匹配。


这种方法需要我计算我的搜索颜色和每个图像的颜色指纹之间的距离。我想知道是否有一种方法可以根据所选颜色(中心点)和预定阈值(或搜索半径)以某种方式指定“搜索区域”。然后构造一个类似 SQL 的查询来返回该区域内的所有图像。

这可能吗??

顺便说一句,我正在使用 PIL 和相关库在 Python 中实现这一点。

谢谢你的帮助!

SR

4

4 回答 4

4

色差 (Delta E) - 两种颜色之间的差异或距离是色彩科学中的一个重要指标。

你可以在这里Python找到代码

请注意,您需要在计算之前转换RGB为。LabDelta E

RGB -> XYZ -> 实验室

附加信息:

布鲁斯·贾斯汀·林德布鲁姆网站

颜色转换数学和公式

颜色增量/比较数学

于 2013-10-21T13:01:37.277 回答
3

您可以通过对每个组件进行比较而不是平方来查找距离来显着节省计算量。

if abs(check.r - search.r) < threshold and
   abs(check.g - search.g) < threshold and
   abs(check.b - search.b) < threshold 

将它与缓存表结合起来可能就足以满足您正在做的任何事情。

于 2009-06-01T18:49:42.627 回答
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

如果没有结果则遍历您的图像目录进行比较并将每个结果(正面或负面)存储在表中。

那么只有在没有缓存结果时才会变慢。如果您的 UI 鼓励用户选择某些有用的预设颜色,您可以预先计算这些颜色并提供更多帮助。

当您将图像添加到目录时,还可以预先计算所有先前执行的搜索的奖励积分。

于 2009-06-01T18:31:12.303 回答
0

我们可以将颜色视为三维空间中的一个点。现在每个图像将位于由其平均颜色定义的空间点。用户在 3-d 空间中选择一个点,而您想要找到最接近该点的图像。

这并不简单,但是比你或我更聪明的人已经做了很多工作(Don Knuth 称之为“邮局问题”)。像往常一样,一个好的起点是Wikipedia 。

于 2009-06-01T20:54:18.867 回答