Как сравнить два изображения для обнаружения дубликатов и обрезанных дубликатов?
Как я могу сравнить два изображения и определить, являются ли они на 100% похожими, или только изменены по цвету, или обрезка?
3 ответа
Ну, абстрактно говоря, вам нужно определить функцию сходства, которая сравнивает два изображения. Чтобы определить, являются ли изображения "похожими на 100%" (равными), вы можете сделать следующее:
- сравнить размеры изображений
- если размеры изображения одинаковы, просто вычтите пиксели друг от друга
if ( sum( abs( pixel_1_i - pixel_2_j ) ) / num_pixels < threshold ) return true
Для случая, когда изображения имеют разный цвет или обрезаны
- применить детектор края к обоим изображениям
- вычислить взаимную корреляцию (в частотной области, FFT)
- найти самый высокий пик
- поместите (меньшую) карту краев в определенную позицию
- рассчитать абсолютную ошибку
if (error < threshold) return true
Кстати: этот подход не будет работать, если ваши изображения масштабируются или поворачиваются.
Дальнейшие исследования:
- взаимная корреляция: FFT (быстрое преобразование Фурье, link1, link2, FFT в C#), заполнение нулями (необходимо для FFT, если входные сигналы имеют разные размеры)
- Обнаружение края: Sobel, Canny (это очень распространенные фильтры обработки изображений, они должны быть доступны в
C#
библиотека, как и БПФ)
Следующее является довольно упрощенным подходом к проблеме и не будет хорошо работать с двумя разными фотографиями одного и того же объекта, сделанными под немного разными углами, но сработает, если у вас будет две копии одного и того же изображения, которые вы хотите проверить.
Случай с двумя одинаковыми изображениями прост - просто переберите пиксельные массивы, вычитая значение RGB из другого. Если разница меньше, чем небольшой допуск, то пиксель идентичен. Таким образом, как только вы обнаружите, что разница в пикселях превышает допуск, вы узнаете, что изображения отличаются.
Можно предусмотреть определенное количество или процент различий, чтобы учесть причины различий по артефактам сжатия.
Чтобы проверить изменения цвета, вы можете посмотреть значения HLS (Hue, Lightness and Saturation). Если пиксели имеют одинаковые значения L & S, но другое значение H, то это просто цвет, который отличается (я думаю).
Обрезка является более сложной, так как вы должны попытаться найти расположение меньшего изображения в большем.
Вы можете использовать дескрипторы объектов, такие как:
SIFT - http://en.wikipedia.org/wiki/Scale-invariant_feature_transform
SURF - http://en.wikipedia.org/wiki/SURF
Затем сравните изображения, используя рассчитанные дескрипторы. Эти дескрипторы позволят вам работать с повернутыми, масштабированными и слегка измененными изображениями.
Также дескрипторы состоят из ориентированных градиентов, что означает, что эти дескрипторы устойчивы к освещению и изменениям цвета.
Вы можете использовать Accord.NET (реализация SURF).