Как я могу определить разницу между двумя изображениями?

179

Вот что я хотел бы сделать:

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

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

Я ищу простоту, а не совершенство. Я использую Python.

перевозчик
источник
Связанный: stackoverflow.com/questions/25977/…
Anoyz

Ответы:

269

Главная идея

Вариант 1. Загрузите оба изображения в виде массивов ( scipy.misc.imread) и рассчитайте поэлементную (попиксельную) разницу. Рассчитайте норму разницы.

Вариант 2. Загрузите оба изображения. Рассчитайте некоторый вектор признаков для каждого из них (например, гистограмму). Рассчитайте расстояние между векторами объектов, а не изображениями.

Тем не менее, есть некоторые решения, которые необходимо принять в первую очередь.

Вопросы

Сначала вы должны ответить на эти вопросы:

  • Являются ли изображения одинаковой формы и размера?

    Если нет, вам может понадобиться изменить их размер или обрезать. Библиотека PIL поможет сделать это на Python.

    Если они взяты с одинаковыми настройками и тем же устройством, они, вероятно, одинаковы.

  • Хорошо ли выровнены изображения?

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

    Если камера и сцена неподвижны, изображения, вероятно, будут хорошо выровнены.

  • Экспозиция изображений всегда одинакова? (Легкость / контрастность одинаковы?)

    Если нет, вы можете нормализовать изображения.

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

  • Важна ли информация о цвете?

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

  • Есть ли четкие края на изображении? Они могут двигаться?

    Если да, вы можете сначала применить алгоритм обнаружения ребер (например, рассчитать градиент с помощью преобразования Собеля или Превитта, применить некоторый порог), затем сравнить ребра в первом изображении с ребрами во втором.

  • Есть ли шум на изображении?

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

  • Какие изменения вы хотите заметить?

    Это может повлиять на выбор нормы для разницы между изображениями.

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

пример

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

Вам понадобится этот импорт:

import sys

from scipy.misc import imread
from scipy.linalg import norm
from scipy import sum, average

Основная функция, чтение двух изображений, преобразование в оттенки серого, сравнение и печать результатов:

def main():
    file1, file2 = sys.argv[1:1+2]
    # read images as 2D arrays (convert to grayscale for simplicity)
    img1 = to_grayscale(imread(file1).astype(float))
    img2 = to_grayscale(imread(file2).astype(float))
    # compare
    n_m, n_0 = compare_images(img1, img2)
    print "Manhattan norm:", n_m, "/ per pixel:", n_m/img1.size
    print "Zero norm:", n_0, "/ per pixel:", n_0*1.0/img1.size

Как сравнить. img1и img22D-массивы SciPy здесь:

def compare_images(img1, img2):
    # normalize to compensate for exposure difference, this may be unnecessary
    # consider disabling it
    img1 = normalize(img1)
    img2 = normalize(img2)
    # calculate the difference and its norms
    diff = img1 - img2  # elementwise for scipy arrays
    m_norm = sum(abs(diff))  # Manhattan norm
    z_norm = norm(diff.ravel(), 0)  # Zero norm
    return (m_norm, z_norm)

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

def to_grayscale(arr):
    "If arr is a color image (3D array), convert it to grayscale (2D array)."
    if len(arr.shape) == 3:
        return average(arr, -1)  # average over the last axis (color channels)
    else:
        return arr

Нормализация тривиальна, вы можете выбрать нормализацию до [0,1] вместо [0,255]. arrздесь массив SciPy, поэтому все операции поэлементны:

def normalize(arr):
    rng = arr.max()-arr.min()
    amin = arr.min()
    return (arr-amin)*255/rng

Запустите mainфункцию:

if __name__ == "__main__":
    main()

Теперь вы можете поместить все это в скрипт и запустить два изображения. Если мы сравним изображение с самим собой, нет никакой разницы:

$ python compare.py one.jpg one.jpg
Manhattan norm: 0.0 / per pixel: 0.0
Zero norm: 0 / per pixel: 0.0

Если мы размываем изображение и сравниваем его с оригиналом, есть некоторая разница:

