Saltar al contenido principal

Suavizado de imágenes

info

Todo el código de ejemplo se encuentra en Google Colab para su ejecución directa. Si no puedes ejecutar OpenCV localmente, puedes usar Google Colab junto con matplotlib para visualizar imágenes. Además las imágenes que se utilizarán en los ejemplos son sudoku_1.jpg y textura.jpg.

Objetivo

  • Aprender los principales métodos de suavizado de imágenes.
  • Comprender cómo los diferentes filtros modifican el ruido y los detalles finos.
  • Aplicar convolución 2D, desenfoques promedio, gaussiano, mediano y bilateral en OpenCV para preparar imágenes para análisis posterior.

Conceptos clave

  • Kernel: Matriz que define la vecindad de píxeles usada para el filtrado.
  • Convolución 2D: Operación que combina el kernel con la imagen para aplicar un efecto (suavizado, detección de bordes, etc.).
  • Desenfoque: Técnica que suaviza la imagen, reduciendo ruido y detalles finos.
  • Desenfoque promedio: Reemplaza cada píxel por el promedio de su vecindad.
  • Desenfoque gaussiano: Suaviza la imagen usando un kernel ponderado según una distribución gaussiana.
  • Desenfoque medio: Reemplaza cada píxel por la mediana de su vecindad, es muy útil para eliminar ruido.
  • Filtro bilateral: Suaviza la imagen preservando bordes y combina proximidad espacial y similitud de color.

Funciones principales en OpenCV

  • cv.filter2D(): Aplica una convolución 2D con el kernel definido.
  • cv.blur(): Desenfoque promedio simple en donde cada píxel se reemplaza por el promedio de su vecindad.
  • cv.GaussianBlur(): Desenfoque gaussiano que pondera píxeles cercanos más fuertemente.
  • cv.medianBlur(): Desenfoque mediano que reemplaza el píxel central por la mediana de su vecindad.
  • cv.bilateralFilter(): Desenfoque bilateral que suaviza la imagen preservando bordes y detalles.

Convolución 2D (Filtrado de imágenes)

La convolución 2D es una operación que combina un kernel con la imagen para modificar los valores de los píxeles. Se utiliza para suavizar, resaltar bordes, detectar patrones o reducir ruido. El efecto depende del tipo de kernel que se aplique. Es la base de muchos filtros en procesamiento de imágenes.

  • Uso típico: Suavizado general, detección de bordes, filtrado lineal, preprocesamiento para segmentación o reconocimiento de objetos.
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img = cv.imread('sudoku_1.jpg')

# Definir un kernel 5x5 para que actúe como un suavizado promedio
kernel = np.ones((5,5),np.float32)/25

# Aplicar el filtro a la imagen con convolución 2D
dst = cv.filter2D(
img, # Imagen original
-1, # -1 indica que el tipo de salida será igual que la imagen original
kernel) # Kernel definido

# Generar plots de imágenes
plt.subplot(121),plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB)),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(cv.cvtColor(dst, cv.COLOR_BGR2RGB)),plt.title('Imagen filtrada')
plt.xticks([]), plt.yticks([])
plt.show()

Desenfoque de imagen

El desenfoque de imagen es una técnica utilizada para reducir el ruido y los detalles finos en una imagen. En OpenCV, existen varios métodos para aplicar desenfoque, cada uno con sus propias características y aplicaciones.

Promedio

El desenfoque promedio reemplaza cada píxel por el promedio de sus vecinos según un kernel definido.

  • Qué hace: Suaviza la imagen reduciendo detalles finos y ruido aleatorio.
  • Cuándo se usa: Cuando se necesita un suavizado general y la pérdida de bordes no es crítica.
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('sudoku_1.jpg')

# Aplicar desenfoque a la imagen
blur = cv.blur(img,(5,5))

# Generar plots de imágenes
plt.subplot(121),plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB)),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(cv.cvtColor(blur, cv.COLOR_BGR2RGB)),plt.title('Imagen con desenfoque')
plt.xticks([]), plt.yticks([])
plt.show()

Desenfoque Gaussiano

El desenfoque gaussiano aplica un kernel ponderado según una distribución gaussiana, dando más peso a los píxeles cercanos al central.

  • Qué hace: Suaviza la imagen mientras preserva algo más la estructura que el promedio simple.
  • Cuándo se usa: Reducción de ruido con mínima distorsión de bordes, preparación de imágenes para detección de bordes o segmentación.
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('sudoku_1.jpg')

# Aplicar desenfoque gaussiano
blur = cv.GaussianBlur(
img, # Imagen de entrada
(5,5), # Tamaño del kernel
0) # Desviación estándar en X (0 = calcular a partir del tamaño del kernel

# Generar plots de imágenes
plt.subplot(121),plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB)),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(cv.cvtColor(blur, cv.COLOR_BGR2RGB)),plt.title('Imagen con desenfoque')
plt.xticks([]), plt.yticks([])
plt.show()

Desenfoque medio

El desenfoque mediano reemplaza cada píxel por la mediana de los valores de sus vecinos.

  • Qué hace: Elimina eficientemente el ruido tipo sal y pimienta sin afectar tanto los bordes.
  • Cuándo se usa: Cuando la imagen contiene píxeles aislados de ruido intenso que se quieren eliminar.
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('sudoku_1.jpg')

# Aplicar desenfoque medio
median = cv.medianBlur(
img, # Imagen de entrada
5) # Tamaño del kernel (debe ser un número impar)

# Generar plots de imágenes
plt.subplot(121),plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB)),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(cv.cvtColor(median, cv.COLOR_BGR2RGB)),plt.title('Imagen con desenfoque')
plt.xticks([]), plt.yticks([])
plt.show()

Filtrado bilateral

El filtro bilateral suaviza la imagen preservando bordes, considerando la proximidad espacial y la similitud de color de los píxeles.

  • Qué hace: Reduce ruido en zonas uniformes mientras mantiene bordes nítidos.
  • Cuándo se usa: Cuando se necesita suavizar manteniendo detalles importantes, ideal para preprocesamiento en detección de bordes o segmentación.
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('textura.jpg')

# Aplicar filtro bilateral
blur = cv.bilateralFilter(
img, # Imagen de entrada
15, # diámetro del vecindario (vecinos del píxel). Más grande = más suavizado.
150, # SigmaColor: cuánto se mezclan los colores; más alto = más mezcla de colores.
150) # SigmaSpace: cuánto se mezclan los píxeles según su distancia; más alto = más suavizado espacial.

# Generar plots de imágenes
plt.subplot(121),plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB)),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(cv.cvtColor(blur, cv.COLOR_BGR2RGB)),plt.title('Imagen con filtro bilateral')
plt.xticks([]), plt.yticks([])
plt.show()