基于Python+OpenCV的双目立体视觉测距:原理、标定与SGBM实战
简介面向人工智能、通信工程、自动化、电子信息、物联网等专业的在校学生、教师与企业开发者这份基于Python和OpenCV的双目立体视觉项目完整实现了图像匹配、视差计算与距离测量流程可直接支撑毕业设计、课程设计、期末大作业或项目初期立项演示。项目已通过导师指导认可答辩评审分达95分源码附带详细注释新手也能看懂并快速部署。压缩包共164个文件、约96.25MB主要包含38个Python源码、10个UI界面文件、论文文档与数据库脚本并配有bmp/jpg等多种格式图像样本用于算法测试目录结构清晰。目前已有190人学习使用系统功能完善、界面美观、操作简便具备较高的实际应用价值。下载后可直接运行调试也可基于现有代码扩展二次开发是计算机相关专业学生高分完成项目的不错参考。1. 双目立体视觉图像匹配与测距为什么 Python OpenCV 比深度相机更适合做测距项目做机器人避障、做物料分拣、做自动驾驶小车只要牵扯到让机器知道目标物离自己多远很多人第一反应是买一台 D435i 深度相机。但深度相机是黑匣子论文里写不清原理答辩时讲不透误差来源换个光照环境还可能直接翻车。基于 Python OpenCV 开发的双目立体视觉图像匹配与测距每一步都有公式可查、有中间结果可调、有现成函数能复现做出来既能在实测里跑通也能在论文里讲透。这个方向适合三类人一是毕设要做视觉测距、需要完整源码和理论支撑的同学二是想在机器人小车或安防项目里加一个低成本测距模块的工程师三是被单目测距的平面标定折腾烦了、想换个稳定方案的人。整条链路就四步标定拿到相机内外参极线校正让左右图严格行对齐SGBM 匹配得到视差图三角测量把视差换算成距离。难点不在最后的除法而在中间的匹配质量。下面按我自己的落地顺序讲每个环节都给能直接跑的 Python 代码和参数说明。跟完你至少能搭出一个在 0.55 米范围内误差小于 5% 的双目测距原型也会知道哪些网上抄来的 SGBM 参数会让视差图彻底花屏。先别急着装包从原理和选型说起。2. 双目测距原理与相机选型先想清楚视差公式再决定硬件怎么摆2.1 对极几何与视差为什么两个摄像头能算出距离双目测距的原理一句话就能讲清同一个空间点在左右两张图里的像素位置不一样这个横向偏移就是视差disparity。视差越大物体离相机越近视差越小物体越远。人眼其实也是这么工作的只不过大脑把视差换算成了深度感知。超声波的方案一次只能拿到一个点的回波而双目一次能拿到整幅画面的深度信息这就是它更适合做视觉感知的原因。设基线 B 是两个相机光心的水平距离f 是焦距像素单位d 是视差像素单位深度 Z 满足 Z f × B / d。这里 f × B 对一套固定安装的相机来说是常数所以深度和视差成反比。在 OpenCV 里可以落到两种实现一种是直接用公式逐点算另一种是构造 Q 矩阵后调用 reprojectImageTo3D 把整张视差图重投影成三维点云。两者数学本质一样后者还能顺手拿到每个点的 X、Y 坐标。理解这个公式还有一个实际价值它决定了项目的误差分布。视差 d 在分母上所以近距离视差大、误差小远距离视差小、误差被放大。很多人到 10 米外测距失败不是代码错了而是物理上就不允许。这个边界我会在第 4 章量化先记在心里双目测距的黄金范围是基线长度的 2050 倍。2.2 相机选型与硬件摆放基线、焦距、分辨率的取舍对毕设和中小型项目来说最常见做法是用两个普通 USB 摄像头自己固定在铝型材或 3D 打印支架上。省钱、灵活但要求两个摄像头型号一致最好是同一批次否则色彩响应和畸变差异会让后面的匹配很痛苦。另一种是买成品的双目工业模组出厂做过硬件同步和标定省事但价格高不少而且内参往往锁死想重新标定反而麻烦。表格对比三种常见方案方案优点缺点适合场景两个 USB 摄像头自组装成本低、参数可换、原理透明无硬件同步、需自己固定和标定毕设、实验室原型成品双目模组出厂硬同步、自带标定贵、内参封闭、资料参差产品原型、户外场景单相机平移拍摄只有一个相机先天一致只能拍静态场景无法实时算法验证、标定学习选型时要搭配着看三个参数。基线 B 越大相同距离下视差越大、误差越小但两相机视野交叠区域变小太近的物体会出画B 太小近距离可以远距离的视差分辨率不够。我的经验是室内桌面场景选 60100mm机器人避障选 100200mm户外远距离至少要 300mm 以上。焦距决定视场角广角镜头看得宽但单位像素对应的视差精度低。分辨率同理2560×720 的横向分辨率明显比 1280×480 利于匹配代价是计算量上涨。还有一条硬性要求摄像头支持手动曝光的话务必关掉自动曝光和自动白平衡这是第 5 章要展开的大坑。2.3 相机标定棋盘格采图与 calibrateCamera 的完整流程标定的目的是拿三样东西左右相机各自的内参和畸变系数以及两相机之间的旋转矩阵 R 和平移向量 T。没有 T 就不知道基线关系没有内参就无法去畸变后面的极线校正和匹配全都无从谈起。标定板最常见的是打印的棋盘格贴在硬纸板上。打印时选择高对比度、表面尽量平整格边长一定要用尺子量准因为它是后续所有距离数值的单位基准。我的采图习惯是左右各拍 2025 对覆盖画面的九个区域也就是四角、四边中点、中心各来几张每张里棋盘格要有不同的倾斜角度避免所有图片都像正面证件照。采集时棋盘格要占画面四分之一以上并且左右图里都必须完整可见。下面是完整的角点提取和双目标定代码import cv2 import numpy as np import glob CHESS_BOARD_SIZE (8, 6) # 内角点数对应打印 10x7 的棋盘 SQUARE_SIZE 25.0 # 格边长单位 mm务必用尺子实测 objp np.zeros((CHESS_BOARD_SIZE[0] * CHESS_BOARD_SIZE[1], 3), np.float32) objp[:, :2] np.mgrid[0:CHESS_BOARD_SIZE[0], 0:CHESS_BOARD_SIZE[1]].T.reshape(-1, 2) objp * SQUARE_SIZE obj_points, left_points, right_points [], [], [] for f in sorted(glob.glob(calib/left_*.jpg)): img_l cv2.imread(f) img_r cv2.imread(f.replace(left_, right_)) gray_l cv2.cvtColor(img_l, cv2.COLOR_BGR2GRAY) gray_r cv2.cvtColor(img_r, cv2.COLOR_BGR2GRAY) ret_l, corners_l cv2.findChessboardCorners(gray_l, CHESS_BOARD_SIZE, None) ret_r, corners_r cv2.findChessboardCorners(gray_r, CHESS_BOARD_SIZE, None) if not (ret_l and ret_r): print(跳过, f) # 有一张图看不到完整棋盘就整对跳过 continue # 亚像素细化把角点精度从像素级提升到亚像素级这是低重投影误差的关键 criteria (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) corners_l cv2.cornerSubPix(gray_l, corners_l, (11, 11), (-1, -1), criteria) corners_r cv2.cornerSubPix(gray_r, corners_r, (11, 11), (-1, -1), criteria) obj_points.append(objp) left_points.append(corners_l) right_points.append(corners_r) # 单目标定先单独得到左右相机的内参和畸变 ret_l, mtx_l, dist_l, _, _ cv2.calibrateCamera( obj_points, left_points, gray_l.shape[::-1], None, None) ret_r, mtx_r, dist_r, _, _ cv2.calibrateCamera( obj_points, right_points, gray_r.shape[::-1], None, None) # 双目标定固定内参为单目标定结果只优化两相机之间的 R 和 T flags cv2.CALIB_FIX_INTRINSIC ret, mtx_l, dist_l, mtx_r, dist_r, R, T, E, F cv2.stereoCalibrate( obj_points, left_points, right_points, mtx_l, dist_l, mtx_r, dist_r, gray_l.shape[::-1], criteria(cv2.TERM_CRITERIA_MAX_ITER cv2.TERM_CRITERIA_EPS, 100, 1e-5), flagsflags) print(双目重投影误差(像素):, ret) print(基线向量 T:, T.ravel())两个参数值得说明。第一个是 CALIB_FIX_INTRINSIC意思是固定单目标定得到的内参只优化 R 和 T这样收敛快、结果稳定如果两个摄像头差异较大可以去掉这个 flag让双目标定顺手把内参微调一遍。第二个是 cornerSubPix 的 (11, 11) 窗口窗口越大角点越平滑但靠近棋盘边缘时容易被邻居干扰11 是折中值。标定完一定要看 stereoCalibrate 返回的重投影误差 ret。我的经验小于 0.3 像素是优秀0.30.5 可用超过 0.5 像素就建议重拍。重拍时优先补两类图画面边缘的斜放棋盘以及左右图里棋盘倾斜方向相反的组。误差大的另一个常见原因是标定板本身不平打印纸贴在弯曲的纸箱上角点坐标就是歪的后面怎么优化都救不回来。3. 立体校正与 SGBM 匹配把左右图变成一张可靠的视差图3.1 为什么选 SGBMBM、SGBM 和深度学习的取舍拿到内外参之后下一步是把左右图校正成行对齐的状态再用匹配算法逐像素找对应点。OpenCV 里的匹配器大致分三个档次选型理由很实际。BMBlock Matching是固定窗口的 SAD绝对差值和搜索速度快但只在纹理丰富的区域靠谱低纹理区域经常出现条状噪声适合实时性要求极高、精度不敏感的场景。SGBMSemi-Global Block Matching半全局块匹配在 BM 基础上引入了多个方向的代价聚合利用相邻像素的平滑性约束精度和速度最均衡是 CPU 上做实时或近实时测距的第一选择。再往上就是深度学习立体匹配网络精度高但需要 GPU 或较强算力且训练数据多来自合成数据集换成自己的摄像头后效果常常打折。工业上常见的 Halcon 块匹配和 OpenCV 的 SGBM 思路同源SGBM 免费、可控、参数透明对毕设来说足够把原理讲清楚。3.2 立体校正stereoRectify 与 remap 完整代码立体校正是整套流程里最容易被跳过的环节。不校正也能算视差但匹配要在二维平面上搜索既慢又容易错校正之后同一个点在左右图上严格落在同一行匹配变成一维搜索SGBM 才能高效工作这也是极线约束的实际含义。OpenCV 的做法是用 stereoRectify 得到校正映射表再用 remap 重映射每一帧import cv2 import numpy as np # mtx_l / dist_l / mtx_r / dist_r / R / T 来自双目标定 image_size (640, 480) # 图像的 (宽, 高)和你实际分辨率一致 # 计算左右相机的校正旋转矩阵 R1/R2 和投影矩阵 P1/P2Q 用于后续转三维坐标 R1, R2, P1, P2, Q, roi1, roi2 cv2.stereoRectify( mtx_l, dist_l, mtx_r, dist_r, image_size, R, T, flagscv2.CALIB_ZERO_DISPARITY, alpha0) # 生成重映射表CV_32FC1 保留亚像素坐标精度别用 CV_16SC2 省这点内存 map1_l, map2_l cv2.initUndistortRectifyMap( mtx_l, dist_l, R1, P1, image_size, cv2.CV_32FC1) map1_r, map2_r cv2.initUndistortRectifyMap( mtx_r, dist_r, R2, P2, image_size, cv2.CV_32FC1) # 每帧执行重映射就是极线校正之后左右图行对齐 rect_l cv2.remap(frame_l, map1_l, map2_l, cv2.INTER_LINEAR) rect_r cv2.remap(frame_r, map1_r, map2_r, cv2.INTER_LINEAR)这里三个参数要知道在干什么。alpha0 表示对校正后的图像做最大程度裁剪去掉无效区域画面最干净alpha1 会保留全部原始像素但四周出现黑边调试时容易干扰判断。Q 矩阵是 4×4 的视差到三维坐标转换矩阵第 4 章测距会用到。remap 的插值选 INTER_LINEAR 就够换成更贵的插值对匹配结果几乎没有提升。校正效果怎么验证把左右图水平拼接后人工目检找一条明显的竖直边缘比如门框、桌沿看它在左右图里是不是落在同一行。更定量的做法是画一条水平扫描线比较同一行左右图的灰度跳变位置。如果明显错位先回标定环节检查别急着调 SGBM。3.3 SGBM 参数逐个拆解numDisparities、blockSize、P1/P2 的调优逻辑SGBM 参数看起来多真正影响结果的就五个。先看一段能直接用的创建代码# OpenCV 4.x 的 SGBM 创建方式 stereo cv2.StereoSGBM_create( minDisparity0, numDisparities64, # 必须是 16 的倍数 blockSize11, # 必须是奇数建议 3~11 P18 * 3 * 11 * 11, # 相邻像素视差变化 1 个单位的惩罚 P232 * 3 * 11 * 11, # 相邻像素视差变化超过 1 的惩罚 disp12MaxDiff1, # 左右一致性检查阈值 uniquenessRatio10, # 匹配唯一性比例 speckleWindowSize100, # 滤除小斑点噪声 speckleRange2, modecv2.STEREO_SGBM_MODE_SGBM ) disparity stereo.compute(rect_l, rect_r).astype(np.float32) / 16.0注意最后一行SGBM 输出的是定点数真实视差值必须除以 16.0。这一步最容易被忽略直接拿原始值算距离会系统性偏大 16 倍是新手翻车排行榜第一名。逐项拆解参数。numDisparities 决定视差搜索范围范围越大能测越近的物体一般从 64 起步如果近处目标区域出现匹配不上的黑色空洞就加大到 96、128但计算量同步上涨远处的无效匹配也会变多。blockSize 是匹配窗口边长窗口越大低纹理区域的空洞越少但边缘越糊、细节越差建议在 311 之间试不要超过 15。P1 和 P2 是平滑惩罚项P2 一般取 P1 的 4 倍它们越大视差图越平滑同时会把细小物体的边缘抹掉。我一般从 P183blockSize^2、P2323blockSize^2 起步噪声明显就两倍两倍往上加。uniquenessRatio 是匹配唯一性门槛太低会产生大量误匹配太高会让低纹理区域变成黑洞1015 是常见区间。调参时建议固定一个调试界面左边显示原图右边用热力图显示视差图。每次只改一个参数跑同一段测试视频对比别凭感觉一次改三个。顺序上先调 numDisparities 到目标距离内没有大块黑洞再调 blockSize 平衡空洞和边缘最后动 P1/P2 处理噪声。4. 从视差图到距离三角测量代码、后处理细节与误差边界4.1 视差图后处理WLS 滤波与空洞填充SGBM 直接输出的视差图通常有两方面毛病一是低纹理区域出现黑斑也就是视差为 0 的无效像素二是物体边缘有椒盐式噪声。对测距来说单帧的坑点位置不稳定直接取均值也会被噪声带偏所以要先做后处理。OpenCV contrib 模块的 WLS 滤波是常见做法它用左图做引导图把彩色图像的边缘信息传递到视差图能在保留物体边缘的同时抹平大片低频噪声# 注意要装 opencv-contrib-python不能和 opencv-python 并存 left_matcher cv2.StereoSGBM_create( numDisparities64, blockSize11, P18 * 3 * 11 * 11, P232 * 3 * 11 * 11) # WLS 需要左右两张视差图先创建与左匹配器参数完全一致的右匹配器 right_matcher cv2.ximgproc.createRightMatcher(left_matcher) wls cv2.ximgproc.createDisparityWLSFilter(left_matcher) wls.setLambda(8000) # 平滑强度越大越平滑 wls.setSigmaColor(1.5) # 引导图颜色权重 disp_left left_matcher.compute(rect_l, rect_r) disp_right right_matcher.compute(rect_r, rect_l) disp_wls wls.filter(disp_left, rect_l, disp_right) # 空洞填充对仍为 0 的无效像素做形态学修补 kernel cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) disp_filled cv2.morphologyEx(disp_wls, cv2.MORPH_CLOSE, kernel)setLambda 是平滑力度8000 是常见起点纹理丰富的场景降到 3000 保留更多细节墙面占比大的场景要加到 15000。有一点必须说清楚MORPH_CLOSE 对空洞的填充只是视觉补偿填补出来的值不代表真实匹配。如果你的测距目标恰好落在空洞区域正确的做法是判定为当前不可测而不是拿修补值硬算一个距离出来这个原则在写论文结论时也要讲反而加分。4.2 三角测量鼠标点击取视差算出距离后处理完就能测距了。常见做法有两种用 reprojectImageTo3D 把整张视差图重投影成三维点云或者用鼠标事件取单点视差直接套公式。前者适合批量测距后者适合交互调试两个都写import cv2 import numpy as np # 方法一Q 矩阵重投影得到每个像素的三维坐标X, Y, Z points_3d cv2.reprojectImageTo3D(disp_filled, Q, handleMissingValuesTrue) Z_map points_3d[:, :, 2] # 单位由标定板格边长决定毫米就全程毫米 # 方法二鼠标点击取单点距离用于交互验证 def on_mouse(event, x, y, flags, param): if event cv2.EVENT_LBUTTONDOWN: d disp_filled[y, x] / 16.0 # 转成真实视差单位像素 if d 0: print(该点无有效视差) return # BASELINE 用实际量出的光心水平距离单位 mm # FOCAL_PX 取左相机内参 mtx_l[0][0]单位像素 Z BASELINE * FOCAL_PX / d print(f({x}, {y}) 视差{d:.2f}px 距离{Z:.0f}mm) cv2.setMouseCallback(disp, on_mouse)两个方法的坑位不同。reprojectImageTo3D 的坐标单位完全取决于标定时的 SQUARE_SIZE如果用的是毫米输出就是毫米如果偷懒把格边长写成 1.0输出就变成格边长的倍数常见事故是把单位写错导致所有距离系统性偏大若干倍。方法二公式里的 BASELINE我建议用尺子实际量两镜头光心之间的水平距离而不是取标定出的 T 分量。标定 T 的单位和标定板一致但光心位置本身有装配误差物理量测往往更接近真实基线。4.3 测距误差边界为什么 5 米外精度急剧下降这一节是很多人不愿意面对的现实。以焦距 f800px、基线 B100mm 的典型配置为例1 米处视差 d 800×100/1000 80px3 米处约 26.7px5 米处只剩 16px。SGBM 的视差分辨率理论上是 1/16 像素但实际受噪声和纹理影响很难稳定优于 1 像素。对公式 Z fB/d 求导可得 δZ ≈ Z²/(fB) × δd按 δd1px 估算目标距离理论视差1px 误差对应距离误差相对误差0.5m160px约 3mm0.6%1m80px约 12.5mm1.3%2m40px约 50mm2.5%3m26.7px约 112mm3.7%5m16px约 312mm6.2%这张表本身就够写论文里的一小节了。它说明两件事一是在有效范围内调好参数双目测距确实能比超声波、单目测距稳得多二是超出 35 米后误差随距离平方增长任何参数调优都救不了物理极限。想测更远只能加长基线、提高分辨率或者换主动光方案这是方案选型阶段就要想清楚的事。5. 双目测距踩坑排查手册标定翻车、纹理稀疏、环境报错的 5 个真实案例5.1 视差图整张扭曲重投影误差超过 0.5 像素现象校正后的左右图行不对齐视差图出现系统性梯度近处物体边缘有双层影子远处距离整体偏大偏小。原因标定图片数量不够、拍摄角度太单一或者棋盘格贴在不平的表面上。最常见的翻车是只拍了十张出头而且全是从正面拍的棋盘格在画面里占的面积还不到四分之一角点提取本身就带误差。解决重新采图左右各 20 对起步覆盖画面的四角、四边、中心九个区域每张棋盘格要有明显倾斜。重拍前先检查标定板是否平整打印纸贴在硬纸板上最稳妥。每次标定后打印 stereoCalibrate 返回的 ret低于 0.5 像素才继续往下走否则后面所有环节都是在错误地基上盖楼。5.2 左右图亮度不一致匹配率骤降视差图全是雪花现象同一物体左右图一明一暗视差图出现大片错误匹配像电视雪花而且随时间闪烁。原因USB 摄像头的自动曝光和自动白平衡是各自独立工作的两个镜头对场景的反应不同导致同一时刻左右图的亮度和色温不一致。SGBM 的代价计算依赖灰度一致性亮度差异一上去匹配结果立刻崩。解决优先关闭两个摄像头的自动曝光、自动白平衡和自动增益改为手动固定参数。可以在 OpenCV 里用 CAP_PROP_AUTO_EXPOSURE、CAP_PROP_EXPOSURE 设置也可以直接通过摄像头自带的 SDK 或工厂模式软件锁死。如果摄像头不支持手动退而求其次是在采集后用 CLAHE 做直方图均衡让左右图灰度分布尽量接近但这是治标不治本。5.3 白墙、天空等低纹理区域出现黑洞现象视差图里目标区域是纯黑的无效像素或者视差值在 0 附近来回跳测出来的距离忽远忽近。原因SGBM 本质上是找左右图的相似纹理块墙面、天空这类区域在局部窗口里几乎没有任何梯度信息匹配代价函数找不到唯一最小值自然给不出可靠视差。解决三个层面处理。场景层面给被测目标增加纹理比如贴二维码、贴标志纸这是效果最直接的。算法层面对纹理极差的区域不强行给视差返回不可测状态让上层逻辑自己处理。工程层面如果测距范围固定就把 SGBM 的计算限制在包含目标的 ROI 内减少整体误匹配对目标区域的干扰。5.4 import cv2 报错与 cv2.error 版本冲突现象pip 安装 opencv 后import cv2 提示 ModuleNotFoundError: No module named cv2或者运行到某个函数时抛出 cv2.error报错信息里出现类似 OpenCV(4.4.0) 的版本字样还有人会遇到opencv 安装成功却找不到 cv2的问题。原因绝大多数是环境混用最常见的是同时安装了 opencv-python 和 opencv-contrib-python两个包互相覆盖文件或者 pip 装到了系统 Python而代码跑在 conda 虚拟环境里。cv2.error 这类运行时错误大多是函数在新旧版本里的 API 签名变了网上抄的代码版本和你安装的版本对不上。解决先统一环境把两个包都卸掉再装一个pip uninstall opencv-python opencv-contrib-python -y pip install opencv-contrib-python -i https://pypi.tuna.tsinghua.edu.cn/simple然后确认运行环境在跑代码的那个解释器里执行 python -c import cv2; print(cv2.version) 验证。项目从头到尾固定在一个虚拟环境里不要今天用系统 Python 明天用 conda。版本选择上推荐装当前 stable 版本而不是追新网上能找到的 SGBM、WLS 示例代码大多基于 OpenCV 3.x 或 4.x先让示例跑通再换新版本。5.5 实时性不够树莓派或笔记本上跑不到目标帧率现象SGBM 在一帧上耗时几百毫秒画面明显卡顿树莓派这种低算力平台上尤其明显。原因numDisparities 和图像分辨率双重拉高了计算量。匹配代价的计算量是 分辨率 × 视差搜索范围两个参数同时放大耗时成倍增长。解决按顺序做三件事。先把图像分辨率降到 640×360测距精度损失有限但速度可能翻倍再把 numDisparities 从 128 降到 64如果目标距离本来就不近这一步影响很小最后把 mode 换成 cv2.STEREO_SGBM_MODE_SGBM_3WAY这是 OpenCV 提供的三路路径快速模式精度略降但速度明显提升。如果还不够就把 SGBM 限定在 ROI 区域内计算这是最直接有效的手段。6. 把测距结果写到论文里精度验证方法与三个稳定测距技巧6.1 精度验证方法实测验证是让这个项目从能跑变成可信的关键一步也是论文里最好用的素材。准备一把卷尺或激光测距仪在固定场景里从 0.5 米到 4 米每隔 0.5 米放置一个带纹理的目标板每个距离采集 30 帧取视差的中值作为该点的测量结果再统计 30 帧里的最大值、最小值和标准差。最后把测量距离和真实距离画成误差曲线计算平均绝对误差和均方根误差。这张图和这组数据比任何原理推导都更能说服答辩评委。6.2 三个稳定测距技巧第一个技巧是多帧中值。静止目标做连续 510 帧测距取中值而不是均值能干净地滤掉 SGBM 的单帧跳变。第二个技巧是 ROI 约束。先框定目标所在区域只对该区域计算视差和距离既提速又避免区域外噪声干扰。第三个技巧是亚像素抛物线插值对某个像素及其左右相邻视差做二次插值能把视差精度从整像素提到亚像素级别公式是 d_sub d - 0.5(d - d-)/(d - 2d d-)对近距离精度提升明显。我最开始做双目测距时把网上的 SGBM 参数原样抄进代码结果在一台普通笔记本上视差图直接花屏折腾了一周才发现问题不在匹配器而在标定。从那以后我养成了一个习惯每换一组摄像头或支架先花半天重新标定再看重投影误差最后才调 SGBM。这套顺序看起来慢实际上是最快的路径。希望这个方向能帮你少走几次弯路也希望你的论文实测数据一次就好看。本文还有配套的精品资源点击获取

