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

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 «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:

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

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’)

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.

>>>  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()”:

>>>  import numpy as np

>>>  import cv2

>>>  import os

>>>

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

>>>

>>>  #CARGAMOS IMAGENES A COMPARAR.

>>>  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:

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()” (que tomará las imágenes a visualizar de forma conjunta), la representación (ya con el método “.imshow()“) de ambas:

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

Obteniendo el siguiente resultado:

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“:

>>> 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 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.

>>> 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.

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

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

>>>  #CARGAMOS IMAGENES A COMPARAR.

>>>  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):

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:

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

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

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

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

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»:

>>> 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()»:

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

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

print(«Las imágenes son distintas»)

>>> compara(imagen1,imagen2)

Las imágenes son distintas

>>>

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:

>>> #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:

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».

 

Antonio Alfonso MartínezProgramador 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 JustCodeIt, compartiendo información relevante sobre desarrollo Web, Mobile, Big Data o Blockchain puedes escribirnos a [email protected] .

Share this:

Leave a comment