Comparación de imágenes en Python con Opencv y Numpy

Contenido del Bootcamp dirigido por:

¿Qué encontrarás en este post?

Comparar imágenes en Python

El objetivo del presente trabajo, es el de comparar la información de 2 archivos de imagen, haciendo uso de la librería «opencv» (en caso de que no lo tengamos instalado, haremos uso del comando «pip») conjuntamente con la librería “numpy”.

El ejercicio que nos proponemos a realizar es sencillamente hacer uso de numpy opencv y «numpy» para comparar la información de dos imágenes y discernir si estas son o no iguales.

Para ello, empezaremos importando los recursos que vamos a emplear:

//imágenes en Python con Opencv y Numpy

>>> import numpy as np >>> import cv2
>>> import os

Cargar archivos de la imagen que queremos comparar

El siguiente paso será cargar los archivos de imagen cuya información queremos comparar. Para ello, usamos el método “.imread()” pasando el nombre del archivo el modo en que queremos que se cargue (1, para imagen en color y 0, para escala de grises):

//imágenes en Python con Opencv y Numpy

>>>  import numpy as np

>>>  import cv2

>>>  import os >>>

>>>  os.chdir(r’C:\Users\Antonio\Documents\Nueva carpeta’)

Comparar la segunda imagen con el método «.imread()»

El siguiente paso será cargar los archivos de imagen cuya información queremos comparar. Para ello, usamos el método “.imread()” pasando el nombre del archivo el modo en que queremos que se cargue (1, para imagen en color y 0, para escala de grises):

>>> import numpy as np >>> import cv2
>>> import os

>>>

>>>  os.chdir(r’C:\Users\Antonio\Documents\Nueva carpeta’) >>>

>>>  #CARGAMOS IMAGENES A COMPARAR.

//imágenes en Python con Opencv y Numpy

>>>  imagen1 = cv2.imread(«Lenna.png»,1)

>>>  imagen2 = cv2.imread(«Lenna2.png»,1) >>>

Para ver la imagen cargada (por ejemplo, la contenida en “imagen1”) podemos hacer uso del método “imshow()”:

//imágenes en Python con Opencv y Numpy

>>>  import numpy as np

>>>  import cv2

>>>  import os

>>>

>>>  os.chdir(r’C:\Users\Antonio\Documents\Nueva carpeta’)

>>>

>>>  #CARGAMOS IMAGENES A COMPARAR.

//imágenes en Python con Opencv y Numpy

>>>  imagen1 = cv2.imread(«Lenna.png»,1)

>>>  imagen2 = cv2.imread(«Lenna2.png»,1) >>>

>>>  #VER «imagen1».

>>>  cv2.imshow(«Photo»,imagen1)

>>>
Lo que abrirá una ventana con la imagen cargada:

imágenes en Python con Opencv y Numpy
compare two images python

Para visualizar la imagen contenida en “imagen2” haríamos exactamente lo mismo. Sin embargo cuando queremos comparar dos imágenes, puede resultar más útil representarlas conjuntamente. Para ello, antes de emplear el método “imshow()” podemos conseguir, con “numpy” y el método “hstack()” o cv2 hstack (que tomará las imágenes a visualizar de forma conjunta), la representación (ya con el método “.imshow()“) de ambas:

//imágenes en Python con Opencv y Numpy

>>>python image similarity

>>> ¿con qué imágenes la compara?

>>> #VER AMBAS IMAGENES.
>>> imas = np.hstack((imagen1,imagen2))
>>> cv2.imshow(«Imagenes»,imas)

Obteniendo el siguiente resultado:

imágenes en Python con Opencv y Numpy

Como se puede comprobar a primera vista, las imágenes contenidas en “imagen1” e “imagen2” son idénticas. No obstante, vamos a comprobarlo haciendo uso de la información contenida en cada pixel (lectura de información que efectuaremos con “numpy“).

Antes de ello, hemos de recordar que podemos obtener la información de color para cada pixel simplemente aplicando la función “print()” al resultado de la lectura mediante “.imread()“. Esto, aplicado a la información de “imagen1“:

//imágenes en Python con Opencv y Numpy

>>> print(imagen1)

[[[125 137 226]
[125 137 226]
[133 137 223]

[122 148 230]
[110 130 221]
[ 90 99 200]]

[[125 137 226]
[125 137 226]
[133 137 223]

[122 148 230]
[110 130 221]
[ 90 99 200]]

[[125 137 226]
[125 137 226]
[133 137 223]

[122 148 230]
[110 130 221]
[ 90 99 200]]

[[60 18 84]
[ 60 18 84]
[ 58 27 92]

[ 84 73 173]
[ 76 68 172]
[ 79 62 177]]

[[57 22 82]
[ 57 22 82]
[ 62 32 96]

[ 79 70 179]
[ 81 71 181]
[ 81 74 185]]

[[57 22 82]
[ 57 22 82]
[ 62 32 96]

[ 79 70 179]
[ 81 71 181]
[ 81 74 185]]]

>>>

Nos daría un array en el que, cada fila, representaría los valores (de 0 a 255) de los canales azul, verde y rojo, (“BGR“) de cada pixel (al ser una imagen en python en la que predominan las tonalidades rojizas, se entiende que los valores más elevados sean los correspondientes al canal rojo).

Partiendo de ahí, vamos a determinar la igualdad (o no) de nuestras imágenes, restando los valores de sus correspondientes arrays, de modo que

solo si ambas imágenes son iguales, (teniendo los mismos valores para cada pixel), el array resultante tendrá todos sus valores igual a cero (al ser la diferencia de ambas). Para esto último, usaremos el método “.subtract()“, que reatará los arrays de “imagen1” e “imagen2“.

Nota:Para la realización de esta operación, es necesario que ambas imágenes posean las mismas dimensiones.

//imágenes en Python con Opencv y Numpy

>>> diferencia = cv2.subtract(imagen1,imagen2)
>>>
>>> print(diferencia)
[[[0 0 0]
[0 0 0]
[0 0 0]

[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]

[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]

[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]

[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]

[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]

[0 0 0]
[0 0 0]
[0 0 0]]]

>>>

Como se ve, el array resultante de la operación (el cual hemos almacenado en la variable “diferencia”) tiene todos sus valores iguales a cero. Partiendo de aquí, podemos crear una función que, dados los dos archivos de imagen, reafirme o desmienta la igualdad entre ellos.

//imágenes en Python con Opencv y Numpy

>>> import cv2
>>> import numpy as np >>> import os
>>>

>>>  os.chdir(r’C:\Users\Antonio\Documents\Nueva carpeta’) >>>

>>>  #CARGAMOS IMAGENES A COMPARAR.

//imágenes en Python con Opencv y Numpy

>>>  imagen1 = cv2.imread(«Lenna.png»,1)

>>>  imagen2 = cv2.imread(«Lenna2.png»,1) >>>

>>>  #FUNCIÓN DE COMPARACIÓN.

>>>  def compara(im1,im2):

diferencia = cv2.subtract(im1,im2) if not np.any(diferencia):

//imágenes en Python con Opencv y Numpy

print(«Las imágenes son iguales») else:

print(«Las imágenes son iguales»)

>>>  compara(imagen1,imagen2) Las imágenes son iguales
>>>

Como se ve, hemos creado una función («compara()») que empieza efectuando la operación de restar los arrays de las imágenes a comparar, para a continuación, comprobar si en el array resultante (contenido en «diferencia») hay algún valor no evaluado como «False» (por ser 0): De no ser así («if not.np.any(diferencia):») se imprimirá el texto que expresa la igualdad de las imágenes. Si, por contra, encuentra dicho valor distinto de 0, se imprimirá el texto que expresa su diferencia: Tal y como habíamos predicho, la función ha verificado dicha igualdad.

Hasta ahora, hemos hecho la prueba con 2 imágenes idénticas. A continuación vamos a ver que sucede si introducimos un cambio en «imagen2» (consistente en el uso de una versión editada de la imagen original, a la que llamamos «Lenna_new.png»). Introducido el cambio, mostraremos la nueva imagen junto a la original:

//imágenes en Python con Opencv y Numpy

>>>  imagen1 = cv2.imread(«Lenna.png»,1)

