第八章

目标检测:摄像头统计客流

第七层 · YOLO/NMS/mAP 用 YOLO 数出书店里有多少人

一、从"分类"到"检测":还要知道"在哪"

"分类只回答'这张图是什么'。目标检测(Object Detection)要回答'图里有什么、在哪'——框出每个目标的位置。"老周画:

分类 vs 检测:
  分类:[整张图] → "这是猫"
  检测:[图] → "这里有一只猫(框A)、那里有一个人(框B)"

  检测输出:
    每个目标一个框(Bounding Box)+ 类别 + 置信度
    框 = 中心点(x,y) + 宽高(w,h)  或  左上角+右下角

  云间书店需求:
    客流统计:检测"人"(person 类)→ 数框
    货架识别:检测"书/商品"→ 统计数量
    收银排队:检测人 + 跟踪(第十一章)

  检测 vs 分类在流程上的差别:
    分类:整图一个标签
    检测:把图"切出"很多区域,每个区域判断是什么
    → 核心问题:怎么找"候选区域"?

"检测 = '在哪找' + '是什么'两步——难点在'在哪找':图里人可能出现在任何位置、任何大小。"


二、检测的两大流派:两阶段 vs 单阶段

"目标检测有两大技术路线。"老周说:

两阶段检测器(Two-stage):
  第一阶段:先生成"候选区域"(可能是目标的框)
  第二阶段:对候选区域分类 + 精修框
  代表:R-CNN 系列 → Fast R-CNN → Faster R-CNN
  特点:准确率高,但慢(两遍流程)
  适合:精度优先(工业质检)

单阶段检测器(One-stage):
  一个网络直接输出"框 + 类别"(一步到位)
  代表:YOLO(You Only Look Once)、SSD
  特点:快(实时),精度略低但已够用
  适合:实时视频(客流统计、自动驾驶)

  YOLO 为什么叫"只看一次":
    传统方法要"滑窗/候选区域"多次看
    YOLO 把整张图喂进网络,一次前向就出所有框
    → 速度快到能实时(30-100 FPS)

  云间书店选 YOLO:实时客流统计,速度优先

"检测选型:要精度选 Faster R-CNN,要速度选 YOLO。 客流统计要实时 → YOLO 是标准答案。面试常问两者区别,这个要背熟。"


三、YOLO 的原理:一次前向,框都出来

"YOLO 的核心思想:把图像分成网格,每个格子负责预测'中心落在这个格子的目标'。"老周画:

YOLO 原理(简化):
  ① 把图分成 S×S 网格(如 7×7)
  ② 每个网格预测:
     - 若干候选框(B 个)
     - 每个框:中心偏移 + 宽高 + 置信度
     - 每个框:各类别概率
  ③ 过滤:置信度低的丢掉
  ④ NMS:重叠的框合并(同一个物体只留一个)

  ┌───┬───┬───┬───┐
  │   │   │   │   │     人的中心在这个格子
  ├───┼───┼───┼───┤     → 这个格子负责"框出人"
  │   │ □ │   │   │
  ├───┼───┼───┼───┤     □ = 预测的框
  │   │   │   │   │
  └───┴───┴───┴───┘

  网格 + 多尺度(YOLOv3+):
    在不同尺寸的特征图上检测(大目标/小目标都行)
    → 小目标检测能力大幅提升

"YOLO = 网格负责制——'每个格子管好自己的辖区'。一次前向,所有格子一起报,所以快。这是 YOLO 的核心直觉。"


四、NMS:重复的框怎么合并

"同一个目标可能被预测出好几个框,怎么只留一个?NMS(非极大值抑制)。"老周说:

NMS(Non-Maximum Suppression)非极大值抑制:
  问题:一个人被框了 5 次(重叠的框)
  目标:只留"最准"的那一个

  流程:
    ① 按置信度排序,先留置信度最高的框
    ② 计算它和其余框的 IoU
    ③ IoU > 阈值(如 0.5)的框 = 重复 → 删掉
    ④ 对剩下的框重复 ①②③

  IoU(Intersection over Union)交并比:
    两个框重叠程度 = 交集面积 / 并集面积
    0 = 不重叠,1 = 完全重合
    IoU > 0.5 通常认为"是同一个目标"

  为什么需要 NMS:
    没有它,一个目标会输出一堆框(丑 + 重复计数)
    客流统计会"一个人数成三个人"

