4.3 对象识别与分类


4.3 对象识别与分类

本节摘要:检测回答"在哪",分类回答"是什么"。本节走通传统分类闭环——数据准备、特征提取、模型训练、预测评估,用 HOG 或颜色直方图特征配合 SVM 完成一个可用的分类器;再看 DNN 分类模型的加载与 top-k 输出解读。核心观点:特征质量决定传统分类上限,数据质量决定深度分类上限。

学习目标

阅读完本节,你应当能够:

  1. 说清对象检测、对象分类、特征提取三个概念的分界
  2. 组织一份正负样本均衡的训练集并完成预处理统一
  3. 用 HOG 特征加 SVM 训练一个小型分类器并预测新样本
  4. 用 DNN 模块跑分类网络并解读 softmax 的 top-k 输出
  5. 用准确率、混淆矩阵评估分类器并定位薄弱类别

先跑起来:训练一个"方块 vs 圆片"分类器

不用公开数据集也能体会完整闭环。准备两类简单形状的图(或程序生成),各几十张:

import cv2 import numpy as np def extract_hog(img): hog = cv2.HOGDescriptor(_winSize=(64, 64), _blockSize=(16, 16), _blockStride=(8, 8), _cellSize=(8, 8), _nbins=9) return hog.compute(cv2.resize(img, (64, 64))).flatten() # X:所有样本的特征堆叠,y:对应标签 0 方块 1 圆片 X = np.float32([...]) # 每行一个 HOG 特征向量 y = np.int32([...]) svm = cv2.ml.SVM_create() svm.setType(cv2.ml.SVM_C_SVC) svm.setKernel(cv2.ml.SVM_LINEAR) svm.train(X, cv2.ml.ROW_SAMPLE, y) _, pred = svm.predict(np.float32([extract_hog(test_img)]))

结构一目了然:特征提取 → 堆成矩阵 → SVM 训练 → predict 预测。样本图片务必先统一尺寸(HOG 的窗口尺寸固定,64×64 是小目标常用档),这是新手最容易踩的格式坑——特征向量长度必须全样本一致,一张尺寸不同的图就会让训练直接崩。

预测一个没见过的新样本,输出 0 或 1,闭环完成。这个玩具规模只有两类、几十样本,但骨架与工业级传统分类器完全一致:换掉特征(颜色直方图、LBP、更精细的 HOG 配置)、换掉类别数,就是产线缺陷分类、纹理分类的真实起点。

核心原理:特征、模型与评估

2.1 三个概念的分界

  • 对象检测:找位置加给类别——"左上角有一只猫"。
  • 对象分类:给定一块已经裁好的区域,判断类别——"这团像素是猫"。
  • 特征提取:把像素翻译成分类器吃得下的数字——"这团像素的梯度分布是某个向量"。

检测与分类经常串联:检测器框出候选区域,分类器精判类别。第 4 章第 1 节的级联检测本质上就是"Haar 特征加一层层二分类"。分清概念的意义在于:系统误判时知道去哪个环节找原因——框不准是检测的问题,框得准但标签错才是分类的问题。

2.2 特征的选择:HOG、颜色、纹理各有领地

特征 捕捉什么 强项场景 弱项场景
HOG 梯度方向分布(形状) 形状主导:行人、标志、工件 颜色主导、形变大的目标
颜色直方图 色彩分布 颜色主导:水果分拣、土地覆盖 同色不同物(红苹果与红消防车)
LBP 纹理 局部二值模式 纹理主导:布料、表面缺陷 光照角度变化敏感

选特征的判断标准是"类别之间的差异体现在哪个维度"。方块与圆片差在形状,HOG 对症;橙子与苹果形状接近颜色有别,颜色直方图更直接。多个特征可以拼接成更长的向量,但维度灾难随之而来——样本数少时,先做特征选择或用 PCA 降维(OpenCV 的 PCA 类可用),而不是盲目拼接。

2.3 SVM:小样本时代的看家模型

