9. Introducción a OpenCV

9.1 Introducción

En el tema 7 ya vimos cómo cargar, visualizar, inspeccionar y manipular imágenes en Python usando bibliotecas como OpenCV, Pillow y NumPy. Es decir, ya conocemos la base práctica: leer archivos, revisar shape y dtype, convertir colores, recortar, redimensionar y guardar resultados.

En este tema el objetivo ya no es repetir esas operaciones, sino enfocar la atención en OpenCV como herramienta central dentro de visión por computadora. Vamos a ver por qué esta biblioteca ocupa un lugar tan importante, qué tipo de problemas resuelve especialmente bien y cómo se conecta con procesamiento clásico, video y aplicaciones en tiempo real.

9.2 ¿Qué es exactamente OpenCV?

OpenCV es una biblioteca de código abierto especializada en procesamiento de imágenes, análisis visual y visión por computadora en tiempo real. A diferencia de otras herramientas más orientadas a edición o manejo general de imágenes, OpenCV fue pensada para construir algoritmos y pipelines visuales completos.

Eso significa que no se limita a abrir o mostrar archivos. También ofrece funciones para:

  • Filtrado y transformaciones geométricas.
  • Detección de bordes, contornos y características.
  • Trabajo con cámaras, video y frames en tiempo real.
  • Preprocesamiento y postprocesamiento para modelos de Deep Learning.
  • Dibujo de cajas, textos y resultados sobre imágenes.
OpenCV no es solo una biblioteca para cargar imágenes: es una plataforma muy completa para construir sistemas de visión por computadora.

9.3 ¿Por qué aprender OpenCV hoy?

Con el avance del Deep Learning, a veces se piensa que OpenCV quedó en segundo plano. En la práctica sigue siendo fundamental, porque gran parte del trabajo real de un sistema visual no consiste solo en ejecutar un modelo, sino en preparar entradas, manipular imágenes, capturar video y presentar resultados.

Incluso en proyectos modernos con redes neuronales, OpenCV suele utilizarse para:

  • Leer imágenes y video.
  • Redimensionar, recortar y transformar entradas.
  • Convertir espacios de color y ajustar formatos.
  • Recortar regiones de interés.
  • Dibujar resultados de inferencia.
  • Conectar el modelo con una cámara o un flujo en tiempo real.

Por eso OpenCV sigue siendo transversal: sirve tanto para visión clásica como para acompañar modelos modernos en aplicaciones reales.

9.4 Instalación en Python

La instalación básica ya la vimos en el tema 7. Aquí conviene sumar una distinción práctica: según el entorno, no siempre instalaremos la misma variante de OpenCV.

La forma más habitual en una computadora de escritorio es:

pip install opencv-python

En cambio, en servidores, contenedores o entornos sin ventanas gráficas suele preferirse:

pip install opencv-python-headless

La versión headless evita dependencias ligadas a interfaces gráficas. Esto reduce problemas de instalación en producción y deja claro que OpenCV puede usarse tanto en aplicaciones locales con ventanas como en entornos puramente de backend.

9.5 Cómo se importa OpenCV

En Python, OpenCV se importa así:

import cv2

El nombre visible en el código es cv2, una convención histórica que aparece en prácticamente todos los tutoriales, ejemplos y proyectos. Conviene acostumbrarse desde el principio porque será la forma estándar de acceder a sus funciones en todo el curso.

9.6 Estructura general de trabajo con OpenCV

Más que pensar OpenCV solo como una secuencia de leer y mostrar imágenes, conviene verla como una biblioteca organizada alrededor de varios tipos de tareas:

  1. Entrada de datos: imágenes, cámaras y video.
  2. Transformaciones: color, tamaño, filtros y geometría.
  3. Análisis visual: bordes, contornos, segmentación y características.
  4. Salida: visualización, guardado y dibujo de resultados.

Esta idea es importante porque ayuda a entender qué papel cumple OpenCV dentro de un pipeline completo: capturar, transformar, analizar y presentar información visual.

9.7 Leer una imagen con OpenCV

La función más conocida para cargar una imagen es cv2.imread:

import cv2

imagen = cv2.imread("foto.jpg")

Si la lectura falla, OpenCV devuelve None. Por eso conviene verificar siempre:

if imagen is None:
    print("No se pudo cargar la imagen")
else:
    print("Imagen cargada correctamente")

9.8 La imagen como arreglo de NumPy

Una ventaja enorme de OpenCV en Python es que las imágenes se representan como arreglos de NumPy. Esto significa que una imagen puede manipularse numéricamente con enorme flexibilidad.

Por ejemplo, podemos inspeccionar forma y tipo de dato:

print(imagen.shape)
print(imagen.dtype)

Si la imagen es color, normalmente obtendremos algo como (alto, ancho, 3) y un tipo como uint8.

9.9 El detalle clave: OpenCV usa BGR

Uno de los puntos más importantes al empezar con OpenCV es recordar que, por defecto, maneja imágenes en formato BGR y no RGB. Esto significa que el orden de los canales es:

  • Azul.
  • Verde.
  • Rojo.

