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
# 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
# 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
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
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
# 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
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ón | Función/Método | Descripción |
|---|---|---|
| Leer video | cv2.VideoCapture() | Lee un archivo de video o una cámara. |
| Leer video fotograma a fotograma | cap.read() | Lee video fotograma a fotograma. |
| Obtener propiedades del video | cap.get(propId) | Obtiene las propiedades del video (como ancho, alto, tasa de fotogramas, etc.). |
| Guardar video | cv2.VideoWriter() | Crea un objeto de escritura de video y guarda el video. |
| Procesamiento de fotogramas de video | Funciones de procesamiento de imágenes (comocv2.cvtColor()) | realizan procesamiento de imágenes en los fotogramas de video. |
| Seguimiento de objetos | cv2.TrackerKCF_create() | Utiliza algoritmos de seguimiento de objetos para rastrear objetos en el video. |
| Detección de movimiento | cv2.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
# 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
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
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
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
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
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
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
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()