>>>  imagen2 = cv2.imread(«Lenna_new.png»,1) >>>

>>>  imas = np.hstack((imagen1,imagen2))

>>>  cv2.imshow(«Imagenes»,imas)

imágenes en Python con Opencv y Numpy

Se ve como en «imagen2» hemos trazado unos caracteres, lo cual, conllevará que ahora el array de «imagen2» tendrá algunos valores distintos de los de «imagen1». Así, si volvemos a repetir la operación de resta antes vista, almacenando el array resultante en «diferencia»:

//imágenes en Python con Opencv y Numpy

>>> diferencia = cv2.subtract(imagen1,imagen2)
>>> print(diferencia)
[[[109 120 198]
[109 120 198]
[54 56 91]

[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]

[[125 137 226]
[125 137 226]
[133 137 223]

[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]

[[125 137 226]
[125 137 226]
[133 137 223]

[  0 0 0]
[  0 0 0]
[  0 0 0]]

[[ 0 0 0]
[  0 0 0]
[  0 0 0]

[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]

[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]

[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]

[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]

[ 0 0 0]
[ 0 0 0]
[0 0 0]]]
>>>

Vemos cómo, ahora, no todos los valores resultantes son 0. Por su parte, debido a que los trazos introducidos para el archivo de «imagen2» son de color negro (valores «BGR»=(0,0,0)), al hacer la resta, los valores distintos de 0 en el nuevo array coincidirán con los valores, para esos pixeles, de las imagen contenida en «imagen1», como veremos más adelante. Por su parte, si ahora aplicamos nuevamente la función «compara()»:

//imágenes en Python con Opencv y Numpy

>>> def compara(im1,im2):
diferencia = cv2.subtract(im1,im2) if not np.any(diferencia):

//imágenes en Python con Opencv y Numpy

print(«Las imágenes son iguales») else:

print(«Las imágenes son distintas»)

//imágenes en Python con Opencv y Numpy

>>> compara(imagen1,imagen2)

Las imágenes son distintas

>>>

Diferencia entre ambas imágenes

Vemos cómo, en efecto, nuestra función certifica la diferencia entre ambos archivos de imagen.

Finalmente, podemos plasmar en un archivo de imagen, el resultado de restar los arrays de nuestras imágenes, almacenado en «diferencia». Para escribir una nueva imagen, usamos el método «.imwrite()» introduciendo como argumentos, el nombre de nuestro nuevo archivo y la variable en la que se encuentra la información a representar en la imagen:

//imágenes en Python con Opencv y Numpy

>>> #CREAR IMÁGEN DE «diferencia».
>>> cv2.imwrite(«im_diferencia.png»,diferencia) True
>>>

Creándose un nuevo archivo de imagen de nombre «im_diferencia.png» en el que los pixeles cuyos valores GBR sean (0,0,0) se mostrarán , naturalmente en negro, mientras los que tenga valores distintos, se mostrarán en colores acordes a sus respectivas intensidades para cada canal:

imágenes en Python con Opencv y Numpy

Vemos aquí, la imagen creada con la información contenida en el array «diferencia». En donde los pixeles cuyos valores son 0,0,0 (fruto de la resta de los valores coincidentes de «imagen1» e «imagen2») aparecen en negro ((0,0,0) son los valores correspondientes al color negro) mientras que los valores, fruto de la diferencia entre la imagen original («imagen1») y los valores (0,0,0) de los caracteres trazados sobre «imagen2» aparecen ahora con las tonalidades originales. Dando lugar a una curiosa versión invertida (en términos de color) con respecto al contenido de «imagen2».

Comparación de imágenes en Python con Opencv y Numpy

Antonio Alfonso MartínezAntonio Alfonso Martínez

Programador y desarrollador autodidacta.

Semanalmente publica en el blog El programador Chapuzas (wordpress) y también colaboro en las páginas “Código Comentado” y “Algoritmos MathPy” de Facebook.

Si quieres formar parte de la comunidad KeepCoding, compartiendo información relevante sobre desarrollo Web, Mobile, Big Data o Blockchain puedes escribirnos a [email protected] .