Esta diferencia no suele importar si solo procesamos la imagen internamente, pero sí se vuelve crítica cuando la visualizamos con otras bibliotecas o mezclamos herramientas que esperan RGB.

La conversión típica es:

imagen_rgb = cv2.cvtColor(imagen, cv2.COLOR_BGR2RGB)

9.10 Mostrar imágenes con OpenCV

OpenCV permite abrir una ventana y mostrar una imagen con funciones muy directas:

cv2.imshow("Imagen", imagen)
cv2.waitKey(0)
cv2.destroyAllWindows()

Estas funciones son muy útiles en programas locales. Sin embargo, en notebooks o entornos remotos suelen preferirse otras opciones, como Matplotlib.

9.11 Mostrar imágenes con Matplotlib después de OpenCV

Cuando usamos Matplotlib para mostrar una imagen cargada con OpenCV, conviene convertirla antes a RGB:

import matplotlib.pyplot as plt

imagen_rgb = cv2.cvtColor(imagen, cv2.COLOR_BGR2RGB)
plt.imshow(imagen_rgb)
plt.axis("off")
plt.show()

Si omitimos la conversión, los colores probablemente se verán alterados.

9.12 Guardar imágenes

OpenCV también permite guardar imágenes procesadas con mucha facilidad:

cv2.imwrite("salida.jpg", imagen)

Esto es útil para exportar resultados intermedios, guardar transformaciones o documentar salidas de un pipeline.

9.13 Conversión a escala de grises

Una de las operaciones más frecuentes al comenzar a procesar imágenes con OpenCV es convertirlas a escala de grises:

gris = cv2.cvtColor(imagen, cv2.COLOR_BGR2GRAY)

Esta operación reduce la imagen a un solo canal y suele ser el punto de partida para filtros, detección de bordes, umbralización y análisis estructural.

9.14 Redimensionado con OpenCV

Otra tarea muy común es cambiar el tamaño de la imagen. OpenCV lo resuelve con cv2.resize:

redimensionada = cv2.resize(imagen, (300, 200))

Recordar que el orden aquí es (ancho, alto). Este detalle suele confundir al principio, porque no coincide con el orden natural de filas y columnas del arreglo.

9.15 Recortes y regiones de interés

Como OpenCV usa arreglos de NumPy, podemos extraer fácilmente una región de interés mediante slicing:

roi = imagen[100:250, 200:400]

Esta operación es extremadamente útil en tareas donde queremos analizar, guardar o procesar solo una parte de la imagen.

9.16 Acceso a cámaras y video

Una de las grandes fortalezas de OpenCV es que no se limita a imágenes estáticas. También puede trabajar con cámaras y archivos de video.

Un ejemplo básico para abrir una cámara es:

import cv2

captura = cv2.VideoCapture(0)

A partir de ahí, se pueden leer frames de manera continua. Esto convierte a OpenCV en una herramienta muy útil para aplicaciones en tiempo real.

9.17 Leer frames desde una cámara

Un patrón básico de captura de video, con la posibilidad de guardar imágenes durante la ejecución, es:

import cv2

captura = cv2.VideoCapture(0)
contador = 0  # para no sobrescribir imágenes

while True:
    ok, frame = captura.read()
    if not ok:
        break

    cv2.imshow("Camara", frame)

    tecla = cv2.waitKey(1) & 0xFF

    if tecla == 27:
        break

    if tecla == ord('s'):
        nombre = f"imagen_{contador}.jpg"
        cv2.imwrite(nombre, frame)
        print(f"Imagen guardada como {nombre}")
        contador += 1

captura.release()
cv2.destroyAllWindows()

Este tipo de bucle es una base muy habitual para demos en tiempo real, lectura de cámara web y prototipos interactivos. Además, muestra cómo capturar eventos de teclado para salir con Esc o guardar frames individuales con la tecla s.

9.18 OpenCV y procesamiento en tiempo real

El hecho de que OpenCV pueda trabajar frame a frame con cámaras y video la vuelve muy importante en aplicaciones donde la latencia importa. Algunos ejemplos son:

  • Sistemas de seguridad.
  • Robótica.
  • Seguimiento de objetos.
  • Inspección industrial en línea.
  • Interfaces visuales interactivas.

Más adelante veremos que esta capacidad también es clave al integrar modelos como YOLO para detección en tiempo real.

9.19 Tipos de operaciones que ofrece OpenCV

Aunque en este tema solo estamos introduciendo la biblioteca, conviene anticipar el tipo de operaciones que nos permitirá resolver:

  • Conversión entre espacios de color.
  • Filtrado y suavizado.
  • Transformaciones geométricas.
  • Detección de bordes y contornos.
  • Umbralización.
  • Morfología matemática.
  • Lectura y escritura de video.
  • Dibujo de líneas, rectángulos y texto.

Gran parte de la próxima sección del curso se apoyará exactamente en estas capacidades.

9.20 OpenCV y Deep Learning

Aunque OpenCV nació antes del auge moderno del Deep Learning, hoy sigue siendo muy útil en pipelines que usan modelos aprendidos. Por ejemplo:

  • Puede preparar imágenes para una red.
  • Puede capturar frames antes de inferir.
  • Puede dibujar cajas y etiquetas sobre predicciones.
  • Puede exportar resultados a video o pantalla.

