三种特征分类器Haar、LBP和HOG

最常用到的三种特征分别为Haar特征、LBP特征及HOG特征,三种特征描述了三种不同的局部信息:

  1. Haar描述的是图像在局部范围内像素值明暗变换信息;

  2. LBP描述的是图像在局部范围内对应的纹理信息;

  3. HOG描述的则是图像在局部范围内对应的形状边缘梯度信息。

    三种特征在图像处理和机器学习领域都得到了广泛的应用,在此做一个总结,方便后面复习。

版本历程

1) Haar:因为之前从OpenCV1.0以来,一直都是只有用haar特征的级联分类器训练和检测(当时的检测函数称为cvHaarDetectObjects,训练得到的也是特征和node放在一起的xml),所以在之后当CascadeClassifier出现并统一三种特征到同一种机制和数据结构下时,没有放弃原来的C代码编写的haar检测,仍保留了原来的检测部分。另外,Haar在检测中无论是特征计算环节还是判断环节都是三种特征中最简洁的,但是笔者的经验中他的训练环节却往往是耗时最长的。

2) LBP:LBP在2.2中作为人脸检测的一种方法和Haar并列出现,他的单个点的检测方法(将在下面看到具体讨论)是三者中较为复杂的一个,所以当检测的点数相同时,如果不考虑特征计算时间,仅计算判断环节,他的时间是最长的。

3) HOG:在2.4.0中才开始出现在该类中的HOG检测,其实并不是OpenCV的新生力量,因为在较早的版本中HOG特征已经开始作为单独的行人检测模块出现。比较起来,虽然HOG在行人检测和这里的检测中同样是滑窗机制,但是一个是级联adaboost,另一个是SVM;而且HOG特征为了加入CascadeClassifier支持的特征行列改变了自身的特征计算方式:不再有相邻cell之间的影响,并且采用在Haar和LBP上都可行的积分图计算,放弃了曾经的HOGCache方式,虽然后者的加速性能远高于前者,而简单的HOG特征也使得他的分类效果有所下降(如果用SVM分类器对相同样本产生的两种HOG特征做分类,没有了相邻cell影响的计算方式下的HOG特征不那么容易完成分类)。这些是HOG为了加入CascadeClassifier而做出的牺牲,不过你肯定也想得到OpenCV保留了原有的HOG计算和检测机制。另外,HOG在特征计算环节是最耗时的,但他的判断环节和Haar一样的简洁。


1、Haar特征

    最容易接触到Haar特征地方应该就是opencv自带的人脸检测器,所采用的就是Haar特征结合Adaboost算法来实现的,利用Haar特征表征人脸在局部范围内像素值的明暗变化信息,结合积分图技巧加速训练一个级联的Adaboost分类器。Haar特征表示如图1所示。

                                                                             图1 Haar特征(摘自博客[1])

    计算过程就是黑色矩形区域内像素值之和减去白色矩形区域内像素值之和,计算过程其实很简单。但是,直接计算的话,针对每一个矩形区域,我们都需要做一次循环,计算区域内像素之和,对每个位置进行滑窗遍历进行Haar特征提取会使得计算量爆炸,因此,一般Haar特征会配合积分图技术一起来使用。

    积分图计算如图2所示,经过计算后,积分图中每个点对应值Inter(x,y)为对应蓝色矩形区域像素值之和。

                       

                                                                           图2 积分图计算示意图

    当需要提取Haar特征时,我们需要计算矩形块中像素值之和时,我们只需要将其四个顶点对应于积分图中的值拿出来,做一个求和操作即可,计算过程如图3所示。

                                   

                                                               图3 利用积分图提取Haar特征原理示意图

    图3中S1区域为要提取特征区域,I1,I2,I3,I4分别对应四个顶点位置对应于积分图中的值,由积分图计算过程不难发现:

                                                                                    I_{1}=S_{1}+S_{2}+S_{3}+S_{4}

                                                                                           I_{2}=S_{2}+S_{4}

                                                                                               I_{3}=S_{4}

                                                                                          I_{4}=S_{4} + S_{3}

    因此,S_{1}=I_{1}-I_{2}-I_{4}+I_{3},一个矩形区域内像素累加求和计算转变成了几个值的加减运算,大大的提升了算法执行效率。