$ python compare.py one.jpg one-blurred.jpg 
Manhattan norm: 92605183.67 / per pixel: 13.4210411116
Zero norm: 6900000 / per pixel: 1.0

PS Весь скрипт Compare.py .

Обновление: соответствующие методы

Поскольку вопрос касается видеопоследовательности, где кадры, вероятно, будут почти одинаковыми, а вы ищете что-то необычное, я хотел бы упомянуть некоторые альтернативные подходы, которые могут быть актуальны:

  • вычитание и сегментация фона (для обнаружения объектов переднего плана)
  • разреженный оптический поток (для обнаружения движения)
  • сравнивая гистограммы или другую статистику вместо изображений

Я настоятельно рекомендую взглянуть на книгу «Обучение OpenCV», главы 9 (Части изображения и сегментация) и 10 (Отслеживание и движение). Первый учит использовать метод вычитания фона, второй дает некоторую информацию о методах оптического потока. Все методы реализованы в библиотеке OpenCV. Если вы используете Python, я предлагаю использовать OpenCV ≥ 2.3 и его cv2модуль Python.

Самый простой вариант вычитания фона:

  • узнать среднее значение μ и стандартное отклонение σ для каждого пикселя фона
  • сравнить текущие значения пикселей с диапазоном (μ-2σ, μ + 2σ) или (μ-σ, μ + σ)

Более продвинутые версии учитывают временные ряды для каждого пикселя и обрабатывают нестатические сцены (например, движущиеся деревья или траву).

Идея оптического потока состоит в том, чтобы взять два или более кадров и назначить вектор скорости каждому пикселю (плотный оптический поток) или некоторым из них (разреженный оптический поток). Для оценки разреженного оптического потока вы можете использовать метод Лукаса-Канаде (он также реализован в OpenCV). Очевидно, что если поток большой (среднее среднее по максимальным значениям поля скорости), то что-то движется в кадре, и последующие изображения более различны.

Сравнение гистограмм может помочь обнаружить внезапные изменения между последовательными кадрами. Этот подход был использован в Курбоне и др., 2010 :

Сходство последовательных кадров. Расстояние между двумя последовательными кадрами измеряется. Если оно слишком высокое, это означает, что второй кадр поврежден и, следовательно, изображение устранено. Расстояние Кульбака – Лейблера , или взаимная энтропия, на гистограммах двух систем отсчета:

$$ d (p, q) = \ sum_i p (i) \ log (p (i) / q (i)) $$

где p и q - это гистограммы фреймов. Порог фиксируется на 0,2.

sastanin
источник
Я получаю в RuntimeWarning: invalid value encountered in double_scalarsстроке 44 ( return (arr-amin)*255/rng) и в ValueError: array must not contain infs or NaNsстроке 30 ( z_norm = norm(diff.ravel(), 0))
BioGeek
@BioGeek, если rngравен нулю. Просто добавьте чек и установитеrng = 1
Haisi
76

Простое решение:

Закодируйте изображение в формате JPEG и найдите существенное изменение в размере файла .

Я реализовал нечто подобное с миниатюрами видео, и добился большого успеха и масштабируемости.

keparo
источник
3
Это очень простое и простое решение, которое намного лучше, чем любое пиксельное сравнение. Если на изображении вашей веб-камеры присутствует небольшой шум или если изображение смещено хотя бы на один пиксель, то прямое сравнение подберет все эти бессмысленные изменения. Более надежным подходом было бы вычисление дискретного косинусного преобразования, а затем сравнение изображений в частотной области. Подобное сжатие JPEG дает вам большинство преимуществ без погружения в теорию Фурье.
AndrewF
Нравится это. Хотя другие решения также работают, это имеет большое преимущество для обычной ситуации: что, если вы не хотите сохранять «базовое» изображение? просто сохраните размер файла как хеш, а затем сравните только числа с вычитанием. В моем случае у меня есть 4 изображения, одно из которых очень похожее, а остальные 3 абсолютно разные. Просто масштабировать до тех же размеров, JPG и вычитать. Действительно мило.
Диего Андрес Диас Эспиноза
60

Вы можете сравнить два изображения, используя функции из PIL .

import Image
import ImageChops

im1 = Image.open("splash.png")
im2 = Image.open("splash2.png")

