双目相机测距结果偏差过大求助:实测3米却显示55厘米
双目行人测距偏差问题排查方案
嗨,我来帮你捋捋这个测距结果偏差巨大的问题!从你描述的流程来看,几个关键环节都可能出了问题,咱们一步步拆解:
一、先盯紧视差计算这个核心环节
1. 你的SGBM代码漏了最关键的一步!
看你贴的SGBM参数设置代码,最后居然没调用 stereo.compute(frame1, frame2, imgDisp) 来计算视差?!如果没执行这一步,imgDisp 就是初始化的空矩阵或者随机值,那后面提取的视差值完全是错的,这绝对是大问题!
2. 视差图的合理性要先确认
就算你补了compute步骤,也要先检查视差图:
- 把视差图归一化转成8位图像显示,看看行人区域的视差值是不是符合“近大远小”的规律——3米远的行人视差应该偏小,要是行人区域的视差特别大,那肯定是匹配错了。
- 你的SGBM参数里
minDisparity=-39,这个值是不是合理?负视差意味着右相机的点在左相机的左边,大概率是立体校正没做好,左右图像没对齐导致的。
3. 视差值提取的细节要核对
你提取视差的代码是这样的:
int x= cornersA[k].x; int y= cornersA[k].y; short pixVal= mapaDisp.at<short>(y,x); float dispFeatures= pixVal/ 16.0f;
这里除以16是对的(OpenCV的SGBM输出的16位视差图是实际视差×16),但要确认:
mapaDisp是不是就是计算得到的imgDisp?有没有做过其他转换导致数值变了?- 光流跟踪的角点是不是真的在行人身上?会不会跟踪飘到背景去了?背景的视差和行人完全不一样,提取错了点的话距离肯定不对。
二、焦距和基线的参数用错了!
1. 焦距不能用原始内参的平均值
你取了两台相机fx、fy的平均值879.85,但双目测距必须用立体校正后的统一焦距!因为立体校正后,两台相机的内参已经被校准成完全一致的(比如统一用左相机的校正后内参),原始的单目内参平均值根本不适用。
正确的做法是从立体标定得到的Q矩阵(重投影矩阵)里提取焦距,Q矩阵的第三行第四列就是校正后的fx值;或者直接用校正后的相机内参的fx。
2. 别用手动测量的基线!
你手动测的64.32mm误差太大了,应该用立体标定后得到的平移向量T的绝对值作为基线——T[0]就是准确的基线长度(和棋盘格单位一致,也就是mm),这个值比手动测量靠谱多了。
三、立体校正的效果要打个问号
你做了校正、去畸变,但要先确认:
- 校正后的左右图像是不是行对齐?把左右图像拼在一起,看同一物体的投影是不是在同一水平线上,这是立体匹配的前提!要是没对齐,视差计算完全是瞎扯。
- 你双目标定的RMS误差是0.36,这个值偏大了,一般双目标定的RMS要控制在0.2以内,误差太大的话校正效果肯定不好,直接影响后续的视差计算。
四、换个方式验证深度计算
别自己手动算深度了,用OpenCV的reprojectImageTo3D函数直接把视差图转成点云,然后取行人区域的点云Z值,这样能避免手动公式的错误,也能直观看到行人的深度分布。
快速验证步骤
- 先补全SGBM的
compute调用,然后显示归一化后的视差图,确认视差分布合理; - 检查校正后的左右图像是否行对齐;
- 用标定得到的Q矩阵和T向量替换你手动的焦距和基线,重新计算;
- 用
reprojectImageTo3D生成点云,查看行人的深度值。
内容的提问来源于stack exchange,提问作者Quantum
相关产品推荐
相关产品推荐