2、LBP特征

    LBP特征对于传统的人脸识别而言,应该是十分有效的。LBP特征提取的思路就是,图像中某一个物体应该包含有多个像素,而且像素与像素之间位置关系应该是连续的,也即是说,在空间位置上有关联的像素信息也是有关联的,因此,可以考虑利用在空间位置上邻近的像素来对当前像素进行二进制编码,这也就是LBP。

    常见的LBP有LBP,CS-LBP,Uniform-LBP,圆形LBP和旋转不变LBP等。

    2.1 LBP、CS-LBP和Uniform-LBP

    其中,LBP、CS-LBP和Uniform-LBP都是基于当前像素的八邻域来计算的,八邻域示意图如图4所示。

                                                                          

                                                                                      图4 八邻域示意图

    LBP计算公式为:

                                                         LBP_{n_{c}}=\sum_{i=0}^{7}2^{i}*f(I_{i}-I_{c}),f(x)=\left\{\begin{matrix} 1 & x>0\\ 0 & elsewise \end{matrix}\right.

    然而原始的LBP存在以下几个问题:

    1) 固定邻域内的编码,对于尺度比较敏感,例如,人脸尺寸发生变化,人脸编码会出现误差;

    2) LBP特征的维度为2^{8}=256维,特征维度过高;

    3)对于光照、旋转等因素敏感。

    针对上述问题,CS-LBP利用中心对称的思想对局部纹理进行描述,其计算公式为:

                                                      CS-LBP_{n_{c}}=\sum_{i=0}^{3}2^{i}*f(I_{i}-I_{i+4}),f(x)=\left\{\begin{matrix} 1 & x>0\\ 0 & elsewise \end{matrix}\right.

     不难发现CS-LBP特征的维度为2^{4}=16维,相较于传统的LBP,大大地降低了特征维度,大大提升了计算效率。同时,这种对称计算的方式,能够在一定程度上应对光照、旋转等因素。

    Uniform-LBP翻译过来可以是等价模式,作者Ojala的灵感来自于,通过大量实验发现:在实际图像中,绝大多数LBP模式最多只包含两次从1到0或从0到1的跳变,因此,在实际应用中,我们只需要统计那些跳变次数在[0,2]之间的二进制模式(这些LBP也称之为等价模式,即Uniform-LBP),经过统计发现,满足这样的LBP总共只有58种,这样,256维的LBP就变成了58维的Uniform-LBP了。

    2.2 圆形LBP和旋转不变LBP

    不难发现,无论是LBP、CS-LBP还是Uniform-LBP都是固定邻域内的编码,对于尺度较为敏感,圆形LBP采用圆形邻域取代3方形邻域,并且可以通过调整半径,将3x3大小领域扩展到任意大小邻域,如图5所示。

                                                                            图5 圆形LBP计算示意图(摘自博客[2])

    对于未落在整数位置的点,可以采用双线性插值来获取,圆形LBP可以在一定程度上缓解尺度因素引起的变化,但是对于旋转因素较为敏感,因此,在圆形LBP的基础上,研究者提出了旋转不变LBP。

    旋转不变LBP对应旋转不变指的是,将圆形领域进行旋转LBP编码,将最小的LBP编码值作为当前像素点的编码值,这样,当物体发生旋转时,能够提取到的LBP编码值具备一定的旋转不变性,旋转不变LBP示意图如图6所示。

                                                                             图6 旋转不变LBP计算示意图

    这里贴一下CS-LBP+Histogram统计的代码:

// (ni - ni+4)* pow(2, i)
Mat CSLBP(const Mat & src, double * lbp_hist, Mat &out)
{
    Mat img;
    src.copyTo(img);
    uchar UTable[16];
    // 计算二进制表示,并通过查表的方式,获取其对应的等价模式下的值
    for (int i = 1; i < img.rows - 1; i++)
    {
        for (int j = 1; j < img.cols - 1; j++)
        {
            uchar code = 0;
            for (int m = 0; m < 4; m++)
            {
                code |= (src.at<uchar>(i - 1, j - 1) >= src.at<uchar>(i + 1, j + 1)) << 0;
                code |= (src.at<uchar>(i, j - 1) >= src.at<uchar>(i, j + 1)) << 1;
                code |= (src.at<uchar>(i + 1, j - 1) >= src.at<uchar>(i - 1, j + 1)) << 2;
                code |= (src.at<uchar>(i + 1, j) >= src.at<uchar>(i - 1, j)) << 3;
            }
            img.at<uchar>(i, j) = code;
        }
    }
     out = img;
    for (int i = 1; i < img.rows - 1; i++)
    {
        for (int j = 1; j < img.cols - 1; j++)
        {
            UTable[img.at<uchar>(i, j)]++;
        }
    }
 
    // 查找最大值
    float max_hist_val = 0;
    for (int i = 0; i < 16; i++)
    {
        if (max_hist_val < UTable[i])
        {
            max_hist_val = UTable[i];
        }
 
    }
    //cout << max_hist_val << endl;
 
    for (int i = 0; i < 16; i++)
    {
        lbp_hist[i] = 1.0 * UTable[i] / max_hist_val;
        //cout << "lbp_hist: " << lbp_hist[i] << endl;
    }
 
 
    Mat LBP_hist = Mat::zeros(32, 17 * 2, CV_8U);
    Mat LBP_hist_color;
    cvtColor(LBP_hist, LBP_hist_color, COLOR_GRAY2BGR);
    for (int i = 0; i < 16; i++)
    {
        //cout << 1 - UTable[i] << endl;
        rectangle(LBP_hist_color,
            Point(i * 2, 32),
            Point((i + 1) * 2, int((1 - lbp_hist[i]) * 32)),
            Scalar(255, 0, 0));
    }
    return LBP_hist_color;
}

    其余几种LBP,可以参考博客[4]。

3、HOG特征

    HOG特征也是一种被广泛应用的特征,这种特征最早用于行人检测领域。当然,方法都是可以相互借鉴的,在另外一个十分著名的开源库dlib中,人脸检测采用的就是HOG特征训练一个SVM分类器的思路来做的,经过评测,对比opencv的haar特征+Adaboost的做法,HOG+SVM会更加准确,当然,在速度上来说haar+Adaboost会更快。

   由于梯度主要对应于图像中的边缘, HOG的基本思路就是统计目标物体的局部形状边缘梯度信息,主要计算步骤如下:

   1) gamma变换:降低局部阴影和光照变化影响;

   2) 梯度计算:利用一阶或二阶差分近似计算图像梯度及方向

    梯度分量计算:

                                            \left\{\begin{matrix} dx= f(x+1,y)-f(x-1,y)&direction\ of \ x \\ dy=f(x,y+1)-f(x,y-1)&direction\ of\ y \end{matrix}\right.

    梯度和方向计算:

                                                                  \left\{\begin{matrix} gradient= \sqrt{dx^{2}+dy^{2}}\\ \theta=atan(\frac{dy}{dx})\end{matrix}\right.

   3) 方向划分:

    这个步骤实际上做的就是将方向对应角度区间离散化及模糊处理。首先,将方向对应角度无符号化,其实本质上就是将位于一条直线上的两个方向都视为一个角度,也即是\theta\theta-\pi视为同一个角度,其中\theta>0,这样方向范围就变成了[0,\pi];然后,将角度范围均等划分为9个bins,每一个bin对应一个角度,所有bins对应的角度为:

                                                                [0,\pi /9,2\pi /9,3\pi /9,...,8\pi /9]

    4) 梯度直方图统计:

    做梯度方向统计时,为什么要考虑对应梯度值?原因很简单,因为实际上,一个像素的梯度值越大,该像素为边缘的可能性越大,在做梯度方向统计时,会考虑到对应梯度值进行加权,然而,加权过程中存在方向位于方向划分的边界上,这个时候就将梯度平均到对应两个区间,计算过程如图7所示。

                                                            图7 梯度直方图计算示意图(摘自参考文献[3])

     例如,红色虚线对应部分,梯度方向\theta\pi /18,这时就将梯度值4平均划分给0和\pi /9对应bin,对应于0度和20度bin各自增加2。如果当前梯度方向\theta位于bins[i]bins[i+1]之间时,将梯度用插值的方式进行分配统计,统计过程如图8所示。

       

                                                                 图8 梯度直方图计算方式(摘自参考文献[3])

    计算过程如下:

                                                                          0:\frac{165-160}{20}*20=21.25

                                                                         160:\frac{180-165}{20}*20=63.75

    而单个像素的梯度对于噪声比较敏感,直接对每一个像素梯度进行统计,得到的特征可能不够鲁棒,因此,将图像进行分块统计,HOG原文是将图像划分为8x8大小的cell,cell的个数为:

                                                                          img.width/8*img.height/8

    为进一步降低HOG特征对于噪声、光照等因素的影响,将cell进一步组合,将2x2个cell组合成一个block,然后对block进行归一化处理。组合过程如图9所示。

                                                                          

                                                                   图9 cell组合成block过程示意图(摘自文献[3])

    组合完之后,每个block表示的向量大小为4x9=36,如果图片大小为128x64,那么cell的个数为:128/8x64/8=16x8,对应block个数为:(16-2+1)*(8-2+1)=15x7=105个,因此,最终得到hog特征的维度为36x105=3780维。

    