相关新闻

RPN区域建议网络原理与实战:从Anchor设计到正负样本划分

RPN区域建议网络原理与实战:从Anchor设计到正负样本划分

1. RPN到底在做什么:从一张图到一堆候选框Region Proposal Network,简称RPN,这玩意儿最早是跟着Faster R-CNN一起出来的。很多人第一次看论文的时候会被“区域建议”这四个字唬住,觉得是个多高深的模块。其实你把它的职责拆开看&a…

2026/10/12 21:53:58 阅读更多 →
前端异常归因自动化:从流式日志回放中精准捕获大模型会话异常

前端异常归因自动化:从流式日志回放中精准捕获大模型会话异常

在现代化大型单页面应用(SPA)的可观测性保障中,以 Sentry 等为代表的前端错误监控平台几乎是每个团队的标准配置。每当线上发生未捕获的 JavaScript 异常时,报警机器人便会向值班群中推送一条报警卡片,附带着清晰的报错…

2026/10/12 21:52:56 阅读更多 →
R语言机器学习实战:从数据预处理到调参预测的完整链路

R语言机器学习实战:从数据预处理到调参预测的完整链路

简介:面向数据科学初学者与有一定统计基础、希望上手监督学习建模的分析人员,这份资源以R语言实现多种机器学习算法,覆盖回归预测、模型对比与数据预处理等常见场景。压缩包共20个文件,以R脚本和CSV数据集为主体:8个R文…