diff = ImageChops.difference(im2, im1)

Объект diff - это изображение, в котором каждый пиксель является результатом вычитания значений цвета этого пикселя во втором изображении из первого изображения. Используя разностное изображение, вы можете сделать несколько вещей. Самым простым является diff.getbbox()функция. Он скажет вам минимальный прямоугольник, который содержит все изменения между вашими двумя изображениями.

Вероятно, вы можете реализовать аппроксимации других вещей, упомянутых здесь, используя функции из PIL.

elifiner
источник
2
Я хочу сохранить изображение разницы. означает объект сравнения, который содержит разницу изображений. я должен сохранить это?
Сагар
2
@Anthony вы можете вызвать save () для объекта diff, указав имя изображения. вот так: diff.save ("diff.png") сохранит для вас разностное изображение.
Сагар
20

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

Используя похожий на numpy синтаксис,

dist_euclidean = sqrt (sum ((i1 - i2) ^ 2)) / i1.size

dist_manhattan = сумма (абс (i1 - i2)) / i1.size

dist_ncc = сумма ((i1 - среднее (i1)) * (i2 - среднее (i2))) / (
  (i1.size - 1) * stdev (i1) * stdev (i2))

Предполагая, что i1и i22D массив изображений в градациях серого.

Мистер Фуз
источник
3
Функции взаимной корреляции изображений встроены в SciPy ( docs.scipy.org/doc/scipy/reference/generated/… ), а быстрая версия с использованием FFT доступна в stsci python ( stsci.edu/resources/software_hardware/pyraf/ stsci_python )
эндолиты
14

Тривиальная вещь, чтобы попробовать:

Измените оба изображения на маленькие миниатюры (например, 64 x 64) и сравните пиксели за пикселем с определенным порогом. Если исходные изображения почти одинаковы, уменьшенные эскизы будут очень похожими или даже точно такими же. Этот метод заботится о шуме, который может возникнуть, особенно в условиях низкой освещенности. Это может быть даже лучше, если вы перейдете в оттенках серого.

Атес Горал
источник
а как бы вы сравнили пиксели?
перевозчик
Как только у вас появятся эскизы, вы можете просто сравнить пиксели один за другим. Вы бы рассчитали «расстояние» значений RGB, если вы работаете в цвете, или просто разницу между серыми тонами, если вы находитесь в оттенках серого.
Атес Горал
1
msgstr "сравнить пиксели один за другим". Что это значит? Если тест не пройден, если ОДИН из 64 ^ 2-пиксельных тестов не пройден?
Федерико А. Рампони
То, что я имел в виду под «сравнением пиктограмм по пикселям с определенным порогом», - это создание нечеткого алгоритма для сравнения пикселей. Если вычисленная разница (зависит от вашего нечеткого алгоритма) превышает определенный порог, изображения «не совпадают».
Атес Горал
1
Очень простой пример, без «нечеткого алгоритма»: параллельный цикл через каждый пиксель (сравните пиксель № n изображения № 1 с пикселем № n изображения № 2) и добавьте разницу в значении к переменной
mk12
7

Я обращаюсь конкретно к вопросу о том, как вычислить, достаточно ли они различны. Я предполагаю, что вы можете понять, как вычитать пиксели один за другим.

Во- первых, я бы кучу изображений с ничего не меняется, и узнать сумму максимальной , что любой пиксель изменяет только из - за изменений в захвате, шум в системе формирования изображения, артефакты сжатия JPEG, и момент к моменту изменения освещения , Возможно, вы обнаружите, что следует ожидать разницы в 1 или 2 бита, даже когда ничего не происходит.

Затем для «настоящего» теста вам нужен такой критерий:

  • то же самое, если до P пикселей отличаются не более чем на E.

Так что, возможно, если E = 0,02, P = 1000, это будет означать (приблизительно), что он будет «другим», если какой-либо один пиксель изменится более чем на ~ 5 единиц (при условии 8-битных изображений), или если более 1000 у пикселей были какие-либо ошибки вообще.

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

