vb.net - palabras - Extraer matrices de transformación y rotación de la homografía?
homonimos y homografos ejemplos (2)
Tengo 2 imágenes consecutivas de una cámara y quiero estimar el cambio en la pose de la cámara:
Calculo el flujo óptico:
Const MAXFEATURES As Integer = 100
imgA = New Image(Of [Structure].Bgr, Byte)("pic1.bmp")
imgB = New Image(Of [Structure].Bgr, Byte)("pic2.bmp")
grayA = imgA.Convert(Of Gray, Byte)()
grayB = imgB.Convert(Of Gray, Byte)()
imagesize = cvGetSize(grayA)
pyrBufferA = New Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte) _
(imagesize.Width + 8, imagesize.Height / 3)
pyrBufferB = New Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte) _
(imagesize.Width + 8, imagesize.Height / 3)
features = MAXFEATURES
featuresA = grayA.GoodFeaturesToTrack(features, 0.01, 25, 3)
grayA.FindCornerSubPix(featuresA, New System.Drawing.Size(10, 10),
New System.Drawing.Size(-1, -1),
New Emgu.CV.Structure.MCvTermCriteria(20, 0.03))
features = featuresA(0).Length
Emgu.CV.OpticalFlow.PyrLK(grayA, grayB, pyrBufferA, pyrBufferB, _
featuresA(0), New Size(25, 25), 3, _
New Emgu.CV.Structure.MCvTermCriteria(20, 0.03D),
flags, featuresB(0), status, errors)
pointsA = New Matrix(Of Single)(features, 2)
pointsB = New Matrix(Of Single)(features, 2)
For i As Integer = 0 To features - 1
pointsA(i, 0) = featuresA(0)(i).X
pointsA(i, 1) = featuresA(0)(i).Y
pointsB(i, 0) = featuresB(0)(i).X
pointsB(i, 1) = featuresB(0)(i).Y
Next
Dim Homography As New Matrix(Of Double)(3, 3)
cvFindHomography(pointsA.Ptr, pointsB.Ptr, Homography, HOMOGRAPHY_METHOD.RANSAC, 1, 0)
y se ve bien, la cámara se movió hacia la izquierda y hacia arriba: Ahora quiero saber cuánto se movió y giró la cámara. Si declaro la posición de mi cámara y lo que está mirando:
'' Create camera location at origin and lookat (straight ahead, 1 in the Z axis)
Location = New Matrix(Of Double)(2, 3)
location(0, 0) = 0 '' X location
location(0, 1) = 0 '' Y location
location(0, 2) = 0 '' Z location
location(1, 0) = 0 '' X lookat
location(1, 1) = 0 '' Y lookat
location(1, 2) = 1 '' Z lookat
¿Cómo calculo la nueva posición y lookat?
Si estoy haciendo todo mal o si hay un método mejor, cualquier sugerencia sería muy bienvenida, ¡gracias!
Bueno, lo que estás viendo es en términos simples un problema del teorema de Pitágoras a ^ 2 + b ^ 2 = c ^ 2. Sin embargo, cuando se trata de aplicaciones basadas en cámara, las cosas no son muy fáciles de determinar con precisión. Ha encontrado la mitad de los detalles que necesita para "a"; sin embargo, encontrar "b" o "c" es mucho más difícil.
La respuesta corta
Básicamente no se puede hacer con una sola cámara. Pero puede hacerse con dos cámaras.
La respuesta de larga duración (Pensé que lo explicaría con más profundidad, sin juego de palabras)
Trataré de explicar, decir que seleccionamos dos puntos dentro de nuestra imagen y movemos la cámara hacia la izquierda. Sabemos que la distancia de la cámara de cada punto B1 es de 20 mm y el punto B2 es de 40 mm. Ahora supongamos que procesamos la imagen y nuestra medida es A1 es (0,2) y A2 es (0,4) estas están relacionadas con B1 y B2 respectivamente. Ahora A1 y A2 no son mediciones; son pixeles de movimiento.
Lo que ahora tenemos que hacer es multiplicar el cambio en A1 y A2 por una constante calculada que será la distancia del mundo real en B1 y B2. NOTA: cada uno de estos es diferente según la medición B *. Todo esto se relaciona con el ángulo de visión o más comúnmente llamado campo de visión en la fotografía a diferentes distancias. Puede calcular con precisión la constante si conoce el tamaño de cada píxel en el CCD de la cámara y el número f del objetivo que tiene dentro de la cámara.
Supongo que este no es el caso, por lo que a diferentes distancias debe colocar un objeto del que conoce la longitud y ver cuántos píxeles ocupa. De cerca, puede usar una regla para facilitar las cosas. Con estas medidas Toma estos datos y forma una curva con una línea de mejor ajuste. Donde el eje X será la distancia del objeto y el eje Y será la relación constante de píxel a distancia con la que deberá multiplicar su movimiento.
Entonces, ¿cómo aplicamos esta curva? Bueno, supongo que es trabajo. En teoría, cuanto mayor sea la medida del movimiento A * más cercano será el objeto a la cámara. En nuestro ejemplo, nuestras relaciones para A1> A2 dicen 5 mm y 3 mm respectivamente, y ahora sabríamos que el punto B1 se movió 10 mm (2x5 mm) y B2 se movió 6 mm (2x6 mm). Pero enfrentémoslo: nunca conoceremos B y nunca podremos decir si una distancia movida es de 20 píxeles de un objeto que se acerca moviéndose muy lejos o un objeto muy lejos moviéndose a una gran distancia. Esta es la razón por la que cosas como Xbox Kinect usan sensores adicionales para obtener información de profundidad que puede vincularse con los objetos dentro de la imagen.
Lo que intenta podría intentarse con dos cámaras, ya que la distancia entre estas cámaras es conocida, el movimiento se puede calcular con mayor precisión (de manera efectiva sin usar un sensor de profundidad). Las matemáticas detrás de esto son extremadamente complejas y sugeriría buscar algunos artículos de revistas sobre el tema. Si desea que explique la teoría, puedo intentarlo.
Toda mi experiencia proviene del diseño de adquisición de video de alta velocidad y procesamiento de imágenes para mi PHD, así que créanme, no se puede hacer con una cámara, lo siento. Espero que algo de esto ayude.
Aclamaciones
Chris
[EDITAR]
Iba a agregar un comentario, pero esto es más fácil debido a la gran cantidad de información:
Dado que es el Kinect, asumiré que tienes información de profundidad relevante asociada con cada punto, si no es así, necesitarás averiguar cómo conseguirlo.
La ecuación con la que deberá comenzar es para el Campo de visión ( FOV ):
o / d = i / f
Dónde:
f es igual a la distancia focal de la lente generalmente dada en mm (es decir, 18 28 30 50 son ejemplos estándar)
d es la distancia del objeto desde la lente recopilada a partir de datos de kinect
o es la dimensión del objeto (o "campo de visión" perpendicular ay bisecado por el eje óptico).
i es la dimensión de la imagen (o "parada de campo" perpendicular ay dividida por el eje óptico).
Necesitamos calcular i , donde o es nuestro desconocido así que para i (que es una medida diagonal),
Necesitaremos el tamaño del píxel en el ccd, esto en micrómetros o en μm, tendrá que encontrar esta información. Para saber, la tomaremos como 14um, que es estándar para una cámara de escaneo de área de rango medio.
Entonces, primero tenemos que calcular la dimensión horizontal ( ih ) que es el número de píxeles del ancho de la cámara multiplicado por el tamaño del píxel del ccd (Usaremos 640 x 320)
entonces: ih = 640 * 14um = 8960um
= 8960/1000 = 8.96mm
Ahora necesitamos la dimensión vertical ( iv ) mismo proceso pero la altura
Entonces: iv = (320 * 14um) / 1000 = 4.48mm
Ahora me encuentro por el teorema de Pitágoras el teorema de Pitágoras a ^ 2 + b ^ 2 = c ^ 2
entonces: i = sqrt (ih ^ 2 _ iv ^ 2)
= 10.02 mm
Ahora asumiremos que tenemos una lente de 28 mm. De nuevo, este valor exacto tendrá que ser descubierto. Entonces nuestra ecuación se reorganiza para darnos o es:
o = (i * d) / f
Recuerde que o será diagonal (asumiremos que el objeto o punto está a 50 mm de distancia):
o = (10.02 mm * 50 mm) / 28 mm
17.89mm
Ahora necesitamos calcular la dimensión horizontal ( oh ) y o la dimensión vertical ( ov ) ya que esto nos dará la distancia por píxel que el objeto ha movido. Ahora, como FOV α CCD o i es directamente proporcional a o , calcularemos una relación k
k = i / o
= 10.02 / 17.89
= 0.56
asi que:
o dimensión horizontal ( oh ):
oh = ih / k
= 8,96 mm / 0,56 = 16 mm por píxel
o dimensión vertical ( ov ):
ov = iv / k
= 4,48 mm / 0,56 = 8 mm por píxel
Ahora tenemos las constantes que necesitamos, usémoslo en un ejemplo. Si nuestro objeto a 50 mm se mueve desde la posición (0,0) a (2,4), las medidas en la vida real son:
(2 * 16 mm, 4 * 8 mm) = (32 mm, 32 mm)
De nuevo, un teorema de Pitágoras: a ^ 2 + b ^ 2 = c ^ 2
Distancia total = sqrt (32 ^ 2 + 32 ^ 2)
= 45.25mm
Complicado, lo sé, pero una vez que tienes esto en un programa, es más fácil. Por lo tanto, para cada punto, deberá repetir al menos la mitad del proceso, ya que d cambiará, por lo tanto, o por cada punto que examine.
Espero que esto te ponga en camino,
Saludos Chris
Para la rotación de cámara pura R = A -1 HA. Para probar esto, considere la homogeneidad de imagen a plano H1 = A y H2 = AR, donde A es la matriz intrínseca de la cámara. Entonces H12 = H2 * H1 -1 = A -1 RA, de la cual puede obtener R
La traducción de la cámara es más difícil de estimar. Si la cámara se traduce, primero debe buscar la matriz fundamental (no la homografía): x T Fx = 0 y luego conviértala en una matriz esencial E = A T FA; Luego puede descomponer E en rotación y traslación E = t x R, donde t x significa una matriz de producto vectorial. La descomposición no es obvia, mira esto .
La rotación que obtenga será exacta, mientras que el vector de traducción solo se podrá encontrar a escala. Intuitivamente, este escalado significa que, a partir de las dos imágenes, no se puede decir realmente si los objetos son pequeños o cercanos, o muy grandes. Para desambiguar podemos usar objetos de tamaño familiar, distancia conocida entre dos puntos, etc.
Finalmente, tenga en cuenta que un sistema visual humano tiene un problema similar: aunque "conocemos" la distancia entre nuestros ojos, cuando están convergentes en el objeto, la disparidad es siempre cero y solo por la disparidad no podemos decir cuál es la distancia. La visión humana se basa en la triangulación de la señal de la versión de los ojos para calcular la distancia absoluta.