cv2 triangulatePoints始终返回相同的Z值

问题描述

我正在尝试使用cv2.triangulatePoints获得3D点,但是它总是返回几乎相同的Z值。我的输出看起来像这样:

output image and output 3d points

如图所示,所有点的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可视化工具):

output

使用我在注释中提到的P1和P2之后的输出

enter image description here

我的错误在哪里?请让我知道是否需要任何进一步的信息。我将更新我的问题。

解决方法

Ciao

不幸的是,我无法直接进行仔细检查,但我的直觉是,您面临的问题基本上是由于选择了第一个投影矩阵

我做了一些研究,发现this great paper既有理论基础又有实践基础。尽管与您的方法略有不同,但是有话值得一说

如果仔细检查,第一个投影矩阵恰好是摄影机矩阵,且最后一列等于零。实际上,第一个摄像头的旋转矩阵简化为单位矩阵,并且对应的平移矢量为空矢量,因此使用this general formula

P = KT

其中P是投影矩阵,K是相机矩阵,而T是旋转矩阵R所获得的矩阵,平移矢量t根据:

T = [R|t]

那么您将得到:

matrices_multiplication

回到您的情况,首先,我建议您改变刚才所说的第一个投影矩阵

此外,我了解到您计划在每个帧上使用不同的内容,但是如果在建议的更改之后这些内容仍然不匹配,那么在您的鞋子中,我将只处理2张图像[我认为您隐式地确实已经建立了aabb]之间的对应关系,首先使用您的算法计算矩阵,然后检查根据上一篇文章获得的矩阵

通过这种方式,您将能够了解/调试哪些矩阵给您带来了麻烦

祝你有美好的一天,
安东尼诺

,

非常感谢@Antonino所做的所有努力。我的网络摄像头非常糟糕。在更改了代码的每个部分并进行了多次试用之后,我决定更改网络摄像头并购买了优质的网络摄像头。它起作用了:D这是结果: enter image description here