Solución:
Puedo sugerir una de las siguientes soluciones:
- Uso de funciones locales de alto nivel: OpenCV incluye SURF, por lo que: para cada cuadro, extraiga las funciones SURF. Luego, cree la característica Kd-Tree (también en OpenCV), luego haga coincidir cada dos marcos consecutivos para encontrar pares de características correspondientes. Introduzca esos pares en cvFindHomography para calcular la homografía entre esos fotogramas. Deformar los marcos según homografías (combinadas ..) para estabilizar. Este es, que yo sepa, un enfoque muy robusto y sofisticado, sin embargo, la extracción y el emparejamiento de SURF pueden ser bastante lentos
- Puede intentar hacer lo anterior con características “menos robustas”, si espera solo un movimiento menor entre dos marcos, por ejemplo, utilice la detección de esquinas de Harris y construya pares de esquinas más cercanas entre sí en ambos marcos, alimente a cvFindHomography y luego como arriba. Probablemente más rápido pero menos robusto.
- Si restringe el movimiento a la traducción, es posible que pueda reemplazar cvFindHomography con algo más … simple, para obtener la traducción entre pares de características (por ejemplo, promedio)
- Utilice la correlación de fase (ref. Http://en.wikipedia.org/wiki/Phase_correlation), si solo espera una traducción entre dos fotogramas. OpenCV incluye DFT / FFT e IFFT, consulte el artículo de wikipedia vinculado sobre fórmulas y explicación.
EDITAR
Tres comentarios que debería mencionar explícitamente, por si acaso:
- Es probable que el enfoque basado en la homografía sea muy exacto, por lo que el objeto estacionario permanecerá estacionario. Sin embargo, las homografías incluyen también la distorsión de la perspectiva y el zoom, por lo que el resultado puede parecer un poco … poco común (o incluso distorsionado para algunos movimientos rápidos). Aunque sea exacto, esto puede resultar menos agradable a la vista; así que utilícelo más bien para un procesamiento posterior o, como, forense. Pero deberías probarlo, también podría ser muy agradable para algunas escenas / movimientos.
- Que yo sepa, al menos varias herramientas gratuitas de estabilización de video utilizan la correlación de fase. Si solo desea “desencajar” la cámara, esto podría ser preferible.
- Hay bastante investigación en este campo. Encontrará algunos enfoques mucho más sofisticados en algunos artículos (aunque es probable que requieran algo más que OpenCV).
OpenCV tiene las funciones estimarRigidTransform () y warpAffine () que manejan muy bien este tipo de problema.
Es tan simple como esto:
Mat M = estimateRigidTransform(frame1,frame2,0)
warpAffine(frame2,output,M,Size(640,480),INTER_NEAREST|WARP_INVERSE_MAP)
Ahora output
contiene el contenido de frame2
que está mejor alineado para adaptarse a frame1
. Para turnos grandes, M será una Matriz cero o puede que no sea una Matriz en absoluto, dependiendo de la versión de OpenCV, por lo que tendría que filtrarlos y no aplicarlos. No estoy seguro de cuán grande es eso; tal vez la mitad del ancho del marco, tal vez más.
El tercer parámetro para estimarRigidTransform es un booleano que le dice si también debe aplicar una matriz afín arbitraria o restringirla a traducción / rotación / escala. Con el fin de estabilizar una imagen de una cámara, probablemente solo desee lo último. De hecho, para la estabilización de imagen de la cámara, es posible que también desee eliminar cualquier escala de la matriz devuelta normalizándola solo para rotación y traslación.
Además, para una cámara en movimiento, probablemente desee muestrear M a través del tiempo y calcular una media.
Aquí hay enlaces a más información sobre estimarRigidTransform () y warpAffine ()
openCV ahora tiene una clase de estabilización de video: http://docs.opencv.org/trunk/d5/d50/group__videostab.html