¿Cómo puedo cuantificar la diferencia entre dos imágenes?


Esto es lo que me gustaría hacer:

Estoy tomando fotos con una webcam a intervalos regulares. Algo así como un lapso de tiempo. Sin embargo, si nada ha cambiado realmente, es decir, la imagen más o menos se ve igual, no quiero almacenar la última instantánea.

Imagino que hay alguna forma de cuantificar la diferencia, y tendría que determinar empíricamente un umbral.

Busco simplicidad en lugar de perfección. Estoy usando python.

Author: Jav_Rock, 2008-10-10

20 answers

Idea general

Opción 1: Cargue ambas imágenes como matrices (scipy.misc.imread) y calcule una diferencia en cuanto a elementos (píxel por píxel). Calcular la norma de la diferencia.

Opción 2: Cargar ambas imágenes. Calcule algún vector de característica para cada uno de ellos (como un histograma). Calcule la distancia entre vectores de entidades en lugar de imágenes.

Sin embargo, hay algunas decisiones que tomar primero.

Preguntas

Usted debe responder a estas preguntas primero:

  • Son imágenes de la misma forma y dimensión?

    Si no, es posible que deba redimensionarlos o recortarlos. La biblioteca PIL ayudará a hacerlo en Python.

    Si se toman con la misma configuración y el mismo dispositivo, probablemente sean los mismos.

  • ¿Las imágenes están bien alineadas?

    Si no, es posible que desee ejecutar la correlación cruzada primero, para encontrar la mejor alineación primero. SciPy tiene funciones para hacerlo.

    Si la cámara y el la escena está quieta, las imágenes probablemente estén bien alineadas.

  • ¿La exposición de las imágenes es siempre la misma? (¿La luminosidad / contraste es lo mismo?)

    Si no, es posible que desee normalizar las imágenes.

    Pero ten cuidado, en algunas situaciones esto puede hacer más mal que bien. Por ejemplo, un solo píxel brillante sobre un fondo oscuro hará que la imagen normalizada sea muy diferente.

  • ¿Es importante la información de color?

    Si quieres para notar los cambios de color, tendrá un vector de valores de color por punto, en lugar de un valor escalar como en la imagen de escala de grises. Necesita más atención al escribir dicho código.

  • ¿Hay bordes distintos en la imagen? Es probable que se mueva?

    Si es así, puede aplicar primero el algoritmo de detección de bordes (por ejemplo, calcular el gradiente con la transformación de Sobel o Prewitt, aplicar algún umbral), luego comparar los bordes de la primera imagen con los bordes del segundo.

  • Hay ruido en la imagen?

    Todos los sensores contaminan la imagen con cierta cantidad de ruido. Los sensores de bajo costo tienen más ruido. Es posible que desee aplicar un poco de reducción de ruido antes de comparar imágenes. El desenfoque es el enfoque más simple (pero no el mejor) aquí.

  • ¿Qué tipo de cambios desea notar?

    Esto puede afectar la elección de la norma a utilizar para la diferencia entre imágenes.

    Considere usar la norma Manhattan (la suma de los valores absolutos) o la norma cero (el número de elementos no es igual a cero) para medir cuánto ha cambiado la imagen. El primero le dirá cuánto está desactivada la imagen, el segundo solo dirá cuántos píxeles difieren.

Ejemplo

Asumo que sus imágenes están bien alineadas, del mismo tamaño y forma, posiblemente con diferente exposición. Para simplificar, las convierto a escala de grises incluso si son imágenes de color (RGB).

Usted necesitará estos importaciones:

import sys

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

Función principal, leer dos imágenes, convertir a escala de grises, comparar e imprimir resultados:

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

Cómo comparar. img1 y img2 son matrices SciPy 2D aquí:

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)

Si el archivo es una imagen en color, imread devuelve una matriz 3D, canales RGB promedio (el último eje de matriz) para obtener la intensidad. No es necesario hacerlo para imágenes en escala de grises (p. ej. .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

La normalización es trivial, puede optar por normalizar a [0,1] en lugar de [0,255]. arr es un Matriz SciPy aquí, por lo que todas las operaciones son en cuanto a elementos:

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

Ejecute la función main:

if __name__ == "__main__":
    main()

Ahora puedes poner todo esto en un script y ejecutarlo contra dos imágenes. Si comparamos la imagen consigo misma, no hay diferencia:

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

Si desenfocamos la imagen y la comparamos con la original, hay alguna diferencia: {[19]]}

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

P.d. Entero compare.py script.

Actualización: técnicas relevantes