2026/10/12 21:52:56 阅读更多 →

最新新闻

iOS TableView 异步加载图片:从原理到实践,告别列表卡顿

iOS TableView 异步加载图片:从原理到实践,告别列表卡顿

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 1:03:48 阅读更多 →
对称边界如何让模态分析生成‘春节快乐’字形

对称边界如何让模态分析生成‘春节快乐’字形

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 1:03:48 阅读更多 →
纯软件STM32入门:无需开发板,仿真环境跑通核心外设

纯软件STM32入门:无需开发板,仿真环境跑通核心外设

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 1:03:48 阅读更多 →
UDS车载诊断实战指南:服务格式、时序与否定响应码解析

UDS车载诊断实战指南:服务格式、时序与否定响应码解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 1:03:48 阅读更多 →
HTML表单交互与DOM操作实战:从零构建可调试的网络编程训练

HTML表单交互与DOM操作实战:从零构建可调试的网络编程训练

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 1:03:48 阅读更多 →
LightGBM因子筛选与BiLSTM时序建模:量化投资策略实战

LightGBM因子筛选与BiLSTM时序建模:量化投资策略实战

简介:这份资源面向计算机相关专业学生、高校教师及量化投资初学者,提供一套将LightGBM与BiLSTM结合进行因子组合选取并构建量化投资策略的完整实践项目,可直接用于毕业设计、课程设计、实训实验或公司项目二次开发。压缩包共1408个文件&#…

2026/10/13 1:02:48 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →