Сравнение изображений с php + gd

Как лучше всего сравнивать два изображения с помощью php и библиотеки Graphic Draw (GD) Library??

Это сценарий:

альтернативный текст

У меня есть изображение, и я хочу найти, какое изображение из данного набора наиболее похоже на него. Наиболее похожее изображение - это фактически одно и то же изображение, но не с точным совпадением пикселей, а с тем же изображением. Я драматизировал разницу между двумя изображениями с помощью номера один в примере, чтобы облегчить понимание того, что я имел в виду.

Несмотря на то, что это не дало последовательных результатов, мой подход заключался в уменьшении изображений до 1 пикселя с помощью imagecopyresampled и посмотрите, насколько близки значения RGB между изображениями.

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

Вот пример вывода при сравнении 4 изображений с целевым изображением, в данном случае логотипом яблока, который соответствует одному из них, но не совсем то же самое:

Исходное изображение:

Красный: 222 Зеленый: 226 Синий: 232

По сравнению с:

http://a1.twimg.com/profile_images/571171388/logo-twitter_normal.png Красный: 183 Зеленый: 212 Синий: 212, индекс подобия 56

Красный: 117 Зеленый: 028 Синий: 028 и индекс несходства 530

Красный: 218 Зеленый: 221 Синий: 221 и индекс несходства 13 Соответствует правильно.

Красный: 061 Зеленый: 063 Синий: 063 и индекс несходство 491

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

Я открыт для других библиотек изображений, таких как iMagick, Gmagick или Cairo для php, но я бы предпочел избегать использования других языков, кроме php.

Заранее спасибо.


person johnnyArt    schedule 10.01.2010    source источник
comment
Итак, вы хотите использовать капчу?   -  person Tor Valamo    schedule 10.01.2010
comment
Не капча, изображения такие же, как я сказал, без поворота, без линий посередине, без размытости. Это часть большого проекта, который у меня есть, и я не могу эффективно его преодолеть.   -  person johnnyArt    schedule 10.01.2010
comment
Возможный дубликат Как обнаружить похожие изображения в PHP?   -  person DanMan    schedule 06.09.2017


Ответы (4)


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

Однако, если вы преобразовали каждое изображение в один и тот же размер, а затем вычислили средний цвет в каждой ячейке 16x16 (или 32x32, 64x64 и т. Д., В зависимости от того, сколько времени обработки / мощности вы хотите использовать), вы сможете сформировать какую-то толкового (-ого) сравнения.

person John Parker    schedule 10.01.2010
comment
Закончил использование моего кода, и, поскольку вы сказали, что это разумно, то, эй, вы получили принятый ответ - person johnnyArt; 11.01.2010
comment
Извините за то, что поднял старую ветку, но я точно в такой же ситуации. Благодаря ссылке imagecopyresampled я могу изменять размер изображений, но как точно вычислить средний цвет в каждом изображении 16x16? - person Marci-man; 07.09.2011
comment
@ Marci-man На самом базовом уровне вы можете использовать imagecolorat, чтобы получить значения RGB для пикселей в этой ячейке, а затем усреднить их, чтобы получить значение для ячейки в целом. - person John Parker; 07.09.2011

Я бы посоветовал, как и middaparka, не выполнять субдискретизацию до изображения размером только 1 пиксель, потому что вы теряете всю пространственную информацию. Понижение частоты дискретизации до 16x16 (или 32x32 и т. Д.), Безусловно, даст лучшие результаты.

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

person NeXuS    schedule 10.01.2010

Я использовал идеи масштабирования, понижающей дискретизации и уровня серого, упомянутые в вопросе и ответах, чтобы применить среднеквадратичную ошибку < / strong> между значениями каналов пикселей для 2 изображений, используя библиотеку GD.

код находится в этом ответе, включая тест с этими идеями.

Также я провел несколько сравнительного анализа и думаю, что даунсэмплинг может не понадобиться в этих маленьких изображениях, потому что метод работает быстро (будучи PHP), всего за долю секунды.

person Leopoldo Sanczyk    schedule 04.09.2020

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

person Bart van Heukelom    schedule 10.01.2010
comment
Чем здесь может помочь алгоритм Левенштейна? Цитирование Расстояние Левенштейна между двумя строками определяется минимальным количеством операций, необходимых для преобразования одной строки в другую, и, поскольку все последовательности будут образованы тремя двузначными числами, количество операций всегда будет равно 3. Если они не имеют одинаковые значения красного, зеленого или синего, что не обязательно означает, что это самый близкий цвет и, более того, самое похожее изображение. - person johnnyArt; 10.01.2010
comment
И в качестве бонуса в PHP уже есть функция levenshtein: php.net/manual/en/ function.levenshtein.php - person Marko; 10.01.2010