ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OpenCV双目视觉测量物体尺寸:从标定到立体匹配实战教程

OpenCV双目视觉测量物体尺寸:从标定到立体匹配实战教程 简介这是一份基于Python和OpenCV实现的双目视觉测量物体尺寸的完整项目适用于本科毕业设计、期末大作业或课程设计环节也适合具备基础编程知识、希望学习计算机视觉实践的读者。项目内包含可直接运行的Python源代码、开发说明文档以及多组左右视角拍摄的样本图片代码行间有详细注释覆盖了从图像读取、特征匹配、视差计算到最终尺寸输出的完整流程便于逐段理解算法原理。压缩包共有23个文件主要类型为图片、Python脚本和Markdown文档其中图片包括左右视角原始样本和测量结果图Python脚本是核心功能实现文档说明了部署方式与开发思路整个包大小仅2.27MB轻量且易于调试。目前已有71人学习下载项目经过严格调试曾获导师认可的高分评价可直接作为期末大作业或毕业设计提交。下载后按照文档配置环境即可顺利运行界面直观、操作简单能够输出测量结果图像是一份实用且完整的项目参考。1. 双目视觉测量被摄物体尺寸两个USB摄像头与OpenCV就能交差做期末大作业选“pythonopencv双目视觉测量被摄物体尺寸”多数人是冲着“听着高级、不用买昂贵设备”去的。一台电脑、两个USB摄像头、一张打印棋盘格就能把物体的长宽高从图像里算出来这确实是一条成本最低的入门路线。但我要先把丑话说在前面这个项目真正的难点不在“有没有OpenCV代码”而在标定精度和立体匹配这两步它们决定你最后测出来的数是毫米级还是厘米级。本文会从原理讲到每一段可复现代码再把我踩过的坑一条条摊开适合期末赶工也适合真想把它做成毕设里一个正经模块的人。2. 先把原理立住三角测距公式与系统数据流2.1 视差与深度Z f·T/d 的物理含义双目视觉测量尺寸的第一步不是识别而是测距离。人类两只眼睛能判断远近靠的是左右眼看到的同一物体存在位置差异这个差异在计算机视觉里叫视差disparity。把两个摄像头水平放置同时拍同一个物体物体在左图里的像素坐标和右图里的像素坐标会有一个水平偏移 d偏移越大物体离相机越近。这个关系用公式写出来就是Z f × T / d其中 Z 是物体到相机平面的深度距离f 是焦距以像素为单位T 是两个相机光心之间的距离叫基线。d 是左右图像上对应匹配点的横坐标差单位是像素。这个公式是整篇代码的地基后面所有“毫米尺寸”都是先从这个 Z 算出来的。有一点要特别提醒这里所有量纲必须统一。f 如果是像素单位T 如果是毫米单位那么 Z 的单位就是毫米。很多同学在这里把 f 填成物理焦距 6mm、T 填成 120mm算出来深度全是错的。OpenCV 标定得到的焦距矩阵 K 里fx 已经是“毫米换算成像素之后的焦距”所以直接用 K[0][0] 作为 f 就行。2.2 为什么单目测不了绝对尺寸双目可以单目相机本质上是一个投影过程把三维世界压缩到二维平面。图像上一个像素对应物体上多大面积完全取决于物体离相机多远。远处一辆卡车和一个近处的玩具车在画面里可能占同样的像素高度单目拿到这张图如果没有额外的距离信息就不可能知道它到底是卡车还是玩具。这就是所谓“单目缺尺度”。有些人会用已知尺寸的参照物去推算比如在物体旁边放一张 A4 纸但换一个距离就要重新算不算真正的测量方案。双目不一样。左右两幅图之间的视差携带了绝对深度信息只要标定准确任何一个像素都能还原出它在相机坐标系下的三维坐标。这就是“两个摄像头能测尺寸”的核心原因。所以这个项目本质上是“先求深度再按几何比例换算尺寸”而不是“识别出物体然后用模板匹配”。理解这一点你再看代码就不会被 OpenCV 里一堆函数弄晕。2.3 系统总体架构与OpenCV模块分工整个系统是一条流水线我一般把它拆成四段图像采集、双目标定、立体匹配、尺寸换算。图像采集就是两个摄像头同步拍左右图OpenCV 里用 VideoCapture(0) 和 VideoCapture(1) 打开注意两个摄像头要尽量水平对齐固定在一个刚性支架上。双目标定用 calibrateCamera 和 stereoCalibrate得到左右相机的内参、畸变系数、旋转矩阵和平移向量。立体匹配用 StereoSGBM_create 生成视差图再用 reprojectImageTo3D 转成三维坐标。尺寸换算则是在三维坐标上做像素距离到毫米距离的映射。OpenCV 在整个流程里承担的职责非常清晰标定模块负责参数求解校正模块负责把左右图拉平匹配模块负责找对应点最终 reprojectImageTo3D 输出一个三维点云。你不需要自己造轮子但要能说出每个函数输入输出是什么期末答辩时老师就爱问这些。工程上还可以把每一步封装成函数标定结果存成 .npz 或 .yaml下一次运行直接加载不用每次重新标定。3. 双目标定与立体匹配精度上限在这里决定3.1 棋盘格标定板制作与图像采集标定板不用买贵的A4 纸打印一张 10×7 的棋盘格格子边长 25mm 或 30mm贴到硬纸板上就行。关键是棋盘格一定要平纸张翘角会让角点检测到错误位置标定结果直接废掉。OpenCV 的 findChessboardCorners 找的是内角点10×7 的格子对应内角点是 9×6代码里传 (9, 6)千万别把格子和角点搞混这个问题我见过太多人卡住。采集图像时左右相机要同时拍用同一块棋盘格在不同距离、不同倾斜角度、不同位置拍 20 到 30 对。这里有个原则棋盘格要出现在画面的各个角落尤其是边缘和四角距离要从近到远拉开倾斜角度要有但不能大到角点检测不出来。网格打印纸反光时可以用哑光纸或者调整光源方向。每拍一对就检查一下能不能检测出角点当场重拍不要等全部拍完再处理。3.2 单目与双目标定代码先把每个摄像头的内参单独标出来再进入双目标定。单独标定可以用 cv2.calibrateCamera也可以直接用 findChessboardCorners 拿到角点后一次性做双目标定。OpenCV 的 stereoCalibrate 要求输入左右图像各自的内参初值所以稳妥做法是先各自标定再联合优化。import cv2 import numpy as np import glob # 内角点数对应 10x7 的棋盘格 pattern_size (9, 6) criteria (cv2.TERM_CRITERIA_EPS cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # 世界坐标系中的棋盘格角点坐标 objp np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32) objp[:, :2] np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2) objpoints [] # 三维参考点 imgpoints_l [] # 左图角点 imgpoints_r [] # 右图角点 left_imgs sorted(glob.glob(left/*.jpg)) right_imgs sorted(glob.glob(right/*.jpg)) for lpath, rpath in zip(left_imgs, right_imgs): img_l cv2.imread(lpath) img_r cv2.imread(rpath) 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, pattern_size, None) ret_r, corners_r cv2.findChessboardCorners(gray_r, pattern_size, None) if ret_l and ret_r: objpoints.append(objp) 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) imgpoints_l.append(corners_l) imgpoints_r.append(corners_r) # 单目标定 ret_l, K1, D1, _1, _2 cv2.calibrateCamera(objpoints, imgpoints_l, gray_l.shape[::-1], None, None) ret_r, K2, D2, _3, _4 cv2.calibrateCamera(objpoints, imgpoints_r, gray_r.shape[::-1], None, None) # 双目标定 flags cv2.CALIB_FIX_INTRINSIC ret, K1, D1, K2, D2, R, T, E, F cv2.stereoCalibrate( objpoints, imgpoints_l, imgpoints_r, K1, D1, K2, D2, gray_l.shape[::-1], flagsflags ) print(重投影误差:, ret) np.savez(stereo_params.npz, K1K1, D1D1, K2K2, D2D2, RR, TT)核心逻辑很简单findChessboardCorners 在左右图里各自找角点cornerSubPix 做亚像素精化让角点坐标更准。然后 calibrateCamera 先用单目标定求出初始内参最后 stereoCalibrate 以这些内参为初值联合求解两相机间的旋转矩阵 R 和平移向量 T。flags 里用 CALIB_FIX_INTRINSIC 表示只优化外参这样能减少优化变量也更稳定。参数说明cornerSubPix 的搜索窗口 (11, 11) 一般够用如果图像分辨率高可以放大到 (21, 21)。objp 里的坐标单位是毫米吗这里其实是无量纲的棋盘格索引因为标定只要求“格子间距一致”不必知道真实毫米值。但如果你最后要从深度图算尺寸建议把 objp 乘以格子实际边长比如 25mm这样 R、T 就有了毫米量纲后面 Q 矩阵输出的深度也直接是毫米。我建议乘上实际边长省得换算。3.3 极线校正与remap双目标定出来的 R 和 T 描述了两个相机之间的几何关系但如果直接对原始左右图做匹配搜索对应点需要在二维平面上找计算量大而且容易出错。极线校正的作用是让左右图像“拉平”使得同一个三维点在两幅图像中落在同一水平线上这样匹配时只需要沿水平方向搜素这就是射极几何里的 epipolar constraint 的工程实现。img_size gray_l.shape[::-1] # alpha 取 0 表示只保留有效像素区域取 -1 保留全部视野 R1, R2, P1, P2, Q, valid1, valid2 cv2.stereoRectify( K1, D1, K2, D2, img_size, R, T, alpha0 ) # 生成重映射表 map1x, map1y cv2.initUndistortRectifyMap(K1, D1, R1, P1, img_size, cv2.CV_32FC1) map2x, map2y cv2.initUndistortRectifyMap(K2, D2, R2, P2, img_size, cv2.CV_32FC1) rect_l cv2.remap(img_l, map1x, map1y, cv2.INTER_LINEAR) rect_r cv2.remap(img_r, map2x, map2y, cv2.INTER_LINEAR) # 验证校正是否成功把左右图左右拼接看角点是否在同一水平线 canvas np.hstack([rect_l, rect_r]) for row in range(0, canvas.shape[0], 20): cv2.line(canvas, (0, row), (canvas.shape[1], row), (0, 255, 0), 1)stereoRectify 的返回值里Q 矩阵是“视差到三维坐标”的投影矩阵后续 reprojectImageTo3D 会用到。P1、P2 是校正后的投影矩阵其中 P1[0][0] 就是校正后的焦距 fx第二章公式里的 f 可以直接从这里取。initUndistortRectifyMap 生成一张查找表remap 按表重采样这两个函数是 OpenCV 对“校正去畸变”的合并实现比先 undistort 再 rectiry 更快。验证校正质量有个土办法把左右校正图并排显示画横向绿线观察棋盘格角点是否落在同一直线上。如果偏差超过两三个像素SGBM 匹配出来的视差图会大量出现错误。这时候检查标定板图像数量是否够多、棋盘格是否平整重新标定一次而不是去调后面的匹配参数。3.4 SGBM生成视差图与深度图极线校正完成后就可以用 SGBMSemi-Global Block Matching求视差。SGBM 是 OpenCV 里综合效果最好的匹配算法比 BM 精度高比 GC 快适合实时测量场景。它的核心思想是先按块匹配代价再沿着多个方向传播能量最小化一个带平滑约束的能量函数。结果是一张视差图每个像素的值表示该点在右图中的水平偏移。sgbm cv2.StereoSGBM_create( minDisparity0, numDisparities128, # 必须能被16整除 blockSize11, # 必须是奇数 P18 * 11 * 11, P232 * 11 * 11, disp12MaxDiff1, uniquenessRatio5, speckleWindowSize100, speckleRange2, preFilterCap32, modecv2.STEREO_SGBM_MODE_SGBM ) disparity sgbm.compute(rect_l, rect_r).astype(np.float32) / 16.0 # 用 Q 矩阵把视差图转成三维点云 points3d cv2.reprojectImageTo3D(disparity, Q, handleMissingValuesTrue) depth points3d[:, :, 2] # 深度图单位毫米SGBM 的每个参数都在影响结果。numDisparities 是最大视差值它决定能测到的最近距离太小的话近处物体匹配不上会出现大片黑色空洞。怎么估算假如摄像头基线 T100mm焦距 fx600最近物体距离 Z200mm最大视差就是 fx×T/Z300那 numDisparities 至少给 320。实际场景如果物体离相机 300mm 以上128 基本够用。blockSize 是匹配块大小越大对纹理细节的容忍越高但边缘越模糊11 或 15 是常用值。P1、P2 是平滑惩罚项控制视差图在弱纹理区域的连续性经验公式就是 P18×blockSizeP232×blockSize噪声大时把 P2 再调大。disparity 除以 16.0 这一步很多人会漏。OpenCV 内部为了精度把视差值放大了 16 倍存成整数直接拿原始整数当视差会得到偏小 16 倍的深度这是网上代码最常见的翻车点。reprojectImageTo3D 用 Q 矩阵把视差和像素坐标映射成三维坐标输出的是 XYZ 三通道深度图取第 2 通道就是毫米单位的距离。如果输出里出现大量 nan 或 0说明视差缺失需要回到参数层面去调。4. 尺寸测量算法从深度图到毫米读数4.1 用背景分离与轮廓提取定位被测物体深度图到手之后下一步是“知道物体在哪”。测量尺寸的前提是框出物体的像素区域我用得最多的方法是把被测物体放在一个颜色与它差异明显的背景上比如深色物体配浅色底板然后在左图里做颜色阈值分割。更省事的方法是直接把物体放到一张白纸上用固定光照拍HSV 阈值分割后提取最大连通域。hsv cv2.cvtColor(rect_l, cv2.COLOR_BGR2HSV) # 以深色物体为例提取暗色区域 mask cv2.inRange(hsv, (0, 0, 0), (180, 255, 100)) mask cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((5, 5), np.uint8)) contours, _ cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contour max(contours, keycv2.contourArea) # 最小外接矩形返回中心、宽高、旋转角 rect cv2.minAreaRect(contour) box cv2.boxPoints(rect) box np.int0(box) # 以矩形中心为ROI中心从深度图取对应区域的深度 cx, cy int(rect[0][0]), int(rect[0][1]) w_px, h_px rect[1][0], rect[1][1]findContours 拿到物体轮廓后minAreaRect 返回的是带旋转角的最小外接矩形这对倾斜摆放的物体特别有用不用先把图像转正。RECT 的宽高就是物体在像素坐标系下的尺寸单位是像素。需要注意轮廓里可能混入背景噪点先 morphologyEx 做开运算去掉小斑点再按面积取最大轮廓这个顺序不要颠倒。ROI 不一定非要用矩形。如果物体形状不规则可以用 cv2.fillPoly 把轮廓填充成掩膜然后只对掩膜内的像素取深度。测量“被摄物体尺寸”在作业场景下一般是规则物体矩形框足够。但你要明白像素宽度 w_px 是从左图轮廓算的它只能告诉我们在图像里物体占多少像素还不能直接说是多少毫米需要下一步结合深度来换算。4.2 像素尺寸换算毫米公式与代码像素到毫米的换算依赖针孔相机模型。一个深度为 Z 的平面上物体实际宽度 W 与像素宽度 p 满足W p × Z / f。这里的 f 是焦距像素值物体离相机越远同样的像素宽度对应的物理尺寸越大。所以深度 Z 的准确性直接乘以到结果里Z 偏了 5%测量结果也偏 5%。这就是为什么说标定和匹配决定了精度的上限。# 取 ROI 内有效深度的中位数避免个别错误点影响 x1, y1 max(0, cx - int(w_px / 2)), max(0, cy - int(h_px / 2)) x2, y2 x1 int(w_px), y1 int(h_px) roi_depth depth[y1:y2, x1:x2] valid roi_depth[roi_depth 0] if len(valid) 100: raise ValueError(有效深度点太少检查标定和匹配参数) z np.median(valid) # 校正后焦距直接取 P1 矩阵 fx P1[0, 0] fy P1[1, 1] # 像素尺寸换算成毫米 width_mm w_px * z / fx height_mm h_px * z / fy print(f物体宽度: {width_mm:.2f} mm, 高度: {height_mm:.2f} mm)为什么用中位数而不用均值深度图里哪怕 SGBM 调得再好物体边缘和弱纹理区域也难免有误匹配的离群点一个离谱的深度值会把均值拉偏但中位数对离群点不敏感。深度图上的物体表面如果不是完美平面z 会有波动用中位数能代表“大多数像素”的距离。如果物体表面有反光深度值会一片一片地错这时候先处理光照再测别指望算法默认抗反光。fy 和 fx 在理论上是一样的但实际标定出来会有细小差别所以宽和高分别用各自方向的焦距。如果被测物体是立体而非平面比如一个盒子那么前后两个面的深度不一样分别对两个面取深度再换算不能在同一个 Z 下算盒子的长和宽。这也是“测量尺寸”和“测平面物体尺寸”的关键区别期末答辩时能说出来会加分。4.3 亚像素边缘与多次测量把误差压到最小minAreaRect 给出的 w_px 和 h_px 精度受轮廓提取影响很大。如果边缘因为光影模糊轮廓会往里缩或往外扩几个像素直接导致毫米数偏大或偏小。一个最简单有效的技巧是在提取轮廓前先用 Canny 边缘检测拿到亚像素级的边缘位置或者对轮廓做最小二乘直线拟合。但做期末项目没必要上复杂算法我一般用两个低成本手段一是增大拍摄分辨率并保证物体尽量占满画面让像素误差占总像素数的比例变小二是同一物体多角度、多次拍摄求平均。measurements [] for _ in range(10): # 重新采集一帧, 重新做轮廓提取和深度换算 width_mm, height_mm measure_from_frame(...) measurements.append((width_mm, height_mm)) arr np.array(measurements) mean_w np.mean(arr[:, 0]) std_w np.std(arr[:, 0])多次测量的均值能抵消一部分随机误差标准差能告诉老师你的系统稳定在什么水平。比如测一个 100mm 宽的物体10 次结果均值 100.8mm、标准差 0.5mm这比一次测出 100.1mm 更有说服力。测量时还有一个细节每次拍摄不要只在原地按快门而是稍微前后移动几厘米再测。这样能暴露深度计算在不同距离下的稳定性如果结果跳动超过 2mm说明标定或匹配参数有问题需要回头调而不是靠多次测量掩盖。5. 避坑记录标定翻车、匹配黑匣子与光照毛刺5.1 现象import cv2 报 ModuleNotFoundError或者 cv2 装上了但调用时报 DLL 加载错误原因最常见的不是代码问题而是 Python 环境混了。标题里一定有人会写“opencv 已安装但找不到 cv2”我遇到过有人用pip install opencv-python装在了系统 Python但实际运行脚本用的是 Anaconda 里另一个解释器。DLL 报错通常发生在 Windows 上OpenCV 依赖的 VC 运行库缺失或者安装的是非官方轮子和 Python 位数不匹配。解决先用python -m pip install opencv-python numpy确保装到当前解释器再用python -c import cv2; print(cv2.__version__)验证。如果还报 DLL 错误去微软官网装对应版本的 Visual C Redistributable。另一个隐蔽坑装了多个 OpenCV 包比如同时有 opencv-python 和 opencv-contrib-python两个包的 cv2 模块冲突建议只保留一个并统一版本。5.2 现象findChessboardCorners 一直返回 False棋盘格的角点检测不到原因十有八九是内角点数传错了。10×7 的棋盘格内角点是 9×6因为最外圈的格子边不算角点。还有人用手机拍标定板导致图像太模糊或棋盘格纸质板扭曲、强反光遮挡了部分角点。另一个常见问题是采集图像时棋盘格离镜头太近超出画面很多。解决先用一张图像单独调试把 pattern_size 从 (6, 4) 开始试检测到后再逐步加大。打印标定板时选择哑光纸贴到亚克力或硬纸板上保证平整。采集时让棋盘格占画面 1/3 到 1/2避免太大或太小每拍一张就在窗口里画上检测到的角点确认无误再存盘。5.3 现象视差图大片黑色空洞或者物体边缘像被刀切过一样原因numDisparities 太小近处物体超出最大视差范围匹配不到对应点blockSize 太大导致边缘过度平滑左右图曝光不一致同一个点的灰度差过大代价函数找不到最佳匹配。SGBM 对光照很敏感左右镜头的自动曝光如果各自调节拍出来的两张图亮度差异会直接体现在错误匹配上。解决用剪刀撑的方式调参。先把 numDisparities 设成当前场景最大视差的 1.5 倍blockSize 先固定 11P1、P2 按经验公式然后把 disp12MaxDiff 改成 1 检查左右一致性。最后手工把两张校正图的亮度做直方图匹配或者直接把摄像头自动曝光关掉固定曝光时间。很多同学忽略这一点总是去调 P1、P2结果是参数越调越乱。5.4 现象同一个物体测十次结果忽大忽小跳动超过 5%原因深度图里物体区域包含背景像素背景深度值远大于物体均值一算就被污染了。或者两个摄像头在标定后发生松动基线 T 改变而标定参数还是旧的相当于用一个错误的几何关系去换算距离。还有一种情况内存里累积了旧的轮廓缓存ROI 范围不是当前帧的。解决先看一眼深度图按像素值把深度可视化确认物体表面是“干净”的。测量代码里加一道深度范围过滤比如只要物体实际深度值在 Z±50mm 范围内的像素用它做中位数。摄像头固定用热熔胶或型材支架标定完做一次“实测校验”放一个已知尺寸物体如果偏差超过 3%重新标定。这个步骤看起来笨但能省掉后面排错的几个小时。5.5 现象标定重投影误差 ret 大于 0.5但代码还能跑出数字原因这里要明白重投影误差的意义。stereoCalibrate 返回的 ret 是所有棋盘角点的平均重投影像素误差0.3 以内算正常超过 0.5 说明图像里角点定位本身就不准可能因为标定板不平、图像模糊或采集对里两张图不是同一时刻拍的。带着这个误差去做极线校正和 SGBM深度图会整体漂移。解决不要急着往下走先重新采集标定图像。采集时清空素材专门拍 30 对清晰、角度多元的图用前面提到的横向绿线验证校正结果。如果重投影误差一直降不下来考虑把标定板换成陶瓷或玻璃基底的工业板几十块钱能显著提升角点稳定性。期末汇报里把 ret 值打印出来作为系统精度指标老师会觉得你很专业。6. 开发文档怎么写 验证精度的一个实用技巧6.1 开发文档的章节骨架标题里有“开发文档说明”期末大作业的评分老师通常要看你文档里能不能把工程思路讲清楚。我建议按五个部分组织项目背景与需求分析、系统原理、系统设计与实现、实验结果与分析、总结与不足。原理部分写三角测量公式和系统流程图设计与实现部分按标定、校正、匹配、测量四个模块分别给关键代码和函数说明实验结果部分放一张测量数据表写清楚被测物体真值、测量值、误差。这里不要写流水账要把“为什么选 SGBM 而不是 BM”这种选型理由写进去。文档里还应该包含参数的最终配置表标定图像数量、SGBM 的 numDisparities、blockSize、重投影误差、实际测量误差。这样即使你的程序不是最优老师也能看到你有迭代调参的过程评分逻辑上这比一句话“测量精度良好”有说服力。另外文档中的截图要统一分辨率和标注尤其是深度图要放热力图否则一片灰黑看不出效果。6.2 精度验证技巧用已知尺寸物体做十次测量验证是整个项目最容易忽略但最加分的一步。找三个已知尺寸的物体最好覆盖小、中、大三个量级比如银行卡85.6mm×54mm、手机约 160mm×75mm、A4 纸210mm×297mm。每个物体测量 10 次记录每次的宽度和高度值计算平均值、最大偏差和标准差然后把结果做成一张表放进文档。true {card_w: 85.6, card_h: 54.0, a4_w: 210.0, a4_h: 297.0} for obj in [card, a4]: ws, hs [], [] for _ in range(10): w_mm, h_mm measure_object(obj) # 封装好的测量函数 ws.append(w_mm) hs.append(h_mm) print(f{obj}: 宽均值{np.mean(ws):.2f} 最大偏差{np.max(np.abs(np.array(ws) - true[obj_w])):.2f} 标准差{np.std(ws):.2f})那个“先测距离再按像素换算”的流程跑通不算完把误差统计出来才算闭环。我自己的习惯是测完先看标准差标准差比平均误差更能反映系统稳定性。如果标准差控制在 0.5mm 以内这个项目已经达到可靠的实验测量级别如果在 2mm 以上优先怀疑标定和深度质量而不是继续调 SGBM 参数。希望这套思路和踩坑记录能帮你在期末周少走几个弯路。本文还有配套的精品资源点击获取
返回列表