Я запускаю проект с открытым исходным кодом, OpenImageIO , который содержит утилиту под названием «idiff», которая сравнивает различия с такими пороговыми значениями (даже более сложными, на самом деле). Даже если вы не хотите использовать это программное обеспечение, вы можете посмотреть на источник, чтобы увидеть, как мы это сделали. Он используется в коммерческих целях довольно редко, и эта методика пороговой разработки была разработана для того, чтобы у нас мог быть набор тестов для программного обеспечения рендеринга и обработки изображений с «опорными изображениями», которые могут иметь небольшие отличия от платформы к платформе или поскольку мы внесли небольшие изменения в алгоритмы, поэтому мы хотели, чтобы операция «соответствовала в пределах допуска».

Ларри Гриц
источник
6

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

https://github.com/nicolashahn/diffimg

Он работает с изображениями одинакового размера и на уровне каждого пикселя, измеряет разницу значений в каждом канале: R, G, B (, A), берет среднюю разницу этих каналов и затем усредняет разницу по все пиксели, и возвращает соотношение.

Например, для 10х10 изображений с белыми пикселями и того же изображения, но с одним пикселем, он стал красным, разница в этом пикселе составляет 1/3 или 0,33 ... (RGB 0,0,0 против 255,0,0 ) и для всех остальных пикселей равен 0. При 100 пикселях всего 0,33 ... / 100 = разность изображения ~ 0,33%.

Я считаю, что это отлично подойдет для проекта OP (я понимаю, что это очень старая публикация, но она публикуется для будущих StackOverflowers, которые также хотят сравнивать изображения в python).

nicolashahn
источник
5

Большинство ответов не будут касаться уровней освещения.

Я бы сначала нормализовал изображение до стандартного уровня освещения, прежде чем делать сравнение.

Лорен Печтель
источник
Если вы делаете периодические снимки и различаете соседние пары, вы, вероятно, можете позволить себе оставить первое после того, как кто-то включит свет.
walkytalky
5

Еще один приятный, простой способ измерить сходство между двумя изображениями:

import sys
from skimage.measure import compare_ssim
from skimage.transform import resize
from scipy.ndimage import imread

# get two images - resize both to 1024 x 1024
img_a = resize(imread(sys.argv[1]), (2**10, 2**10))
img_b = resize(imread(sys.argv[2]), (2**10, 2**10))

# score: {-1:1} measure of the structural similarity between the images
score, diff = compare_ssim(img_a, img_b, full=True)
print(score)

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

duhaime
источник
3
Да, skimageдействительно приятно использовать для этого приложения. Я from skimage.measure import compare_ssim, compare_mseмного использую. skimage.measure документы .
Ximiki
3

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

Я бы предложил вейвлет-преобразование ваших фреймов (для этого я написал расширение C с использованием преобразования Хаара); затем, сравнивая индексы наибольших (пропорционально) вейвлет-факторов между двумя изображениями, вы должны получить числовое приближение сходства.

tzot
источник
2

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

Может быть, с OpenCV вы могли бы использовать сопоставление с шаблоном. Предполагая, что вы используете веб-камеру, как вы сказали:

  1. Упростить изображения (возможно, с порогом?)
  2. Примените сопоставление с шаблоном и проверьте max_val с помощью minMaxLoc.

Совет: max_val (или min_val в зависимости от используемого метода) даст вам числа, большие числа. Чтобы получить разницу в процентах, используйте сопоставление шаблонов с тем же изображением - результат будет вашим 100%.

Псевдокод для примера:

previous_screenshot = ...
current_screenshot = ...

# simplify both images somehow

# get the 100% corresponding value
res = matchTemplate(previous_screenshot, previous_screenshot, TM_CCOEFF)
_, hundred_p_val, _, _ = minMaxLoc(res)

# hundred_p_val is now the 100%

res = matchTemplate(previous_screenshot, current_screenshot, TM_CCOEFF)
_, max_val, _, _ = minMaxLoc(res)

difference_percentage = max_val / hundred_p_val

# the tolerance is now up to you

Надеюсь, поможет.

zanfranceschi
источник
1

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

shoosh
источник
Мне не кажется, что этот ответ приятно звучит: «Я ищу простоту, а не совершенство. Я использую Python».
PilouPili
Я думаю, поскольку этот поток вопросов получает много трафика, а заголовок, который рисует большинство зрителей, посвящен тому, как количественно определить разницу между двумя изображениями, он имеет здесь значение.
Данорам
1

