Aprende a generar el hash perceptual de una imagen con Python.

Cómo determinar si 2 imágenes son iguales o no con el hash perceptual en Python

Un hash perceptual es una cadena generada (hash) que se produce mediante un algoritmo especial. Este hash perceptual es una huella dactilar basada en alguna imagen de entrada, que se puede usar para comparar imágenes calculando la distancia de Hamming (que básicamente cuenta el número de bits individuales diferentes). Si utiliza otra técnica de hash para comparar imágenes, hacer el más mínimo cambio en la imagen generará un hash totalmente diferente (por ejemplo, MD5 o SHA1).

En este artículo, le mostraremos cómo generar diferentes versiones de un hash perceptual a partir de imágenes en Python.

1. Descarga el proyecto imagehash

Para comparar 2 imágenes y verificar si son perceptualmente iguales utilizando un hash perceptual en Python, nos basaremos en la propuesta del proyecto imagehash de @JohannesBuchner. Este proyecto es una biblioteca de hash de imágenes escrita en Python que admite:

  • hash promedio ( aHash )
  • percepción hash ( pHash )
  • hash de diferencias ( dHash )
  • hash de wavelet ( wHash )

Puede obtener el código fuente de este proyecto con Git usando el siguiente comando:

git clone https://github.com/JohannesBuchner/imagehash.git

Después de clonarlo, podrá seguir el resto del tutorial. Para obtener más información sobre esta biblioteca, visite el repositorio oficial en Github aquí.

2. Instalar dependencias

El proyecto imagehash necesita previamente algunas dependencias para funcionar correctamente, se pueden instalar fácilmente con pip (si no está instalado, instale pip con sudo apt install python-pip) y leyendo la lista de requisitos del proyecto, así que cambie de directorio:

cd imagehash

Y luego instala las dependencias con:

pip install -r conda-requirements.txt

Las dependencias son:

  • six : Six proporciona utilidades simples para resumir las diferencias entre Python 2 y Python 3. Está diseñado para admitir bases de código que funcionan en Python 2 y 3 sin modificaciones. seis consta de un solo archivo de Python, por lo que es fácil de copiar en un proyecto.
  • Pillow : Pillow es el simpático tenedor PIL de Alex Clark and Contributors. PIL es la biblioteca de imágenes de Python de Fredrik Lundh y colaboradores.
  • numpy : NumPy es el paquete fundamental para la computación científica con Python. Contiene entre otras cosas.
  • scipy : SciPy es un ecosistema de software de código abierto basado en Python para matemáticas, ciencia e ingeniería.
  • pywavelets : PyWavelets es un software de transformación de ondas de código abierto para Python. Combina una interfaz simple de alto nivel con un rendimiento de C y Cython de bajo nivel.

Después de la instalación de las bibliotecas, ahora podrás usarla y generar los diferentes hashes que ofrece esta biblioteca.

3. Comparación de imágenes

Puedes seguir estos ejemplos para generar los diferentes hashes perceptuales que se pueden generar con este proyecto de Python:

A. Hash promedio

La forma más fácil de generar un hash perceptual y probablemente la que elija, se puede implementar fácilmente como se muestra en el siguiente ejemplo:

# example_averagehash.py

# Import dependencies
from PIL import Image
import imagehash

# Create the Hash Object of the first image
HDBatmanHash = imagehash.average_hash(Image.open('batman_hd.jpg'))
print('Batman HD Picture: ' + str(HDBatmanHash))

# Create the Hash Object of the second image
SDBatmanHash = imagehash.average_hash(Image.open('batman_sd.jpg'))
print('Batman HD Picture: ' + str(SDBatmanHash))

# Compare hashes to determine whether the pictures are the same or not
if(HDBatmanHash == SDBatmanHash):
    print("The pictures are perceptually the same !")
else:
    print("The pictures are different, distance: " + (HDBatmanHash - SDBatmanHash))

