手把手玩转双目三维重建:从摄像头到点云工厂

双目三维重建系统 (双目标定+立体校正+双目测距+点云显示+多种点云处理算法) Python源码:基于OpenCV的图像处理,Open3D的点云处理,基于深度学习的立体匹配和视差计算方法 代码包含: 1、支持双USB/单USB连接线的双目摄像头 2、支持单目相机标定支持双目相机标定无需 Matlab标定 3、另提供基于Matlab工具箱的标定方法 4、支持使用WLS滤波器对SGBM算法视差图进行滤波,并通过高斯滤波和相机参数得到点云三维坐标 5、提供基于深度学习的立体匹配和视差计算参考实验项目 6、支持双目测距,误差在lcm内(鼠标点击图像即可获得其深度距离),支持Open3D和PCL点云显示 7、提供部分常用的点云处理算法Python例程源码 提供所有文件的执行流程和提示

两枚摄像头组成的立体视觉系统就像人眼,拍张照就能算出物体离你多远。今天咱们用Python+OpenCV+Open3D,自己搭个能测距、能生成点云的实战系统。准备好你的摄像头和键盘,直接开干!

硬件准备:给双目摄像头接上电

市面常见的双目模组分两种:单USB接口(左右目图像合并传输)和双USB独立传输。代码里已经封装了这两种情况的视频流读取方法:

# 单USB设备示例(图像左右拼接)
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
left_img = frame[:, :frame.shape[1]//2]
right_img = frame[:, frame.shape[1]//2:]

# 双USB设备示例(需提前确认设备索引)
cap_left = cv2.VideoCapture(0)
cap_right = cv2.VideoCapture(1)

标定:给摄像头做个体检

别急着拍!摄像头出厂都有畸变,得先标定。用棋盘格在镜头前晃悠拍20张图,系统自动计算内参和畸变系数。这里有个偷懒技巧——直接用A4纸打印棋盘格,贴硬纸板上当标定板。

# 自动检测棋盘格角点
ret, corners = cv2.findChessboardCorners(gray_img, (9,6), None)
if ret:
    # 亚像素级角点优化
    cv2.cornerSubPix(gray_img, corners, (11,11), (-1,-1), criteria)
    obj_points.append(objp)
    img_points.append(corners)

# 双目标定核心代码(得到相机矩阵和相对位置)
ret, K1, D1, K2, D2, R, T, E, F = cv2.stereoCalibrate(
    obj_points, img_points_l, img_points_r, 
    K1, D1, K2, D2, (w,h), flags=cv2.CALIB_FIX_INTRINSIC)

立体校正:让画面对齐得像强迫症

标定完要做图像校正,让左右图的每一行严格水平对齐。想象给两个摄像头戴上了特制眼镜,画面瞬间整齐划一。

# 计算校正映射表
R1, R2, P1, P2, Q, _, _ = cv2.stereoRectify(
    K1, D1, K2, D2, (w,h), R, T, alpha=0)
mapx1, mapy1 = cv2.initUndistortRectifyMap(K1, D1, R1, P1, (w,h), cv2.CV_32F)
mapx2, mapy2 = cv2.initUndistortRectifyMap(K2, D2, R2, P2, (w,h), cv2.CV_32F)

# 实时校正演示
left_rect = cv2.remap(left_img, mapx1, mapy1, cv2.INTER_LINEAR)
right_rect = cv2.remap(right_img, mapx2, mapy2, cv2.INTER_LINEAR)

深度计算:SGBM算法与WLS滤波的默契配合

SGBM算法算出的视差图像被泼了墨水?上WLS滤波器!这对黄金搭档能让视差图边缘更干净:

# SGBM参数配置(重点调整这几个参数!)
window_size = 5
min_disp = 0
num_disp = 64
stereo = cv2.StereoSGBM_create(
    minDisparity=min_disp,
    numDisparities=num_disp,
    blockSize=window_size,
    P1=8*3*window_size**2,
    P2=32*3*window_size**2)

# WLS滤波
wls_filter = cv2.ximgproc.createDisparityWLSFilter(stereo)
disparity = stereo.compute(left_rect, right_rect).astype(np.float32)/16.0
filtered_disp = wls_filter.filter(disparity, left_rect)

点云生成:从二维到三维的魔法时刻

拿到视差图后,结合Q矩阵就能算出三维坐标。Open3D的三行代码可视化让点云显示变得超简单:

# 视差转点云
points = cv2.reprojectImageTo3D(filtered_disp, Q)
mask = (filtered_disp > filtered_disp.min())
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points[mask])
o3d.visualization.draw_geometries([pcd])

实战技巧:

  1. 标定失败?检查棋盘格是否完全进入画面,尝试不同倾斜角度
  2. 视差图出现断层?适当增大numDisparities参数,但别超过摄像头实际视差范围
  3. 点云稀疏?用双边滤波预处理图像,削弱噪声干扰

系统还集成了深度学习立体匹配模型(比如PSMNet),替换传统方法只需修改几行代码。想要测距功能?鼠标点选图像任意位置,控制台直接输出该点距离——实测键盘按键这类小物体误差能控制在1cm以内。

源码包里附赠了点云降采样、法线估计、ICP配准等常用算法,直接运行main.py跟着提示操作就能体验完整流程。遇到坑?记得查文档里的Q&A部分,常见问题都已整理好解决方案。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值