Esto muestra que OpenCV no compite con PyTorch. Más bien, lo complementa.

9.21 Ventajas prácticas de OpenCV

Algunas razones por las que OpenCV es tan usada en proyectos reales son:

  • Es rápida.
  • Tiene una API muy amplia.
  • Está disponible en varios lenguajes.
  • Tiene mucha documentación y ejemplos.
  • Se integra con hardware y video.
  • Permite pasar rápido de idea a prototipo.

En otras palabras, ofrece una combinación muy valiosa de potencia, madurez y practicidad.

9.22 Limitaciones y precauciones

Como toda herramienta, OpenCV también requiere ciertos cuidados:

  • Hay que recordar la convención BGR.
  • Algunas funciones de visualización no funcionan bien en todos los entornos.
  • La API es extensa y al principio puede resultar abrumadora.
  • No reemplaza por sí sola bibliotecas de Deep Learning para entrenamiento.

La clave es no intentar aprender toda la biblioteca de una vez, sino dominar primero las funciones realmente necesarias para cada etapa.

9.23 Un ejemplo mínimo integrado

Un ejemplo corto y representativo podría ser:

import cv2

imagen = cv2.imread("foto1.jpg")

if imagen is None:
    raise ValueError("No se pudo cargar la imagen")

gris = cv2.cvtColor(imagen, cv2.COLOR_BGR2GRAY)
redimensionada = cv2.resize(gris, (300, 200))

cv2.imwrite("resultado.jpg", redimensionada)

Este ejemplo resume varias ideas fundamentales:

  • Carga.
  • Verificación.
  • Conversión de color.
  • Redimensionado.
  • Guardado.

9.24 Modos de lectura de imágenes

OpenCV no solo permite leer una imagen: también permite decidir cómo se la quiere leer. Esto es importante porque a veces conviene cargar directamente en color, en escala de grises o incluso conservar el canal alfa.

import cv2

color = cv2.imread("foto1.png", cv2.IMREAD_COLOR)
gris = cv2.imread("foto1.png", cv2.IMREAD_GRAYSCALE)
sin_cambios = cv2.imread("foto1.png", cv2.IMREAD_UNCHANGED)

Elegir bien el modo de lectura evita conversiones innecesarias y ayuda a adaptar mejor la entrada al problema que queremos resolver.

9.25 Interpolación al redimensionar

Cuando usamos cv2.resize, no solo importa el tamaño final. También importa el método de interpolación, porque de eso depende cómo se calculan los nuevos píxeles y qué tan suave o nítido queda el resultado.

import cv2

imagen = cv2.imread("foto1.jpg")

if imagen is None:
    raise ValueError("No se pudo cargar la imagen")

pequena = cv2.resize(imagen, (200, 150), interpolation=cv2.INTER_AREA)
grande = cv2.resize(imagen, (1200, 900), interpolation=cv2.INTER_CUBIC)

En general, INTER_AREA suele funcionar bien para reducir tamaño, mientras que INTER_LINEAR o INTER_CUBIC se usan mucho al ampliar. Este detalle influye en la calidad visual y también puede afectar el rendimiento de un pipeline.

9.26 OpenCV como puente en un pipeline visual

Una forma muy útil de pensar OpenCV es verla como una biblioteca puente entre distintas etapas de un sistema visual. Puede tomar datos desde disco o cámara, transformarlos, entregarlos a un modelo y luego dibujar o guardar el resultado final.

Ese rol intermedio es una de las razones por las que aparece tan seguido en proyectos reales:

  • Conecta adquisición de datos con procesamiento.
  • Facilita el preprocesamiento antes de inferencia.
  • Permite postprocesar y visualizar resultados.
  • Sirve tanto en scripts simples como en aplicaciones en tiempo real.

Por eso, aprender OpenCV no significa solo aprender funciones aisladas, sino entender cómo encaja dentro de un flujo completo de visión por computadora.

9.27 Qué debes recordar de este tema

  • OpenCV es una de las bibliotecas más importantes en visión por computadora.
  • En Python se importa como cv2.
  • Permite trabajar con imágenes, video, cámaras y una gran variedad de operaciones clásicas.
  • Las imágenes cargadas con OpenCV son arreglos de NumPy.
  • Por defecto, OpenCV trabaja en BGR y no en RGB.
  • También permite controlar cómo se leen y redimensionan las imágenes.
  • Su valor no desaparece con el Deep Learning; al contrario, complementa muy bien esos pipelines.

9.28 Conclusión

OpenCV es una herramienta fundamental porque conecta teoría y práctica de forma muy directa. Permite tomar una imagen o una señal de video y empezar a transformarla, medirla y prepararla para tareas más avanzadas.

Dominar OpenCV no significa aprender toda su API de memoria, sino entender cómo encaja en un flujo de visión real y cómo usar sus funciones más importantes de manera consistente.

En el próximo tema entraremos ya en el procesamiento básico de imágenes con OpenCV, donde veremos operaciones concretas que empiezan a modificar el contenido visual de forma útil.