Python | Operaciones de Transformación de Intensidad en Imágenes

Las transformaciones de intensidad se aplican a las imágenes para la manipulación del contraste o la umbralización de la imagen. Estos están en el dominio espacial, es decir, se realizan directamente en los píxeles de la imagen en cuestión, en lugar de realizarse en la transformada de Fourier de la imagen.

Las siguientes son transformaciones de intensidad de uso común:

  1. Negativos de imagen (lineal)
  2. Transformaciones de registro
  3. Transformaciones de ley de potencia (gamma)
  4. Funciones de transformación lineal por partes

Procesos de
dominio espacial: los procesos de dominio espacial se pueden describir mediante la ecuación: g(x, y) = T[f(x, y)]donde f(x, y)está la imagen de entrada, T es un operador en f definido sobre una vecindad del punto (x, y) y g(x, y)es la salida.

Negativos de imagen –

Los negativos de imagen se tratan en este artículo . Matemáticamente, suponga que una imagen pasa de los niveles de intensidad 0 a (L-1). Generalmente, L = 256. Entonces, la transformación negativa se puede describir mediante la expresión s = L-1-r donde r es el nivel de intensidad inicial y s es el nivel de intensidad final de un píxel. Esto produce un negativo fotográfico.

Transformaciones de registro –

Matemáticamente, las transformaciones logarítmicas se pueden expresar como s = clog(1+r). Aquí, s es la intensidad de salida, r>=0 es la intensidad de entrada del píxel y c es una constante de escala. c viene dado por 255/(log (1 + m)), donde m es el valor máximo de píxel en la imagen. Se realiza para garantizar que el valor de píxel final no exceda (L-1), o 255. En la práctica, la transformación de registros asigna un rango estrecho de valores de entrada de baja intensidad a un rango amplio de valores de salida.

Considere la siguiente imagen de entrada.

A continuación se muestra el código para aplicar la transformación de registro a la imagen.

import cv2
import numpy as np
  
# Open the image.
img = cv2.imread('sample.jpg')
  
# Apply log transform.
c = 255/(np.log(1 + np.max(img)))
log_transformed = c * np.log(1 + img)
  
# Specify the data type.
log_transformed = np.array(log_transformed, dtype = np.uint8)
  
# Save the output.
cv2.imwrite('log_transformed.jpg', log_transformed)

A continuación se muestra la salida transformada en registro.

Transformación de ley de potencia (gamma) –

Las transformaciones de ley de potencia (gamma) se pueden expresar matemáticamente como s = cr^{\gamma}. La corrección gamma es importante para mostrar correctamente las imágenes en una pantalla, para evitar que las imágenes se decoloren o se oscurezcan cuando se ven desde diferentes tipos de monitores con diferentes configuraciones de visualización. Esto se hace porque nuestros ojos perciben imágenes en una curva en forma de gamma, mientras que las cámaras capturan imágenes de forma lineal. A continuación se muestra el código de Python para aplicar la corrección gamma.

import cv2
import numpy as np
  
# Open the image.
img = cv2.imread('sample.jpg')
  
# Trying 4 gamma values.
for gamma in [0.1, 0.5, 1.2, 2.2]:
      
    # Apply gamma correction.
    gamma_corrected = np.array(255*(img / 255) ** gamma, dtype = 'uint8')
  
    # Save edited images.
    cv2.imwrite('gamma_transformed'+str(gamma)+'.jpg', gamma_corrected)

A continuación se muestran las salidas con corrección de gamma para diferentes valores de gamma.

gama = 0,1:

Gama = 0,5:

Gama = 1.2:

Gama = 2.2:

Como se puede observar tanto en las salidas como en el gráfico, gamma>1 (indicado por la curva correspondiente a la etiqueta de ‘n-ésima potencia’ en el gráfico), la intensidad de los píxeles disminuye, es decir, la imagen se oscurece. Por otro lado, gamma<1 (indicado por la curva correspondiente a la etiqueta ‘raíz enésima’ en el gráfico), la intensidad aumenta, es decir, la imagen se vuelve más clara.

Funciones de transformación lineales por partes –

Estas funciones, como sugiere su nombre, no son completamente lineales por naturaleza. Sin embargo, son lineales entre ciertos intervalos de x. Una de las funciones de transformación lineal por partes más utilizadas es el estiramiento de contraste.

El contraste se puede definir como:

Contrast =  (I_max - I_min)/(I_max + I_min)

Este proceso amplía el rango de niveles de intensidad en una imagen para que abarque toda la intensidad de la cámara/pantalla. La siguiente figura muestra el gráfico correspondiente al estiramiento del contraste.

Con (r1, s1), (r2, s2) como parámetros, la función amplía los niveles de intensidad esencialmente reduciendo la intensidad de los píxeles oscuros y aumentando la intensidad de los píxeles claros. Si r1 = s1 = 0 y r2 = s2 = L-1, la función se convierte en una línea recta de puntos en el gráfico (lo que no produce ningún efecto). La función aumenta monótonamente para que se conserve el orden de los niveles de intensidad entre los píxeles.

A continuación se muestra el código de Python para realizar el estiramiento de contraste.

import cv2
import numpy as np
  
# Function to map each intensity level to output intensity level.
def pixelVal(pix, r1, s1, r2, s2):
    if (0 <= pix and pix <= r1):
        return (s1 / r1)*pix
    elif (r1 < pix and pix <= r2):
        return ((s2 - s1)/(r2 - r1)) * (pix - r1) + s1
    else:
        return ((255 - s2)/(255 - r2)) * (pix - r2) + s2
  
# Open the image.
img = cv2.imread('sample.jpg')
  
# Define parameters.
r1 = 70
s1 = 0
r2 = 140
s2 = 255
  
# Vectorize the function to apply it to each value in the Numpy array.
pixelVal_vec = np.vectorize(pixelVal)
  
# Apply contrast stretching.
contrast_stretched = pixelVal_vec(img, r1, s1, r2, s2)
  
# Save edited image.
cv2.imwrite('contrast_stretch.jpg', contrast_stretched)

Producción:

Publicación traducida automáticamente

Artículo escrito por Anannya Uberoi 1 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 *