Como la pregunta es sobre una secuencia de video, cuando es probable que los marcos sean casi los mismos, y busque algo inusual, me gustaría mencionar algunos enfoques alternativos que pueden ser relevantes:

  • resta y segmentación de fondo (para detectar objetos en primer plano)
  • flujo óptico escaso (para detectar movimiento)
  • comparando histogramas u otras estadísticas en lugar de imágenes

Recomiendo encarecidamente echar un vistazo al libro "Learning OpenCV", Capítulos 9 (Partes de imágenes y segmentación) y 10 (Seguimiento y movimiento). El primero enseña a usar el método de sustracción de fondo, el segundo da algo de información sobre los métodos de flujo óptico. Todos los métodos están implementados en la biblioteca OpenCV. Si usa Python, sugiero usar OpenCV ≥ 2.3, y su módulo cv2 Python.

La versión más simple de la resta de fondo:

  • conozca el valor promedio μ y la desviación estándar σ para cada píxel del fondo
  • compare los valores actuales de píxeles con el rango de (μ-2σ,μ+2σ) o (μ-σ, μ+σ)

Las versiones más avanzadas tienen en cuenta las series temporales para cada píxel y manejan escenas no estáticas (como árboles en movimiento o hierba).

La idea del flujo óptico es tomar dos o más fotogramas, y asignar un vector de velocidad a cada píxel (flujo óptico denso) o a algunos de ellos (flujo óptico escaso). Para estimar el flujo óptico escaso, puede usar el método de Lucas-Kanade (también se implementa en OpenCV). Obviamente, si hay un montón de flujo (alto promedio sobre los valores máximos del campo de velocidad), entonces algo se está moviendo en el marco, y las imágenes posteriores son más diferentes.

La comparación de histogramas puede ayudar a detectar cambios repentinos entre fotogramas consecutivos. Este enfoque se utilizó en Courbon et al, 2010:

Similitud de fotogramas consecutivos. Se mide la distancia entre dos fotogramas consecutivos. Si es demasiado alto, significa que el segundo cuadro está dañado y por lo tanto la imagen se elimina. La distancia Kullback-Leibler , o entropía mutua, en los histogramas de los dos fotogramas:

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

Donde p y p son los histogramas de los marcos se utilizan. El umbral se fija en 0.2.

 215
Author: sastanin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-21 17:15:21

Una solución simple:

Codifica la imagen como un jpegy busca un cambio sustancial en el tamaño del archivo .

He implementado algo similar con miniaturas de video, y tuve mucho éxito y escalabilidad.

 67
Author: keparo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-10 04:44:19

Puede comparar dos imágenes usando las funciones de PIL.

import Image
import ImageChops

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

diff = ImageChops.difference(im2, im1)

El objeto diff es una imagen en la que cada píxel es el resultado de la sustracción de los valores de color de ese píxel en la segunda imagen de la primera imagen. Usando la imagen diff puedes hacer varias cosas. La más simple es la función diff.getbbox(). Le dirá el rectángulo mínimo que contiene todos los cambios entre sus dos imágenes.

Probablemente pueda implementar aproximaciones del otro cosas mencionadas aquí usando funciones de PIL también.

 48
Author: gooli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-13 06:50:17

Dos métodos populares y relativamente simples son: (a) la distancia euclidiana ya sugerida, o (b) la correlación cruzada normalizada. La correlación cruzada normalizada tiende a ser notablemente más robusta para los cambios de iluminación que la simple correlación cruzada. Wikipedia da una fórmula para la correlación cruzada normalizada. También existen métodos más sofisticados, pero requieren un poco más de trabajo.

Usando una sintaxis similar a numpy,

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

dist_manhattan = sum(abs(i1 - i2)) / i1.size

dist_ncc = sum( (i1 - mean(i1)) * (i2 - mean(i2)) ) / (
  (i1.size - 1) * stdev(i1) * stdev(i2) )

Suponiendo que i1 y i2 son 2D matrices de imágenes en escala de grises.

 19
Author: Mr Fooz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-10 03:47:44

Una cosa trivial para probar:

Remuestrear ambas imágenes a miniaturas pequeñas (por ejemplo, 64 x 64) y comparar las miniaturas píxel por píxel con un cierto umbral. Si las imágenes originales son casi las mismas, las miniaturas remuestreadas serán muy similares o incluso exactamente iguales. Este método se ocupa del ruido que puede ocurrir especialmente en escenas con poca luz. Incluso puede ser mejor si vas en escala de grises.

 13
Author: Ates Goral,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-10 03:49:32

Estoy abordando específicamente la cuestión de cómo calcular si son "lo suficientemente diferentes". Supongo que puedes averiguar cómo restar los píxeles uno por uno.

