对象在基本矩阵计算和投影后看起来是倾斜的

Object Looking Skewed After Essential Matrix Calculation and Projection

我正在尝试从两个图像计算基本矩阵和投影矩阵。然后我将使用它们将 3D 对象投影到图像上。我用的两张图是

我选择了一些像素对应关系,并将其提供给基于 SVD 的最小二乘机制,书中说该机制为我提供了基本矩阵。我使用下面的代码来完成这项任务(代码主要基于 Eric Solem 的计算机视觉编程和 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)

我计算了基本矩阵,然后是投影矩阵,然后用它来投影 3D 立方体。结果:

这看起来有点歪,我不确定为什么会这样。关于如何解决这个问题有什么想法吗?

谢谢,

首先,您似乎正在使用 9 个点计算基本矩阵。你可以只使用 8 来做到这一点(因为比例是一个自由参数,你可以将基本参数乘以一个标量,它会保持不变,所以你可以固定一个参数并只使用 8 个点,但我离题了。)但是,实际上,这是一个非常糟糕的主意,因为您的 8 点可能空间配置不佳。所以你想要做的是 select N 匹配(例如 600),并使用像 RANSAC to determine the best Essential matrix. But aside from that, what I'd recommend to debug such applications is this: compute the Fundalental 矩阵 F 这样的算法基于你刚刚计算的 Essential .现在您可以 select 图像 1 中的一个点,然后在第二个图像中显示相应的对极线。这将帮助您直观地评估并从而调试 Essential 的估计。