4. 特征提取入门:Haar特征与积分图、HOG特征原理、LBP特征原理

好,咱们进入第四章。这一章可以说是整个交通标志识别系统的「眼睛」——特征提取。

你想想看,一张图片里像素点那么多,直接扔给分类器去学,效果往往很差。为什么?因为原始像素里包含太多噪声和冗余信息了。我们需要把图像里真正有用的「模式」提炼出来,这就是特征提取干的事。

我个人习惯把特征提取比作「画像」。你不需要把每根头发丝都画出来,只需要抓住五官比例、轮廓这些关键信息,就能认出一个人。今天咱们聊三种经典特征:Haar、HOG 和 LBP。它们各有各的脾气,也各有各的用武之地。

4.1 Haar特征与积分图

Haar特征,说白了就是计算图像中相邻矩形区域的像素灰度差。它最早被用在人脸检测上,Viola-Jones那个经典框架就是靠它吃饭的。

Haar特征有几种基本模板:边缘特征、线性特征、中心特征。比如一个两矩形的特征,左边白右边黑,计算白色区域像素和减去黑色区域像素和。这个差值能反映出图像的局部明暗变化。

举个例子,交通标志里的「禁止驶入」标志,红色圆环中间是白色。如果用Haar特征去扫,圆环边缘处就会产生强烈的响应。嗯,这里要注意,Haar特征对边缘、线条这类结构特别敏感。

核心思想: Haar特征 = 白色矩形像素和 - 黑色矩形像素和

但问题来了——你要在图像上滑动窗口,每个窗口要计算多个矩形区域的像素和。如果每次都从头加一遍,计算量会爆炸。怎么办?

积分图就是来救场的。它是个很巧妙的数据结构,能在常数时间内算出任意矩形区域的像素和。

积分图的定义很简单:

// 积分图每个位置的值 = 该位置左上角所有像素的和
integral(x, y) = sum(i<=x, j<=y) image(i, j)

有了积分图,要算任意矩形区域的和,只需要做三次加减法:

// 矩形区域 (x1,y1) 到 (x2,y2) 的像素和
sum = integral(x2, y2) 
    - integral(x1-1, y2) 
    - integral(x2, y1-1) 
    + integral(x1-1, y1-1)

我在项目中遇到过一个问题:用Haar特征做交通标志检测时,光照变化影响很大。同一个标志,晴天和阴天拍出来的Haar特征值能差好几倍。后来我做了归一化处理,才把效果稳住。

我的经验: Haar特征适合检测有明显边缘结构的物体,比如矩形标志牌、圆形标志。但它对旋转和尺度变化比较敏感,实际使用时需要配合多尺度扫描。

4.2 HOG特征原理

HOG,全称是Histogram of Oriented Gradients,方向梯度直方图。这玩意儿在行人检测领域一战成名,后来被广泛用在各种目标检测任务里。

HOG的核心思想是什么?图像的局部形状,可以用梯度方向分布来描述。说白了,就是看每个像素点周围是「朝哪个方向变亮或变暗」的。

HOG特征的提取步骤大致如下:

  1. 计算梯度: 用Sobel算子之类的,算出每个像素的水平梯度和垂直梯度,然后得到梯度幅值和方向。
  2. 划分细胞单元: 把图像分成一个个小格子,比如8×8像素为一个cell。
  3. 统计梯度方向直方图: 在每个cell里,把梯度方向分成9个bin(比如0-20度、20-40度...),按梯度幅值加权投票。
  4. 块归一化: 把相邻的几个cell组成一个block,对block内的直方图做归一化,抵抗光照变化。
  5. 串联特征: 把所有block的特征向量串起来,就是最终的HOG特征。

你可能会问:为什么要分cell和block两层?直接在整个图上统计不行吗?

其实不行。局部统计能保留空间信息,block归一化又能增强鲁棒性。我刚开始学的时候也觉得这步骤有点繁琐,但后来做实验发现,少一步效果就差一截。

关键参数: cell大小、block大小、bin数量、步长。这些参数直接影响特征的质量和维度。

我记得有一次做限速标志识别,用HOG特征配合SVM分类器,准确率能到95%以上。但HOG的缺点也很明显——特征维度高,计算慢。一个64×128的图像,HOG特征维度能到3780维。你想想看,实时处理视频流的时候,这个计算量可不小。

避坑指南: 我曾经在HOG的cell大小上栽过跟头。对于交通标志这种小目标,cell设太大(比如16×16)会丢失细节信息。建议从8×8开始调参。

4.3 LBP特征原理

LBP,Local Binary Pattern,局部二值模式。这玩意儿的特点是:计算简单、光照鲁棒性好、纹理描述能力强。

LBP的基本思想很直观:对每个像素,把它和周围的邻居像素做比较。邻居比它大就记为1,比它小就记为0。这样一圈比较下来,就得到一个二进制数,这个数就是该像素的LBP值。

// 原始LBP的计算(3×3邻域)
// 中心像素值为c,周围8个像素值为p0-p7
// LBP = sum( (pi >= c) ? 2^i : 0 )

举个例子,中心像素值是128,周围8个像素分别是[130, 120, 135, 110, 140, 115, 125, 132],比较后得到[1,0,1,0,1,0,0,1],对应的二进制就是10101001,十进制是169。

然后呢?对整个图像的所有像素计算LBP值,再统计直方图,这个直方图就是图像的LBP特征。

LBP有几个变体,我常用的有:

  • 圆形LBP: 不局限于3×3邻域,可以在任意半径的圆上采样,适应不同尺度的纹理。
  • 旋转不变LBP: 对LBP值做循环移位,取最小值,这样图像旋转后特征不变。
  • 均匀模式LBP: 只保留二进制串中0/1跳变次数不超过2的模式,能大幅降低特征维度。
我的建议: 做交通标志识别时,LBP特别适合用来提取标志内部的纹理信息。比如「禁止停车」标志里的斜杠纹理,用LBP就能很好地捕捉到。

三种特征各有千秋。我个人的经验是:

特征 优点 缺点 适用场景
Haar 计算快(配合积分图)、对边缘敏感 对光照和旋转敏感 人脸检测、简单形状检测
HOG 对形状描述能力强、抗光照好 维度高、计算慢 行人检测、交通标志识别
LBP 计算简单、光照鲁棒、纹理描述好 对噪声敏感、缺乏全局信息 纹理分类、人脸识别

在实际项目中,我经常把这几种特征组合起来用。比如用Haar做快速粗筛,再用HOG做精细分类。或者把HOG和LBP的特征向量拼接起来,形成一个更强的特征描述子。

好了,这一章的内容就到这儿。特征提取是计算机视觉的基石,把这些基础打牢了,后面做分类、检测才能得心应手。下一章咱们聊聊分类器的选择,到时候见。