"NMS 是检测的'去重机制'——没有 NMS,检测结果没法用。IoU 概念在后面评估指标(mAP)里也用到,必须吃透。"


五、用 YOLO 做客流统计:实战代码

"现在动手:用现成 YOLO 模型(Ultralytics YOLOv8)做客流统计。"老周写:

# 安装
pip install ultralytics
from ultralytics import YOLO
import cv2

# 1. 加载预训练模型(COCO 数据集,80 类含 person)
model = YOLO("yolov8n.pt")       # n = 轻量版(快)

# 2. 图片检测
results = model("store_front.jpg")

# 3. 解析结果:框出"人"
img = cv2.imread("store_front.jpg")
for r in results:
    for box in r.boxes:
        x1, y1, x2, y2 = box.xyxy[0].tolist()   # 框坐标
        conf = box.conf[0].item()                # 置信度
        cls = int(box.cls[0].item())             # 类别
        name = model.names[cls]                  # 类别名

        if name == "person" and conf > 0.5:      # 只数人
            cv2.rectangle(img, (int(x1), int(y1)),
                          (int(x2), int(y2)), (0, 255, 0), 2)
            cv2.putText(img, f"{name} {conf:.2f}",
                        (int(x1), int(y1)-5),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 1)

# 4. 统计
num_people = sum(
    1 for r in results for b in r.boxes
    if model.names[int(b.cls[0])] == "person" and b.conf[0] > 0.5)
print(f"识别到 {num_people} 人")

cv2.imshow("result", img)
cv2.waitKey(0)
用现成模型的流程:
  下载预训练权重 → 推理 → 解析框 → 后处理
  重点:解析 YOLO 输出(xyxy/conf/cls)+ 按业务过滤

  完整客流统计(进阶,第十一章细讲):
    视频逐帧检测 → 目标跟踪(同一人给同一ID)
    → 画"越线计数"(进门+1)→ 统计时段客流

"2023 年起,用 Ultralytics 一行代码就能跑 YOLO——训练、推理、导出都封装好了。工程上'会用现成模型'比'手写检测器'重要得多。"


六、评估指标:mAP 怎么算

"检测模型好不好,看 mAP(mean Average Precision)。"老周说:

mAP(平均精度均值):
  检测评估核心指标

  先看"一次预测对不对":
    预测框 vs 真实框 IoU > 0.5(阈值)→ 算对(TP)
    IoU 不够 → 算错(FP)
    没预测到的真实目标 → 漏检(FN)

  精确率(Precision):预测的框里,多少是对的?= TP/(TP+FP)
  召回率(Recall):真实目标里,多少被找到了?= TP/(TP+FN)
  二者权衡:阈值高 → 精确率高召回低;阈值低 → 反过来

  AP:精确率-召回率曲线下的面积(一个类别一个 AP)
  mAP:所有类别 AP 的平均
  mAP@0.5:IoU 阈值 0.5 下的 mAP(常用)
  mAP@0.5:0.95:多个 IoU 阈值的平均(COCO 标准)

  怎么看:
    mAP 越高越好(0-1)
    云间书店场景:人检测 mAP@0.5 > 0.9 就很稳

"mAP 是检测的'体检报告'——面试必考、项目必用。记住:精确率管'准不准',召回率管'全不全',mAP 管'整体好不好'。"


七、章末:老周的第八章总结

第七层:目标检测
├── 任务:图里有什么 + 在哪(框+类别+置信度)
├── 两阶段:R-CNN 系(准,慢)/ 单阶段:YOLO(快,实时)
├── YOLO:网格负责制,一次前向出所有框
├── NMS:去重(IoU 交并比 > 0.5 = 同一目标)
├── 实战:Ultralytics YOLOv8 客流统计(数 person)
├── mAP:检测评估指标(精确率/召回率曲线面积)
└── 选型:实时视频用 YOLO(云间书店客流统计)
第九层(预告):图像分割 —— 把书架从背景里抠出来

"小陈,门口摄像头装上了——YOLO 把每个进门的人都框出来,客流数据唰唰地涨!"老周说,"但王姐看了监控又提新要求:'我想知道哪些区域人多,能不能把书架和人都分开显示?'——这就是图像分割:不只是框出人,而是把'每一块像素'分类。下一章,我们玩点更精细的。"

✌ 语言