如果你刚开始做机器视觉项目,多半会卡在同一个地方:图像能读进来了,灰度图、滤波、边缘这些基础操作也会了,结果一接手“检测玻璃有没有划痕”这类真实需求,瞬间不知道从哪下手。机器视觉里那个帮你把“能看到图”变成“能判断结果”的关键环节,就是特征提取。这篇系列开篇,我就把特征提取从头讲清楚——它到底在干什么、为什么缺了它项目做不成、主流方法有哪些、真实项目里怎么用,以及新手该怎么学。
1. 特征提取是什么?先定位它在机器视觉里的角色
1.1 机器“看”到的世界和你想的不一样
人眼看到一张照片,自动就会知道哪里有猫、哪里有划痕、哪里有螺丝。但相机和程序不是这么工作的。相机传给程序的不是“画面”,而是一个巨大的数值矩阵——以一台300万像素的工业相机为例,一张灰度图就是300万个0到255之间的整数排列成的二维数组。再把颜色算上,就是几百万甚至上千万个数字。
你要是直接把这堆数字丢给一个分类器去判断“有没有划痕”,会遇到非常现实的三重麻烦。第一重,维度实在太高,不光占内存,训练和推理的速度也扛不住;第二重,单个像素值对噪声和光照极其敏感,光源抖一下,大量像素跟着变,判断结果就飘了;第三重,也是最要命的:像素值本身不携带任何语义,你看着“知道这是边缘”,程序看着只是一个数字突然从100跳到200,它不知道这背后代表什么。这就是机器视觉领域常说的“语义鸿沟”,而特征提取正是用来填平这道鸿沟的。
1.2 什么是“特征”,什么是“特征提取”
“特征”这个词听着玄,其实可以一句话讲明白:它是图像里能够反映目标属性、又能把你关心的目标和别的东西区分开来的那种“关键模式”。比如一张玻璃划痕图,划痕区域和正常玻璃区域在灰度、纹理、梯度方向上都不太一样,这些不一样的地方就是特征。
而特征提取,就是从原始像素数据中把这部分关键模式提取出来,转换成一个更紧凑、更容易被算法处理的描述。你可以把它理解成给图像做“摘要”。就像你向朋友描述一个人,不会从发根到尾椎骨一寸一寸讲,而是说“黑短发、圆脸、戴黑框眼镜”——几个关键属性一讲,朋友就能在人群里认出来。特征提取干的就是这件事,它把一张图压缩成一段特征向量,这段向量保留了和任务相关的核心信息,同时又剔除了大量冗余和噪声。
1.3 特征提取处在视觉链路的哪个环节
完整的机器视觉链路一般是这样的:图像采集、预处理(去噪、增强、几何校正)、特征提取、特征选择或降维、分类或匹配、结果输出。特征提取处在中间偏前的位置,承上启下。
这个位置很微妙。上游如果没做好,图像本身不清晰、光照不均匀,那特征提取再强也“无米下锅”;下游如果不够好,特征提取得再精巧,分类器也发挥不出来。所以做视觉项目,一半精力其实都花在特征提取以及它上下游的配合上。很多新手以为特征提取只是可选的一步,实际上它是决定整个方案上限的地基——特征要是选跑偏了,后面算法调得再花哨也救不回来。
2. 特征提取解决的核心问题:降维、鲁棒性和语义化
2.1 降维:别让几百万维数据压垮你的算法
特征提取最直观的作用就是降维。一张300万像素的图,直接做分类就是一个300万维的输入向量。如果你用的是支持向量机、最近邻这类依赖距离计算的算法,几万张图进去,计算量直接爆炸;即便硬算完,高维空间里样本会变得极其稀疏,模型过拟合几乎是必然的。
提取特征之后,维度会大幅度降下来。举个例子,经典的行人检测方案里,一张64×128像素的输入图,提取HOG特征后得到的是一个3780维的向量;换成ORB特征,一张图也就几百个描述子。数据量从百万级降到几百到几千维,内存占用、训练时间、推理延迟全部下降一到两个数量级。这里要强调的是,降维不是简单粗暴地“砍数据”,而是用更紧凑的形式把和任务相关的判别信息保留下来,删掉那些对判断没帮助甚至有害的部分。
2.2 鲁棒性:光照变了、角度变了,特征依然稳定
工业现场最让人头疼的不是算法本身,而是环境不稳定。同一块玻璃,早上和下午的光照不同,相机位姿稍微偏一点,成像结果就差别很大。直接比较像素值的话,同一物体的两幅图可能被判定为完全不同的东西。特征提取的第二个核心目标就是增强鲁棒性。
常见的鲁棒性指标有这么几类:灰度不变性,像LBP这类纹理特征对光照的单调变化不敏感;尺度不变性,物体拉近拉远都能被认出来,SIFT就是代表;旋转不变性,物体旋转一定角度后还能匹配上,SIFT和ORB都具备;平移不变性,卷积神经网络通过池化在一定程度上能容忍位置移动。这个特性在项目里直接决定了系统稳不稳。但也要提醒一句,不变性不是白拿的,追求更多不变性往往意味着更重的计算量或更多误匹配。如果你的相机是固定安装的,产品位置也基本固定,就不必所有项目都上SIFT,用固定角度、固定距离下表现好且计算快的特征反而更合适。
2.3 语义化:让特征可以解释、可以被理解
除了降维和鲁棒性,特征提取还有一个不太被提起但很重要的价值:它把原本无法解释的像素数值,转换成了可以被“讨论”和“调优”的语义信息。当你看到LBP直方图在某一区间的分布明显偏高,你能判断出“这块区域纹理偏粗糙”,然后决定要不要增强光照或调整相机角度。
这一点在项目排查问题时特别有用。像素值不行,你只能怀疑“算法有问题”;有了特征,你能定位到“是纹理特征区分度不够,还是边缘特征被噪声干扰了”。做工程的人都知道,可解释性就是效率,特征提取给你提供的就是这种基于理解去调试的能力,这在深度学习叠加可解释技术之前,几乎是工业视觉里唯一靠谱的调试抓手。
3. 主流特征提取方法拆解:从边缘到深度学习
3.1 边缘与角点:Canny和Harris打开了几何特征的窗
边缘是图像里最基本的特征之一,它表示灰度发生剧烈变化的位置,对应物体的轮廓、表面的划痕、或者部件之间的分界线。Canny边缘检测是工程上最常用的实现,流程分四步:先用高斯滤波降噪,再计算每个像素的梯度幅值和方向,接着做非极大值抑制,让边缘变成单像素宽的“细线”,最后用双阈值检测和连接边缘。
Canny有两个关键参数:高阈值和低阈值。高阈值用于确定哪些是强边缘,低阈值用于把断断续续的弱边缘连接起来。实操时我的习惯是:先在小范围ROI区域里调参,观察边缘是不是连续、有没有把噪声也圈进来,定了合适的阈值范围再套到全图去跑。Harris角点则用来定位“两条边相交”的位置,是后续关键点检测、图像配准、目标定位的重要基础。
3.2 纹理特征:LBP为什么在工业缺陷检测里经久不衰
工业缺陷检测,比如玻璃划痕、织物破洞、金属表面的裂纹,本质上都是纹理异常检测。局部二值模式(LBP)在这方面非常经典,它比较某个像素和它周围8个邻域像素的灰度:邻域像素灰度大于等于中心像素记为1,小于记为0。这样按固定方向读取,8个二进制位组成一个0到255之间的LBP值。统计整张图的LBP值分布,就得到LBP直方图,这个直方图就能作为纹理特征描述符。
LBP最大的优点是对光照变化不敏感。比如玻璃在打光后不同位置亮度不均,但这种单调的灰度变化不会大幅改变局部的“大小关系”,所以LBP值相对稳定,而划痕造成的是局部纹理结构突变,在直方图上会产生明显分布差异。我在实际项目中验证过,如果用几百个样本训练深度学习模型,效果往往不稳定,但LBP直方图+简单的统计阈值,几百毫秒就能跑出结果,上线验证也快,非常适合小样本的工业场景。
3.3 梯度特征:HOG怎么成为目标检测的一代名将
方向梯度直方图(HOG)的核心思想是:物体局部区域内的梯度方向和强度分布,能很好地描述外形。它不像SIFT去找“点”,而是统计一组区域内梯度方向的分布,因此对整体的形状信息把握得特别好。
HOG提取流程大致是这样:把图像划分成小单元,常见是8×8像素的cell;在每个cell里计算每个像素的梯度大小和方向,把梯度方向划分成9个区间,按梯度大小加权投票,得到这个cell的方向直方图;然后把相邻2×2的cell组成一个block,在block内部做归一化,这一步能有效消除局部光照和阴影的影响;最后把整张图所有block的直方图串联起来,得到完整的特征向量。
HOG最经典的应用是行人检测,2005年Dalal和Triggs提出的HOG结合线性SVM方法,在当时直接把行人检测推到了一个新高度。即使在今天的工业场景里,HOG配合SVM依旧是很多表面缺陷分类、车辆检测项目的骨干方案,尤其是在训练样本不充裕的情况下非常能打。
3.4 关键点特征:SIFT和ORB让图像能够“对得上号”
很多场景要解决的是“找对应关系”的问题:同一物体在两张图中出现在不同位置、不同角度,要把它们对应起来,然后计算偏移量或者位姿。这就需要提取关键点特征。
SIFT(尺度不变特征变换)是这个领域最经典的算法。它先在尺度空间中检测极值点作为候选关键点,过滤掉低对比度和边缘响应的点,再为每个关键点分配主方向,最后计算一个128维的梯度直方图描述子。这个描述子的特点是:图像旋转30度、缩放50%、亮度发生很大变化时,描述子依然比较稳定,匹配准确率高。缺点是速度偏慢。
ORB则可以理解为“FAST角点检测+BRIEF描述子”的组合,它最大的优势是快,比SIFT要快一个数量级以上,适合实时性要求高的场景,比如机械臂抓取、视觉SLAM、增强现实。选型时我有条经验:如果现场帧率要求在30fps以上,又需要做特征匹配,ORB是优先选择;如果精度优先且离线处理,SIFT更稳妥。
3.5 深度特征提取器:从“设计特征”走向“学习特征”
2012年之后,卷积神经网络在大规模图像分类上取得突破,特征提取的范式也发生了转变。CNN里的一系列卷积层本质上就是一个特征提取器,前几层学到的是边缘、纹理等底层特征,中间层学到的是局部结构,深层学到的是部件和语义信息。
深度学习特征和传统手工特征的一个关键区别是:手工特征需要人来设计思路、调整参数,而CNN通过数据驱动自动学习出适配任务的特征表示。这个能力在大规模数据下非常强大,所以在人脸识别、目标检测、语义分割等领域,深度特征已经是主流。但它的代价也不小:需要大量标注数据、需要昂贵算力、特征的可解释性差。工业缺陷检测这种小样本场景,直接套深度学习常常会过拟合,效果反而不如传统特征。我的态度很明确:先用传统特征跑通流程,再在数据量支持的情况下考虑深度学习,不要一上来就往神经网络上冲。
4. 特征提取在真实项目里的落地推演
4.1 玻璃划痕检测:LBP直方图把“瑕疵”暴露出来
拿热词里提到的玻璃划痕检测来说,一套基于传统特征提取的方案可以这样落地。第一步是成像设计,用低角度光源照明,划痕区域会因为光散射产生和周围玻璃不同的灰度表现;第二步是预处理,用中值滤波去掉灰尘带来的细密噪声,再用对比度增强突出划痕;第三步是特征提取,在感兴趣区域里计算LBP直方图,同时统计划痕方向的连通域长度、面积占比等几何特征;第四步是判定,当直方图分布明显偏离正常样本范围、面积占比超过阈值时,判为NG。
这套方案的好处是,不需要大量带标注样本,只要几十张正常样本统计出阈值范围就能上线。实际部署的时候要注意,光源状态是决定成败的关键,光源衰减或者角度松动都会让特征分布发生变化,所以现场要定期维护光源,最好在软件里加入正常样本特征分布的监控告警。
4.2 产线元件定位:ORB特征点匹配算出精确位姿
另一个常见需求是让机械臂准确抓取工件,关键是要定位出工件在相机视野里的位置和旋转角度。用传统特征提取可以这样实现:离线阶段,对标准工件拍摄模板图,提取ORB特征点,组成模板描述子库;在线阶段,实时拍摄工件图像,同样提取ORB特征点,把实时特征和模板特征做匹配,得到一组对应点;然后通过RANSAC算法剔除误匹配,利用剩下的正确匹配点计算单应性矩阵,从矩阵中解出工件的位置和旋转角;最后把位姿发送给机械臂。
这个流程里最影响精度的是两点。一是光源和背景的稳定性,背景出现杂乱物体时会产生很多干扰特征点;二是“最小匹配点数”不能设太低,我一般要求至少保持20对以上有效匹配才进行计算,否则单应性矩阵很容易被噪声带偏。
4.3 表面缺陷分类:HOG+SVM是数据稀少时的救命稻草
当任务从“检出缺陷”升级到“区分缺陷类型”(比如漏底、划伤、脏污),就需要分类器出马了。在小样本场景下,HOG+SVM是非常经典且可靠的组合。做法是:采集每类缺陷图片各三五十张,做图像增强和数据扩增;对每张图做分块处理,对每个块提取HOG特征;把所有块特征串联作为整图的特征向量;用归一化后的特征向量训练一个线性SVM;在验证集上调整HOG的cell大小、block大小和SVM的正则化参数。
这套方法在样本量不足100张的情况下也能训练出可用的分类器,训练时间通常只有几秒到几分钟。相比之下,深度学习在这个数据规模下基本没法收敛。等到项目积累了上千张经过验证的标注样本,再考虑用CNN替代,才是稳妥的演进路径。
5. 新手怎么学特征提取:路线、工具与避坑心得
5.1 一条务实的机器视觉学习路线
如果你刚入门,我建议按这个顺序走。先打牢图像处理基础:灰度变换、滤波、阈值分割、形态学操作,这些是特征提取的前置条件。然后理解特征提取的数学动机:为什么降维、什么是不变性,这几个概念通了,后面看算法才不会一头雾水。接着用OpenCV逐个实现传统特征提取算法,从Canny、Harris到LBP、HOG、ORB,不要只看文档,一定要自己跑一遍并可视化成图。再往后把特征提取和分类器结合起来,做一个完整的场景实验,比如区分正常图像和有缺陷图像。等传统方法跑熟了,再去接触深度特征和预训练模型,会顺畅得多。
参考书方面,《机器视觉算法与应用》第二版是不少学校和培训机构的教材,覆盖面广,从成像原理到特征提取、匹配、深度学习都有,适合当工具书随手翻。关键是看书的时候要配合代码实操,只看不写代码,学完第二天基本就忘了。
5.2 工具到底怎么选
做特征提取,最常用的就是OpenCV,Canny、SIFT、ORB、HOG这些都有现成接口,适合快速验证。scikit-image的代码可读性比OpenCV好,LBP和HOG实现都很清晰,适合用来理解算法内部逻辑。Halcon、VisionPro这类商业视觉库在工业界用得很多,很多算子封装得很完善,但价格不低;如果目标是对接工业项目,读一读它们的文档和案例也很有帮助。别忘了Python生态下的matplotlib和NumPy,特征提取调试离不开可视化,把特征图打印出来看,很多问题一眼就能定位。
5.3 我踩过的三个坑,希望你别踩
第一个坑是只调算法,不控成像。很多新手拿到图就开始换算法调参数,辛辛苦苦调了一下午,其实问题出在光源直射产生反光,把特征完全破坏了。先解决成像质量,再去调特征提取,顺序不能反。
第二个坑是特征贪多求全。每个项目都想把HOG、LBP、SIFT全用上,特征维度堆到几万维,实际效果反而变差,又慢又容易过拟合。正确的做法是先用少量特征做快速验证,看哪个维度区分度最高,再考虑加特征或用PCA降维。
第三个坑是只会套函数不懂原理。OpenCV调用一下很简单,但遇到问题就不知道从哪排查。比如HOG特征突然不管用了,至少你要知道可能是归一化参数、cell大小或者光照预处理出了问题,这就是原理的价值。我每次调参的时候都会把中间结果打印出来看,拿特征图和原图叠加分析,几次下来对算法的理解就会深很多。
最后说点个人体会。做了这么多年视觉项目,我越来越觉得特征提取是机器视觉工程师的基本功,一点都不过时。很多朋友一上来就想学深度学习做识别,结果样本不够、效果忽好忽坏,回头发现传统特征提取加简单分类器反而稳得一批。你要是能把特征提取这套东西吃透,不管是做传统算法还是以后切深度学习,都会比别人顺畅很多。下一篇系列文章,我会结合实际代码,把HOG、LBP和ORB三种特征提取方法的实现细节和参数调优过一遍,到时候咱们一起跑代码,看特征图说话。