![]() |
Поиск совпадающих картинок
Вложений: 4
Привет, ребята :)
Вот в чем суть проблемы: есть папка A, в которой имеется порядка 10 000 изображений такого вида: Вложение 29208 Вложение 29209 и есть папка B, в которой имеется порядка 100 изображений такого вида: Вложение 29210 Вложение 29211 И задача состоит в том, что нужно среди изображений из папки A найти совпадающие с изображениями из папки B. Также известно следующее: 1) Водяной знак присутствует только на картинках из папки B, располагается в центре изображения и имеет фиксированные размеры. 2) Если картинки совпадают, как на примере выше, то они точно имеют одинаковые размеры и отличаются, по сути, только наличием водяного знака. 3) Картинки из папки A могут иметь различные размеры. 4) Фон картинки необязательно белый и может быть сколь угодно пестрым. 5) И самое коварное – неизвестно, есть ли в папке A изображение совпадающее с изображением из папки B. Я попробовал решить задачу в лоб: 1) Берем очередную картинку из папки B и последовательно сравниваем ее со всеми картинками из папки A. 2) Если их размеры не совпадают, то переходим к следующей картинке из папки A. 3) Если размеры совпадают начинаем сравнивать их попиксельно. И если (кол-во совпавших пикселей / полное кол-во пикселей) > 0.8, то считаем изображения совпадающими. Код AS3:
Проблема в том, что иногда алгоритм ошибается, неверно определяя совпадение картинок. Думаю здесь дело в большом количестве белого фона, что гарантирует превышение лимита совпадения в 0.8. Но дело в том, что я не представляю как подобрать нужную константу вместо 0.8, потому что картинка может быть и меньших размеров (приведенные выше были 500x500), и тогда водяной знак будет занимать значительную площадь изображения. Подскажите, как быть? P.S. Также вместо getPixel32 я использовал BitmapData.compare, но это не суть, так как относится уже к реализации. |
Я бы с blend mode поэксперементировал. Первое что пришло в голову.
|
Попытаться перед сравнением вырезать водяной знак из картинки оригинала (где его нет) и картинки теста (где он есть) и потом уже сравнивать, если на оригинальной картинке фон четко белый, а на тестируемой пестрый, то из белого фона оригинальной картинки можно сделать маску и наложить на пестрый фон исследуемой картинки и таким образом он из пестрого тоже станет белым.
|
"Накладываем" попарно картинки друг на друга с каким-то блендмодом (точно не могу сказать, каким именно), смотрим область "разности" изображений. Если она очень близка к области вотермарка — считаем, это эти изображения идентичны. Я бы попробовал бы сначала так.
|
Есть метод BitmapData#compare
Потом получаем прямоугольник через getColorBoundsRect и смотрим его размер - если он близок к размеру ватермарка - значит изображения идентичные. Правда это не сработает если идентичные картинки имеют разные размеры (правда какие же тогда они идентичные?) |
Цитата:
Добавлено через 8 минут Есть только нюанс, что если картинки в jpeg, при сохранении после наложения ватермарка некоторые пиксели могут не соответствовать исходным (артефакты оптимизации). Поэтому коэфициент соответствия все же не будет 100%, надо подбирать. |
Alex Lexcuk, вы немного неправильно поняли про пестрый фон. Совпадающие картинки не будут отличаться фоном. То есть и вы и Wolsh предложили одну и ту же схему – удаление либо вставка ватермарки, т.е. попытка сведения изображений к абсолютно идентичным. А caseyryan, Hauts и Котяра предлагают несколько иной подход (хотя в общем-то тоже сравнение, но встроенными функциями). Хотя оба подхода можно объединить :)
Спасибо всем большое :) вывели из тупика, пойду экспериментировать. Позже отпишусь о результатах. (да, про getColorBoundsRect я не знал) |
Может быть придумать "похожесть"? Например, если картинка похожа на 90%, то с ней и работаем.
|
Dip52, как бы про это и речь, как эту "похожесть" придумать.
|
Цитата:
Потом полученные конторы помещаем в специальный объект (он уже там идёт по координате x=0 и y=0). Эти конторы сравниваем по признакам: если углы у линий похожи, то вероятность "похожести" повышается". Так как фон не обязательно белый, то изначально задать список характерных цветов на картинке. Можно так: когда удастся начертить контуры мольберта, тогда вырезаем этот мольберт и выделяем характерные цвета для мольберта. |
| Часовой пояс GMT +4, время: 16:50. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.