~~~~未完待续,后面补充代码及应用。

参考文献:

[1] https://blog.csdn.net/xiaowei_cqu/article/details/8216109

[2] https://blog.csdn.net/kuweicai/article/details/79039218

[3] https://www.learnopencv.com/histogram-of-oriented-gradients/

[4] https://blog.csdn.net/lsq2902101015/article/details/48680779

 

 

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是您的第一个问题:掌握经典图像特征描述符HOGLBP、Haar-like的基本原理和各自特点。 1. HOG(Histogram of Oriented Gradients) 特征描述符 HOG 特征描述符是一种用于在图像中检测对象的特征描述符。其基本原理是通过计算图像中每个像素点的梯度方向和大小,然后将其转换为每个像素所在区域的直方图。这些直方图在后续的分类器中使用。HOG 特征描述符最常用于行人检测和人脸检测。 HOG 特征描述符的特点是:它对于光照、旋转和缩放的变化具有一定的不变性。 2. LBP(Local Binary Pattern) 特征描述符 LBP 特征描述符是一种用于在图像中检测纹理的特征描述符。其基本原理是通过比较每个像素的灰度值与其周围像素的灰度值,将这些比较结果组成一个二进制编码的模式。这些模式在后续的分类器中使用。LBP 特征描述符最常用于人脸检测和纹理分类。 LBP 特征描述符的特点是:它对于光照和噪声的变化具有一定的不变性。 3. Haar-like 特征描述符 Haar-like 特征描述符是一种用于在图像中检测边缘和纹理的特征描述符。其基本原理是通过计算图像中不同大小和形状的矩形区域的灰度值之和的差异,将这些差异组成一个特征向量。这些特征向量在后续的分类器中使用。Haar-like 特征描述符最常用于人脸检测。 Haar-like 特征描述符的特点是:它对于光照变化具有一定的不变性。 这些特征描述符可以用于图像分类、物体检测和目标跟踪等任务。 接下来是您的第二个问题:利用这些特征描述符进行特征提取,编程实现基于Adaboost的目标检测算法。 基于Adaboost的目标检测算法是一种经典的机器学习算法,它可以使用上述特征描述符进行特征提取,并在后续的分类器中使用。下面是该算法的步骤: 1. 收集样本数据,并将其标记为正样本或负样本。 2. 提取样本数据的特征描述符,包括HOGLBP和Haar-like等。 3. 使用Adaboost算法进行特征选择和分类器训练。 4. 使用训练好的分类器对新的图像进行目标检测。 在具体实现时,可以使用Python语言和OpenCV库来实现该算法。其中,OpenCV库提供了各种特征描述符的实现,以及Adaboost算法的实现。下面是一个简单的示例代码: ``` python import cv2 # 加载正样本和负样本数据 positive_samples = [] negative_samples = [] # 提取HOG特征描述符 hog = cv2.HOGDescriptor() # 提取LBP特征描述符 lbp = cv2.CascadeClassifier() # 提取Haar-like特征描述符 haar = cv2.CascadeClassifier() # 训练分类器 classifier = cv2.CascadeClassifier() # 加载待检测的图像 image = cv2.imread() # 进行目标检测 rects = classifier.detectMultiScale(image) # 输出检测结果 for rect in rects: cv2.rectangle(image, rect, (0, 255, 0), 2) cv2.imshow('Object Detection', image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 以上代码仅供参考,具体实现方式可以根据实际需求进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值