Procesamiento de video con OpenCV

El video se compone de una serie de fotogramas de imagen consecutivos, y cada fotograma es una imagen estática.

El núcleo del procesamiento de video es procesar estos fotogramas de imagen. Las tareas comunes de procesamiento de video incluyen lectura de video, reproducción de video, guardado de video, procesamiento de fotogramas, etc.

Aplicaciones del procesamiento de video

  • Análisis de video: mediante técnicas de procesamiento de video, se puede analizar el movimiento, los objetos, los eventos, etc., en el video.
  • Mejora de video: aplicar procesamiento como reducción de ruido, mejora y estabilización al video para aumentar su calidad.
  • Edición de video: realizar operaciones como cortar, unir y agregar efectos especiales al video.
  • Monitoreo en tiempo real: supervisar escenas en tiempo real mediante cámaras y realizar detección de objetos, análisis de comportamiento, etc.

OpenCV proporcionacv2.VideoCaptureycv2.VideoWriterdos clases, utilizadas respectivamente para la lectura y escritura de video. Además, OpenCV ofrece abundantes funciones de procesamiento de imágenes que permiten realizar diversas operaciones en los fotogramas de video.

Lectura y reproducción de video

Leer archivos de video

Para leer un archivo de video, primero se debe crear uncv2.VideoCaptureobjeto y especificar la ruta del archivo de video.

Ejemplo

import cv2

# Crear objeto VideoCapture para leer el archivo de video
cap = cv2.VideoCapture('example.mp4')

# Verificar si el video se abrió correctamente
if not cap.isOpened():
    print("Error: Could not open video.")
    exit()

# Leer el fotograma de video
while True:
    ret, frame = cap.read()
   
    # Si se llega al último fotograma, salir del bucle
    if not ret:
        break
   
    # Mostrar el fotograma actual
    cv2.imshow('Video', frame)
   
    # Pulsar la tecla 'q' para salir
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

# Liberar recursos
cap.release()
cv2.destroyAllWindows()

Leer video de la cámara

Además de leer archivos de video, OpenCV también puede leer video directamente desde la cámara; solo hay que establecer elcv2.VideoCaptureparámetro con el índice de la cámara (normalmente 0):

Ejemplo

import cv2

# Crear objeto VideoCapture para leer el video de la cámara
cap = cv2.VideoCapture(0)

# Verificar si la cámara se abrió correctamente
if not cap.isOpened():
    print("Error: Could not open camera.")
    exit()

# Leer el fotograma de video
while True:
    ret, frame = cap.read()
   
    # Si se llega al último fotograma, salir del bucle
    if not ret:
        break
   
    # Mostrar el fotograma actual
    cv2.imshow('Camera', frame)
   
    # Pulsar la tecla 'q' para salir
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

# Liberar recursos
cap.release()
cv2.destroyAllWindows()

Procesamiento de fotogramas de video

Operaciones básicas con fotogramas

Después de leer un fotograma de video, se pueden aplicar diversas operaciones de procesamiento de imágenes a cada fotograma.

Por ejemplo, se puede convertir el fotograma a imagen en escala de grises:

Ejemplo

import cv2

cap = cv2.VideoCapture('example.mp4')

while True:
    ret, frame = cap.read()
   
    if not ret:
        break
   
    # Convertir el fotograma a imagen en escala de grises
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
   
    # Mostrar el fotograma en escala de grises
    cv2.imshow('Gray Video', gray_frame)
   
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

Guardado de fotogramas

Al procesar fotogramas de video, a veces es necesario guardar los fotogramas procesados como un nuevo archivo de video.

Se puede utilizar la clasecv2.VideoWriterpara lograrlo:

Ejemplo

import cv2

cap = cv2.VideoCapture('example.mp4')

# Obtener la tasa de fotogramas y las dimensiones del video
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# Crear objeto VideoWriter para guardar el video procesado
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, fps, (width, height))

while True:
    ret, frame = cap.read()
   
    if not ret:
        break
   
    # Convertir el fotograma a imagen en escala de grises
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
   
    # Escribir el fotograma en escala de grises en el video de salida
    out.write(cv2.cvtColor(gray_frame, cv2.COLOR_GRAY2BGR))
   
    # Mostrar el fotograma en escala de grises
    cv2.imshow('Gray Video', gray_frame)
   
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

cap.release()
out.release()
cv2.destroyAllWindows()

Aplicaciones avanzadas del procesamiento de video

Detección de objetos en video

OpenCV ofrece varios algoritmos de detección de objetos, como el clasificador de características Haar, HOG + SVM, etc.

A continuación se muestra un ejemplo de detección de rostros utilizando el clasificador de características Haar:

Ejemplo

import cv2

# Cargar el clasificador de características Haar
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

cap = cv2.VideoCapture('example.mp4')

while True:
    ret, frame = cap.read()
   
    if not ret:
        break
   
    # Convertir el fotograma a imagen en escala de grises
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
   
    # Detectar rostros
    faces = face_cascade.detectMultiScale(gray_frame, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
   
    # Dibujar rectángulos en el fotograma para marcar los rostros
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
   
    # Mostrar el fotograma con las marcas de rostros
    cv2.imshow('Face Detection', frame)
   
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

Detección de movimiento en video

La detección de movimiento es una aplicación importante en el procesamiento de video. Se pueden detectar objetos en movimiento calculando las diferencias entre fotogramas.

A continuación se muestra un ejemplo sencillo de detección de movimiento:

Ejemplo

import cv2

cap = cv2.VideoCapture('example.mp4')

# Leer el primer fotograma
ret, prev_frame = cap.read()
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)