En este caso, ejecutar el script con python example_averagehash.py generará la siguiente salida en la terminal:

Batman HD Picture: 030f4f0f87070301
Batman HD Picture: 030f4f0f87070301
The pictures are perceptually the same !

Como las imágenes de batman son las mismas, solo que la primera imagen tiene una resolución mayor que la primera, generarán el mismo hash  030f4f0f87070301, ¡aunque no sean el mismo archivo! Puedes leer una explicación teórica muy detallada de cómo se genera el hash promedio en este blog.

B. Percepción Hash (pHash)

Con el cálculo Perceptual Hash, que sigue esta implementación , se puede usar así:

# example_phash.py

# Import dependencies
from PIL import Image
import imagehash

# Create the Hash Object of the first image
HDBatmanHash = imagehash.phash(Image.open('batman_hd.jpg'))
print('Batman HD Picture: ' + str(HDBatmanHash))

# Create the Hash Object of the second image
SDBatmanHash = imagehash.phash(Image.open('batman_sd.jpg'))
print('Batman HD Picture: ' + str(SDBatmanHash))

# Compare hashes to determine whether the pictures are the same or not
if(HDBatmanHash == SDBatmanHash):
    print("The pictures are perceptually the same !")
else:
    print("The pictures are different, distance: " + (HDBatmanHash - SDBatmanHash))

En este caso, ejecutar el script con python example_phash.py generará la siguiente salida en la terminal:

Batman HD Picture: a8d14ab75aa9c62b
Batman HD Picture: a8d14ab75aa9c62b
The pictures are perceptually the same !

C. Diferencia de hash (dHash)

Con el cálculo de Difference Hash, que sigue esta implementación , se puede usar así:

# example_dhash.py

# Import dependencies
from PIL import Image
import imagehash

# Create the Hash Object of the first image
HDBatmanHash = imagehash.dhash(Image.open('batman_hd.jpg'))
print('Batman HD Picture: ' + str(HDBatmanHash))

# Create the Hash Object of the second image
SDBatmanHash = imagehash.dhash(Image.open('batman_sd.jpg'))
print('Batman HD Picture: ' + str(SDBatmanHash))

# Compare hashes to determine whether the pictures are the same or not
if(HDBatmanHash == SDBatmanHash):
    print("The pictures are perceptually the same !")
else:
    print("The pictures are different, distance: " + (HDBatmanHash - SDBatmanHash))

En este caso, ejecutar el script con python example_dhash.py generará la siguiente salida en la terminal:

Batman HD Picture: bf9f97372c2ebbb3
Batman HD Picture: bf9f97372c2ebbb3
The pictures are perceptually the same !

D. Hash de ondas (wHash)

Con el cálculo Wavelet Hash, que sigue esta implementación, se puede usar así:

# example_whash.py

# Import dependencies
from PIL import Image
import imagehash

# Create the Hash Object of the first image
HDBatmanHash = imagehash.whash(Image.open('batman_hd.jpg'))
print('Batman HD Picture: ' + str(HDBatmanHash))

# Create the Hash Object of the second image
SDBatmanHash = imagehash.whash(Image.open('batman_sd.jpg'))
print('Batman HD Picture: ' + str(SDBatmanHash))

# Compare hashes to determine whether the pictures are the same or not
if(HDBatmanHash == SDBatmanHash):
    print("The pictures are perceptually the same !")
else:
    print("The pictures are different, distance: " + (HDBatmanHash - SDBatmanHash))

En este caso, ejecutar el script con python example_whash.py generará la siguiente salida en la terminal:

Batman HD Picture: 074fdfdf87070301
Batman HD Picture: 074fdfdf87070301
The pictures are perceptually the same !

Que te diviertas ❤️!


Interesado en la programación desde los 14 años, Carlos es un programador autodidacta, fundador y autor de la mayoría de los artículos de Our Code World.

Conviertete en un programador más sociable

Patrocinadores