Primero, tomaría un montón de imágenes con nada cambiando, y descubriría la cantidad máxima que cualquier píxel cambia solo debido a las variaciones en la captura, el ruido en el sistema de imagen, los artefactos de compresión JPEG y los cambios momento a momento en la iluminación. Tal vez usted encontrará que las diferencias de 1 o 2 bits son es de esperar incluso cuando nada se mueve.

Entonces para la prueba" real", desea un criterio como este:

  • lo mismo si hasta P píxeles difieren en no más de E.

Entonces, tal vez, si E = 0.02, P = 1000, eso significaría (aproximadamente) que sería "diferente" si cualquier píxel cambia en más de ~5 unidades (suponiendo imágenes de 8 bits), o si más de 1000 píxeles tenían algún error.

Esto se pretende principalmente como una buena técnica de "triage" para rápidamente identifique imágenes que estén lo suficientemente cerca como para no necesitar un examen adicional. Las imágenes que "fallan" pueden entonces ser más una técnica más elaborada/costosa que no tendría falsos positivos si la cámara sacudiera poco, por ejemplo, o fuera más robusta a los cambios de iluminación.

Corro un proyecto de código abierto, OpenImageIO, que contiene una utilidad llamada "idiff" que compara las diferencias con umbrales como este (incluso más elaborado, en realidad). Incluso si no desea utilizar este software, es posible que desee mirar la fuente para ver cómo lo hicimos. Se usa comercialmente bastante y esta técnica de umbral se desarrolló para que pudiéramos tener un conjunto de pruebas para el software de renderizado y procesamiento de imágenes, con "imágenes de referencia" que podrían tener pequeñas diferencias de plataforma a plataforma o como hicimos pequeños ajustes a los algoritmos de tha, por lo que queríamos una operación de "coincidencia dentro de la tolerancia".

 7
Author: Larry Gritz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-14 16:10:21

La mayoría de las respuestas dadas no se refieren a los niveles de iluminación.

Primero normalizaría la imagen a un nivel de luz estándar antes de hacer la comparación.

 5
Author: Loren Pechtel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-10 03:55:20

¿Has visto el algoritmo para encontrar imágenes similares pregunta? Échale un vistazo para ver sugerencias.

Sugeriría una transformación de wavelet de sus marcos (he escrito una extensión C para eso usando la transformación de Haar); luego, comparando los índices de los factores de wavelet más grandes (proporcionalmente) entre las dos imágenes, debería obtener una aproximación de similitud numérica.

 2
Author: tzot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:53

Tuve un problema similar en el trabajo, estaba reescribiendo nuestro punto final de transformación de imagen y quería comprobar que la nueva versión estaba produciendo la misma o casi la misma salida que la versión anterior. Así que escribí esto:

Https://github.com/nicolashahn/diffimg

Que opera en imágenes del mismo tamaño, y en un nivel por píxel, mide la diferencia en los valores en cada canal: R, G, B (, A), toma la diferencia promedio de esos canales, y luego promedia la diferencia sobre todos los píxeles, y devuelve una relación.

Por ejemplo, con una imagen de 10x10 píxeles blancos, y la misma imagen pero un píxel ha cambiado a rojo, la diferencia en ese píxel es 1/3 o 0.33... (RGB 0,0,0 vs 255,0,0) y en todos los demás píxeles es 0. Con 100 píxeles en total, 0.33.../ 100 = a ~0.33% diferencia en la imagen.

Creo que esto funcionaría perfectamente para el proyecto de OP (me doy cuenta de que este es un post muy antiguo ahora, pero publicando para el futuro StackOverflowers que también quieren comparar imágenes en python).

 2
Author: nicolashahn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-27 15:27:49

Me disculpo si esto es demasiado tarde para responder, pero ya que he estado haciendo algo similar, pensé que podría contribuir de alguna manera.

Tal vez con OpenCV podrías usar la coincidencia de plantillas. Asumiendo que estás usando una webcam como dijiste:

  1. Simplificar las imágenes (umbral tal vez?)
  2. Aplicar la coincidencia de plantilla y comprobar el max_val con minMaxLoc

Consejo: max_val (o min_val dependiendo del método utilizado) le dará números, números grandes. Para conseguir la diferencia en porcentaje, utilice la plantilla que coincide con la misma imagen the el resultado será su 100%.

Pseudo código para ejemplificar:

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

Espero que ayude.

 2
Author: zanfranceschi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-15 16:08:16

Earth movers distance podría ser exactamente lo que necesitas. Sin embargo, podría ser abit pesado de implementar en tiempo real.

 1
