C++ 立体声系统-使用OpenCv获取3d位置

C++ 立体声系统-使用OpenCv获取3d位置,c++,opencv,stereo-3d,correspondence,C++,Opencv,Stereo 3d,Correspondence,我有一个带两个摄像头的立体声系统。我校准了这些照相机。我尝试计算每个指尖之间的距离。在左图中,我使用凸包查找指尖。我计算这些点的外极线,在右图上画外极线。如何计算每个指尖的三维位置?我用C++和OpenCV .< /P> 图片下方有5个窗口。他们是: 正确的形象,, 左图, 使用右图像上的凸面外壳查找指尖, 在左图上画极线, 在左侧图像上查找对应点 立体声校准后,我的.yml文件在下面 %YAML:1.0 CM1: !!opencv-matrix rows: 3 cols: 3 dt:

我有一个带两个摄像头的立体声系统。我校准了这些照相机。我尝试计算每个指尖之间的距离。在左图中,我使用凸包查找指尖。我计算这些点的外极线,在右图上画外极线。如何计算每个指尖的三维位置?我用C++和OpenCV .< /P> 图片下方有5个窗口。他们是: 正确的形象,, 左图, 使用右图像上的凸面外壳查找指尖, 在左图上画极线, 在左侧图像上查找对应点

立体声校准后,我的.yml文件在下面

%YAML:1.0
CM1: !!opencv-matrix
 rows: 3
 cols: 3
 dt: d
 data: [ 1.4947330489959640e+02, 0., 8.5026435902438408e+01, 0.,
   1.7045159164506524e+02, 6.8513237416979280e+01, 0., 0., 1. ]
CM2: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 1.4947330489959640e+02, 0., 7.6063817190941975e+01, 0.,
   1.7045159164506524e+02, 6.9869364400956655e+01, 0., 0., 1. ]
D1: !!opencv-matrix
rows: 1
cols: 5
dt: d
data: [ 4.6664660489275862e+00, -9.5605452982913761e+01, 0., 0.,
   4.4411083031870203e+02 ]
D2: !!opencv-matrix
rows: 1
cols: 5
dt: d
data: [ -2.6243438145377401e-01, 3.1158182596121313e+00, 0., 0.,
   -6.9555261934841601e+00 ]
R: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ -9.9870707407742809e-01, 5.0820157566619700e-02,
   1.2213814337059467e-03, -4.6584627039081256e-02,
   -9.2456021193091820e-01, 3.7817758664136281e-01,
   2.0348285218473684e-02, 3.7763173343769685e-01,
   9.2573226215224258e-01 ]
T: !!opencv-matrix
rows: 3
cols: 1
dt: d
data: [ -5.0257191774306198e-01, -5.1791340062890008e+00,
   -1.7104054803114692e+00 ]
E: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ -1.8506509733057530e-01, -3.5371782058656147e+00,
   -4.1476544229091719e+00, 1.7184205294528965e+00,
   1.0286402846218139e-01, 4.6315798080871423e-01,
   -5.1490256443274198e+00, 7.2786240503729882e-01,
   -1.8373573684783620e-01 ]
 F: !!opencv-matrix
  rows: 3
 cols: 3
 dt: d
 data: [ -2.0635586643392613e-06, -3.4586914187982223e-05,
   -4.3677532717492718e-03, 1.6802903312164187e-05,
   8.8202517402136951e-07, -8.1218529743132760e-04,
   -9.5988974549000728e-03, 3.6330053228360980e-03, 1. ]

由于您无法确保使用您的方法对两幅图像都能获得准确的指尖,因此我将使用不同的方法:

  • 首先使用它可以获得手的深度图像
  • 然后使用现有算法在深度图像中获取指尖
  • 最后利用深度信息重建指尖的三维位置

您可能需要一些基于3D-2D点对应的快速简单解决方案。然后将点拟合到三维模型,可以自由找到很多手的三维模型,即: OpenCV提供了一个很好的方法——solvePnP——可以执行拟合步骤。 我们需要做到以下几点:

  • 下载一个免费的模型
  • 使用任何三维编辑器编辑模型(即:)
  • 标记每个指尖的位置,我们将得到五个3D点
  • 将它们保存在文件中作为参考模型
  • opencv程序将为您找到五个2D点
  • 现在有了模型点(3d)和真实图像点(2D),必须使用solvePnP函数拟合它们: solvePnP(模型点、图像点、cameraMatrix..一些校准参数)
  • 我们将得到一个3x3矩阵,您可以将其定义为: 双卡马特[9]={x_中心,0,x_移位, 0,y_中心,y_移位, 0, 0, 1 }; //“校准矩阵”:XyCenter,YyCenter点是考虑图像中心的焦距I. XyCenter=YSenter Center=30 cameraMatrix=Mat(3,3,CV_64FC1,calMat)
  • 通过这些步骤,您可以在移动手的任何时刻估计每个指尖的3D位置

  • 使用
    cv::undortpoints()
    取消二维点的扭曲。将未变形点从两个摄影机传递到
    cv::triangulatePoints()
    (连同摄影机投影矩阵)和
    cv::Mat
    ,以存储(同质)三维坐标。调用
    convertPointsFromogeneous()
    以获取普通(非均匀)3D点。注:投影矩阵是来自
    cv::stereorective
    和/或
    /samples/cpp/stereou calib.cpp
    的P1和P2。你可能会发现它很有用。

    我不需要深度。我想计算x,y,z坐标。@Holazolli这只是第一步。一旦获得每个像素的深度,就可以恢复实际的世界坐标,因为您知道到所描绘像素的距离以及角度(基于坐标和视野的垂直和水平)。