![]() |
|
||||||||||
|
|||||
|
Привет, ребята
![]() Вот в чем суть проблемы: есть папка A, в которой имеется порядка 10 000 изображений такого вида: и есть папка B, в которой имеется порядка 100 изображений такого вида: И задача состоит в том, что нужно среди изображений из папки A найти совпадающие с изображениями из папки B. Также известно следующее: 1) Водяной знак присутствует только на картинках из папки B, располагается в центре изображения и имеет фиксированные размеры. 2) Если картинки совпадают, как на примере выше, то они точно имеют одинаковые размеры и отличаются, по сути, только наличием водяного знака. 3) Картинки из папки A могут иметь различные размеры. 4) Фон картинки необязательно белый и может быть сколь угодно пестрым. 5) И самое коварное – неизвестно, есть ли в папке A изображение совпадающее с изображением из папки B. Я попробовал решить задачу в лоб: 1) Берем очередную картинку из папки B и последовательно сравниваем ее со всеми картинками из папки A. 2) Если их размеры не совпадают, то переходим к следующей картинке из папки A. 3) Если размеры совпадают начинаем сравнивать их попиксельно. И если (кол-во совпавших пикселей / полное кол-во пикселей) > 0.8, то считаем изображения совпадающими. if (WMBitmapData.width == picBitmapData.width && WMBitmapData.height == picBitmapData.height) { var coinCount:int = 0; var w:int = WMBitmapData.width; var h:int = WMBitmapData.height; for (var a:int = 0; a < w; ++a) for (var b:int = 0; b < h; ++b) { if (WMBitmapData.getPixel32(a, b) == picBitmapData.getPixel32(a, b)) ++coinCount; } if (Number(coinCount) / Number(w * h) > 0.8) { // Фиксируем совпадение ... } } Проблема в том, что иногда алгоритм ошибается, неверно определяя совпадение картинок. Думаю здесь дело в большом количестве белого фона, что гарантирует превышение лимита совпадения в 0.8. Но дело в том, что я не представляю как подобрать нужную константу вместо 0.8, потому что картинка может быть и меньших размеров (приведенные выше были 500x500), и тогда водяной знак будет занимать значительную площадь изображения. Подскажите, как быть? P.S. Также вместо getPixel32 я использовал BitmapData.compare, но это не суть, так как относится уже к реализации. |
|
|||||
|
Попытаться перед сравнением вырезать водяной знак из картинки оригинала (где его нет) и картинки теста (где он есть) и потом уже сравнивать, если на оригинальной картинке фон четко белый, а на тестируемой пестрый, то из белого фона оригинальной картинки можно сделать маску и наложить на пестрый фон исследуемой картинки и таким образом он из пестрого тоже станет белым.
__________________
Гоночка |
|
|||||
|
блогер
Регистрация: Feb 2008
Адрес: Россия, Новосибирск, Академгородок
Сообщений: 2,113
Записей в блоге: 1
|
"Накладываем" попарно картинки друг на друга с каким-то блендмодом (точно не могу сказать, каким именно), смотрим область "разности" изображений. Если она очень близка к области вотермарка — считаем, это эти изображения идентичны. Я бы попробовал бы сначала так.
__________________
hauts.ru |
|
|||||
|
буду краток
модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
|
Есть метод BitmapData#compare
Потом получаем прямоугольник через getColorBoundsRect и смотрим его размер - если он близок к размеру ватермарка - значит изображения идентичные. Правда это не сработает если идентичные картинки имеют разные размеры (правда какие же тогда они идентичные?)
__________________
Отряд Котовскага |
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Цитата:
Добавлено через 8 минут Есть только нюанс, что если картинки в jpeg, при сохранении после наложения ватермарка некоторые пиксели могут не соответствовать исходным (артефакты оптимизации). Поэтому коэфициент соответствия все же не будет 100%, надо подбирать.
__________________
Reality.getBounds(this); |
|
|||||
|
Alex Lexcuk, вы немного неправильно поняли про пестрый фон. Совпадающие картинки не будут отличаться фоном. То есть и вы и Wolsh предложили одну и ту же схему – удаление либо вставка ватермарки, т.е. попытка сведения изображений к абсолютно идентичным. А caseyryan, Hauts и Котяра предлагают несколько иной подход (хотя в общем-то тоже сравнение, но встроенными функциями). Хотя оба подхода можно объединить
![]() Спасибо всем большое вывели из тупика, пойду экспериментировать. Позже отпишусь о результатах. (да, про getColorBoundsRect я не знал) |
|
|||||
|
Регистрация: Aug 2012
Сообщений: 297
|
Может быть придумать "похожесть"? Например, если картинка похожа на 90%, то с ней и работаем.
|
|
|||||
|
Регистрация: Aug 2012
Сообщений: 297
|
Программным образом нарисовать контуры мольбертов. Рисование будет происходить таким образом: чертим линию, допустим снизу, на коричневом цвете (если 1 пиксель коричневый, а 2 белый, то ищем в какой стороне есть коричневый). Сначала чертим эти линии на исходном, потом с ватермарком.
Потом полученные конторы помещаем в специальный объект (он уже там идёт по координате x=0 и y=0). Эти конторы сравниваем по признакам: если углы у линий похожи, то вероятность "похожести" повышается". Так как фон не обязательно белый, то изначально задать список характерных цветов на картинке. Можно так: когда удастся начертить контуры мольберта, тогда вырезаем этот мольберт и выделяем характерные цвета для мольберта. |
![]() |
![]() |
Часовой пояс GMT +4, время: 13:08. |
|
|
« Предыдущая тема | Следующая тема » |
| Теги |
| распознавание изображений |
|
|