OpenCV: Procesamiento y análisis
Descubre cómo transformar, segmentar y extraer características clave de imágenes para tareas de visión por computador avanzadas.
Aprende OpenCV GRATIS y certifícateEn OpenCV, el procesamiento de imágenes y vídeos se basa en un conjunto amplio de funciones que permiten ejecutar tareas como la lectura de archivos multimedia, la transformación de sus píxeles y la extracción de características relevantes para análisis posteriores. Al trabajar con Python, se emplea el módulo cv2
, que ofrece interfaces optimizadas para desarrollar aplicaciones en tiempo real o para proyectos de análisis computacional.
Es común comenzar con la carga de imágenes para su posterior manipulación. Para ello, se utiliza la función cv.imread()
y se pueden mostrar en pantalla con cv.imshow()
. Por ejemplo:
import cv2 as cv
imagen = cv.imread("ruta/de/archivo.jpg")
cv.imshow("Ventana de imagen", imagen)
cv.waitKey(0)
cv.destroyAllWindows()
La escritura en disco se logra con cv.imwrite()
, que acepta la ruta de destino y el objeto de imagen. Estas operaciones son básicas, pero esenciales para cualquier flujo de trabajo con OpenCV.
Tras la lectura, se suelen aplicar transformaciones iniciales, como cambios de dimensión, giros o volteretas horizontales y verticales. Funciones como cv.resize()
, cv.rotate()
y cv.flip()
permiten modificar la imagen según sea necesario. Un ejemplo:
imagen_redimensionada = cv.resize(imagen, (640, 480))
imagen_rotada = cv.rotate(imagen, cv.ROTATE_90_CLOCKWISE)
imagen_invertida = cv.flip(imagen, 0)
Con estos métodos, el procesamiento de datos se facilita al ajustar el tamaño o la orientación del contenido multimedia.
Otro aspecto relevante es la conversión entre espacios de color, como pasar de BGR a escala de grises o de BGR a HSV. Mediante la función cv.cvtColor()
, se emplean constantes como cv.COLOR_BGR2GRAY
o cv.COLOR_BGR2HSV
. El uso de diferentes espacios de color resulta esencial para el análisis de patrones y la detección de regiones específicas:
gris = cv.cvtColor(imagen, cv.COLOR_BGR2GRAY)
hsv = cv.cvtColor(imagen, cv.COLOR_BGR2HSV)
Con esta técnica, se pueden aislar características como el tono y la saturación para resolver problemas de segmentación.
En binarización, se emplean métodos de umbralización para separar el primer plano del fondo. La función cv.threshold()
implementa el umbral fijo, mientras que cv.adaptiveThreshold()
realiza un cálculo local para cada región de la imagen. Un ejemplo de umbral fijo sería:
_, binaria = cv.threshold(gris, 127, 255, cv.THRESH_BINARY)
Este tipo de procesamiento es útil en aplicaciones de reconocimiento de caracteres o para resaltar contornos en fondo uniforme.
Entre las operaciones de morfología para tratar imágenes binarias, destacan la erosión y la dilatación. Existen otras como apertura y cierre, que se consiguen combinando esas dos. Se pueden aplicar mediante funciones como cv.erode()
y cv.dilate()
. Su utilidad radica en refinar figuras o eliminar ruido:
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
erosionada = cv.erode(binaria, kernel, iterations=1)
dilatada = cv.dilate(binaria, kernel, iterations=1)
Así se atenúan imperfecciones o se resaltan áreas concretas en la imagen procesada.
La detección de bordes es esencial para encontrar límites y formas. El detector de Canny, con cv.Canny()
, calcula gradientes de intensidad y determina la presencia de contornos nítidos. Con bordes bien definidos, se facilita la posterior búsqueda de características:
bordes = cv.Canny(gris, 100, 200)
Este método proporciona resultados fiables en reconocimiento de objetos, seguimiento de trayectorias y otras tareas de análisis.
Para extraer contornos, se recurre a la función cv.findContours()
, que retorna la información de las curvas cerradas que definen las regiones relevantes de la imagen. Posteriormente, se pueden dibujar sobre la imagen original con cv.drawContours()
:
contornos, _ = cv.findContours(binaria, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
cv.drawContours(imagen, contornos, -1, (0, 255, 0), 2)
Con ello se obtienen líneas que representan el perfil de cada figura encontrada, facilitando mediciones y clasificaciones geométricas.
La localización de características como esquinas o puntos de interés se apoya en detectores especializados, entre los que se incluyen ORB o SIFT. Con cv.ORB_create()
puede identificarse una serie de keypoints en la imagen y describirlos para matching posterior. Esta técnica resulta útil en la detección y seguimiento de patrones:
orb = cv.ORB_create()
kp, des = orb.detectAndCompute(imagen, None)
imagen_con_kp = cv.drawKeypoints(imagen, kp, None, color=(0,255,0))
De esta manera, se obtienen descriptores que pueden compararse para realizar emparejamientos en sistemas de reconocimiento.
La captura de vídeo se realiza con cv.VideoCapture()
. En un bucle, se leen los fotogramas y se procesan uno a uno:
cap = cv.VideoCapture("ruta/de/video.mp4")
while True:
ret, frame = cap.read()
if not ret:
break
# procesamiento por fotograma
cv.imshow("Ventana de vídeo", frame)
if cv.waitKey(1) & 0xFF == 27:
break
cap.release()
cv.destroyAllWindows()
Este enfoque permite aplicar en cada fotograma operaciones similares a las que hemos visto para imágenes, como conversión de color, detección de bordes o extracción de contornos.
En situaciones donde resulta necesario realizar sustracción de fondo, existen métodos como cv.createBackgroundSubtractorMOG2()
. Esta técnica modela el fondo de la escena y marca píxeles en movimiento como primer plano:
fondo = cv.createBackgroundSubtractorMOG2()
mascara = fondo.apply(frame)
Dicha aproximación se utiliza para seguimiento de objetos en entornos con movimiento continuo y ayuda a descartar las regiones estáticas del vídeo.
Para tareas de reconocimiento específico, la detección de rostros o de objetos de forma general se apoya en clasificadores preentrenados o en redes neuronales. Con cascadas Haar y la función detectMultiScale()
, se pueden identificar regiones en la imagen que cumplan con patrones predefinidos. Por ejemplo, para rostros:
cascade = cv.CascadeClassifier("haarcascade_frontalface_default.xml")
rostros = cascade.detectMultiScale(gris, scaleFactor=1.1, minNeighbors=5)
for (x, y, w, h) in rostros:
cv.rectangle(imagen, (x, y), (x+w, y+h), (255, 0, 0), 2)
Estas técnicas se integran con el bucle de lectura de vídeo para efectuar una detección continua, con aplicaciones en seguridad, interacción y reconocimiento biométrico.
Lecciones de este módulo de OpenCV
Lecciones de programación del módulo Procesamiento y análisis del curso de OpenCV.
Ejercicios de programación en este módulo de OpenCV
Evalúa tus conocimientos en Procesamiento y análisis con ejercicios de programación Procesamiento y análisis de tipo Test, Puzzle, Código y Proyecto con VSCode.