Opencv示例程序:关于双目视觉,标定,立体矫正,立体匹配(视差算法),点云,双目三维重建的原理以及代码 已经打包成软件 直接运行即可 可实现标定匹配点云可视化测距目标检测yolo 我看详细的视频效果 每一步都有教程可以直接用

双目视觉这玩意儿听起来高大上,实际拆开看也就是几个关键步骤的排列组合。这次直接把整套流程打包成了开箱即用的软件,标定、矫正、匹配、点云一气呵成,顺手还集成了YOLO目标检测和测距功能。咱们直接上干货,边看代码边唠原理。

先看标定环节的硬核代码片段:

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((6*9,3), np.float32)
objp[:,:2] = np.mgrid[0:9,0:6].T.reshape(-1,2)

ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
    objpoints, imgpoints, gray.shape[::-1], None, None)

这里用的经典棋盘格标定法,objp生成的是三维空间中的虚拟坐标点。calibrateCamera返回的内参矩阵mtx和畸变系数dist是后续矫正的关键。注意棋盘格行列数(6x9)得根据实际标定板调整,搞反了直接标定扑街。

矫正阶段的核心操作就这两行:

left_mapx, left_mapy = cv2.initUndistortRectifyMap(...)
right_mapx, right_mapy = cv2.initUndistortRectifyMap(...)

生成的映射表直接存成XML,运行时直接读取应用。实测中发现用remap函数处理视频流时,GPU加速能提升5倍帧率,笔记本摄像头都能实时跑。

立体匹配这块试过BM和SGBM算法,最终选了SGBM:

stereo = cv2.StereoSGBM_create(
    minDisparity=0,
    numDisparities=64,
    blockSize=5,
    P1=8*3*5**2,
    P2=32*3*5**2)

参数P1、P2不是玄学,经验公式是P1=8通道数窗口尺寸平方。调试时盯着视差图的边缘响应,锯齿太多就调大numDisparities,但超过128后显存开始报警。

Opencv示例程序:关于双目视觉,标定,立体矫正,立体匹配(视差算法),点云,双目三维重建的原理以及代码 已经打包成软件 直接运行即可 可实现标定匹配点云可视化测距目标检测yolo 我看详细的视频效果 每一步都有教程可以直接用

点云生成看似简单:

points = cv2.reprojectImageTo3D(disparity, Q)
colors = cv2.cvtColor(left_frame, cv2.COLOR_BGR2RGB)
mask = disparity > disparity.min()

但实测中mask处理不当会导致点云爆炸,这里用视差阈值过滤无效点比直接判断Z值更靠谱。点云保存为PLY时,加上RGB信息能让mesh看起来更带感。

测距功能在代码里其实就是空间坐标换算:

def get_distance(point):
    return np.sqrt(point[0]**2 + point[1]**2 + point[2]**2)

但结合YOLO检测框的中心点坐标后,就能实现特定目标的距离测量。注意这里的世界坐标要经过手眼标定转换,否则测出来的是相机坐标系下的相对值。

整套代码用PyQt做了可视化界面,关键数据流用队列实现线程隔离。运行时CPU占用最狠的还是立体匹配部分,把SGBM参数里的mode设为cv2.STEREOSGBMMODE_HH能激活全尺寸动态规划,不过显卡没个6G显存建议别轻易尝试。

遇到最多的问题还是标定质量,建议至少用20组不同角度的棋盘格图片。有个邪门技巧:手持标定板快速晃动拍摄的视频抽帧,比规规矩矩摆拍的效果更好——因为实际应用时摄像头就是动态的,这算不算某种程度的数据增强?

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