我正在尝试实时测量从立体声对到场景中检测到的人的距离。首先,我使用9x6棋盘(方形尺寸为59 mm)分别校准两个摄像机,并且我获得了两个摄像机的均方根误差在0.15和0.19之间。使用获得的参数,我校准了立体声对,均方根误差为0.36。后来,我纠正了,unistort并重新映射立体声对给我这个结果: rectified and undistorted stereo
完成后,我用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的结果:disparity map。
为了检测场景中的人我使用了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;
对于场景中一个人跟踪的每个角落的差异,我计算了最大差异并使用公式((焦点*基线)/ 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 camera1:904.7; fy camera1:845.7; fx camera2:913.9; fy camera2:855.1
** T [0,0]矩阵的结果与我手动测量的基线相匹配,因此我认为这是正确的基线。
**由于棋盘的方形尺寸以毫米为单位,我认为基线必须在同一单位,这就是为什么我在基线上放置了64.32毫米。
距离的结果是aprox。 55厘米,但真正的距离是300厘米。我已多次检查,但测量的距离仍然不正确:distanceResult
请帮助我!,我不知道我做错了什么。
***我在osx系统中使用opencv 2.4.9。
答案 0 :(得分:0)
我认为你的单位犯了一个错误: 焦距以像素为单位提供, 基线以cm为单位 差异以像素提供。 对? 根据公式,你有pix * cm / pix = cm。但是你将它除以10并获得dm。所以你的距离大约是55dm,是300的两倍。这对你来说并不是一个坏的例子。
答案 1 :(得分:0)
您不能在整流图像上使用简单的并行摄像机三角测量公式,因为您需要撤消整流单应性。