Operaciones morfológicas
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 la imagen que se utilizará en los ejemplos son imagen.png.
Objetivo
- Aprender los principales métodos de operaciones morfológicas aplicados a imágenes.
- Comprender cómo el kernel modifica la forma y estructura de los objetos en una imagen.
- Aplicar erosión, dilatación, apertura, cierre, gradiente, top-hat y black-hat en OpenCV para preprocesamiento y análisis.
Conceptos clave
- Kernel: matriz que define la forma y vecindad usada en la operación morfológica.
- Erosión: reduce las regiones brillantes de una imagen.
- Dilatación: expande las regiones brillantes de una imagen.
- Apertura: erosión seguida de dilatación, elimina ruido pequeño.
- Cierre: dilatación seguida de erosión, rellena huecos pequeños.
- Gradiente morfológico: diferencia entre dilatación y erosión, resalta bordes.
- Sombrero de copa (top-hat): diferencia entre la imagen original y su apertura, resalta detalles claros.
- Sombrero negro (black-hat): diferencia entre el cierre y la imagen original, resalta detalles oscuros.
Funciones principales en OpenCV
cv.erode()
: Aplica erosión a la imagen usando un kernel.cv.dilate()
: Aplica dilatación a la imagen usando un kernel.cv.morphologyEx()
: Aplica operaciones morfológicas avanzadas:cv.MORPH_OPEN
: Apertura.cv.MORPH_CLOSE
: Cierre.cv.MORPH_GRADIENT
: Gradiente morfológico.cv.MORPH_TOPHAT
: Sombrero de copa.cv.MORPH_BLACKHAT
: Sombrero negro.
Teoría de operaciones morfológicas
Las operaciones morfológicas provienen de la teoría matemática de la morfología, utilizada originalmente para el análisis de estructuras en imágenes binarias. La idea central es modificar la geometría de los objetos presentes en la imagen en función de la forma del kernel.
Existen dos transformaciones básicas:
- Erosión: Encoge los objetos.
- Dilatación: Expande los objetos.
A partir de ellas se definen transformaciones combinadas que permiten limpiar ruido, rellenar huevos o destacar contornos.

