Найти изображения аналогичного цвета - PullRequest
7 голосов
/ 01 июня 2009

Исходя из предложений здесь @ ТАК, я каталогизировал средний цвет для набора стоковых изображений.
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)
если расстояние <порог, то соответствует. </p>


Этот метод потребовал бы, чтобы я вычислил расстояние между моим цветом поиска и цветным отпечатком каждого изображения. Мне было интересно, есть ли способ как-то указать «область поиска» на основе выбранного цвета (центральная точка) и предварительно определенного порога (или радиуса поиска). Затем создайте SQL-подобный запрос, чтобы вернуть все изображения, попадающие в эту область.

Возможно ли это?

Кстати, я реализую это на Python, используя PIL и связанные библиотеки.

Спасибо за вашу помощь ТАК!

* +1025 * SR

Ответы [ 4 ]

4 голосов
/ 21 октября 2013

Разница в цвете (Delta E) - разница или расстояние между двумя цветами представляет интерес для науки о цвете.

Вы можете найти Python код здесь

Обратите внимание, что вам нужно преобразовать RGB в Lab до вычисления Delta E.

RGB -> XYZ -> Lab

Дополнительная информация:

Сайт Брюса Джастина Линдблума

Преобразование математики и формул

Цвет дельта / математика сравнения

3 голосов
/ 01 июня 2009

Вы можете значительно сэкономить на вычислениях, сравнивая каждый компонент, а не возводя в квадрат, чтобы найти расстояние.

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

Объединение этого с таблицами кеша, вероятно, будет достаточно для того, что вы делаете.

1 голос
/ 01 июня 2009

Если бы это был я, я бы стал менее любопытным и кэшировал бы поиски во вторичной таблице, например:

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

и если нет результатов для , которые , то проведите сравнение с вашим каталогом изображений и сохраните каждый результат, положительный или отрицательный, в таблице.

Тогда это будет медленным, только когда результаты не будут кэшированы. Если ваш пользовательский интерфейс побуждает пользователя выбирать определенные полезные предустановленные цвета, вы можете предварительно рассчитать их и помочь еще больше.

Также бонусные баллы за предварительный расчет всех ранее выполненных поисков при добавлении изображения в каталог.

0 голосов
/ 02 июня 2009

Мы можем рассматривать цвет как точку в трехмерном пространстве. Теперь каждое изображение будет в точке пространства, определенной его средним цветом. Пользователь выбирает точку в трехмерном пространстве, и вы хотите найти изображение, ближайшее к этой точке.

Это не просто, но много работы было проделано людьми, умнее вас или меня (Дон Кнут называет это «проблемой почтового отделения»). Хорошее место для начала - в Википедии , как обычно.

...