Мои пользователи загружают изображения на мой сайт, и я хотел бы сначала сначала предложить им уже загруженные изображения. Моя идея состоит в том, чтобы: 1. создать какой-то образ «хэша» каждого существующего изображения. 2. создать хэш недавно загруженного изображения и сравнить его с другим в базе данных.
Я нашел несколько интересных решений, таких как http://www.pureftpd.org/project/libpuzzle или или http://phash.org/ и т. д., но у них есть одна или несколько проблем
Я был бы в порядке, чтобы найти только ОЧЕНЬ похожие изображения (например, разный размер, 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.
Теперь остается только определить функцию подобия. Честно говоря, это специфическая проблема. Это зависит от того, что вы называете похожим. Но ковариация, как правило, является хорошей отправной точкой, просто нужны ваши два изображения того же размера, которые, я думаю, не имеют большого значения. Тем не менее вы можете найти множество других идей, которые ищут «меры сходства между двумя изображениями».