Figura 1: Imagen original vs. Imagen con erosión vs. Imagen con dilatación.
Erosión
La erosión reduce el tamaño de los objetos brillantes (blancos) en una imagen. El kernel "desgasta" los bordes, eliminando pequeños detalles o ruido aislado.
- Útil para: Eliminar puntos blancos pequeños o separar objetos pegados.
- Python (PC con entorno gráfico)
- Python (Google Colab)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('patente_2.png', cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de la operación de erosión
erosion = cv.erode(
img, # Imagen de entrada
kernel, # Kernel
iterations = 1) # Número de iteraciones para aplicar la erosión
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(erosion, cmap="gray"),plt.title('Imagen con erosión')
plt.xticks([]), plt.yticks([])
plt.show()
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())[0]
img = cv.imread(filename, cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de la operación de erosión
erosion = cv.erode(
img, # Imagen de entrada
kernel, # Kernel
iterations = 1) # Número de iteraciones para aplicar la erosión
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(erosion, cmap="gray"),plt.title('Imagen con erosión')
plt.xticks([]), plt.yticks([])
plt.show()
Dilatación
La dilatación expande las regiones brillantes, haciendo que los objetos crezcan. Tiende a rellenar huevos y a unir componentes cercanos.
- Útil para: Destacar características, unir fragmento de un objeto o rellenar espacios.
- Python (PC con entorno gráfico)
- Python (Google Colab)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('patente_2.png', cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de dilatación
dilation = cv.dilate(
img, # Imagen de entrada
kernel, # Kernel
iterations = 1) # Número de iteraciones
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(dilation, cmap="gray"),plt.title('Imagen con dilatación')
plt.xticks([]), plt.yticks([])
plt.show()
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())[0]
img = cv.imread(filename, cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de dilatación
dilation = cv.dilate(
img, # Imagen de entrada
kernel, # Kernel
iterations = 1) # Número de iteraciones
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(dilation, cmap="gray"),plt.title('Imagen con dilatación')
plt.xticks([]), plt.yticks([])
plt.show()
Apertura
La apertura combina erosión seguida de dilatación. Permite eliminar ruido fino sin afectar demasiado el tamaño de los objetos principales.
- Útil para: Eliminar pequeños puntos blancos dispersos en el fondo.
- Python (PC con entorno gráfico)
- Python (Google Colab)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('patente_2.png', cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de apertura morfológica
opening = cv.morphologyEx(
img, # Imagen de entrada
cv.MORPH_OPEN, # Tipo de operación morfológica
kernel) # Kernel
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(opening, cmap="gray"),plt.title('Imagen con apertura')
plt.xticks([]), plt.yticks([])
plt.show()
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())[0]
img = cv.imread(filename, cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de apertura morfológica
opening = cv.morphologyEx(
img, # Imagen de entrada
cv.MORPH_OPEN, # Tipo de operación morfológica
kernel) # Kernel
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(opening, cmap="gray"),plt.title('Imagen con apertura')
plt.xticks([]), plt.yticks([])
plt.show()
Cierre
El cierre combina dilatación seguida de erosión. Tiende a cerrar huecos pequeños o líneas negras dentro de un objeto blanco.
- Útil para: Rellenar pequeños espacios o grietas dentro de los objetos.
- Python (PC con entorno gráfico)
- Python (Google Colab)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('patente_2.png', cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de cierre morfológico
closing = cv.morphologyEx(
img, # Imagen de entrada
cv.MORPH_CLOSE, # Tipo de operación morfológica
kernel) # Kernel
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(closing, cmap="gray"),plt.title('Imagen con cierre')
plt.xticks([]), plt.yticks([])
plt.show()
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())[0]
img = cv.imread(filename, cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de cierre morfológico
closing = cv.morphologyEx(
img, # Imagen de entrada
cv.MORPH_CLOSE, # Tipo de operación morfológica
kernel) # Kernel
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(closing, cmap="gray"),plt.title('Imagen con cierre')
plt.xticks([]), plt.yticks([])
plt.show()
Gradiente morfológico
El gradiente morfológico es la diferencia entre la dilatación y la erosión de una imagen. Resalta los bordes de los objetos, ya que muestra las zonas donde la forma cambia.
- Útil para: Detección de contornos.
- Python (PC con entorno gráfico)
- Python (Google Colab)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('patente_2.png', cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de gradiente morfológico
gradient = cv.morphologyEx(
img, # Imagen de entrada
cv.MORPH_GRADIENT, # Tipo de operación morfológica
kernel) # Kernel
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(gradient, cmap="gray"),plt.title('Imagen con gradiente morfológico')
plt.xticks([]), plt.yticks([])
plt.show()
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())[0]
img = cv.imread(filename, cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de gradiente morfológico
gradient = cv.morphologyEx(
img, # Imagen de entrada
cv.MORPH_GRADIENT, # Tipo de operación morfológica
kernel) # Kernel
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(gradient, cmap="gray"),plt.title('Imagen con gradiente morfológico')
plt.xticks([]), plt.yticks([])
plt.show()
Sombrero de copa (Top-hat)
El sombrero de copa es la diferencia entre la imagen original y su apertura. Resalta las regiones claras que son más pequeñas que el kernel.
- Útil para: Detectar detalles brillantes
- Python (PC con entorno gráfico)
- Python (Google Colab)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('patente_2.png', cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de sombrero de copa
tophat = cv.morphologyEx(
img, # Imagen de entrada
cv.MORPH_TOPHAT, # Tipo de operación morfológica
kernel) # Kernel
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(tophat, cmap="gray"),plt.title('Imagen con sombrero de copa')
plt.xticks([]), plt.yticks([])
plt.show()
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())[0]
img = cv.imread(filename, cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de sombrero de copa
tophat = cv.morphologyEx(
img, # Imagen de entrada
cv.MORPH_TOPHAT, # Tipo de operación morfológica
kernel) # Kernel
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(tophat, cmap="gray"),plt.title('Imagen con sombrero de copa')
plt.xticks([]), plt.yticks([])
plt.show()
Sombrero negro (Black-hat)
El sombrero de copa es la diferencia entre la imagen original y su apertura. Resalta las regiones claras que son más pequeñas que el kernel.
- Útil para: Detectar detalles brillantes sobre fondos oscuros.
- Python (PC con entorno gráfico)
- Python (Google Colab)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('patente_2.png', cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de sombrero negro
blackhat = cv.morphologyEx(
img, # Imagen de entrada
cv.MORPH_BLACKHAT, # Tipo de operación morfológica
kernel) # Kernel
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(tophat, cmap="gray"),plt.title('Imagen con erosión')
plt.xticks([]), plt.yticks([])
plt.show()
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())[0]
img = cv.imread(filename, cv.IMREAD_GRAYSCALE)
# Creación del kernel 5x5
kernel = np.ones((5,5),np.uint8)
# Aplicación de sombrero negro
blackhat = cv.morphologyEx(
img, # Imagen de entrada
cv.MORPH_BLACKHAT, # Tipo de operación morfológica
kernel) # Kernel
# Generar plots de imágenes
plt.figure(figsize=(12, 8))
plt.subplot(121),plt.imshow(img, cmap="gray"),plt.title('Imagen original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(tophat, cmap="gray"),plt.title('Imagen con erosión')
plt.xticks([]), plt.yticks([])
plt.show()