Ecualización de histograma

La ecualización de imagenes tiene como objetivo mejorar la visualización de una imagen mediante un procedimiento que fomenta la uniforme existencia de intensidades dentro de la imagen. Dicha uniformidad permite aprovechar el todo el rango de valores que la imagen puede expresar y por tanto permite que esta incremente su contraste.

Imagen antes de la ecualización

Histograma antes de la ecualización

Función de probabilidad antes de la ecualización

Imagen después de la ecualización

Histograma despues de la ecualización

Función de probabilidad despues de la ecualización

Como se puede observar, la ecualización permite aprovechar el todo el rango de valores de intensidad de una imagen, lo cual en múltiples ocasiones facilita la clara precepción de las caracteristicas de la imagen de interes. Para implementar dicho procedimiento, solo es necesario seguir los siguientes pasos:

Script empleado en el ejemplo:

import cv2

import numpy as np

import matplotlib.pyplot as plt

import seaborn as sns

from scipy import interpolate


def main():

    # Se carga la imagen a trabajar

    imagen = cv2.imread('bosque.jpg')

    

    # Se acomoda la informacion para ser trabajada por canales

    canales = np.array(cv2.split(imagen))

    

    col = ['b', 'g', 'r']

    resultado = canales

    

    hist_antes = np.zeros((3, 256))

    hist_despu = np.zeros((3, 256))

    

    fun_pro_antes = np.zeros((3, 256))

    fun_pro_despu = np.zeros((3, 256))

    

    # Se ecualiza cada canal de forma independiente

    for i, canal in enumerate(canales):

        # Se calcula el histograma del canal

        hist = cv2.calcHist(canal, [0], None, [256], [0,256])

        hist = np.transpose(hist)[0]

        

        # Se guarda el histograma del canal

        hist_antes[i] = hist

        

        # Se calcula la funcion de probabilidad

        fp = hist.cumsum()

        fp = (fp/fp[-1])

        

        # Se guarda la funcion de probabilidad del canal

        fun_pro_antes[i] = fp

        

        # Se pasa la imagen por la funcion de probabilidad y se remapea

        resultado[i] = (fp[canal]*255).astype(int)

                

        # Se calcula el histograma del canal ecualizado

        hist = cv2.calcHist(resultado[i], [0], None, [256], [0,256])

        hist = np.transpose(hist)[0]

        

        # Se guarda el histograma del canal ecualizado

        hist_despu[i] = hist

        

        # Se calcula la funcion de probabilidad del canal ecualizado

        fp = hist.cumsum()

        fp = (fp/fp[-1])

        

        # Se guarda la funcion de probabilidad del canal ecualizado

        fun_pro_despu[i] = fp

        

    imagen_ecualizada = cv2.merge(resultado)

    

    # Se muestra la imagen original

    plt.figure(dpi=300)

    plt.tight_layout() 

    plt.axis('off')

    plt.imshow(cv2.cvtColor(imagen, cv2.COLOR_BGR2RGB), vmin=0, vmax=255)

    plt.show()

    cv2.imwrite('Original.png', imagen)

    

    # Se muestra la imagen ecualizada

    plt.figure(dpi=300)

    plt.tight_layout() 

    plt.axis('off')

    plt.imshow(cv2.cvtColor(imagen_ecualizada, cv2.COLOR_BGR2RGB), vmin=0, vmax=255)

    plt.show()

    cv2.imwrite('Ecualizada.png', imagen_ecualizada)

    

    #Se muestran los histogramas antes de procesar

    plt.figure(figsize=(8, 6), dpi=300)

    for i, hist in enumerate(hist_antes):

        plt.plot(np.arange(256), hist, color = col[i])

    plt.tight_layout()

    plt.savefig('Histograma original.png', dpi=300, bbox_inches='tight')

    plt.show()

    

    #Se muestran los histogramas antes de procesar

    plt.figure(figsize=(8, 6), dpi=300)

    for i, hist in enumerate(hist_despu):

        plt.plot(np.arange(256), hist, color = col[i])

    plt.tight_layout()

    plt.savefig('Histograma ecualizado.png', dpi=300, bbox_inches='tight')

    plt.show()

    

    #Se muestran los histogramas antes de procesar

    plt.figure(figsize=(8, 6), dpi=300)

    for i, fun_pro in enumerate(fun_pro_antes):

        plt.plot(np.arange(256), fun_pro, color = col[i])

    plt.tight_layout()

    plt.savefig('Funcion de probabilidad original.png', dpi=300, bbox_inches='tight')

    plt.show()

    

    #Se muestran los histogramas antes de procesar

    plt.figure(figsize=(8, 6), dpi=300)

    for i, fun_pro in enumerate(fun_pro_despu):

        plt.plot(np.arange(256), fun_pro, color = col[i])

    plt.tight_layout()

    plt.savefig('Funcion de probabilidad ecualizado .png', dpi=300, bbox_inches='tight')

    plt.show()

    


if __name__ == '__main__':

    sns.set_theme(style= 'darkgrid' )

    main()