2016-10-11 4 views
1

J'essaie de calculer une matrice essentielle et une matrice de projection à partir de deux images. Je vais ensuite les utiliser pour projeter un objet 3D sur l'image. Les deux images que j'ai utilisées sontObjet semblant asymétrique après le calcul de la matrice essentielle et la projection

enter image description here enter image description here

j'ai choisi quelques correspondances de pixels et engraissé qui à un SVD base moins mécanisme carré que les livres disent me donne la matrice essentielle. J'ai utilisé le code ci-dessous pour cette tâche (code est basé principalement sur Eric Programmation de Solem Computer Vision avec le livre Python):

import scipy.linalg as lin 
import pandas as pd 

def skew(a): 
    return np.array([[0,-a[2],a[1]],[a[2],0,-a[0]],[-a[1],a[0],0]]) 

def essential(x1,x2): 
    n = x1.shape[1] 
    A = np.zeros((n,9)) 
    for i in range(n): 
     A[i] = [ x1[0,i]*x2[0,i], \ 
      x1[0,i]*x2[1,i], \ 
      x1[0,i]*x2[2,i], \ 
      x1[1,i]*x2[0,i], \ 
      x1[1,i]*x2[1,i], \ 
      x1[1,i]*x2[2,i], \ 
      x1[2,i]*x2[0,i], \ 
      x1[2,i]*x2[1,i], \ 
      x1[2,i]*x2[2,i]] 

    U,S,V = lin.svd(A) 
    F = V[-1].reshape(3,3) 
    return F 

def compute_P_from_essential(E): 
    U,S,V = lin.svd(E) 
    if lin.det(np.dot(U,V))<0: V = -V 
    E = np.dot(U,np.dot(np.diag([1,1,0]),V))   
    Z = skew([0,0,-1]) 
    W = np.array([[0,-1,0],[1,0,0],[0,0,1]])  
    P2 = [np.vstack((np.dot(U,np.dot(W,V)).T,U[:,2])).T, 
      np.vstack((np.dot(U,np.dot(W,V)).T,-U[:,2])).T, 
      np.vstack((np.dot(U,np.dot(W.T,V)).T,U[:,2])).T, 
      np.vstack((np.dot(U,np.dot(W.T,V)).T,-U[:,2])).T] 
    return P2 


points = [ \ 
    [266,163,296,160],[265,237,297,266],\ 
    [76,288,51,340],[135,31,142,4],\ 
    [344,167,371,156],[48,165,71,164],\ 
    [151,68,166,56],[237,26,259,19],\ 
    [226,147,254,140]] 

df = pd.DataFrame(points) 
df['uno'] = 1. 
x1 = np.array(df[[0,1,'uno']].T) 
x2 = np.array(df[[2,3,'uno']].T) 
print x1 
print x2 
E = essential(x1,x2) 
P = compute_P_from_essential(E) 

import pandas as pd 

x0 = 3.; y0 = 1.; z0 = 1. 

print df.shape 
e = 1 
cube = [[x0,y0,z0],[x0+e,y0,z0],[x0+e,y0+e,z0],[x0,y0+e,z0], 
     [x0,y0,z0+e],[x0+e,y0,z0+e],[x0+e,y0+e,z0+e],[x0,y0+e,z0+e]] 
cube = pd.DataFrame(cube) 
cube['1'] = 1. 

xx = np.dot(P[1], cube.T) * 100. 
xx[1,:] = 360-xx[1,:] 
#xx = xx/xx[2] 
print xx[0].shape 
plt.plot(xx[0], xx[1],'.') 
plt.xlim(0,640) 
plt.ylim(0,360) 

I calculé la matrice essentielle, la matrice de projection, puis utilisée que pour projeter une Cube 3D Le résultat:

enter image description here

Cela semble biaisé, je ne sais pas pourquoi cela est arrivé. Des idées pour résoudre le problème?

Merci,

Répondre

1

Tout d'abord, il semble que vous calculer la matrice essentielle en utilisant exactement 9 points. Vous pouvez le faire en utilisant seulement 8 (puisque l'échelle est un paramètre libre, vous pouvez multiplier l'essentiel par un scalaire et il restera le même afin que vous puissiez fixer l'un des paramètres et utiliser 8 points, mais je m'égare). en pratique c'est une très mauvaise idée car vos 8 points peuvent avoir une mauvaise configuration spatiale. Donc ce que vous voulez faire est de sélectionner N correspond (600 par exemple), et d'utiliser un algorithme comme RANSAC pour déterminer la meilleure matrice essentielle. Mais à part ça, ce que je recommande pour déboguer de telles applications est la suivante: calculer la matrice FundalentalF basée sur l'essentiel que vous venez de calculer. Vous pouvez maintenant sélectionner un point dans l'image 1 et afficher la ligne épipolaire correspondante dans le second. Cela vous aidera à évaluer visuellement et ainsi déboguer l'estimation de l'essentiel.