尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

目标检测与定位实战:从坐标回归到空间测距的完整指南

目标检测与定位实战:从坐标回归到空间测距的完整指南 做视觉项目这些年我越来越确定一件事目标检测和定位基本是分不开的。无论是安防摄像头数人、质检机器找缺陷还是机器人抓取零件客户嘴上说的是“让电脑自己看见东西”落到代码里其实就是两件事——先把图像里有个什么类别认出来再把目标的位置用坐标表达出来。这里面既有二维图像上的检测框回归也有从图像坐标换算到真实空间位置的三维定位。这篇文章是我结合实际项目整理的一套概述和实操笔记不会去复述原论文里的数学推导重点是从“要做什么、怎么选型、有哪些坑”讲起。适合刚入门的同学搞清楚整个技术轮廓也适合准备做检测方向课程设计或工程项目的朋友拿来当路线参考。整篇会分五个部分先把“检测定位”这个说法拆开讲再聊数据和标注然后是模型与指标接着是工程落地最后列一堆我在项目里真实踩过的雷。内容偏长但干货密度不低。1. 从应用反推原理目标检测里的“定位”不止一种1.1 定位的第一层含义是“把它框出来”目标检测的经典定义是分类加回归分类判断图像区域里是什么回归输出目标在图像中的位置。你可以把整个过程想象成在一堆书里找一本指定封面的书——分类任务负责识别这是不是目标书籍定位任务则要说出它是在书架第几排第几本的位置。实际代码落地时定位这部分的输出通常有两种形式。一种是边界框的中心点坐标、宽度和高度比如(cx, cy, w, h)另一种是左上角和右下角两个顶点坐标比如(xmin, ymin, xmax, ymax)。这两种表达本质上等价但因为数据集的格式偏好不同在做格式转换时特别容易出问题这一点后面会细说。再往后延伸一点普通检测框默认是轴对齐矩形也就是正着画出来的框。但在遥感图像里目标往往是任意朝向的比如飞机、船、建筑物这时候必须用旋转框(cx, cy, w, h, theta)才能准确框住目标。遥感图像标注里大量涉及旋转框的使用这也是“定位”这个概念在细分领域里的一种延伸。分类和定位在损失函数里是可以分开计算的。分类一般用交叉熵损失定位则用 Smooth L1、L1 或者近年更流行的 GIoU、CIoU 等回归损失。实际操作中你会发现很多模型“认得出目标但框不准”问题往往出在回归分支的损失权重设置或者数据标注本身质量而不是模型不认识这个类别。1.2 定位的第二层含义是“求出真实空间坐标”如果项目只要求在图片上画框那到上面那一步就结束了。但很多场景——比如机器人抓取、无人车避障、无人机降落——需要知道目标在真实世界中的三维坐标这时候的定位就是另一个维度的问题。按传感器输入不同大体有三条路线单目相机只用普通摄像头利用几何约束和先验尺寸估计距离成本最低但对距离误差比较敏感适合近距离、平面性强的场景。双目或多目相机通过左右视图的视差计算深度精度受基线长度和标定质量影响。在室内中近距离场景精度较高但在纹理稀少的地方容易匹配失败。RGB-D 相机或激光雷达直接获取深度信息或点云数据精度最高但硬件成本也最高。机器人定位和自动驾驶场景通常走这条路。三维目标检测在算法层也有自己的体系。传统方案里可以把二维检测结果结合几何约束投影到三维空间现在更主流的是直接设计三维检测网络比如在点云或体素特征上处理的 PointPillars、CenterPoint 这类方法。不过对于普通项目来说如果只是“基于图像”做定位最务实的路线通常是二维目标检测 深度估计/标定测距这个组合可以覆盖大部分学业和中小型工程需求。2. 数据是定位精度的地基2.1 公开数据集与标注格式别小看坐标约定做目标检测绕不开数据格式。不同数据集、不同模型框架对标注的定义差异特别大我第一次做数据集转换时就因为在归一化坐标和像素坐标之间弄混了导致训练出来的模型在验证集上框全部偏移。主流的公开数据集有这些COCO标注格式为 JSON框坐标形式是[x, y, width, height]单位是像素x和y是左上角坐标。PASCAL VOC标注格式是 XML每个目标写xmin, ymin, xmax, ymax同样是像素。YOLO 系训练格式纯文本 Txt每一行是class_id x_center y_center width height全部归一化到 0~1 之间。DOTA 等遥感数据集使用旋转框格式通常是(cx, cy, w, h, theta)。如果你用 LabelImg 或者 Labelme 做标注导出的格式会不一样。LabelImg 一般直接输出 VOC XML 或 YOLO 格式Labelme 则输出 JSON里面保存的是多边形的顶点坐标需要自己转换成矩形框。很多做遥感图像标注和医学图像标注的人更习惯用 Labelme因为它可以标不规则形状、旋转框不只是正矩形。以最常见的“VOC 转 YOLO”为例转换逻辑是这样的假设图像宽为W、高为H标注框为xmin, ymin, xmax, ymax那么x_center ((xmin xmax) / 2) / W y_center ((ymin ymax) / 2) / H box_width (xmax - xmin) / W box_height (ymax - ymin) / H这个转换看起来简单但有两个常见的坑一是坐标宽高算出来的结果必须落在 0~1 之间如果出现负数或者大于 1说明原始标注越界了要检查原图和标签是否对得上二是很多新手会忘记归一化直接把几百几千的像素值写进 YOLO 格式模型训练直接崩溃。另一个容易忽视的点是标注框的宽高本身要考虑数据集的统计特征。如果你的目标普遍是小尺寸物体比如远处的行人、小动物、遥感小目标那么标注框的宽高统计会和常规目标差别很大。这直接影响后面 anchor 的设定也会影响小目标检测的召回率。2.2 标注工具选择与数据增强的隐性坑工具选型其实不难快速做矩形框标注LabelImg 就够了如果涉及不规则目标、旋转框或者分割掩码用 Labelme 更合适。现在很多团队也直接用在线标注平台做多人协同但不管用什么工具最终你都要面对一个绕不开的问题——数据增强时的标签同步。数据增强是提高检测泛化能力的重要手段随机翻转、缩放、平移、Mosaic 拼接都很好用。但每次对图像做几何变换目标框坐标必须同步跟着变。比如水平翻转后原来是(x, y)的像素坐标会变成(width - 1 - x, y)标注框的左下右上关系也要相应调换。一旦增强代码里只处理了图像、没处理标签训练时你看到的其实是“图像变了但框没变”的错位数据模型学到的定位就是扭曲的。我见过不止一个项目训练集里增强部分框和目标错位严重模型训练完后在验证集上精确率能看但召回率一直上不去而且框总偏向图像的某个方向。排查到最后就是数据增强和标签没有同步导致的。所以在你写增强管线之前先把“标签跟随图像变换”这个原则写死在代码注释里能省掉后面至少两天的排查时间。话说回来还有一类让检测框架更稳定的图像预处理技术比如图像去模糊、图像超分辨率重建。低分辨率图像会明显伤害小目标检测的召回率。现在有不少项目会在检测前接一个轻量超分模型先提升图像分辨率再做检测。这种方案有效但要注意如果超分模型改变了图像尺寸检测框的坐标必须映射回原图大小否则下游系统拿到的坐标就错位了。3. 模型与评价如何量化“检测准不准、定位准不准”3.1 从 YOLO 到 Transformer选型原则目标检测算法发展到现在大的路线其实可以分成三类两阶段检测以 Faster R-CNN、Mask R-CNN 为代表先通过区域提议网络给出候选框再逐框分类和回归。精度高但推理慢适合精度要求大于实时性的场景。单阶段检测以 YOLO 系列为代表直接在一次前向过程中输出类别和框位置。速度快精度已经和两阶段方法差距很小是目前工程落地的主流选择。Transformer 检测以 DETR 为代表把检测建模成集合预测问题不需要 anchor 和 NMS 后处理结构简洁但训练收敛慢模板也更重目前在中大目标上表现好小目标仍是短板。我用一张表来总结主流方案的取舍方案速度精度工程难度适用场景Faster R-CNN慢高中等离线分析、高精度场景YOLOv5/YOLOv8快较高容易实时检测、边缘设备YOLO-tiny/Nano很快中容易移动端、低算力设备DETR 系中高较高大目标场景、研究项目这几年移动端检测有个趋势就是把模型体积压缩到极致。网上看到的“macs仅5mb的目标检测模型”这类说法通常是指模型本身用轻量化骨干网络加深度可分离卷积实现算力消耗和模型体积都非常小。对于嵌入式项目比如树莓派或者手机端实时检测这种模型很有价值。但代价是精度有限尤其小目标检测能力明显弱于大模型所以选型前先想清楚目标尺寸分布再做决定。除了算法本身还有一个趋势值得关注多模态目标检测。现在很多新模型尝试把文本描述、语音提示和图像特征融合在一起让“检测”这个任务从固定类别列表走向开放词汇。虽然普通项目未必用得上但如果你的应用需要动态调整检测类别多模态方案会是一个值得关注的方向。3.2 必须看懂的评价指标项目汇报时领导或客户通常会问三个问题检测准不准、定位准不准、运行快不快。这三个问题分别对应着几组指标我给你逐个说清楚。IoU交并比是所有检测指标的地基。它计算的是预测框和真实框的交集面积除以并集面积取值范围 0~1越接近 1 代表定位越准。比如预测框和真实框完美重合时 IoU1完全不重合时 IoU0。有了 IoU 之后就可以定义 TP真正例和 FP假正例。一般设定一个阈值比如 IoU ≥ 0.5 算一个正确检测低于阈值就认为是误检。基于这些统计再算精度 Precision查准率和召回率 Recall查全率。把不同置信度下的 Precision 和 Recall 画成曲线曲线下的面积就是 AP多个类别的 AP 取平均就是 mAP。mAP 是检测任务最常用的综合指标。但这里有一个关键细节mAP50 和 mAP75 的差别直接反映了模型定位精度的高低。mAP50 只要求预测框和真实框的 IoU 超过 0.5所以框稍微偏一点也会被认为预测正确mAP75 要求 IoU 超过 0.75定位稍微差一点就会被扣分。如果一个模型 mAP50 很高但 mAP75 很低说明模型能认出目标但框中心或尺寸偏了——这在“基于图像的目标检测与定位”项目中是必须关注的。红外小目标检测里的评价参数会更特殊。小目标通常指像素面积小于 9×9 或者在整幅图像中面积占比极低的目标这类目标用常规的 mAP 来评估会因为正样本极少而失去区分度。行业内会使用专门的小目标检测评价参数比如目标信号与背景杂波比 SCRG、信杂比增益 SFG、检测概率和虚警率等。简单理解就是不仅要看检测出来多少还要看在杂波背景下虚警是否压得住以及目标信号相对背景有没有被增强。如果做的是红外、遥感这类小目标项目千万别只用 mAP 汇报结果那会掩盖很多真正重要的能力缺陷。3.3 相机标定与空间定位计算如果你的项目最终要输出目标在真实空间中的位置只靠二维检测框是不够的。这里离不开相机标定和坐标换算。相机标定要做的事情是求出相机内参fx, fy, cx, cy和畸变系数。简单说内参描述了像素坐标和相机坐标系之间的关系。假设目标在相机坐标系下的深度为Z其像素坐标为(u, v)那么相机坐标系下的三维坐标为X_c (u - cx) * Z / fx Y_c (v - cy) * Z / fy Z_c Z这个公式我在项目里用过无数次。它的意义是只要知道像素坐标和深度就能反推目标相对于相机的位置。深度Z可以通过深度相机直接获取也可以通过双目视差计算对于单目相机则需要额外信息比如已知目标高度或地面约束来估。标定这一步看起来不起眼但误差会直接传导到最终的定位结果中。我做过一个测试把棋盘格标定图片从 10 张减少到 5 张内参重投影误差几乎翻倍测距误差从 2% 飙升到 5% 以上。所以如果你追求毫米级的空间定位精度标定这一步的钱和时间千万不要省。拍摄标定板时要覆盖画面各个位置、各个角度至少 15 张有效图片并且保证棋盘格在画面中清晰完整。4. 落地部署时绕不开的工程细节4.1 依赖安装与环境配置从“无法定位软件包”说起目标检测项目的第一个劝退点往往不是算法而是环境安装。尤其在做 ROS 和视觉融合的项目时你可能会遇到“无法定位软件包 ros-noetic-desktop-full”这类的报错。这个问题绝大多数情况下不是包不存在而是软件源里没有对应版本的包索引。常见原因有三个第一没更新软件源包列表还是旧的第二当前系统版本与 ROS 发行版不匹配比如 Noetic 对应 Ubuntu 20.04你在更低版本的系统装就会找不到第三第三方源没有正确添加。排查方式很简单先确认系统版本和架构再确认已添加的 apt 源地址执行更新后再安装。Python 环境下也有类似问题。很多人用 pip 直接安装 torch 或者 opencv装完才发现 CPU 版本的包装了 GPU 机器上训练慢到怀疑人生。我的习惯是项目一开始就把依赖环境写清楚最好用 requirements.txt 加 docker 镜像保证换一台机器也能复现。踩过几次“本地能跑服务器跑不起来”的坑之后你会明白环境锁定比模型调参还重要。4.2 推理时的坐标换算与图像质量预处理模型训练和推理的数据输入尺寸通常和原图不一致。比如 YOLO 训练时会把图 resize 到 640×640 或者 1280×1280模型输出的检测框坐标是相对于输入尺寸的要还原到原始图像坐标就必须把缩放比例和 padding 信息记下来。这里最常见的一个坑是 letterbox 填充。很多检测流程会把长宽比不一致的图填充到正方形比如把 1920×1080 的图加灰边变成 640×640。如果模型输出的坐标没有先减去 padding 再除以缩放比例所有框都会整体偏移。我在代码里专门封装了一个坐标还原函数核心就是记录scale和pad两个变量推理结束后统一做映射避免在多个地方重复计算导致出错。图像质量对检测定位的影响也很直接。运动模糊、低光照、低分辨率会同时伤害分类置信度和回归精度。如果业务场景出现这种问题常见做法是前置图像去模糊或图像超分辨率重建模块。但同样要注意超分模型的输出尺寸如果和原图不一致检测出来的框坐标需要按比例还原回去。此外超分重建本身可能改变目标边缘位置在像素级要求高的项目里必须预先评估这种坐标偏移是否在可接受范围。对于超大尺寸的遥感图另一个常用技巧是切片推理SAHI 类方法把大图切成重叠的小块分别检测再把结果合并到原图坐标系。这个方案对小目标检测的提升非常明显但合并时要注意块与块之间重复目标的 NMS 处理以及不同块边缘目标的坐标偏移补偿。4.3 模型量级与部署轻量化模型是否够用如果你的项目跑在边缘设备上比如手机、盒子或者小车模型体积和算力就是硬约束。前面提到的“macs仅5mb的目标检测模型”本质是用 MobileNet、ShuffleNet 这类轻量骨干做特征提取同时把 YOLO 的检测头精简牺牲一部分精度换取极小的体积和极快的速度。我的经验是轻量模型在目标尺寸较大、背景简单、类别少的场景下完全够用。一旦场景里有大量小目标、密集目标或遮挡轻量模型表现就明显下降。不要盲目为了“模型小”去选型先把业务目标分布测一遍再决定模型规模。模型部署时还有一个容易忽略的问题训练框架和推理框架之间的算子兼容性。PyTorch 训练出来的模型转 ONNX 再转 TensorRT经常遇到某个自定义算子不支持导致转换失败。做法是尽量在模型结构设计阶段避开过于冷门的算子比如自定义的归一化层和特殊激活函数优先选用 ONNX 标准算子域覆盖范围内的操作会大幅减少落地阻力。5. 实操中我踩过的几个定位大坑5.1 增强后标签没跟着变这个坑在前面提过但真的值得再多说一遍。在 Transformer 检测器和 YOLO 模型中使用随机裁剪、旋转、色彩抖动时色彩抖动不会影响坐标但几何变换一定会影响。最容易出错的是随机裁剪裁剪区域变化后框的坐标、尺寸甚至目标是否还在画面内都需要重新计算。如果裁剪把目标切掉了一部分还要决定是保留残框还是丢弃该目标。没有统一标准的情况下我是按“裁剪后目标可见面积低于原框 30% 就丢弃”处理的这样能减少大量脏标签。5.2 置信度阈值与 NMS 的“两难”推理时调参最揪心的环节是置信度阈值和 NMS 的 IoU 阈值。置信度阈值调高误检变少但漏检变多调低召回率提高但会出现一堆可信度不高的框。NMS 的 IoU 阈值影响的是重叠框的去重强度阈值设太小密集场景里相邻的真实目标会被误杀掉一个设太大一个目标周围会残留大量重叠框看起来定位“不确定”框一直在飘。这里我给出一个相对通用的起点配置置信度阈值 0.25NMS IoU 阈值 0.45然后根据验证集表现做微调。对于密集场景比如人群、货架商品NMS 阈值可以适当放宽到 0.5 或 0.55但要密切关注是否把两个靠近的真实目标合并成了一个。5.3 小目标检测到底改哪些参数我总结过一套针对小目标检测的调优顺序按优先级从高到低排列提高输入分辨率把小图放大再检测是提升小目标召回率最直接的手段。使用多尺度特征层在特征金字塔中增加高分辨率特征层P2 层保留更多小目标的空间信息。调整 anchor 尺寸通过 K-Means 聚类自己数据集的框尺寸得到更适配的 anchor。调整损失权重如果定位不准增加回归损失的权重如果漏检严重增加分类损失的权重。使用切片推理对超大图做分块检测避免目标在降采样后消失。如果这些手段都试过小目标仍然差就要考虑是不是数据太少、标注质量太差而不是模型结构问题。模型能学习到的信息上限取决于数据的质量和数量这一点永远绕不开。5.4 一张速查表常见定位问题排查为了让你排查起来更方便我把项目里遇到的定位相关高频问题整理成了一张速查表现象可能原因解决措施所有框整体偏移坐标未还原到原图尺度检查 resize/letterbox 的 scale 和 pad 是否恢复框的中心点随机偏移增强时标签未同步变换检查几何增强代码中的标签更新逻辑框普遍偏大或偏小数据标注本身尺度不一致抽查标注框统一标注规范mAP50 高、mAP75 低回归精度不够调高回归损失权重、提高输入分辨率小目标全部漏检下采样倍数过大或 anchor 尺寸不适配用 P2 层、切片推理、重新聚类 anchor空间定位距离偏大相机标定误差或深度估计不准重新标定相机、增加标定图片、提高深度数据质量这张表不是万能药方但覆盖了我在多个项目里反复遇到的典型问题。每次模型效果变差先把问题归到它们对应的环节再针对性解决效率会高很多。根据我自己的经验做目标检测与定位项目时先把二维检测框做好再考虑空间定位顺序不要颠倒。很多初学者一上来就想做三维坐标测距结果二维框还没稳后面的误差全被放大了。建议在一开始就把“定位误差”单独列一项指标不要只看 mAP因为 mAP 高不代表框中心点准而空间定位恰好对中心点极其敏感。另外训练完第一个版本不要急着调参先做一轮错误样例分析把标注问题、数据分布问题、模型问题分开归类这个习惯能帮你节省大量的后期时间。
返回列表