首页 > 解决方案 > 使用立体相机的距离结果不佳

问题描述

我正在尝试实时测量从立体声对到场景中检测到的人的距离。首先,我使用 9x6 棋盘格(59 毫米的正方形)分别校准了两个相机,我得到了两个相机的 0.15 到 0.19 之间的 rms 误差。使用获得的参数,我校准了立体声对,rms 误差为 0.36。后来,我对立体声对进行了矫正、不失真和重新映射,得到了这个结果: 矫正和不失真的立体声

完成后,我使用 stereoSGBM 计算立体对应。我就是这样做的:

Mat imgDisp= Mat(frame1.cols, frame1.rows,CV_16S);

cvtColor(frame1, frame1, CV_BGR2GRAY);
cvtColor(frame2, frame2, CV_BGR2GRAY);

//parameters for stereoSGBM
  stereo.SADWindowSize = 3;
  stereo.numberOfDisparities = 144;
  stereo.preFilterCap = 63;
  stereo.minDisparity = -39;
  stereo.uniquenessRatio = 10;
  stereo.speckleWindowSize = 100;
  stereo.speckleRange = 32;
  stereo.disp12MaxDiff = 1;
  stereo.fullDP = false;
  stereo.P1 = 216;
  stereo.P2 = 864;

double minVal; double maxVal;
minMaxLoc(imgDisp, &minVal, &maxVal);

return imgDisp; 

我在这里附上了stereoSGBM的结果:视差图

为了检测场景中的人,我使用了 hog + svm(默认的人检测器)并使用光流(cvCalcOpticalFlowPyrLK())跟踪了那个人。使用在立体对应过程中获得的视差图,我获得了从一个人跟踪的每个角落的视差如下:

int x= cornersA[k].x;
int y= cornersA[k].y;

short pixVal= mapaDisp.at<short>(y,x); 
float dispFeatures= pixVal/ 16.0f;

通过为场景中的一个人跟踪每个角落的视差,我计算了最大视差并使用公式 ((focal*baseline)/disp) 计算了该像素中的深度:

float Disp =maxDisp_v[p];

cout<< "max disp"<< Disp<<endl;
float d = ((double)(879.85* 64.32)/(double)(Disp))/10; //distance in cms.

** 对于焦距,我计算了在相机矩阵 [3x3] 参数中获得的 fx 和 fy 之间的平均值:

CM1: [9.0472706037497187e+02 0. 3.7829164759284492e+02
0. 8.4576999835299739e+02 1.8649783393160138e+02 0. 0. 1.]

CM2: [9.1390904648169953e+02 0. 3.5700689147467887e+02 0. 8.5514555697053311e+02 2.1723345133656409e+02 0. 0. 1.]

所以FX相机1:904.7;fy camera1:845.7;fx 摄像机 2:913.9;fy相机2:855.1

** T[0,0] 矩阵的结果与我手动测量的基线相匹配,因此我认为这是正确的基线。

**由于棋盘格的正方形大小以毫米为单位,我假设基线必须在同一个单位中,这就是为什么我将 64.32 毫米放在基线中。

距离的结果是近似的。55 厘米,但实际距离是 300 厘米。我检查了很多次,但测量的距离仍然不正确:distanceResult

请帮助我!,我不知道我做错了什么。

*** 我在 osx 系统中使用 opencv 2.4.9。

标签: opencvcameracomputer-visionstereo-3dstereoscopy

解决方案


您不能在校正后的图像上使用简单的平行相机三角测量公式,因为您需要撤消校正单应性。

使用cv2.reprojectImageTo3D


推荐阅读