引言
计算机视觉(Computer Vision,CV)是让机器从图像或视频中提取结构化信息的学科。工业界真正落地一个 CV 需求时,难点往往不在某个模型,而在于把「业务问题」翻译成「一个定义清晰的任务」,再配上可度量的指标、可复现的数据管线和可运维的推理服务。很多项目失败并非因为网络不够深,而是任务定义含糊、指标与业务脱节、训练与线上分布不一致。
本文先给出 CV 任务的全景地图,再逐类拆解输入输出与评估指标,接着拆解从数据到上线的工程链路,最后用两个最小可运行示例把「读图到输出」和「批量评估」串起来。读完之后,你应该能为一个模糊需求选出正确的任务类型与评估指标。
目录
- 计算机视觉在工业界的定位
- 任务全景
- 分类任务的输入输出与指标
- 检测任务的输入输出与指标
- 分割任务的输入输出与指标
- 姿态、检索、OCR 与跟踪
- 从数据到上线的工程链路
- 可运行示例一:端到端推理
- 可运行示例二:批量评估与指标计算
- 选型与权衡
- 常见坑清单
- 数据集与基准
- 传统 CV 与深度学习的分工
- 硬件与算力规划
- 落地路线图
- 小结
1. 计算机视觉在工业界的定位
CV 的价值来自「用可控成本替代重复性人眼判断」。典型场景包括:
- 工业质检:表面缺陷检测、字符识别(OCR)、尺寸测量。
- 安防与交通:人脸识别、车牌识别、行人检测与多目标跟踪。
- 医疗影像:病灶分割、细胞计数、影像配准。
- 零售与互联网:商品识别、以图搜图、内容审核、虚拟试穿。
- 自动驾驶与机器人:障碍物检测、车道线分割、位姿估计、深度估计。
这些场景有三个共性:输入是像素、输出是结构化标签、对延迟和稳定性有硬约束。因此工程上要同时权衡精度、延迟、成本三件事,而不是只刷榜。一个在公开数据集上 SOTA 的模型,如果单帧要 200 毫秒,就直接出局实时质检场景。
2. 任务全景
CV 的任务可以按「输出粒度」排列,从整图一个标签,到每个像素一个标签,再到每个目标的每个关键点一个坐标。
| 任务 | 输入 | 输出 | 典型模型 | 主指标 |
|---|---|---|---|---|
| 图像分类 | 一张图 | 一个类别(或 N 个概率) | ResNet、EfficientNet、ViT | Top-1 / Top-5 Accuracy |
| 目标检测 | 一张图 | 若干 bbox + 类别 | YOLOv8/v11、Faster R-CNN | mAP@0.5 、mAP@0.5:0.95 |
| 语义分割 | 一张图 | 每像素类别 | U-Net、DeepLabv3+ | mIoU |
| 实例分割 | 一张图 | 每实例掩码 | Mask R-CNN、YOLOv8-seg | AP_mask、mAP |
| 全景分割 | 一张图 | 前景实例 + 背景语义 | Panoptic FPN | PQ |
| 姿态估计 | 一张图 | 关键点坐标 | HRNet、MediaPipe Pose | PCK、OKS、AP |
| 图像检索 | 一张图 | 相似图排序 | 度量学习 + FAISS | Recall@K、mAP |
| 深度估计 | 一张图 | 每像素深度 | MiDaS、Depth Anything | AbsRel、δ<1.25 |
| OCR | 一张图 | 文本串 + 位置 | DBNet + CRNN、PaddleOCR | 字符准确率、Hmean |
| 多目标跟踪 | 视频 | 轨迹 ID + bbox | ByteTrack、BoT-SORT | MOTA、IDF1 |
一个实际系统常常是多个任务的串联。例如「车牌识别」等于检测(定位车牌)+ 矫正(透视变换)+ OCR(识别字符);「智能货柜」等于检测 + 分类 + 跟踪。因此选型时先画数据流,再逐环节选模型,最后统一评估端到端指标,而不是各环节各自为战。
3. 分类任务的输入输出与指标
分类是最基础的任务:输入一张 H×W×3 的图,输出 C 维概率向量。工程上要注意:
- 输入尺寸通常固定为 224×224 或 384×384,ResNet-50 默认 224×224。
- 输出经 softmax 得到概率,线上常按阈值或 Top-K 决策。
- 类别不平衡时用加权交叉熵或 Focal Loss。
指标上,ImageNet 的参考值有助于判断模型是否正常:ResNet-50 约 76.1% Top-1 / 92.9% Top-5,EfficientNet-B0 约 77.1% Top-1,ViT-B/16 在 JFT 预训练后可达 84% 以上。Top-1 适合单标签,Top-5 用于衡量「大致方向对不对」。
4. 检测任务的输入输出与指标
检测要同时回答「在哪」和「是什么」。输出是若干 (x1, y1, x2, y2, class, score) 元组。核心概念:
- IoU:预测框与真实框的交并比,阈值 0.5 时判为命中。
- NMS:非极大值抑制,去掉重叠的冗余框,阈值通常 0.45 到 0.5。
- mAP@0.5 :IoU 阈值 0.5 下各类别 AP 的平均。
- mAP@0.5 :0.95:IoU 从 0.5 到 0.95、步长 0.05 取平均,是 COCO 主指标,更严格。
参考值:YOLOv8n 在 COCO 上约 37.3 mAP@0.5 :0.95,YOLOv8m 约 50.2;Faster R-CNN(ResNet-50-FPN)约 37.4。检测的工程难点在小目标与密集遮挡,详见目标检测与 YOLO 系列工程落地。
5. 分割任务的输入输出与指标
分割把标签细化到像素或实例:
- 语义分割:每像素一个类别,不区分同类不同个体。
- 实例分割:每个实例一个掩码,能数出「有几个」。
- 全景分割:前景用实例、背景用语义,统一表达。
指标上,语义分割看 mIoU,医学场景常用 Dice(F1),实例分割看 AP_mask。Cityscapes 上 DeepLabv3+ 约 80% mIoU 级别;COCO 上 Mask R-CNN(ResNet-50-FPN)约 34.6 AP_mask。分割的标注成本是检测的数倍,通常先用少量精细标注验证可行性,详见图像分割与实例分割。
6. 姿态、检索、OCR 与跟踪
- 姿态估计:输出人体关键点坐标,指标 PCK(正确关键点比例)与 OKS(目标关键点相似度)。HRNet-W32 在 COCO 上约 74.4 AP。
- 图像检索:把图编码成向量,用 FAISS 做近邻检索,指标 Recall@K 与 mAP。
- OCR:检测文本区域(DBNet)加识别字符(CRNN),指标是字符准确率与 Hmean。
- 多目标跟踪:给每帧的检测框分配稳定 ID,指标 MOTA 与 IDF1。
这些任务往往复用同一套骨干与数据管线,工程上应尽量统一预处理与推理框架,降低维护成本。
7. 从数据到上线的工程链路
一个可运维的 CV 系统包含六个阶段,任何一环断裂都会让线上效果崩塌。
7.1 需求与任务定义
先把业务语言转成可标注的任务。例如「找出画面里有没有人没戴安全帽」要拆成:目标检测(人、安全帽)+ 逻辑规则(人框内是否有安全帽框)。任务定义要明确:类别体系、最小可接受目标尺寸、可接受的误报与漏报比例。
7.2 数据采集与标注
采集要覆盖线上分布:不同光照、角度、分辨率、季节、设备。标注要写规范文档,明确边界框的贴合标准、遮挡与截断如何标。数据集格式(VOC XML、COCO JSON、YOLO txt)与工具(Label Studio、CVAT)的细节见数据标注与数据集工程。
7.3 训练与评估
训练要有固定的训练集 / 验证集 / 测试集划分,防止数据泄漏。评估指标必须与业务对齐:安全场景更看重召回率(漏报代价高),而推荐场景更看重精确率。训练策略与迁移学习见模型训练与迁移学习。
7.4 模型导出与优化
训练框架(PyTorch)与推理环境往往不同,需要导出为 ONNX、TensorRT、NCNN 等格式。导出后要做数值对齐验证,确认 FP32 与量化版本的输出误差在可接受范围。压缩与端侧部署见模型压缩与端侧部署。
7.5 服务化
把模型包成高吞吐低延迟的推理服务,支持动态批处理、多实例并发、灰度发布。细节见视觉服务化与推理加速。
7.6 监控与回流
线上要监控输入分布漂移、置信度分布、推理延迟与错误率。低置信度样本、人工复核样本应回流到标注队列,形成数据闭环。
8. 可运行示例一:端到端推理
下面的代码用 torchvision 加载 ImageNet 预训练的 ResNet-50,对一张图片做分类推理,输出 Top-5 类别与概率。它覆盖了「读图、预处理、前向、后处理」的完整链路。
import torch
import torch.nn.functional as F
from torchvision.models import resnet50, ResNet50_Weights
from PIL import Image
# 1. 加载预训练模型与配套的预处理
weights = ResNet50_Weights.IMAGENET1K_V2
model = resnet50(weights=weights).eval()
preprocess = weights.transforms() # resize 256 -> center crop 224 -> normalize
# 2. 读图并预处理(自动处理 BGR/RGB 与归一化,避免手写踩坑)
img = Image.open("dog.jpg").convert("RGB")
batch = preprocess(img).unsqueeze(0) # (1, 3, 224, 224)
# 3. 前向推理,禁用梯度以省显存
with torch.inference_mode():
logits = model(batch) # (1, 1000)
probs = F.softmax(logits, dim=1)[0] # (1000,)
# 4. 取 Top-5 并映射回类别名
categories = weights.meta["categories"]
top5_prob, top5_idx = probs.topk(5)
for prob, idx in zip(top5_prob.tolist(), top5_idx.tolist()):
print(f"{categories[idx]:<25s} {prob:.4f}")
# 5. 打印模型规模,便于评估部署成本
n_params = sum(p.numel() for p in model.parameters())
print(f"ResNet-50 params: {n_params / 1e6:.1f}M") # 约 25.6M
这段代码在 CPU 上单张推理约几十毫秒,在 T4 GPU 上可降到 5 毫秒以内。注意 weights.transforms() 自动带上与预训练一致的归一化参数,手写预处理时最常见的错误就是用了错误的均值方差或忘了 BGR 到 RGB 的转换。
9. 可运行示例二:批量评估与指标计算
上线前需要一套可复现的评估脚本。下面用 COCO 风格的方式计算分类准确率与检测的 IoU,便于把业务指标固定下来。
import torch
import numpy as np
from torchvision.models import resnet18, ResNet18_Weights
# --- 分类 Top-1 评估 ---
model = resnet18(weights=ResNet18_Weights.IMAGENET1K_V1).eval()
preprocess = ResNet18_Weights.IMAGENET1K_V1.transforms()
def top1_accuracy(images, labels):
correct = 0
with torch.inference_mode():
for img, y in zip(images, labels):
logits = model(preprocess(img).unsqueeze(0))
pred = int(logits.argmax(dim=1))
correct += int(pred == y)
return correct / len(labels)
# --- 检测 IoU 计算 ---
def iou(box_a, box_b):
# box 格式 [x1, y1, x2, y2]
xa, ya = max(box_a[0], box_b[0]), max(box_a[1], box_b[1])
xb, yb = min(box_a[2], box_b[2]), min(box_a[3], box_b[3])
inter = max(0, xb - xa) * max(0, yb - ya)
area_a = (box_a[2] - box_a[0]) * (box_a[3] - box_a[1])
area_b = (box_b[2] - box_b[0]) * (box_b[3] - box_b[1])
union = area_a + area_b - inter
return inter / union if union > 0 else 0.0
print(iou([0, 0, 10, 10], [5, 5, 15, 15])) # 25 / 175 ≈ 0.1429
把 IoU 与准确率封装成可复用的评估函数,是保证「训练指标」与「上线指标」一致的关键一步。
10. 选型与权衡
选型不是「哪个模型 SOTA 用哪个」,而是在约束下找可行解。
| 维度 | 倾向 | 代价 |
|---|---|---|
| 只要位置 | 检测 | 需要框级标注 |
| 要精确边界 | 分割 | 标注成本数倍于检测 |
| 极致实时 | 轻量检测 / 分类 | 精度下降 |
| 极致精度 | 大骨干 + 两阶段 | 延迟高、显存大 |
| 数据极少 | 迁移学习 + 增强 | 上限受限 |
| 类别频繁变化 | 开放词汇 / CLIP 类方法 | 推理更贵 |
几条实用原则:
- 能用分类解决就不要上检测;分类的标注与推理成本都低一个数量级。
- 目标极小(小于 32 像素)时,检测器要调高输入分辨率或改 anchor 设置,否则 mAP 断崖式下跌。
- 若标注预算有限,先做少量高质量标注验证可行性,再决定是否扩大。
- 端侧设备优先考虑量化友好的骨干(MobileNet、YOLO-n 系列),避免部署阶段返工。
- 优先复用现成预训练权重与成熟框架(torchvision、ultralytics、timm),把精力放在数据与业务逻辑上。
- 先确定推理硬件再选模型,避免训完发现端侧跑不动。
- 多任务系统尽量共享骨干与预处理,减少重复工程与内存占用。
- 指标要能离线复现,同一测试集、同一脚本,避免「口头指标」。
11. 常见坑清单
- 指标与业务脱节:只盯 mAP,忽略了业务最关心的漏报率。
- 训练集与线上分布不一致:实验室拍的数据与现场光照、角度差异巨大。
- 数据泄漏:同一段视频的相邻帧被分到训练集和验证集,验证指标虚高。
- 预处理不一致:训练用 RGB 归一化,线上用 BGR 未归一化。
- 忽略后处理:检测的 NMS 阈值、分类的阈值都会显著影响线上指标。
- 不监控漂移:上线后摄像头更换、季节变化导致分布漂移而无感知。
- 只测平均延迟:忽略 P99,尾延迟导致用户体验崩塌。
- 类别体系混乱:标注、训练、线上三处的类别顺序不一致。
- 盲目追新:换最新骨干的收益常常小于补齐难例数据的收益。
- 评估集污染:测试集被反复用于调参,最终指标不可信。
- 忽略硬件差异:在 A100 上调好的批大小搬到 T4 直接 OOM。
- 缺乏回滚:新模型上线没有灰度与回滚方案,出问题只能整体下线。
- 忘记固定随机种子:实验无法复现,团队沟通成本陡增。
- 忽略标注一致性:多人标注缺乏仲裁,噪声标签拖垮模型。
- 用错坐标系:标注用 xywh,推理输出 xyxy,混用导致框全错位。
12. 数据集与基准
选择数据集决定了你的模型上限与迁移起点。下表列出 CV 最常用的公开数据集。
| 数据集 | 规模 | 类别数 | 任务 | 典型用途 |
|---|---|---|---|---|
| ImageNet-1K | 128 万训练图 | 1000 | 分类 | 预训练骨干 |
| COCO | 33 万图 / 150 万实例 | 80 | 检测 / 分割 / 关键点 | 检测分割基准 |
| Pascal VOC | 约 1.1 万图 | 20 | 检测 / 分割 | 轻量实验 |
| Open Images | 900 万图 | 600 | 检测 | 大规模预训练 |
| Cityscapes | 5000 精细标注图 | 19 | 语义分割 | 自动驾驶 |
| COCO Keypoints | 20 万图 | 17 关键点 | 姿态估计 | 人体姿态 |
使用公开数据集有两点要注意:一是许可协议,商用前确认能否使用;二是域差异,公开数据上训好的模型直接搬到工业现场往往掉点严重,需要用少量现场数据微调。
13. 传统 CV 与深度学习的分工
深度学习并非万能,传统 CV 在若干场景仍是更优解:
- 几何变换与标定:相机标定、透视矫正、立体匹配,用解析方法比网络更准更稳。
- 可解释性与合规:需要给出确定性依据的场合,形态学与阈值法更易审计。
- 极小数据:样本只有几十张时,模板匹配与特征点方法比训网络更实际。
- 预处理:直方图均衡、去噪、色彩校正,作为深度模型的输入前处理。
实战里最常见的是混合方案:传统方法做预处理与几何校正,深度模型做语义判断,后处理再用规则兜底。例如车牌识别用透视变换矫正,再用检测加 OCR 识别。
14. 硬件与算力规划
算力决定了模型规模与批大小的上限。
| 平台 | 典型算力 | 适用场景 | 备注 |
|---|---|---|---|
| CPU(x86) | 数十 GFLOPS | 轻量分类、预处理 | 延迟高,做兜底 |
| NVIDIA T4 | 65 TFLOPS FP16 | 云端推理 | 支持 INT8,性价比高 |
| NVIDIA A10 / L4 | 125 / 121 TFLOPS FP16 | 云端推理 | L4 能效更好 |
| NVIDIA A100 | 312 TFLOPS FP16 | 训练与大批量推理 | 显存 40/80GB |
| Jetson Orin | 数十 TOPS | 边缘设备 | 功耗受限,需量化 |
| 手机 NPU | 数 TOPS | 端侧 | 算子支持有限 |
规划时要区分「训练算力」与「推理算力」:训练看显存与互连,推理看延迟、吞吐与能效。端侧部署优先选量化友好、算子支持广的模型,详见模型压缩与端侧部署。
15. 落地路线图
一个 CV 项目从零到上线,可以按下面的顺序推进,每一步都有明确的交付物:
- 需求澄清:写清业务目标、类别体系、可接受的误报漏报比例、延迟与硬件约束。
- 数据摸底:盘点现有数据量、分布与标注情况,判断缺口。
- 基线方案:用现成预训练模型加少量数据跑通端到端,得到一个可用的基线指标。
- 数据迭代:针对基线暴露的失败案例补采补标,做难例挖掘。
- 模型迭代:在数据到位后升级骨干或训练策略,通常收益小于数据迭代。
- 压缩与导出:量化、剪枝、导出 ONNX 或 TensorRT,验证数值一致性。
- 服务化:搭推理服务,做压测,确定批大小与并发数。
- 监控与回流:上线监控指标,建立低置信度样本回流机制。
经验上,第 4 步(数据迭代)的收益往往大于第 5 步(换模型)。把精力优先投在数据质量与分布覆盖上,比追逐最新网络结构更划算。
16. 小结
CV 工程的核心是把业务需求翻译成任务,再配上一套可度量的指标与可复现的管线。任务全景决定了「选什么」,工程链路决定了「能不能上线」,评估指标决定了「团队往哪优化」。记住主线:需求 → 任务 → 数据 → 训练 → 导出 → 服务 → 监控回流,任何一环缺失都会让系统在真实环境中失效。
延伸阅读
- OpenCV 图像基础与预处理 — 打通读图与预处理链路
- 目标检测与 YOLO 系列工程落地 — 检测任务的完整实战
- 计算机视觉基础入门 — 图像处理与 CNN 分类基础
- AI 计算机视觉专题 — 更广的算法视角
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。