Intereting Posts
Как отправить уведомление по электронной почте при посещении страницы? PHP-таблица обновлений в MySQL не работает запрос cURL, дающий мне 505 http code.Что делать? Как я могу перенаправить перенаправление JS? Apache показывает php-код вместо выполнения PHP GD Текст и специальные символы / кодирование? Doctrine manyToMany возвращает PersistentCollection вместо ArrayCollection неразрывное пространство utf-8 0xc2a0 и preg_replace странное поведение PHP sleep () не работает Заголовок PHP – Content-type: image / jpeg – Не работает в Internet Explorer Отображение сообщения, когда набор результатов пуст Нужна помощь с регулярным выражением, чтобы удалить квадратные скобки и что-нибудь между Есть ли способ отправить параметры в функцию обратного вызова, не создавая сначала мою собственную функцию? Zend_Cache: после загрузки кэшированных данных кодировка символов кажется испорченной PEAR Spreadsheet_Excel_Writer insertBitmap () работает неправильно

Найти похожие изображения в (чистом) PHP / MySQL

Мои пользователи загружают изображения на мой сайт, и я хотел бы сначала сначала предложить им уже загруженные изображения. Моя идея состоит в том, чтобы: 1. создать какой-то образ «хэша» каждого существующего изображения. 2. создать хэш недавно загруженного изображения и сравнить его с другим в базе данных.

Я нашел несколько интересных решений, таких как http://www.pureftpd.org/project/libpuzzle или или http://phash.org/ и т. д., но у них есть одна или несколько проблем

  1. им нужно какое-то нестандартное расширение для PHP (или вообще не в PHP) – это было бы хорошо для меня, но я хотел бы создать его как плагин для моей популярной CMS, которая используется во многих средах без моего контроля.
  2. они сравнивают два изображения, но мне нужно сравнить их со многими (например, тысячами), и делать это один за другим будет очень неэффективным / медленным … …

Я был бы в порядке, чтобы найти только ОЧЕНЬ похожие изображения (например, разный размер, resaved jpg или другой коэффициент сжатия jpg).

Единственная идея, которую я получил, – изменить размер изображения, например, 5px * 5px * 256 цветов, создать строковое представление, а затем найти то же самое. Но я предполагаю, что он может создавать небольшие различия в цветах даже с двумя одинаковыми изображениями разного размера, поэтому поиск только 100% -ного же будет бесполезным.

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

Есть ли простой способ?

Раньше у меня была такая же проблема.

Не стесняйтесь копировать то, что я сделал, и, надеюсь, это поможет вам решить вашу проблему.


Как я это решил

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

Следующий вариант (который работает) был меньшим изображением (например, вашей идеей 5px ), и я сделал именно это, но с изображениями 10px * 10px . То, как я создал «хэш» для каждого изображения, было imagecolorat() .

См. Здесь php.net.

Получив цвета rgb для изображения, я округлил их до ближайших 50 , так что цвета были менее конкретными. Это число ( 50 ) – это то, что вы хотите изменить в зависимости от того, насколько конкретно вы хотите, чтобы ваши поиски были.

например:

 // Pixel RGB rgb(105, 126, 225) // Original rgb(100, 150, 250) // After rounding numbers to nearest 50 

Сделав это для каждого пикселя ( 10px * 10px даст вам 100 rgb() назад), я затем превратил их в массив и сохранил их в базе данных как base64_encode() и serialize() .

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


Советы

  • Чем больше 50 но и округление rgb , тем менее конкретным будет ваш поиск (и наоборот).

  • Если вы хотите, чтобы ваш SQL был более конкретным, может быть лучше хранить дополнительную / конкретную информацию об изображении в базе данных, чтобы вы могли ограничить поиск, который вы получаете в базе данных. например . если соотношение сторон составляет 4:3 , только вытаскивайте изображения около 4:3 из базы данных. (и т.д)

  • Трудно получить это прекрасно 5px * 5px , поэтому предложение phpthumb . Я использовал его с синтаксисом:

 phpthumb.php?src=IMAGE_NAME_HERE.png&w=10&h=10&zc=1 // &w= width of your image // &h= height of your image // &zc= zoom control. 0:Keep aspect ratio, 1:Change to suit your width+height 

Удачи, надеюсь, я мог бы помочь.

Для простой реализации PHP проверьте: https://github.com/kennethrapp/phasher

Однако – интересно, есть ли встроенная функция mySql для «сравнения» (см. Выше класс php)

Я уменьшаю изображение до 8×8, затем конвертирую RGB в 1-байтовый HSV, поэтому хеш результата составляет 172 байта.

 HSVHSVHSVHSVHSVHSVHSVHSV... (from 8x8 block, 172 bytes long) 0fff0f3ffff4373f346fff00... 

Это не на 100% точно (некоторые дубликаты не найдены), но он работает хорошо и выглядит так, что нет ложных положительных результатов.

Введя это в академическом порядке, то, что вы ищете, – это функция подобия, которая принимает два изображения и возвращает индикатор того, насколько далеки / похожи эти два изображения. Этот индикатор может быть легко десятичным числом в диапазоне от -1 до 1 (далеко друг от друга, чтобы очень близко). Когда у вас есть эта функция, вы можете установить изображение в качестве ссылки и сравнить все изображения с ним. Затем поиск похожих изображений на один так же просто, как найти для него самый близкий коэффициент подобия, который выполняется с помощью простого поиска по двойному полю внутри RDBMS, например MySQL.

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