Python 点云的视差贴图已禁用

Python 点云的视差贴图已禁用,python,opencv,face-recognition,point-clouds,open3d,Python,Opencv,Face Recognition,Point Clouds,Open3d,我正在尝试使用Python和OpecCV从两幅图像进行3D人脸重建。我设法使用此处的说明执行相机校准,然后应用cv2.stereoCalibrate()和cv2.stereovertive()。然后,使用cv2.StereoSGBM计算视差图,最后使用cv2.reprojectionto3d生成点云。后者使用open3d库显示。但是,StereoSGBM.compute()的结果非常嘈杂,生成的点云看起来与实际情况完全不同 我尝试过的事情: 规范化视差贴图:该算法输出一个值介于-16和240之

我正在尝试使用Python和OpecCV从两幅图像进行3D人脸重建。我设法使用此处的说明执行相机校准,然后应用
cv2.stereoCalibrate()
cv2.stereovertive()
。然后,使用
cv2.StereoSGBM
计算视差图,最后使用
cv2.reprojectionto3d
生成点云。后者使用
open3d
库显示。但是,
StereoSGBM.compute()
的结果非常嘈杂,生成的点云看起来与实际情况完全不同

我尝试过的事情:

  • 规范化视差贴图:该算法输出一个值介于-16和240之间的2D数组,因此我将其分别调整为0和255之间,以及0.0和1.0之间。第一种选择更好
  • 将值除以16(如我在C++实现中看到的)
  • 调整GBM的参数。我甚至构建了一个GUI来调整参数,但是结果仍然不令人满意
  • 然而,使用StereoBM没有太大差异
  • 使用不同的测试图像
  • 使用灰度图像
  • 在0.0->1.0范围内对其进行规格化
  • 裁剪未失真的图像
  • 重新实现
    cv2.重新投影到3D
    ,结果相同
  • 手动删除视差贴图中的背景
  • 使用uint8和float32。使用浮动,重投影效果更好
结果图像:

  • 首字母:

  • 校准后:

  • 视差图(右侧参数):

  • 点云(从非常特定的角度看人):

我可以做些什么来获得有用的结果?我甚至不知道这些图像应该是什么样子。我的校准好像有问题吗?我有一种感觉,图像真的很糟糕(因为透视失真很大),但不幸的是,我不得不处理这些图像

一些代码存根:

_, self.camera_matrix, self.distortion, _, _ = \
            cv2.calibrateCamera(self.object_points, self.image_points, self.image_size, None, None)

error, _, _, _, _, self.rotation, self.translation, _, _ = \
            cv2.stereoCalibrate(self.camera_left.object_points,
                                self.camera_left.image_points,
                                self.camera_right.image_points,
                                self.camera_left.camera_matrix,
                                self.camera_left.distortion,
                                self.camera_right.camera_matrix,
                                self.camera_right.distortion,
                                self.camera_left.image_size,
                                flags=cv2.CALIB_FIX_INTRINSIC)

self.rotation_left, self.rotation_right, self.perspective_left, self.perspective_right, self.Q, self.roi_left, self.roi_right = \
            cv2.stereoRectify(self.camera_left.camera_matrix,
                              self.camera_left.distortion,
                              self.camera_right.camera_matrix,
                              self.camera_right.distortion,
                              self.camera_left.image_size,
                              self.rotation,
                              self.translation,
                              flags=cv2.CALIB_ZERO_DISPARITY)

self.rotation_left, self.rotation_right, self.perspective_left, self.perspective_right, self.Q, self.roi_left, self.roi_right = \
            cv2.stereoRectify(self.camera_left.camera_matrix,
                              self.camera_left.distortion,
                              self.camera_right.camera_matrix,
                              self.camera_right.distortion,
                              self.camera_left.image_size,
                              self.rotation,
                              self.translation,
                              flags=cv2.CALIB_ZERO_DISPARITY)

self.block_matching = cv2.StereoSGBM().create() # params not mentioned here, but they are set
disparity = self.block_matching.compute(undistorted_left, undistorted_right)
disparity = cv2.convertScaleAbs(disparity, beta=16)

point_cloud = cv2.reprojectImageTo3D(disparity_image, Q)
point_cloud = point_cloud.reshape(-1, point_cloud.shape[-1])
point_cloud = point_cloud[~np.isinf(point_cloud).any(axis=1)]

pcl = open3d.geometry.PointCloud()
pcl.points = open3d.utility.Vector3dVector(point_cloud)
open3d.visualization.draw_geometries([pcl])