问题描述
我正在尝试使用cv2.triangulatePoints获得3D点,但是它总是返回几乎相同的Z值。我的输出看起来像这样:
如图所示,所有点的Z值几乎相同。没有深度。这是我的三角剖分:
def triangulate(self,proj_mat1,pts0,pts1):
proj_mat0 = np.zeros((3,4))
proj_mat0[:,:3] = np.eye(3)
pts0,pts1 = self.normalize(pts0),self.normalize(pts1)
pts4d = cv2.triangulatePoints(proj_mat0,pts0.T,pts1.T).T
pts4d /= pts4d[:,3:]
out = np.delete(pts4d,3,1)
print(out)
return out
这是我的投影矩阵计算:
def getP(self,rmat,tvec):
P = np.concatenate([rmat,tvec.reshape(3,1)],axis = 1)
return P
这是我得到rmat,tvec并调用三角剖分的部分:
E,mask = cv2.findEssentialMat(np.array(aa),np.array(bb),self.K)
_,R,t,mask = cv2.recoverPose(E,np.array(aa),self.K)
proj_mat1 = self.getP(R,t)
out = self.triangulate(proj_mat1,np.array(aa,dtype = np.float32),np.array(bb,dtype = np.float32))
我的相机矩阵:
array([[787.8113353,0.,318.49905794],[ 0.,786.9638204,245.98673477],1. ]])
我的投影矩阵1:
array([[1.,0.],[0.,1.,0.]])
说明:
- aa和bb是2帧中的匹配点。
- self.K是我的相机矩阵
- 从基本矩阵中提取旋转和平移矩阵 从匹配的关键点计算出的
- 基本矩阵。每帧都会改变。
- 投影矩阵2每帧都会更改。
更改第一个投影矩阵后的输出(我从matplotlib切换为穿山甲作为3D可视化工具):
使用我在注释中提到的P1和P2之后的输出:
我的错误在哪里?请让我知道是否需要任何进一步的信息。我将更新我的问题。
解决方法
Ciao
不幸的是,我无法直接进行仔细检查,但我的直觉是,您面临的问题基本上是由于选择了第一个投影矩阵
我做了一些研究,发现this great paper既有理论基础又有实践基础。尽管与您的方法略有不同,但是有话值得一说
如果仔细检查,第一个投影矩阵恰好是摄影机矩阵,且最后一列等于零。实际上,第一个摄像头的旋转矩阵简化为单位矩阵,并且对应的平移矢量为空矢量,因此使用this general formula:
P = KT
其中P
是投影矩阵,K
是相机矩阵,而T
是旋转矩阵R
所获得的矩阵,平移矢量t
根据:
T = [R|t]
那么您将得到:
回到您的情况,首先,我建议您改变刚才所说的第一个投影矩阵
此外,我了解到您计划在每个帧上使用不同的内容,但是如果在建议的更改之后这些内容仍然不匹配,那么在您的鞋子中,我将只处理2张图像[我认为您隐式地确实已经建立了aa
和bb
]之间的对应关系,首先使用您的算法计算矩阵,然后检查根据上一篇文章获得的矩阵
通过这种方式,您将能够了解/调试哪些矩阵给您带来了麻烦
祝你有美好的一天,
安东尼诺
非常感谢@Antonino所做的所有努力。我的网络摄像头非常糟糕。在更改了代码的每个部分并进行了多次试用之后,我决定更改网络摄像头并购买了优质的网络摄像头。它起作用了:D这是结果: