482_目标检测算法总结¶
一句话说明¶
目标检测不只说"图里有猫",还要画出边界框定位猫在哪里,是自动驾驶、安防监控的核心视觉任务。
核心知识点¶
- 两阶段检测器:先提候选框(RPN),再分类+精修(Faster RCNN系列)——精度高但慢
- 单阶段检测器:直接回归框和类别(YOLO、SSD)——快速,适合实时应用
- 锚框(Anchor):预设不同尺度和长宽比的参考框,候选框在其基础上偏移
- 无锚框(Anchor-free):FCOS、CenterNet直接预测中心点或角点,更灵活
- 评估指标:mAP(mean Average Precision),多IoU阈值下的精度均值
经典算法对比¶
| 算法 | 类型 | 速度 | 精度 | 特点 |
|---|---|---|---|---|
| Faster RCNN | 两阶段 | 慢 | 高 | RPN生成候选框,精度标杆 |
| YOLO v5 | 单阶段 | 极快 | 中高 | 工程化成熟,部署友好 |
| YOLO v8 | 单阶段 | 极快 | 高 | Ultralytics最新版,anchor-free |
| SSD | 单阶段 | 快 | 中 | 多尺度特征图检测 |
| DETR | Transformer | 慢 | 高 | 端到端无NMS,无锚框 |
| DINO | Transformer | 中 | 最高 | 改进DETR,SOTA |
代码示例¶
# ---- 1. YOLOv8 推理(最快上手)----
# pip install ultralytics
from ultralytics import YOLO
from PIL import Image
# 加载预训练YOLOv8模型(n/s/m/l/x 对应从小到大)
model = YOLO('yolov8m.pt') # m=medium,平衡速度和精度
# 对图片进行推理
results = model('image.jpg',
conf=0.5, # 置信度阈值(低于此的框被过滤)
iou=0.45) # NMS的IoU阈值
# 处理检测结果
for r in results:
boxes = r.boxes # 检测框对象
for box in boxes:
x1, y1, x2, y2 = box.xyxy[0].tolist() # 边界框坐标
conf = box.conf[0].item() # 置信度
cls = int(box.cls[0].item()) # 类别ID
label = model.names[cls] # 类别名称
print(f"{label}: {conf:.2f} @ [{x1:.0f},{y1:.0f},{x2:.0f},{y2:.0f}]")
# 可视化(带框的图片)
annotated = results[0].plot() # 返回带标注的numpy图像
Image.fromarray(annotated).save('result.jpg')
# ---- 2. YOLOv8 自定义数据集微调 ----
# 数据集需要YOLO格式:
# dataset/
# images/train/*.jpg
# images/val/*.jpg
# labels/train/*.txt # 每行: class_id cx cy w h (归一化坐标)
# labels/val/*.txt
# 配置文件 data.yaml:
# train: dataset/images/train
# val: dataset/images/val
# nc: 2 # 类别数
# names: ['cat', 'dog']
model = YOLO('yolov8m.pt') # 从预训练权重开始微调
results = model.train(
data='data.yaml', # 数据配置文件
epochs=100,
imgsz=640, # 输入图像尺寸
batch=16,
lr0=0.01, # 初始学习率
workers=4,
device='cuda',
project='runs/detect', # 保存路径
name='exp1'
)
# ---- 3. Faster RCNN(两阶段,高精度)----
import torchvision
from torchvision.models.detection import fasterrcnn_resnet50_fpn
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
import torch
# 加载预训练Faster RCNN(COCO 80类)
model = fasterrcnn_resnet50_fpn(
weights=torchvision.models.detection.FasterRCNN_ResNet50_FPN_Weights.COCO_V1
)
# 替换分类头(适配自定义类别数)
num_classes = 3 # 背景 + 2个类别(背景必须包含)
in_features = model.roi_heads.box_predictor.cls_score.in_features
model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
# 推理模式
model.eval()
import torchvision.transforms.functional as F
from PIL import Image
img = Image.open("test.jpg").convert("RGB")
img_tensor = F.to_tensor(img).unsqueeze(0) # (1, 3, H, W)
with torch.no_grad():
predictions = model(img_tensor)
# 解析预测结果
pred = predictions[0]
for box, label, score in zip(pred['boxes'], pred['labels'], pred['scores']):
if score > 0.5: # 过滤低置信度
print(f"类别{label}: {score:.3f} @ {box.int().tolist()}")
# ---- 4. 计算 mAP 评估 ----
# pip install torchmetrics
from torchmetrics.detection.mean_ap import MeanAveragePrecision
metric = MeanAveragePrecision(iou_type="bbox")
# 格式:list of dict,每张图一个dict
preds = [{"boxes": torch.tensor([[10, 20, 100, 200]]),
"scores": torch.tensor([0.9]),
"labels": torch.tensor([0])}]
targets = [{"boxes": torch.tensor([[15, 25, 105, 205]]),
"labels": torch.tensor([0])}]
metric.update(preds, targets)
result = metric.compute()
print(f"mAP@0.5: {result['map_50']:.4f}")
print(f"mAP@0.5:0.95: {result['map']:.4f}")
面试常问点¶
- NMS(非极大值抑制)的作用?
过滤同一目标的重叠候选框,只保留得分最高的,IoU超过阈值的框被抑制
FPN(特征金字塔网络)解决了什么问题?
多尺度目标检测:用不同层次的特征图检测不同大小的目标(浅层检小目标)
YOLO系列相比Faster RCNN的优势和劣势?
- 优势:速度快(实时)、端到端、工程友好
劣势:对小目标和密集目标检测效果略差
DETR(Detection Transformer)的创新点?
- 用Transformer的cross-attention取代NMS,端到端没有后处理步骤
速查表¶
| 场景 | 推荐 |
|---|---|
| 实时检测 | YOLOv8n/s |
| 高精度 | Faster RCNN / DINO |
| 快速部署 | YOLOv8 ONNX导出 |
| 小目标 | SAHI + 切片推理 |
| 评估 | torchmetrics MeanAveragePrecision |