Как насчет расчета Манхэттенского расстояния двух изображений. Это дает вам n * n значений. Тогда вы могли бы сделать что-то вроде среднего по строке, чтобы уменьшить до n значений, и функцию над этим, чтобы получить одно единственное значение.

Тобиас
источник
1

Мне очень повезло с изображениями jpg, снятыми одной и той же камерой на штативе, благодаря (1) значительному упрощению (например, переходу от 3000 пикселей в ширину до 100 пикселей или даже меньше) (2) сведению каждого массива jpg в один вектор (3) попарно коррелирует последовательные изображения с помощью простого алгоритма корреляции для получения коэффициента корреляции (4) квадратный коэффициент корреляции для получения r-квадрата (то есть доли изменчивости в одном изображении, объясняемой изменением в следующем) (5), как правило, в моем приложении если r-квадрат <0,9, я говорю, что два изображения разные, и что-то произошло между ними.

Это надежно и быстро в моей реализации (Mathematica 7)

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

Я не знаю, как использовать Python, но уверен, что он тоже делает корреляции, нет?

Римский циферблат
источник
1

Вы можете вычислить гистограмму обоих изображений, а затем рассчитать коэффициент Бхаттачарьи , это очень быстрый алгоритм, и я использовал его для обнаружения изменений в кадре в видео по крикету (в C с использованием openCV)

vishalv2050
источник
Не могли бы вы рассчитать коэффициент на самих изображениях?
эндолит
Вам нужно будет рассчитать гистограммы для изображений (с размером ячейки гистограммы в соответствии с требованиями).
vishalv2050
1

Посмотрите, как вейвлеты Haar реализованы в isk-daemon . Вы можете использовать его код C ++ imgdb для вычисления различий между изображениями на лету:

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

Эта технология позволяет пользователям любого веб-сайта или программного обеспечения, относящегося к изображениям, делать наброски на виджете, какое изображение они хотят найти, и веб-сайт отвечает им наиболее похожими изображениями или просто запрашивает более похожие фотографии на каждой странице сведений об изображении.

Рикардо Кабрал
источник
1

У меня была та же проблема, и я написал простой модуль Python, который сравнивает два изображения одинакового размера, используя ImageChops подушки, для создания черно-белого разностного изображения и суммирует значения гистограммы.

Вы можете получить либо этот счет напрямую, либо процентное значение по сравнению с полным черным или белым различием.

Он также содержит простую функцию is_equal с возможностью задания нечеткого порога для (и в том числе) прохода изображения как равного.

Подход не очень сложен, но, возможно, полезен для других, кто борется с той же проблемой.

https://pypi.python.org/pypi/imgcompare/

datenhahn
источник
1

Несколько более принципиальный подход заключается в использовании глобального дескриптора для сравнения изображений, такого как GIST или CENTRIST. Хеш-функция, как описано здесь , также предоставляет аналогичное решение.

Феликс Гольдберг
источник
1
import os
from PIL import Image
from PIL import ImageFile
import imagehash
  
#just use to the size diferent picture
def compare_image(img_file1, img_file2):
    if img_file1 == img_file2:
        return True
    fp1 = open(img_file1, 'rb')
    fp2 = open(img_file2, 'rb')

    img1 = Image.open(fp1)
    img2 = Image.open(fp2)

    ImageFile.LOAD_TRUNCATED_IMAGES = True
    b = img1 == img2

    fp1.close()
    fp2.close()

    return b





#through picturu hash to compare
def get_hash_dict(dir):
    hash_dict = {}
    image_quantity = 0
    for _, _, files in os.walk(dir):
        for i, fileName in enumerate(files):
            with open(dir + fileName, 'rb') as fp:
                hash_dict[dir + fileName] = imagehash.average_hash(Image.open(fp))
                image_quantity += 1

    return hash_dict, image_quantity