Author: shoosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-10 02:48:35

Qué tal calcular la Distancia de Manhattan de las dos imágenes. Eso le da n * n valores. Entonces usted podría hacer algo como un promedio de fila para reducir a n valores y una función sobre eso para obtener un solo valor.

 1
Author: Tobias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-10 02:53:30

He estado teniendo mucha suerte con las imágenes jpg tomadas con la misma cámara en un trípode por (1) simplificar en gran medida (como pasar de 3000 píxeles de ancho a 100 píxeles de ancho o incluso menos) (2) aplanar cada matriz jpg en un solo vector (3) correlacionar en pares imágenes secuenciales con un algoritmo de correlación simple para obtener el coeficiente de correlación (4) coeficiente de correlación de cuadratura para obtener r-cuadrado (es decir, fracción de variabilidad en una imagen explicada por la variación en la siguiente) (5) generalmente en mi aplicación si r-cuadrado

Esto es robusto y rápido en mi implementación (Mathematica 7)

Vale la pena jugar con la parte de la imagen que le interesa y enfocarse en eso recortando todas las imágenes a esa pequeña área, de lo contrario se perderá un cambio distante de la cámara pero importante.

No se como usar Python, pero estoy seguro que hace correlaciones, también, no?

 1
Author: Roman Dial,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-19 21:28:00

Puede calcular el histograma de ambas imágenes y luego calcular el Coeficiente Bhattacharyya , este es un algoritmo muy rápido y lo he utilizado para detectar cambios de disparo en un video de cricket (en C usando OpenCV)

 1
Author: vishalv2050,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-24 20:44:46

Echa un vistazo a cómo las Wavelets de Haar son implementadas por isk-daemon. Puedes usar su código C++ imgdb para calcular la diferencia entre imágenes sobre la marcha:

Isk-daemon es un servidor de base de datos de código abierto capaz de agregar búsquedas de imágenes (visuales) basadas en contenido a cualquier sitio web o software relacionado con imágenes.

Esta tecnología permite a los usuarios de cualquier sitio web o software relacionado con imágenes dibujar en un widget qué imagen quieren encontrar y hacer que el sitio web responda ellos las imágenes más similares o simplemente solicitar fotos más similares en cada página de detalle de la imagen.

 1
Author: Ricardo Cabral,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-16 21:11:08

Tuve el mismo problema y escribí un simple módulo python que compara dos imágenes del mismo tamaño usando ImageChops de pillow para crear una imagen diff en blanco y negro y resume los valores del histograma.

Puede obtener esta puntuación directamente, o un valor porcentual en comparación con una diferencia completa entre negro y blanco.

También contiene una función is_equal simple, con la posibilidad de suministrar un umbral difuso bajo (e incluyendo) la imagen pasa como igual.

El enfoque no es muy elaborado, pero tal vez es de utilidad para otros que luchan con el mismo problema.

Https://pypi.python.org/pypi/imgcompare /

 1
Author: datenhahn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-21 00:23:54

Un enfoque algo más basado en principios es usar un descriptor global para comparar imágenes, como GIST o CENTRIST. Una función hash, como se describe aquí, también proporciona una solución similar.

 1
Author: Felix Goldberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-29 00:53:36

Otra forma agradable y sencilla de medir la similitud entre dos imágenes:

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)

Si otros están interesados en una forma más poderosa de comparar la similitud de imágenes, armé un tutorial y una aplicación web para medir y visualizar imágenes similares usando Tensorflow.

 1
Author: duhaime,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-30 16:29:02
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', 6))
    r = compare_image_dir_with_hash('image1\\', image2\\', 10)
    for k in r.keys():
        print(k, r.get(k))


if __name__ == '__main__':
    main()
  • Salida:

    False
    Verdadero
    image2 \ 5.imagen jpg 1 \ 815.jpg
    image2 \ 6.imagen jpg 1 \ 819.jpg
    image2 \ 7.imagen jpg 1 \ 900.jpg
    image2 \ 8.imagen jpg 1 \ 998.jpg
    image2 \ 9.imagen jpg 1\1012.jpg

  • Las imágenes de ejemplo:

    • 815.jpg
      815.jpg

    • 5.jpg
      5.jpg

 1
Author: admin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-29 11:34:08

Creo que simplemente podría calcular la distancia euclidiana (es decir, sqrt(suma de cuadrados de diferencias, píxel por píxel)) entre la luminancia de las dos imágenes, y considerarlas iguales si esto cae bajo algún umbral empírico. Y será mejor que lo hagas envolviendo una función C.

 0
Author: Federico A. Ramponi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-10 04:08:13