Сравните два изображения python/linux путь

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

У меня есть два JPGs. Рассмотрение их, я вижу, что они на самом деле идентичны. Но по некоторым причинам у них есть другой размер файла (каждого вытягивают от резервного копирования, другой другая загрузка), и таким образом, у них есть другая md5 контрольная сумма.

Как может я эффективно и уверенно сравнивать два изображения в том же смысле, поскольку человек был бы в состоянии видеть, что они явно идентичны?

Пример: http://static.peterbe.com/a.jpg и http://static.peterbe.com/b.jpg

Обновление

Я записал этот сценарий:

import math, operator
from PIL import Image
def compare(file1, file2):
    image1 = Image.open(file1)
    image2 = Image.open(file2)
    h1 = image1.histogram()
    h2 = image2.histogram()
    rms = math.sqrt(reduce(operator.add,
                           map(lambda a,b: (a-b)**2, h1, h2))/len(h1))
    return rms

if __name__=='__main__':
    import sys
    file1, file2 = sys.argv[1:]
    print compare(file1, file2)

Тогда я загрузил два визуально идентичных изображения и выполнил сценарий. Вывод:

58.9830484122

Кто-либо может сказать мне, каково подходящее сокращение должно быть?

Обновление II

Различие между a.jpg и b.jpg - то, что второй был сохранен с PIL:

b=Image.open('a.jpg')
b.save(open('b.jpg','wb'))

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

39
задан Peter Bengtsson 18 December 2009 в 13:05
поделиться

5 ответов

Существует проект OSS, который использует WebDriver для создания снимков экрана, а затем сравнивает изображения, чтобы увидеть, есть ли какие-либо проблемы ( http://code.google.com/p/ файтинг-макет-ошибки /) ). Он делает это, открывая файл в поток, а затем сравнивая каждый бит.

Возможно, вы сможете сделать что-то подобное с PIL .

РЕДАКТИРОВАТЬ:

После дополнительных исследований я нашел

h1 = Image.open("image1").histogram()
h2 = Image.open("image2").histogram()

rms = math.sqrt(reduce(operator.add,
    map(lambda a,b: (a-b)**2, h1, h2))/len(h1))

на http://snipplr.com/view/ 757 / compare-two-pil-images-in-python / и http://effbot.org/zone/pil-comparing-images.htm

25
ответ дан 27 November 2019 в 02:31
поделиться

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

  • если ваша проблема заключается в том, чтобы увидеть, есть ли переворачивание битов в ваших JPEG-файлах, попробуйте отобразить разностное изображение (возможно, было небольшое изменение локально?),

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

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

код:

def FTfilter(image,FTfilter):
    from scipy.fftpack import fft2, fftshift, ifft2, ifftshift
    from scipy import real
    FTimage = fftshift(fft2(image)) * FTfilter
    return real(ifft2(ifftshift(FTimage)))
    #return real(ifft2(fft2(image)* FTfilter))


#### whitening
def olshausen_whitening_filt(size, f_0 = .78, alpha = 4., N = 0.01):
    """
    Returns the whitening filter used by (Olshausen, 98)

    f_0 = 200 / 512

    /!\ you will have some problems at dewhitening without a low-pass

    """
    from scipy import mgrid, absolute
    fx, fy = mgrid[-1:1:1j*size[0],-1:1:1j*size[1]]
    rho = numpy.sqrt(fx**2+fy**2)
    K_ols = (N**2 + rho**2)**.5 * low_pass(size, f_0 = f_0, alpha = alpha)
    K_ols /= numpy.max(K_ols)

    return  K_ols

def low_pass(size, f_0, alpha):
    """
    Returns the low_pass filter used by (Olshausen, 98)

    parameters from Atick (p.240)
    f_0 = 22 c/deg in primates: the full image is approx 45 deg
    alpha makes the aspect change (1=diamond on the vert and hor, 2 = anisotropic)

    """

    from scipy import mgrid, absolute
    fx, fy = mgrid[-1:1:1j*size[0],-1:1:1j*size[1]]
    rho = numpy.sqrt(fx**2+fy**2)
    low_pass = numpy.exp(-(rho/f_0)**alpha)

    return  low_pass

(бесстыдная копия с http://www.incm.cnrs-mrs.fr/LaurentPerrinet/Publications/Perrinet08spie )

4
ответ дан 27 November 2019 в 02:31
поделиться

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

С PIL и Numpy вы можете сделать это довольно легко:

import Image
import numpy
import sys

def main():
    img1 = Image.open(sys.argv[1])
    img2 = Image.open(sys.argv[2])

    if img1.size != img2.size or img1.getbands() != img2.getbands():
        return -1

    s = 0
    for band_index, band in enumerate(img1.getbands()):
        m1 = numpy.array([p[band_index] for p in img1.getdata()]).reshape(*img1.size)
        m2 = numpy.array([p[band_index] for p in img2.getdata()]).reshape(*img2.size)
        s += numpy.sum(numpy.abs(m1-m2))
    print s

if __name__ == "__main__":
    sys.exit(main())

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

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

11
ответ дан 27 November 2019 в 02:31
поделиться

Во-первых, я должен отметить, что они не идентичны ; b был повторно сжат и потерял качество. Вы можете увидеть это, если внимательно посмотрите на хороший монитор.

Чтобы определить, что они субъективно «одинаковы», вам нужно будет сделать что-то вроде того, что предложил Фортран, хотя вам придется произвольно установить порог «одинаковости» . » Чтобы сделать s независимым от размера изображения и немного более разумно обрабатывать каналы, я бы подумал о применении евклидова расстояния RMS (среднеквадратическое значение) в цветовом пространстве между пикселями двух изображений. У меня нет времени писать код прямо сейчас, но в основном для каждого пикселя вы вычисляете

(R_2 - R_1) ** 2 + (G_2 - G_1) ** 2 + (B_2 - B_1) ** 2

, добавляя член

(A_2 - A_1) ** 2

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

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

2
ответ дан 27 November 2019 в 02:31
поделиться

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

1
ответ дан 27 November 2019 в 02:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: