Procesamiento de Imágenes en Tiempo Real con OpenCV y Python

Clase 4 de 16Curso de Visión Artificial con Python

Resumen

El procesamiento de imágenes con OpenCV se ha convertido en una herramienta fundamental para el análisis visual en entornos comerciales. Esta tecnología permite a las empresas obtener información valiosa sobre el comportamiento de sus clientes, optimizar la distribución de productos y mejorar la experiencia de compra. A continuación, exploraremos cómo implementar soluciones de visión por computadora para un caso real de análisis de flujo de clientes en una tienda.

¿Qué es OpenCV y por qué es importante para el análisis visual?

OpenCV (Open Source Computer Vision Library) es una biblioteca de código abierto diseñada específicamente para la manipulación y análisis de imágenes y video. Esta potente herramienta ofrece numerosas ventajas que la convierten en la elección preferida para proyectos de visión por computadora:

  • Procesamiento en tiempo real optimizado para ejecutar algoritmos complejos a alta velocidad
  • Compatibilidad multiplataforma con Python, Java y C++
  • Amplio conjunto de herramientas que incluyen detección de bordes, reconocimiento facial y segmentación de imágenes
  • Comunidad activa que constantemente genera tutoriales y documentación actualizada

Para comenzar a trabajar con OpenCV en Python, necesitamos instalar la biblioteca y realizar algunas importaciones básicas:

# Instalación (si no está instalada)
# pip install opencv-python matplotlib

# Importaciones necesarias
import cv2
import matplotlib.pyplot as plt

¿Cómo cargar y manipular imágenes con OpenCV?

Carga básica de imágenes

El primer paso para trabajar con imágenes es cargarlas correctamente. OpenCV proporciona métodos simples pero potentes para esta tarea:

# Definir la ruta de la imagen
path = "data/centro_comercial.jpg"

# Cargar la imagen
image = cv2.imread(path)

# Verificar si la imagen se cargó correctamente
if image is not None:
    # Convertir de BGR a RGB para visualización con Matplotlib
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    
    # Mostrar la imagen
    plt.figure()
    plt.title("Imagen capturada por CCTV")
    plt.imshow(image_rgb)
    plt.axis('off')
    plt.show()
else:
    print("No se pudo cargar la imagen")

Es importante destacar que OpenCV maneja las imágenes en formato BGR (Blue, Green, Red), mientras que la mayoría de las otras bibliotecas, como Matplotlib, utilizan el formato RGB (Red, Green, Blue). Por esta razón, es necesario realizar una conversión de color cuando se trabaja con ambas bibliotecas simultáneamente.

Captura y visualización de video en tiempo real

Para capturar video desde una webcam, OpenCV ofrece una interfaz sencilla:

# Iniciar la captura de video (0 para la primera cámara, 1 para la segunda, etc.)
cap = cv2.VideoCapture(1)

if not cap.isOpened():
    print("No se pudo abrir la cámara")
else:
    while True:
        # Capturar frame por frame
        ret, frame = cap.read()
        
        if not ret:
            print("No se pudo leer el frame")
            break
            
        # Mostrar el frame resultante
        cv2.imshow('Frame CCTV', frame)
        
        # Salir si se presiona 'q'
        if cv2.waitKey(1) == ord('q'):
            break
            
    # Liberar el objeto de captura y cerrar ventanas
    cap.release()
    cv2.destroyAllWindows()

Carga de videos pregrabados

De manera similar, podemos cargar y reproducir videos almacenados en el disco:

# Cargar un video desde archivo
video_path = "data/video_tienda.mp4"
cap = cv2.VideoCapture(video_path)

if not cap.isOpened():
    print("No se pudo abrir el video")
else:
    while True:
        # Capturar frame por frame
        ret, frame = cap.read()
        
        if not ret:
            print("No se pudo leer el frame")
            break
            
        # Mostrar el frame resultante
        cv2.imshow('Video CCTV', frame)
        
        # Salir si se presiona 'q'
        if cv2.waitKey(25) == ord('q'):
            break
            
    # Liberar el objeto de captura y cerrar ventanas
    cap.release()
    cv2.destroyAllWindows()

¿Qué técnicas de mejora y anotación podemos aplicar a las imágenes?

Ajuste de brillo y contraste

Para mejorar la calidad visual de las imágenes, especialmente en condiciones de iluminación variable, podemos ajustar el brillo y el contraste:

# Ajustar brillo y contraste
contrast_factor = 1.2  # Mayor que 1 aumenta el contraste
brightness_value = 30  # Valor positivo aumenta el brillo

# Aplicar transformación
enhanced_image = cv2.convertScaleAbs(image, alpha=contrast_factor, beta=brightness_value)

# Convertir para visualización
enhanced_image_rgb = cv2.cvtColor(enhanced_image, cv2.COLOR_BGR2RGB)

# Mostrar imagen mejorada
plt.figure()
plt.title("Imagen con brillo y contraste ajustados")
plt.imshow(enhanced_image_rgb)
plt.axis('off')
plt.show()

# Guardar la imagen procesada
cv2.imwrite("ccv_imagen_correccion.jpg", enhanced_image)

Corrección de color y normalización

Para ajustes más avanzados de color, podemos trabajar en el espacio de color HSV (Hue, Saturation, Value):

import numpy as np

# Convertir a HSV
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# Aumentar la saturación
hsv_image[:, :, 1] = hsv_image[:, :, 1] * 1.5  # Multiplicar el canal de saturación

# Asegurar que los valores estén dentro del rango válido
hsv_image[:, :, 1] = np.clip(hsv_image[:, :, 1], 0, 255)

# Convertir de vuelta a BGR y luego a RGB para visualización
saturated_image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR)
saturated_image_rgb = cv2.cvtColor(saturated_image, cv2.COLOR_BGR2RGB)

# Mostrar imagen con saturación ajustada
plt.figure()
plt.title("Imagen con saturación ajustada")
plt.imshow(saturated_image_rgb)
plt.axis('off')
plt.show()

# Guardar la imagen procesada
cv2.imwrite("ajuste_saturacion.jpg", saturated_image)

Anotaciones en imágenes

Una de las funcionalidades más útiles de OpenCV es la capacidad de añadir anotaciones a las imágenes, como líneas, rectángulos y texto:

# Crear una copia de la imagen original
annotated_image = image.copy()

# Dibujar una línea
cv2.line(annotated_image, (50, 50), (200, 50), (255, 0, 0), 3)  # Azul en BGR

# Dibujar un rectángulo
cv2.rectangle(annotated_image, (100, 100), (300, 200), (0, 255, 0), 2)  # Verde en BGR

# Añadir texto
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(annotated_image, "Zona de alto tráfico", (100, 90), font, 0.7, (0, 0, 255), 2)  # Rojo en BGR

# Convertir para visualización
annotated_image_rgb = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB)

# Mostrar imagen anotada
plt.figure()
plt.title("Imagen con anotaciones")
plt.imshow(annotated_image_rgb)
plt.axis('off')
plt.show()

Comparación de todas las técnicas aplicadas

Para visualizar el impacto de las diferentes técnicas, podemos mostrar todas las imágenes procesadas juntas:

plt.figure(figsize=(15, 10))

# Imagen original
plt.subplot(2, 2, 1)
plt.title("Imagen original")
plt.imshow(image_rgb)
plt.axis('off')

# Imagen con brillo y contraste ajustados
plt.subplot(2, 2, 2)
plt.title("Brillo y contraste ajustados")
plt.imshow(enhanced_image_rgb)
plt.axis('off')

# Imagen con saturación ajustada
plt.subplot(2, 2, 3)
plt.title("Saturación ajustada")
plt.imshow(saturated_image_rgb)
plt.axis('off')

# Imagen con anotaciones
plt.subplot(2, 2, 4)
plt.title("Imagen anotada")
plt.imshow(annotated_image_rgb)
plt.axis('off')

plt.tight_layout()
plt.show()

El procesamiento de imágenes con OpenCV ofrece un mundo de posibilidades para el análisis visual en entornos comerciales. Desde el seguimiento del flujo de clientes hasta la identificación de zonas de alto tráfico, estas técnicas pueden proporcionar información valiosa para la toma de decisiones estratégicas. ¿En qué situaciones específicas aplicarías estas técnicas de procesamiento de imágenes? Comparte tus ideas y experiencias en los comentarios.