En este artículo, conoceremos la técnica de flujo óptico denso de Gunnar FarneBack, que se publicó en un artículo de investigación llamado ‘Estimación de movimiento de dos fotogramas basada en expansión polinomial’ por Gunnar Farneback en 2003.
Requisitos previos:
flujo óptico OpenCV :
el flujo óptico es conocido como el patrón de movimiento aparente de los objetos, es decir, es el movimiento de los objetos entre cada dos fotogramas consecutivos de la secuencia, que es causado por el movimiento del objeto que se captura o de la cámara que lo captura. Considere un objeto con intensidad I (x, y, t) , después del tiempo dt , se mueve por dx y dy , ahora, la nueva intensidad sería, I (x+dx, y+dy, t+dt) .
Suponemos que las intensidades de los píxeles son constantes entre los dos fotogramas, es decir,
I (x, y, t) = I (x+dx, y+dy, t+dt)
La aproximación de Taylor se realiza en el lado derecho, lo que da como resultado ,
Al dividir por δt , obtenemos la ecuación de flujo óptico , es decir,
donde, u = dx/dt yv = dy/dt .
Además, dI/dx es el gradiente de imagen a lo largo del eje horizontal, dI/dy es el gradiente de imagen a lo largo del eje vertical y dI/dt es a lo largo del tiempo.
Como solo tenemos una ecuación para encontrar dos incógnitas, usamos diferentes métodos para resolver,
- Flujo óptico disperso (método de Lucas Kanade)
- Flujo óptico denso (método de Gunnar Farneback)
Flujo óptico de Gunnar Farneback
En el flujo óptico denso, observamos todos los puntos (a diferencia de Lucas Kanade, que funciona solo en los puntos de las esquinas detectados por el algoritmo Shi-Tomasi ) y detectamos los cambios de intensidad de píxeles entre los dos cuadros, lo que da como resultado una imagen con resaltado. píxeles, después de convertir al formato hsv para una visibilidad clara.
Calcula la magnitud y la dirección del flujo óptico a partir de una serie de vectores de flujo, es decir, (dx/dt, dy/dt) . Más tarde, visualiza el ángulo (dirección) del flujo por tono y la distancia (magnitud) del flujo por el valor de la representación de color HSV. Para que la visibilidad sea óptima, la fuerza de HSV se establece en 255. OpenCV proporciona una función cv2.calcOpticalFlowFarneback para mirar en un flujo óptico denso.
Sintaxis:
cv2.calcOpticalFlowFarneback(prev, next, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags[, flow])
Parámetros:
- prev : Primera imagen de entrada en formato de canal único de 8 bits.
- siguiente: Segunda imagen de entrada del mismo tipo y del mismo tamaño que la anterior .
- pyr_scale: parámetro que especifica la escala de la imagen para construir pirámides para cada imagen (escala < 1). Una pirámide clásica es generalmente de escala 0.5, cada nueva capa agregada, se reduce a la mitad a la anterior.
- niveles: niveles = 1 dice que no hay capas adicionales (solo la imagen inicial). Es el número de capas de la pirámide incluyendo la primera imagen.
- winsize : es el tamaño de ventana promedio, cuanto mayor sea el tamaño, más robusto es el algoritmo para el ruido y proporciona una detección de movimiento rápida, aunque da campos de movimiento borrosos.
- iteraciones : Número de iteraciones a realizar en cada nivel de la pirámide.
- poly_n : normalmente es 5 o 7, es el tamaño de la vecindad de píxeles que se utiliza para encontrar la expansión polinomial entre los píxeles.
- poly_sigma : desviación estándar de la gaussiana que es para que las derivadas sean suaves como base de la expansión del polinomio. Puede ser 1,1 para poli = 5 y 1,5 para poli = 7.
- flow : imagen de flujo calculada que tiene un tamaño similar al anterior y el tipo CV_32FC2.
- banderas: puede ser una combinación de
OPTFLOW_USE_INITIAL_FLOW usa el flujo de entrada como aproximación inicial.
OPTFLOW_FARNEBACK_GAUSSIAN utiliza el filtro gaussiano winsize*winsize .
Código:
Python3
# Importing libraries import cv2 import numpy as np # Capturing the video file 0 for videocam else you can provide the url capture = cv2.VideoCapture("video_file.avi") # Reading the first frame _, frame1 = capture.read() # Convert to gray scale prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY) # Create mask hsv_mask = np.zeros_like(frame1) # Make image saturation to a maximum value hsv_mask[..., 1] = 255 # Till you scan the video while(1): # Capture another frame and convert to gray scale _, frame2 = capture.read() next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY) # Optical flow is now calculated flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0) # Compute magnite and angle of 2D vector mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1]) # Set image hue value according to the angle of optical flow hsv_mask[..., 0] = ang * 180 / np.pi / 2 # Set value as per the normalized magnitude of optical flow hsv_mask[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX) # Convert to rgb rgb_representation = cv2.cvtColor(hsv_mask, cv2.COLOR_HSV2BGR) cv2.imshow('frame2', rgb_representation) kk = cv2.waitKey(20) & 0xff # Press 'e' to exit the video if kk == ord('e'): break # Press 's' to save the video elif kk == ord('s'): cv2.imwrite('Optical_image.png', frame2) cv2.imwrite('HSV_converted_image.png', rgb_representation) prvs = next capture.release() cv2.destroyAllWindows()
Aporte
Producción:
- https://docs.opencv.org/2.4/modules/video/doc/motion_analysis_and_object_tracking.html
Publicación traducida automáticamente
Artículo escrito por anchal_agarwal y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA