Coincidencia de histogramas con OpenCV, scikit-image y Python

La coincidencia de histogramas se usa para normalizar la representación de imágenes, se puede usar para la coincidencia de características, especialmente cuando las imágenes provienen de fuentes diversas o en condiciones variadas (dependiendo de la luz, etc.). cada imagen tiene un número de canales, cada canal se empareja individualmente. La coincidencia de histogramas solo es posible si el número de canales coincide en las imágenes de entrada y de referencia.

El objetivo principal de la coincidencia de histogramas es:

  • Para cada imagen, necesitamos crear histogramas.
  • Echa un vistazo al histograma de la imagen de referencia.
  • Usando el histograma de referencia, actualice los valores de intensidad de píxeles en la imagen de entrada para que coincidan.

método match_histograms():

Este método se utiliza para modificar el histograma acumulativo de una imagen para que coincida con el histograma de otra. Para cada canal, la modificación se realiza de forma independiente.

Sintaxis: skimage.exposure.match_histograms(imagen, referencia, *, channel_axis=Ninguno, multicanal=Falso)

Parámetros:

  • imagen : ndarray. Este parámetro es nuestra imagen de entrada, puede ser una imagen en escala de grises o en color.
  • referencia : imagen de referencia. imagen de referencia para que coincida con los histogramas.
  • channel_axis : parámetro opcional. int o Ninguno. Si se especifica Ninguno, se supondrá que la imagen está en escala de grises (canal único). si no, este argumento especifica el eje de la array que corresponde a los canales.
  • multicanal: parámetro opcional. valor booleano. El emparejamiento debe hacerse de forma independiente para cada canal. Esta opción ha quedado obsoleta; en su lugar, utilice el eje del canal.

Ejemplo 1: uso de OpenCV y scikit-image.

El código comienza con la importación de los paquetes necesarios, la lectura de imágenes usando el método imread() de OpenCV y luego verificamos la cantidad de canales de la imagen de entrada y la imagen de referencia; si no coinciden, no podemos realizar la comparación de histogramas. match_histograms se utiliza para encontrar la imagen coincidente. Se trazan histogramas para cada canal.

Python3

# import packages
import matplotlib.pyplot as plt
from skimage import exposure
from skimage.exposure import match_histograms
import cv2
  
# reading main image
img1 = cv2.imread("img.jpeg")
  
# checking the number of channels
print('No of Channel is: ' + str(img1.ndim))
  
# reading reference image
img2 = cv2.imread("2Fw13.jpeg")
  
# checking the number of channels
print('No of Channel is: ' + str(img2.ndim))
  
image = img1
reference = img2
  
matched = match_histograms(image, reference ,
                           multichannel=True)
  
  
fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, 
                                    figsize=(8, 3),
                                    sharex=True, sharey=True)
  
for aa in (ax1, ax2, ax3):
    aa.set_axis_off()
  
ax1.imshow(image)
ax1.set_title('Source')
ax2.imshow(reference)
ax2.set_title('Reference')
ax3.imshow(matched)
ax3.set_title('Matched')
  
plt.tight_layout()
plt.show()
  
fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(8, 8))
  
for i, img in enumerate((image, reference, matched)):
    for c, c_color in enumerate(('red', 'green', 'blue')):
        img_hist, bins = exposure.histogram(img[..., c], 
                                            source_range='dtype')
        axes[c, i].plot(bins, img_hist / img_hist.max())
        img_cdf, bins = exposure.cumulative_distribution(img[..., c])
        axes[c, i].plot(bins, img_cdf)
        axes[c, 0].set_ylabel(c_color)
  
axes[0, 0].set_title('Source')
axes[0, 1].set_title('Reference')
axes[0, 2].set_title('Matched')
  
plt.tight_layout()
plt.show()

Producción:

Ejemplo 2: usando solo scikit-image:

Este ejemplo es similar al anterior, excepto que cargamos imágenes del paquete skimage.data. Luego hacemos coincidir histogramas, mostramos imágenes y trazamos histogramas.

Python3

# importing packages
import matplotlib.pyplot as plt
from skimage import data
from skimage import exposure
from skimage.exposure import match_histograms
  
# loading data
reference = data.moon()
image = data.camera()
  
# matching histograms
matched = match_histograms(image, reference, 
                           multichannel=True,)
  
fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, 
                                    ncols=3, 
                                    figsize=(8, 3),
                                    sharex=True, 
                                    sharey=True)
for aa in (ax1, ax2, ax3):
    aa.set_axis_off()
  
# displaying images
ax1.imshow(image)
ax1.set_title('Source image')
ax2.imshow(reference)
ax2.set_title('Reference image')
ax3.imshow(matched)
ax3.set_title('Matched image')
  
plt.tight_layout()
plt.show()

Producción»

Visualización del histograma de las imágenes utilizadas anteriormente.

Python3

# displaying histograms.
fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(8, 8))
  
for i, img in enumerate((image, reference, matched)):
    for c, c_color in enumerate(('red', 'green', 'blue')):
        img_hist, bins = exposure.histogram(img[..., c],
                                            source_range='dtype')
        axes[c, i].plot(bins, img_hist / img_hist.max())
        img_cdf, bins = exposure.cumulative_distribution(img[..., c])
        axes[c, i].plot(bins, img_cdf)
        axes[c, 0].set_ylabel(c_color)
  
axes[0, 0].set_title('Source image')
axes[0, 1].set_title('Reference image')
axes[0, 2].set_title('Matched image')
  
plt.tight_layout()
plt.show()

Producción:

Publicación traducida automáticamente

Artículo escrito por isitapol2002 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *