Python. Сравнение изображений при помощи OpenCV
В этой статье мы займемся задачей сравнений изображений при помощи библиотеки OpenCV на Python. Вы ни разу не задавались вопросам, как Гугл находит похожие изображения? Действительно, как? Самый простой способ – это сжать картинку до маленького размера и уже потом сравнить попиксельно полученные мини изображение.
Давайте воспроизведем данный пример на Python. Вот текст программы:
import cv2
import difflib
#Функция вычисления хэша
def CalcImageHash(FileName):
image = cv2.imread(FileName) #Прочитаем картинку
resized = cv2.resize(image, (8,8), interpolation = cv2.INTER_AREA) #Уменьшим картинку
gray_image = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY) #Переведем в черно-белый формат
avg=gray_image.mean() #Среднее значение пикселя
ret, threshold_image = cv2.threshold(gray_image, avg, 255, 0) #Бинаризация по порогу
#Рассчитаем хэш
_hash=""
for x in range(8):
for y in range(8):
val=threshold_image[x,y]
if val==255:
_hash=_hash+"1"
else:
_hash=_hash+"0"
return _hash
def CompareHash(hash1,hash2):
l=len(hash1)
i=0
count=0
while i<l:
if hash1[i]!=hash2[i]:
count=count+1
i=i+1
return count
hash1=CalcImageHash("фФайл 1")
hash2=CalcImageHash("Файл 2")
print(hash1)
print(hash2)
print(CompareHash(hash1, hash2))
В этой программе мы используем библиотеку OpenCV. Для ее установки нужно запустить в командной строке питона pip install opencv-python, а для использования просто в начале программы на питоне импортируем библиотеку: import cv2.
А теперь попробуем ее в действии. Итак, поехали, пусть у нас есть две вот такие картинки:
Изображение 1

Изображение 2

Это один и тот же пейзаж снятый с балкона отеля, но в разное время. И вот что выдает алгоритм сравнения:
0000000000100000001000111111011111111110111011110000010000000000
0000000000110000111100111111101111111111001011110000001000000000
11
Результат сравнения 11, запомнит это число и попробуем другие картинки, и так рассмотрим следующую:
Изображение 3

Сравним изображения 1 и 3:
0000000000100000001000111111011111111110111011110000010000000000
0011000000110000000000110010001000011000000111101011111111111111
33
В итоге у нас получилось 33, что больше, чем в случае с картинками 1 и 2, что логично, так как третья картинка вообще другая. Но что если сравнить ее с похожей, где танцуют такие же девушки? Собственно, следующая картинка то же самое, но снято несколько секунд или минут позже, и с иного ракурса.
Изображение 4

Сравним картинки 3 и 4
0011000000110000000000110010001000011000000111101011111111111111
0000000000000000000000000000100100111110011111111111111110111111
18
Что мы видим? Результат сравнения уменьшился – картинки все-таки похожие. Но, стоит заметить, он слегка больше, чем результат сравнения первых двух картинок. Действительно, картинки 3 и 4 менее похожи, чем 1 и 2, так как количество девушек поменялось, а так же их поза и задний план из-за того, что был выбран другой ракурс.
И еще одно сравнение.
Изображение 5:

Сравниваем картинки 3 и 5:
0011000000110000000000110010001000011000000111101011111111111111
0000000000000000000000000100100001111111000111111101111100010011
23
И картинки 4 и 5:
0000000000000000000000000000100100111110011111111111111110111111
0000000000000000000000000100100001111111000111111101111100010011
11
Как видим, данный метод действительно позволяет обнаружить похожие картинки. Кроме того, он достаточно хорошо работает и в случае, когда у картинок разный размер, а так же нормально работает при наличии на изображении небольшого шума (шум исчезает при масштабировании картинки).
Правда, у этого алгоритма есть ряд недостатков:
- Одинаковые картинки, но с разной цветовой гаммой, алгоритм может классифицировать как очень похожие. Например, девушка в полный рост в красном платье и девушка в полный рост на том же фоне, но в зеленом платье будут посчитаны алгоритмом как почти идентичные.
- Алгоритм не будет работать при сдвиге и повороте изображения: одинаковый ландшафт, снятый с другого ракурса, сдвинутый или под другим углом алгоритм посчитает разными изображениями.