SVM 在"特征几百到几千维、样本几百到几千个"的规模下表现稳定,核函数里 LINEAR 快而稳,RBF 核能拟合非线性边界但要调 C 与 gamma(网格搜索加交叉验证是标准做法)。OpenCV 的 ml 模块还提供 KNearest、RTrees、Boosting 等经典模型,接口形态一致。样本规模上万后,训练速度与精度的平衡点逐渐移向梯度提升树或直接上深度模型。

2.4 DNN 分类:拿来主义的正确姿势

深度分类不必自己训练。DNN 模块加载预训练网络(如 GoogLeNet、ResNet 的 ONNX 或框架格式),推理后拿到 softmax 概率分布:

blob = cv2.dnn.blobFromImage(img, 1.0, (224, 224), (104, 117, 123), swapRB=True, crop=False) net.setInput(blob) probs = net.forward().flatten() top = probs.argsort()[-5:][::-1] # top-5 类别索引

三个细节:均值参数 (104,117,123) 是该模型训练时的通道均值减除,属于"复刻训练预处理"铁律的应用;softmax 输出是全类别的概率分布,惯例看 top-5 而非只看第一名(ImageNet 有 1000 类,"柴犬"排第二"秋田"排第一不算失败);迁移学习(冻结主干只训最后分类层)可以在小数据集上定制类别,但训练要出 OpenCV 找深度学习框架,DNN 模块只管推理。

2.5 评估:不看混淆矩阵等于没评估

准确率是样本均衡时的概览指标,类别不均衡时会严重误导(99% 负样本时全预测负样本也有 99% 准确率)。混淆矩阵逐类别看漏检与误报的分布,找到"最容易被认成谁"的类别对,往往直接指向特征或样本的短板(两类形状太像、某一类样本太少)。训练前留出 20–30% 做测试集,交叉验证在小样本场景比单次划分可信。

工程实践要点

3.1 数据集的三个卫生习惯

样本量尽量均衡(每类至少几十张,相差悬殊时加权或重采样);训练与测试严格分离(测试集混进训练集得出的准确率是自欺);预处理全程统一(训练用了均衡化,线上推理也必须用)。三个习惯成本极低,违反的代价是模型"实验室九十分、上线六十分"。

3.2 从玩具到产线的升级路径

玩具分类器效果不好时的排查顺序:先看特征可视化(HOG 的 drawKeypoints 式诊断不存在,但可以对比两类特征的均值差异),再看样本质量与数量,最后才调 SVM 参数。多数失败在前两步——特征没选对维度,或样本覆盖不了实际光照姿态的变化。深度模型同理:数据质量与数量是第一变量,网络结构是第二。

3.3 类别设计也有取舍

100 类的大一统分类器常不如拆成"粗分类 5 类 + 每类内细分"的两级结构好维护。业务上近似的类别(同一工件的三种缺陷)合并训练再人工细分,往往比硬拆三类的精度更高。类别怎么设计,取决于下游怎么消费结果。

⚠️ 常见坑:特征向量里混入了不同尺寸样本导致长度不一致,训练时报维度错误——务必在特征提取前统一 resize。另一个坑是标签数组用了 float,SVM 的 predict 输出对不上,标签保持 int32。

💡 关键直觉:传统分类的上限由特征决定,深度分类的上限由数据决定。改进效果时先问"我喂给它的信息够不够分辨这些类别",再问"模型调参空间还有没有"——顺序反了就是无休止的调参内耗。

3.4 动手实验清单

  1. 程序生成方块与圆片各 100 张(加随机噪声与位置变化),跑通训练与预测,记录测试准确率。
  2. 把颜色直方图特征与 HOG 拼接,对比拼接前后的准确率变化,体会特征互补与维度代价。
  3. 故意让两类样本数量 1:9,观察准确率的虚假繁荣与混淆矩阵的真实惨状。
  4. 加载一个预训练 DNN 分类网络,对三张常见物体照片跑 top-5,观察概率分布的集中程度。

