我正在尝试从两个图像计算基本和投影矩阵。然后我将使用它们将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立方体。结果:
这看起来有些偏差,我不确定为什么会这样。关于如何解决这个问题的任何想法?
谢谢,
答案 0 :(得分:1)
首先,看起来你正在使用9个点来计算基本矩阵。你可以只使用8来做这个(因为scale是一个自由参数,你可以将基数乘以标量,它将保持不变,所以你可以修复其中一个参数,只使用8个点,但我离题了。)但是,在实践中,这是一个非常糟糕的主意,因为你的8点可能具有较差的空间配置。所以你想要做的是选择N个匹配(例如600),并使用像RANSAC这样的算法来确定最佳的基本矩阵。但除此之外,我建议调试此类应用程序的是:根据您刚刚计算的Essential计算Fundalental矩阵 F 。现在,您可以选择图像1中的一个点,然后在第二个中显示相应的极线。这将有助于您在视觉上评估并调试Essential的估算。