想象一个场景:你们学校拍了一张 8000×6000 的千人大合影,打印出来能贴满整面墙。你的任务是找出照片里所有戴小红帽的人——可他们的帽子在这堵墙上只有指甲盖那么大。直接盯着整面墙看,眼睛很快就花了,帽子仿佛溶进了背景里。这就是目标检测算法面对“小目标”时的真实处境:目标明明就在画面里,却因为太小,特征被背景淹没,最终被漏掉。好在这道难题有解法。工程师们像经验丰富的侦探一样,总结出一套“看清小目标”的策略:把墙面裁成小块凑近了看(切图推理);用修图 App 放大模糊区域(超分辨率增强);平时多收集小红帽的小图来练眼力(数据增强);用和帽子差不多大的取景框辅助扫描(Anchor 设计);最后把几招组合成一条流水线(多策略组合)。今天这篇文章,就用这个“找小红帽”的故事,把这套策略彻底讲清楚。
小目标检测是安防监控、遥感测绘、自动驾驶等场景的刚需技能。掌握这套策略组合,你就能在实际项目中把检测器的召回率从“凑合”提升到“可用”,这是 CV 工程师的核心竞争力之一。
目录
可视化演示
展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。
本节配有交互动效(进入视口后自动加载,约 3KB)。
系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T
小目标难点:为什么小红帽这么难找
新手侦探拿到那幅贴满整面墙的千人大合影,第一反应是站到三米外,双手叉腰,眯起眼睛扫视整面墙。几分钟后他就放弃了——墙上一张张脸都是模糊的色块,要找的小红帽更是只有绿豆大。人眼如此,目标检测算法也一样:当目标的像素少得可怜时,再聪明的模型也“看不清”。
在目标检测里,小目标通常指面积小于 32×32 像素的目标。一张 8000×6000 的大图里,这样的小目标只占整张图的十万分之几。检测器的骨干网络为了提取全局特征,会把图片一层层下采样(把多个像素合并成一个特征点),小目标经过几层之后,可能只剩一两个特征点,信息几乎“蒸发”。
业界沿用 COCO 数据集的定义来判断小目标:目标面积小于 32×32 即 1024 像素就算小目标。小目标的三个难题由此而来:特征稀少,能用来判别的纹理和边缘太少;占比极低,容易与背景混淆;在下采样过程中快速丢失,深层特征图里根本没有它的立足之地。
所以小红帽难找,不是侦探眼力差,而是目标在“缩小”的过程中把信息弄丢了。明白了这个物理瓶颈,接下来的每一招,本质上都是在和信息丢失作斗争。
- 目标宽高w 和 h 分别代表目标在图像中的宽和高,单位是单个像素,它们决定了目标在画面上占多大地方。
- 像素面积把宽和高相乘,得到目标占用的总像素数,这就是衡量目标“大小”的核心依据。
- 小目标阈值业界常用的 COCO 数据集规定,面积小于 32×32=1024 的目标属于小目标,需要额外策略。
切图推理:把大画裁成小块看
老侦探拿出一把美工刀,把墙面平均切成九块,每块大约一米见方。他凑到每一块面前仔细看,但在下刀之前,他特意让相邻两块之间重叠了半拃宽——如果不重叠,帽子正好骑在切缝上,就会被切成两半,谁也认不出来。
切图推理(Tiling Inference)做的正是这件事:把大图分割成互相重叠的子图,分别送入检测器,再把检测结果合并回原图坐标。重叠区域是精髓所在,它保证每个目标至少完整出现在一个子图里。合并时,同一个目标可能出现在多个子图中,需要按 IoU 去重,通常使用 NMS(非极大值抑制)完成。
切图为什么能提升小目标效果?因为子图不再经历“为了看全局而拼命缩小”的过程,目标在子图里保持原始分辨率,特征信息被完整保留。代价也很直接:子图数量多,推理次数成倍增加,所以子图尺寸和重叠比例需要按精度与速度要求折中。
一块一块凑近看,每一块都足够清晰;那些骑在裁缝线上的帽子,也因为重叠而幸免于难。切图是“用空间换清晰”的朴素而有效的第一招。
- 原图与子图宽度整张大图宽为 W 像素,每块子图宽为 w 像素,子图在保证清晰的前提下尽量小。
- 重叠区域相邻子图共享 o 像素宽的重叠部分,目的是防止目标正好被切缝分成两半。
- 切片数量每次向右滑动 w-o 像素,能放下的子图数向上取整,再加 1 就是这一边需要的切片数。
超分增强:给照片装上放大镜
有一块区域让侦探犯了难:隐约有个红色影子,但模糊得像一团雾,怎么也看不清是不是帽子。他掏出手机,对准那块区域拍了一张特写,然后打开修图 App 里的“超分修复”功能。几秒钟后,模糊的色块变成了清晰的帽檐和帽顶轮廓。
超分辨率增强(Super-Resolution)的思路一模一样:训练一个模型 F,学习从低分辨率图像 I_LR 恢复高分辨率图像 I_HR 的映射。在检测之前,先对小目标区域做超分放大 r 倍,让输入检测器的目标拥有更多的有效像素,相当于在检测前先“加深照片细节”。
超分模型通常用成对的低分/高分图像训练,采用像素级重建损失,让生成的图像尽量接近真实高分辨率图。但必须清醒:超分不是无中生有,它只能还原模型在训练中学过的细节模式。如果原图信息已经耗尽,放大的只是模糊本身。因此超分计算量大、增益不稳定,实践中常只对可疑小区域局部使用。
修图 App 不是魔法。它把小红帽补成“它见过的最像帽子的样子”,如果照片里真的什么都没有,它也只能画出一块模糊的红色。超分是锦上添花,不是雪中送炭。
- 低分辨率输入I_LR 是包含小目标的原始低分辨率图像,目标细节已经模糊不清。
- 超分映射超分模型 F 学习低分辨率到高分辨率的映射关系,把模糊细节“还原”出来。
- 放大倍数输出高分辨率图的宽是输入图的 r 倍,总像素量变成原来的 r² 倍,目标随之变大变清晰。
数据增强:给训练集补小目标样本
连着找了三天,侦探发现自己对小红帽的“眼力”越来越差。原因很简单:他平时只看这一张合影,合影里小红帽就那么几个。于是他改变了训练方式——找来几十张不同场景的照片,把里面的小红帽裁剪出来,再贴到新照片的栏杆上、草丛里、人群中,反复看、反复认。
检测模型也有同样的“经验不足”问题。数据集中小目标样本天然稀缺:大目标离得近、占画面大、好标注;小目标远而小,出现频率低、标注成本高。复制粘贴增强(Copy-Paste Augmentation)把小目标实例裁剪出来,在图像中寻找合适位置粘贴,同时生成对应的标注框,让一个实例变成多个样本,几乎不增加标注成本。
增强后的小目标样本量可以用公式估算:新增样本等于粘贴次数乘以小目标实例数。但有两条红线:第一,粘贴位置要语义合理,不能把船贴到天上;第二,遮挡比例要低,否则被遮挡的目标反而成了难学的负样本。
练眼力不能只盯着一张照片看。把小红帽贴进各种合理却又陌生的场景,反复叮嘱检测器“任何位置出现的帽子都算数”,它才会真正记住小目标的样子。
- 原始样本数N 是训练集中原有的小目标实例框数量,通常远少于大目标。
- 粘贴实例与次数N_small 是被裁剪出来的小目标实例数,K 是每个实例额外粘贴到新位置的次数。
- 增强后总量把原有样本和新增样本相加,得到增强后的小目标样本数,样本均衡问题随之缓解。
Anchor 设计:按真实目标定制取景框
侦查进入收尾阶段,侦探发现自己的眼睛虽然够了,但“框”不够用。他用大拇指和食指比划取景框,比划出来的框总是太大,一下框住好几个人,判断不了到底谁戴了帽子。于是他从口袋里掏出一叠卡片——有指甲盖大的小方框、有小竖框、有小横框——专门用和帽子差不多大的框去套候选区域。
检测器里的 Anchor(锚框)就是这叠卡片。检测器预测目标时,不是在图上凭空画框,而是以预设的 Anchor 为起点做微调回归。小目标需要小尺寸的 Anchor;如果预设框全是适合大目标的尺寸,小目标的候选框从起点就“偏了”——好比拿脸盆去套硬币,永远套不准。
Anchor 尺寸不能拍脑袋。经典做法是拿训练集所有真实框做 K-Means 聚类,距离度量用 1-IoU:两个框越相似,IoU 越大,距离越小。聚类得到的 k 组宽高,就是最贴合数据分布的 Anchor 集合。此外,Anchor 太小会导致正样本少、训练不稳定,需要配合合理的正样本分配策略(如 IoU 阈值匹配)。
取景框太大盖过目标,太小又只框住背景。真正的答案不在侦探手里,而在“数据”手里——把小红帽的尺寸统计出来,框自然就合适了。这就是 Anchor 设计与数学统计的默契配合。
- 锚框宽高a 和 b 分别代表两个框的宽高集合,检测器以 Anchor 为起点做位置和尺寸的回归修正。
- 交并比IoU 衡量两个框的重叠程度,等于交集面积除以并集面积,取值范围在 0 到 1 之间。
- 聚类距离用 1 减去 IoU 作为 K-Means 的距离,距离越小代表 Anchor 越接近真实目标的形状。
多策略组合:全家桶才是最强方案
最后一晚,侦探把四件工具全部铺在桌上,排成一条流水线:先切图逐块扫描全墙;遇到模糊的红色影子,用超分 App 放大复检;扫描时手里捏着统计出来的帽子尺寸取景框;而支撑这一切的,是过去几天用复制粘贴法练出来的敏锐眼力。天亮之前,所有小红帽都被找到了。
实践中的小目标检测也是如此:数据增强和 Anchor 设计在训练阶段生效,让模型“学得更准”;切图和超分在推理阶段生效,让检测器“看得更清”。四者分工互补,组合效果显著优于任何单一策略——这正是“数据决定上限,策略逼近下限”的体现。
但组合不是无脑堆叠。切图让推理次数成倍增加,超分又叠加一层计算开销,因此工程上常用“先粗筛、后精查”的流程:先用低成本的整图检测,只对置信度低的区域做切图与超分复检;最终用 F1 分数综合评估精确率与召回率。
没有一招制敌的银子弹。成熟的方案是让每种策略在最需要它的位置上各司其职,像一条装配线一样协作。找到所有小红帽的,不是某一件工具,而是工具的组合。
- 精确率 P预测为正例的框中,真正是小目标的比例,衡量“框出来的东西对不对”。
- 召回率 R所有真实小目标中,被成功找到的比例,衡量“该找的有没有漏掉”。
- 调和平均用 2PR/(P+R) 综合两者,任何一个偏低都会拉低 F1,防止只追求单方面指标。
AI 应用场景
遥感与无人机巡检
阶段:推理阶段(切图推理 + 超分复检)
解决的问题:无人机航拍一张照片覆盖数平方公里,目标(车辆、违法建筑、病虫害植株)往往只有几十像素,整图直接检测漏检严重。切图推理把大图切成带重叠的瓦片,避免小目标因下采样丢失;超分再对可疑低置信区域做放大复检。
具体案例:农业无人机对 5000 亩麦田巡飞,将航拍图按 640×640 大小、30% 重叠切块检测锈病植株,对置信度低的小块做超分复检,漏检率从 35% 降到 12%。
自动驾驶感知
阶段:数据准备与训练阶段(复制粘贴增强 + Anchor 设计),推理阶段(多策略组合)
解决的问题:远处行人和小交通标志是事故高发诱因,但实车采集的远距离小目标样本稀少且类别不均衡。复制粘贴增强把标注好的行人贴进不同路况,K-Means 统计远目标尺寸设计小 Anchor,让模型在训练时“见过足够多的小人”。
具体案例:某智能驾驶团队在训练集中把行人小目标复制粘贴到城市、高速、夜间三类场景,小目标样本量提升 3 倍,远距离行人召回率提升 11 个百分点。
工业质检
阶段:全流程(数据增强 + 切图 + 小 Anchor)
解决的问题:PCB 板上的微小焊点缺陷、布匹上的断纱只有几个像素,且良品率极高导致缺陷样本稀缺。先复制粘贴扩充缺陷样本,推理时对高分辨率大图切图保持细节,并用小 Anchor 提升定位精度。
具体案例:某面板厂用 8K 线扫相机检测 1cm² 内的微划痕,切图 + 增强 + 小 Anchor 组合后,缺陷召回率从 71% 提升到 93%,过检率基本不变。
Python 演示
import math def make_image(H, W, objects): """生成一张灰度图, objects 为 (中心x, 中心y, 半径) 的亮斑列表.""" img = [[0] * W for _ in range(H)] for (cx, cy, r) in objects: for y in range(max(0, cy - r), min(H, cy + r + 1)): for x in range(max(0, cx - r), min(W, cx + r + 1)): if (x - cx) ** 2 + (y - cy) ** 2 <= r * r: img[y][x] = 255 return img def downsample(img, k): """把图像缩小 k 倍, 模拟骨干网络的下采样.""" H, W = len(img), len(img[0]) out = [] for y in range(0, H - k + 1, k): row = [] for x in range(0, W - k + 1, k): mean = sum(img[y + i][x + j] for i in range(k) for j in range(k)) // (k * k) row.append(255 if mean > 180 else 0) out.append(row) return out def detect(img): """玩具检测器: 每个亮像素扩展成 3x3 候选框.""" boxes = [] h, w = len(img), len(img[0]) for y in range(h): for x in range(w): if img[y][x] >= 200: boxes.append([max(0, x - 1), max(0, y - 1), min(w - 1, x + 1), min(h - 1, y + 1), 1.0]) return boxes def iou(a, b): """计算两个框的交并比.""" x1, y1 = max(a[0], b[0]), max(a[1], b[1]) x2, y2 = min(a[2], b[2]), min(a[3], b[3]) inter = max(0, x2 - x1 + 1) * max(0, y2 - y1 + 1) area_a = (a[2] - a[0] + 1) * (a[3] - a[1] + 1) area_b = (b[2] - b[0] + 1) * (b[3] - b[1] + 1) union = area_a + area_b - inter return inter / union if union > 0 else 0.0 def nms(boxes, thr=0.4): """非极大值抑制: 去掉与高得分框重叠过多的重复框.""" boxes = sorted(boxes, key=lambda b: b[4], reverse=True) keep = [] while boxes: best = boxes.pop(0) keep.append(best) boxes = [b for b in boxes if iou(best, b) < thr] return keep def scale_boxes(boxes, k): """把下采样空间的框坐标映射回原图.""" return [[b[0] * k, b[1] * k, b[2] * k + k - 1, b[3] * k + k - 1, b[4]] for b in boxes] def tile_detect(img, tile=64, overlap=16): """切图推理: 重叠切片检测后坐标映射回原图并合并.""" H, W = len(img), len(img[0]) step = tile - overlap merged = [] for y0 in range(0, H - tile + 1, step): for x0 in range(0, W - tile + 1, step): patch = [row[x0:x0 + tile] for row in img[y0:y0 + tile]] for (x1, y1, x2, y2, s) in detect(patch): merged.append([x1 + x0, y1 + y0, x2 + x0, y2 + y0, s]) return nms(merged) def recall_at(boxes, objects): """统计检测框中心与真实目标中心重合的比例.""" hits = 0 for (cx, cy, _) in objects: ok = False for b in boxes: bcx = (b[0] + b[2]) // 2 bcy = (b[1] + b[3]) // 2 if abs(bcx - cx) <= 4 and abs(bcy - cy) <= 4: ok = True if ok: hits += 1 return hits / len(objects) def main(): H, W = 128, 128 objects = [(20, 20, 10), (70, 45, 2), (100, 100, 3), (50, 92, 2)] img = make_image(H, W, objects) k = 4 full = scale_boxes(nms(detect(downsample(img, k))), k) tiled = tile_detect(img, 64, 16) print("整图下采样检测召回率: %.2f" % recall_at(full, objects)) print("切图推理检测召回率: %.2f" % recall_at(tiled, objects)) if __name__ == "__main__": main()
def make_image(H, W, objects):生成一张带小目标亮斑的灰度图,半径越小目标越小。row.append(255 if mean > 180 else 0)模拟下采样把小目标的亮度平均掉,小目标因此消失。boxes.append([max(0, x - 1), max(0, y - 1),把每个亮像素扩展成 3×3 候选框,模拟检测头。return inter / union if union > 0 else 0.0计算两个候选框的重叠程度 IoU,用于去重。boxes = [b for b in boxes if iou(best, b) < thr]NMS 抑制重复框,一个目标只留一个框。merged.append([x1 + x0, y1 + y0, x2 + x0, y2 + y0, s])子图坐标映射回原图,是切图合并的关键一步。print("整图下采样检测召回率: %.2f" % recall_at(full, objects))输出两种路线的召回率对比结果。
常见误区
误区小目标看不清,直接用超分辨率把整张图放大两倍再检测不就行了?放大之后目标变大了,应该就能检测到了吧。
正解超分不能凭空创造信息。模型只是学习“低分到高分”的映射,把细节从模糊中“还原”出来;如果原图小目标已经只剩几个像素,超分放大只会把马赛克放大,还白白增加计算量。超分更合理的用法是只对可疑小区域做,并和切图配合。
为何常见:人眼放大照片时确实看得更清,因为原照片本来就有细节;而模型对信息缺失的图片做放大时,没有新信息可用。
误区切图时重叠区域越大,越不容易切到目标,那就让相邻子图尽量多重叠,把重叠设到子图的一半以上。
正解重叠越大,同一目标出现在更多子图里,推理次数和合并去重的负担成倍增长;而且目标被切碎成两半时,即使有重叠,两半的分辨率都会下降。实践中重叠取子图边长的 10%-30% 即可。
为何常见:只看到“避免目标被切断”的一面,没有权衡计算开销和合并复杂度。
误区现在的检测器都有 FPN 特征金字塔,小目标统一交给高层特征处理就行,不用专门设计策略。
正解FPN 缓解了小目标特征不足的问题,但受限于下采样步长,32×32 以下的目标在深层特征中仍可能只有一两个特征点。FPN 是“地基”,切图、超分、数据增强是在地基上继续加码,组合才有效。
为何常见:把“缓解”误当成“解决”,低估了小目标信息的物理瓶颈。
误区数据增强嘛,把小目标裁剪出来,随机粘贴到画面任意位置就行,贴得越多样本越丰富。
正解随意粘贴会破坏场景语义,比如把船贴到天上、把红绿灯贴到农田里。检测器会学到“位置和上下文”的错位关联,导致真实场景中误检。粘贴位置应尽量合理,并避开严重遮挡。
为何常见:只关注样本数量,忽略了数据分布的真实性,以为“多”就一定“好”。
面试题
Q1. 在 COCO 数据集中,目标面积小于哪个值会被划分为「小目标」?
- A.16×16 即 256 像素
- B.32×32 即 1024 像素← 正确答案
- C.64×64 即 4096 像素
- D.128×128 即 1.6 万像素
答案:B。像“找小红帽”一样,COCO 把面积小于 32×32=1024 像素的目标称为小目标。A 过小,C、D 过大,都不符合业界通行定义。
Q2. 切图推理时相邻子图为什么要保留重叠区域?
- A.减少总计算量
- B.防止目标被切缝切断← 正确答案
- C.让图片分辨率更高
- D.方便标注数据
答案:B。小红帽如果恰好站在拼接缝上,会被切成两半,两个子图各剩半顶帽子,都检测不出来。重叠让目标完整出现在至少一个子图中。重叠实际上增加计算量,A 反了;C、D 与切图无关。
Q3. K-Means 聚类设计 Anchor 尺寸时,常用什么作为距离度量?
- A.欧氏距离
- B.曼哈顿距离
- C.1 减去 IoU← 正确答案
- D.余弦距离
答案:C。Anchor 的“相似”要看框与框的交叠程度,用 1-IoU 当距离,越相似的框距离越近。欧氏距离会把大框和小框混为一谈,不符合“框定目标”的语义。
Q4. 小目标经过骨干网络多次下采样后容易漏检的根本原因是?
- A.计算量突然增大
- B.特征被压缩到极少像素← 正确答案
- C.图片颜色太单调
- D.目标移动速度太快
答案:B。下采样如同把合影缩小,小红帽的像素被不断合并,最后可能只剩一两个特征点,检测器“无米下锅”。A、C、D 都不是小目标特有的物理瓶颈。
Q5. 复制粘贴增强小目标样本时,最关键的一条注意事项是?
- A.粘贴位置要语义合理← 正确答案
- B.粘贴次数越多越好
- C.只增强大目标
- D.粘贴后无需标注
答案:A。把船贴到天上会误导检测器建立错误的位置-类别关联。粘贴位置合理、遮挡适度,同时必须同步生成标注框,才是有益的增强。
Q6. 关于超分辨率增强,下列说法正确的是?
- A.能从模糊中凭空创造新信息
- B.只能还原模型学过的细节模式← 正确答案
- C.对任意小目标都稳定有效
- D.完全替代切图推理
答案:B。超分像修图 App,它把“最像帽子的样子”补出来,但无法无中生有。信息太少的区域放大后可能仍是马赛克,因此通常只作为辅助策略,不能替代切图。
Q7. 原图 1000×1000,子图 500×500,子图间重叠 100 像素,至少需要多少个子图?
- A.4 个
- B.6 个
- C.9 个← 正确答案
- D.12 个
答案:C。每个方向滑动步长为 500-100=400 像素,按公式 n=⌈(1000-500)/400⌉+1=3,两个方向 3×3=9 个。这题考察对切图数量公式的理解。
Q8. 以下哪些属于常见的小目标检测策略?
- A.切图推理← 正确答案
- B.超分辨率增强← 正确答案
- C.复制粘贴增强← 正确答案
- D.缩小输入图像
答案:ABC。切图、超分、复制粘贴分别对应“分块看、放大看、多练眼力”三条路线。缩小输入图像会让目标更小,方向完全反了。
Q9. 关于切图推理合并结果,下列说法正确的有?
- A.子图检测框需映射回原图坐标← 正确答案
- B.重叠区的同一目标需要去重← 正确答案
- C.检测结果可以直接累加不用管
- D.常用 NMS 或者 IoU 去重← 正确答案
答案:ABD。子图坐标要加上偏移量映射回原图;同一目标在多个子图中会出现多次,必须用 NMS 去重;直接累加会造成大量重复框,C 说法错误。
Q10. 关于多策略组合的正确理解有哪些?
- A.策略越多效果必然越好
- B.需权衡精度与推理开销← 正确答案
- C.可训练推理阶段分工配合← 正确答案
- D.所有场景都用同一套组合
答案:BC。切图和超分增加推理计算量,组合时必须权衡精度与速度;数据增强和 Anchor 设计在训练阶段生效,属于推理前的“准备功夫”。策略组合要按场景配置,A、D 都过于绝对。