3.5 常见疑问与解答

SVM 训练很慢怎么办?

先查两点:特征维度是否虚高(几千维里一半是没区分力的维度,PCA 降维常能砍掉一大半而不掉精度)、样本里是否有大量近重复(清洗后训练快得多)。都排除后仍慢,换 LINEAR 核(RBF 的核矩阵计算是平方复杂度)、或减小 cache 参数重试。小数据集上这些手段通常够用。

训练集准确率很高、新样本很差,什么原因?

过拟合三嫌疑:训练测试混分(回到第 3.6 条的数据卫生)、特征里混入了"背景泄漏"(比如一类样本全在白墙前拍的特征里学到了墙)、样本多样性不足(只覆盖了一种光照姿态)。依次排查,第三个最常见,解法是补样本或做数据增强(翻转、亮度扰动、裁剪——注意增强要模拟真实变化,不是越多越好)。

深度模型的迁移学习在 OpenCV 里能做吗?

DNN 模块只推理不训练。想用自己的十类数据微调一个分类网络,去专业框架训练,完成后导出 ONNX 回来部署。OpenCV 在这条流水线里的角色是"最后一公里的推理引擎",分工明确。

分类器的类别数有上限吗?

传统方法受特征区分度限制,几十类是舒适区,上百类时手工特征的混淆急剧上升;深度模型在千类规模仍然从容(ImageNet 是千类竞赛起家的)。类别数过百,直接考虑深度方案,别在手工特征上硬撑。

3.6 实战配方:小样本缺陷分类的完整走法

工业缺陷分类是传统分类最典型的落地场景(缺陷样本稀缺、类别不均衡),用一套完整走法收束本节。

第一步定义类别。与产线工艺员一起把缺陷归并成"可分"的类别——划痕与压痕若总在同类位置出现且外观接近,先合并成"表面缺陷"大类,分得越细样本越不够。类别设计是分类系统的第一决策(本节 3.3)。

第二步采数据。每类至少五十张起步(能到一百五更好),覆盖不同光照角度与位置;正常品样本可以多采(它免费)。采集时同步记录拍摄条件,后续排查"换批次效果掉"时这是唯一的线索。

第三步选特征。表面缺陷的判别多在纹理与形状维度,LBP 或 HOG 起步;颜色敏感的缺陷(锈斑)加颜色直方图拼起来。特征向量用三十到五十张做可视化检查(不同类别的特征分布能分开再训,分不开换特征,别硬训)。

第四步训练与评估。SVM 线性核起步,八二分训练测试,混淆矩阵看薄弱类;类不均衡时给少数类加权。测试准确率过线后,再留一批"隔天的全新样本"做盲测——同一批采的样本互相相似,盲测才是真成绩。

第五步上线兜底。分类器输出置信度(SVM 的决策距离归一化),低于阈值的样本 routed 到人工复核而非硬给标签。缺陷检测的代价函数天然不对称(漏检流出损失大、误检只是多看一眼),兜底设计比再涨两个点准确率更有价值。

本节要点回顾

  • 三概念分界:检测给位置、分类给标签、特征做翻译;排错先定位环节再动手。
  • 特征按差异维度选:形状差用 HOG、颜色差用直方图、纹理差用 LBP,拼接要防维度灾难。
  • 闭环五步:数据卫生 → 特征提取 → 训练测试分离 → 评估看混淆矩阵 → 迭代补短板。
  • SVM 是小样本看家模型:几百样本几千维特征的规模下稳定,LINEAR 核优先,RBF 需调参。
  • DNN 分类是拿来主义:加载预训练网络、复刻预处理、看 top-k 概率;定制训练去专业框架。
  • 上限归属:传统分类拼特征,深度分类拼数据,改进顺序别颠倒。

静态图的所有武器都到手了。下一章把它们搬上时间轴:视频读取、背景减除与目标跟踪,一条从摄像头到跟踪结果的完整链路。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U