while True:
    ret, frame = cap.read()
   
    if not ret:
        break
   
    # Convertir el fotograma actual a imagen en escala de grises
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
   
    # Calcular la diferencia entre el fotograma actual y el anterior
    frame_diff = cv2.absdiff(prev_gray, gray_frame)
   
    # Aplicar binarización a la imagen de diferencia
    _, thresh = cv2.threshold(frame_diff, 30, 255, cv2.THRESH_BINARY)
   
    # Mostrar el resultado de la detección de movimiento
    cv2.imshow('Motion Detection', thresh)
   
    # Actualizar el fotograma anterior
    prev_gray = gray_frame
   
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

Funciones comunes

FunciónFunción/MétodoDescripción
Leer videocv2.VideoCapture()Lee un archivo de video o una cámara.
Leer video fotograma a fotogramacap.read()Lee video fotograma a fotograma.
Obtener propiedades del videocap.get(propId)Obtiene las propiedades del video (como ancho, alto, tasa de fotogramas, etc.).
Guardar videocv2.VideoWriter()Crea un objeto de escritura de video y guarda el video.
Procesamiento de fotogramas de videoFunciones de procesamiento de imágenes (comocv2.cvtColor())realizan procesamiento de imágenes en los fotogramas de video.
Seguimiento de objetoscv2.TrackerKCF_create()Utiliza algoritmos de seguimiento de objetos para rastrear objetos en el video.
Detección de movimientocv2.createBackgroundSubtractorMOG2()Utiliza algoritmos de sustracción de fondo para detectar objetos en movimiento en el video.

cv2.VideoCapture

Definición:
cv2.VideoCaptureSe utiliza para capturar fotogramas de video desde un archivo de video o una cámara.

Sintaxis:

cv2.VideoCapture(source)

Descripción de parámetros:

  • source: ruta del archivo de video o índice de la cámara (normalmente 0 para indicar la cámara predeterminada).

Ejemplo

import cv2

# Abrir la cámara predeterminada
cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    if not ret:
        break
    cv2.imshow('Frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

cv2.VideoWriter

Definición:
cv2.VideoWriterSe utiliza para escribir fotogramas de video en un archivo de video.

Sintaxis:

cv2.VideoWriter(filename, fourcc, fps, frameSize)

Descripción de parámetros:

  • filename: nombre del archivo de video de salida.
  • fourcc: códec de video (comocv2.VideoWriter_fourcc(*'XVID'))。
  • fps: tasa de fotogramas.
  • frameSize: tamaño del fotograma (ancho, alto).

Ejemplo

import cv2

cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    out.write(frame)
    cv2.imshow('Frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
out.release()
cv2.destroyAllWindows()

cv2.cvtColor

Definición:
cv2.cvtColorSe utiliza para convertir una imagen de un espacio de color a otro.

Sintaxis:

cv2.cvtColor(src, code)

Descripción de parámetros:

  • src: imagen de entrada.
  • code: código de conversión de espacio de color (comocv2.COLOR_BGR2GRAY)。

Ejemplo

import cv2

img = cv2.imread('image.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('Gray Image', gray)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.resize

Definición:
cv2.resizeSe utiliza para redimensionar una imagen.

Sintaxis:

cv2.resize(src, dsize)

Descripción de parámetros:

  • src: imagen de entrada.
  • dsize: tamaño de la imagen de salida (ancho, alto).

Ejemplo

import cv2

img = cv2.imread('image.jpg')
resized = cv2.resize(img, (320, 240))
cv2.imshow('Resized Image', resized)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.Canny

Definición:
cv2.CannySe utiliza para la detección de bordes.

Sintaxis:

cv2.Canny(image, threshold1, threshold2)

Descripción de parámetros:

  • image: imagen de entrada.
  • threshold1: primer umbral.
  • threshold2: segundo umbral.

Ejemplo

import cv2

img = cv2.imread('image.jpg', 0)
edges = cv2.Canny(img, 100, 200)
cv2.imshow('Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.findContours

Definición:
cv2.findContoursSe utiliza para encontrar contornos en una imagen.

Sintaxis:

cv2.findContours(image, mode, method)

Descripción de parámetros:

  • image: imagen de entrada.
  • mode: modo de recuperación de contornos (comocv2.RETR_TREE)。
  • method: método de aproximación de contornos (comocv2.CHAIN_APPROX_SIMPLE)。

Ejemplo

import cv2

img = cv2.imread('image.jpg', 0)
contours, _ = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)
cv2.imshow('Contours', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.drawContours

Definición:
cv2.drawContoursSe utiliza para dibujar contornos en una imagen.

Sintaxis:

cv2.drawContours(image, contours, contourIdx, color, thickness)

Descripción de parámetros:

  • image: imagen de entrada.
  • contours: lista de contornos.
  • contourIdx: índice del contorno (-1 indica dibujar todos los contornos).
  • color: color del contorno.
  • thickness: grosor de la línea del contorno.

Ejemplo

import cv2

img = cv2.imread('image.jpg', 0)
contours, _ = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)
cv2.imshow('Contours', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.putText

Definición:
cv2.putTextSe utiliza para dibujar texto sobre una imagen.

Sintaxis:

cv2.putText(image, text, org, fontFace, fontScale, color, thickness)

Descripción de parámetros:

  • image: imagen de entrada.
  • text: texto a dibujar.
  • org: coordenada de la esquina inferior izquierda del texto.
  • fontFace: tipo de fuente (comocv2.FONT_HERSHEY_SIMPLEX)。
  • fontScale: escala de la fuente.
  • color: color del texto.
  • thickness: grosor de la línea del texto.

Ejemplo

import cv2

img = cv2.imread('image.jpg')
cv2.putText(img, 'Hello, OpenCV!', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
cv2.imshow('Text', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Otras extensiones