def compare_image_with_hash(image_file_name_1, image_file_name_2, max_dif=0):
    """
    max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.
    recommend to use
    """
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    hash_1 = None
    hash_2 = None
    with open(image_file_name_1, 'rb') as fp:
        hash_1 = imagehash.average_hash(Image.open(fp))
    with open(image_file_name_2, 'rb') as fp:
        hash_2 = imagehash.average_hash(Image.open(fp))
    dif = hash_1 - hash_2
    if dif < 0:
        dif = -dif
    if dif <= max_dif:
        return True
    else:
        return False


def compare_image_dir_with_hash(dir_1, dir_2, max_dif=0):
    """
    max_dif: The maximum hash difference is allowed, the smaller and more accurate, the minimum is 0.

    """
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    hash_dict_1, image_quantity_1 = get_hash_dict(dir_1)
    hash_dict_2, image_quantity_2 = get_hash_dict(dir_2)

    if image_quantity_1 > image_quantity_2:
        tmp = image_quantity_1
        image_quantity_1 = image_quantity_2
        image_quantity_2 = tmp

        tmp = hash_dict_1
        hash_dict_1 = hash_dict_2
        hash_dict_2 = tmp

    result_dict = {}

    for k in hash_dict_1.keys():
        result_dict[k] = None

    for dif_i in range(0, max_dif + 1):
        have_none = False

        for k_1 in result_dict.keys():
            if result_dict.get(k_1) is None:
                have_none = True

        if not have_none:
            return result_dict

        for k_1, v_1 in hash_dict_1.items():
            for k_2, v_2 in hash_dict_2.items():
                sub = (v_1 - v_2)
                if sub < 0:
                    sub = -sub
                if sub == dif_i and result_dict.get(k_1) is None:
                    result_dict[k_1] = k_2
                    break
    return result_dict


def main():
    print(compare_image('image1\\815.jpg', 'image2\\5.jpg'))
    print(compare_image_with_hash('image1\\815.jpg', 'image2\\5.jpg', 7))
    r = compare_image_dir_with_hash('image1\\', 'image2\\', 10)
    for k in r.keys():
        print(k, r.get(k))


if __name__ == '__main__':
    main()
  • вывод:

    False
    True
    image2 \ 5.jpg image1 \ 815.jpg
    image2 \ 6.jpg image1 \ 819.jpg
    image2 \ 7.jpg image1 \ 900.jpg
    image2 \ 8.jpg image1 \ 998.jpg
    image2 \ 9.jpg image1 \ 1012 .jpg

  • Пример изображения:

    • 815.jpg
      815.jpg

    • 5.jpg
      5.jpg

админ
источник
0

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

Федерико А. Рампони
источник
0

Существует множество метрик для оценки того, как выглядят два изображения / как они выглядят.

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

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

Классические подходы:

Предиктор видимых различий: алгоритм оценки точности изображения ( https://www.spiedigitallibrary.org/conference-proceedings-of-spie/1666/0000/Visible-differences-predictor--an-algorithm-for-the-- оценка-из / 10.1117 / 12.135952.short? SSO = 1 )

Оценка качества изображения: от видимости ошибок до структурного сходства ( http://www.cns.nyu.edu/pub/lcv/wang03-reprint.pdf )

FSIM: индекс сходства функций для оценки качества изображения ( https://www4.comp.polyu.edu.hk/~cslzhang/IQA/TIP_IQA_FSIM.pdf )

Среди них SSIM (оценка качества изображения: от видимости ошибки до структурного сходства) является самым простым для вычисления, и его накладные расходы также невелики, как сообщается в другой статье «Оценка качества изображения на основе градиентного сходства» ( https: //www.semanticscholar .org / paper / Оценка качества изображения на основе градиента - Лю-Лин / 2b819bef80c02d5d4cb56f27b202535e119df988 ).

Есть много других подходов. Взгляните на Google Scholar и найдите что-то вроде «визуальной разницы», «оценки качества изображения» и т. Д., Если вы заинтересованы / действительно заботитесь об искусстве.

cyfex
источник
0

Существует простое и быстрое решение, использующее numpy путем вычисления среднего квадрата ошибки:

before = np.array(get_picture())
while True:
    now = np.array(get_picture())
    MSE = np.mean((now - before)**2)

    if  MSE > threshold:
        break

    before = now
Ариан Солтани
источник