【特征检测】HOG特征算法

【特征检测】HOG特征算法简介 nbsp nbsp nbsp nbsp HOG HistogramofO 的简写 特征检测算法 最早是由法国研究员 Dalal 等在 CVPR 2005 上提出来的 一种解决人体目标检测的图像描述子 是一种用于表征图像局部梯度方向和梯度强度分布特性的描述符 其主要思想是 在边缘具体位置未知的情况下 边缘方向的分布也可以很好的表示行人目标的外形轮廓 nbsp nbsp nbsp nbsp Dalal 等提出的 HOG

简介

        HOG(Histogram of Oriented Gridients的简写)特征检测算法,最早是由法国研究员Dalal等在CVPR-2005上提出来的,一种解决人体目标检测的图像描述子,是一种用于表征图像局部梯度方向和梯度强度分布特性的描述符。其主要思想是:在边缘具体位置未知的情况下,边缘方向的分布也可以很好的表示行人目标的外形轮廓。

        Dalal等提出的HOG+SVM算法,在进行行人检测取得了极大地成功后,更多新算法不断涌现,不过大都是以HOG+SVM的思路为主线。

HOG特征算法

        HOG特征检测算法的几个步骤:颜色空间归一化—>梯度计算—>梯度方向直方图—>重叠块直方图归一化—>HOG特征。下面分别对其进行介绍。

1、颜色空间归一化

        由于图像的采集环境、装置等因素,采集到的人脸图像效果可能不是很好,容易出现误检或漏检的情况,所以需要对采集到的人脸进行图像预处理,主要是处理光线太暗或太强的情况,这里有两次处理:图像灰度化、Gamma校正。

①图像灰度化

       对于彩色图像,将RGB分量转化成灰度图像,其转化公式为:

【特征检测】HOG特征算法

②Gamma校正

       在图像照度不均匀的情况下,可以通过Gamma校正,将图像整体亮度提高或降低。在实际中可以采用两种不同的方式进行Gamma标准化,平方根、对数法。这里我们采用平方根的办法,公式如下(其中γ=0.5):

【特征检测】HOG特征算法

代码:

int main() { Mat picture = imread("test.jpg", 0);//灰度 Mat img; picture.convertTo(img, CV_32F); //转换成浮点 sqrt(img, img); //gamma校正 normalize(img, img, 0, 255, NORM_MINMAX, CV_8UC1);//归一化像素值[0,255] imshow("原图", picture); imshow("Gamma校正", img); waitKey(); return 0; }

结果:

【特征检测】HOG特征算法【特征检测】HOG特征算法

2、梯度计算

对经过颜色空间归一化后的图像,求取其梯度及梯度方向。分别在水平和垂直方向进行计算,梯度算子为:

【特征检测】HOG特征算法

【特征检测】HOG特征算法

代码:

/* Copyright (c) 2015 Jingshuang Hu @filename:demo.cpp @datetime:2015.08.06 @author:HJS @e-mail: @blog:http://blog.csdn.net/hujingshuang */ #include 
  
    #include 
   
     #include 
    
      #include 
     
       #include 
      
        using namespace cv; using namespace std; int main() { Mat picture = imread("test.jpg", 0);//灰度 Mat img; picture.convertTo(img, CV_32F); //转换成浮点 sqrt(img, img); //gamma校正 normalize(img, img, 0, 255, NORM_MINMAX, CV_32F);//归一化[0,255]浮点数 Mat gradient = Mat::zeros(img.rows, img.cols, CV_32F);//梯度 Mat theta = Mat::zeros(img.rows, img.cols, CV_32F);//角度 for (int i = 1; i < img.rows - 1; i++) { for (int j = 1; j < img.cols - 1; j++) { float Gx, Gy; Gx = img.at 
       
         (i, j + 1) - img.at 
        
          (i, j - 1); Gy = img.at 
         
           (i + 1, j) - img.at 
          
            (i - 1, j); gradient.at 
           
             (i, j) = sqrt(Gx * Gx + Gy * Gy);//梯度模值 theta.at 
            
              (i, j) = float(atan2(Gy, Gx) * 180 / CV_PI);//梯度方向[-180°,180°] } } normalize(gradient, gradient, 0, 255, NORM_MINMAX, CV_8UC1);//归一化[0,255] 无符号整型 normalize(img, img, 0, 255, NORM_MINMAX, CV_8UC1); imshow("原图", picture); imshow("Gamma校正", img); imshow("梯度图", gradient); waitKey(); return 0; } 
             
            
           
          
         
        
       
      
     
    
  

结果:

【特征检测】HOG特征算法 【特征检测】HOG特征算法 【特征检测】HOG特征算法

3、梯度方向直方图

        将图像划分成若干个cells(单元),8×8=64个像素为一个cell相邻的cell之间不重叠。在每个cell内统计梯度方向直方图,将所有梯度方向划分为9bin(即9维特征向量),作为直方图的横轴,角度范围所对应的梯度值累加值作为直方图纵轴,每个bin的角度范围如下。

【特征检测】HOG特征算法

4、重叠块直方图归一化

        以下有关计算,请认真分析假设有一幅图像大小为220×310,将其划分成若干个8×8cells,显然220÷8=27.5、310÷8=38.75不是整数,也就是说划分之后依然还有多余像素不能构成cell。处理办法是将图像缩放成能被8整除的长宽(如216×304),再划分。216÷8=27304÷8=38,因此,216×304的图像可以得到27×38cells,没有重叠。

Mat picture = imread("test.jpg", 0);//灰度 resize(picture, picture, cvSize(int(picture.cols / 8) * 8, int(picture.rows / 8) * 8));//转化成能被8除尽的行、列

        由于图像中光照情况和背景的变化多样,梯度值的变化范围会比较大,因而良好的特征标准化对于检测率的提高相当重要。标准化的方法多种多样,大多数的都是将celll放在block中,然后标准化每个block

        以上述缩放后的图像为例,共得到27×38cell,也就是将图像划分成了27×38个单元;将上下左右相邻的2×2cells当做一个block整体,如下所示(为方便观察,每个颜色框故意错开了一点),黑色8×8像素为一个cell粉红绿框都是一个block,即每个框内2×2cell组成一个block。故27×38cell可划分成26×37block,每个block16×16像素。相邻block之间是有重叠的,这样有效的利用了相邻像素信息,对检测结果有很大的帮助。

【特征检测】HOG特征算法

接下分别对每个block进行标准化,一个block内有4cell,每个cell9维特征向量,故每个block就由4×9=36维特征向量来表征。

【特征检测】HOG特征算法

由于L2-norm简单且在检测中效果相对较好,故一般采用它。

        经过上述对有重叠部分block的直方图归一化之后,将所有block的特征向量都组合起来,则形成26x37x36=34632维特征向量,这就是HOG特征,这个特征向量就可以用来表征整个图像了。

        实际上,在运用的时候,我们通常是选取一幅图像中的一个窗口来进行特征提取,依然以上述220X310大小图像为例,经过缩放处理后为216×304,但并不直接提取整个图像的HOG特征,而是用一个固定大小的窗口在图像上滑动,滑动的间隔为8个像素,opencv中默认的窗口大小为128×64(高128,宽64),即有(128÷8)x(64÷8)=16×8cell,也即有15×7block,这样一来一幅图像就可以取到(27-16)x(38-8)=11×30=330(27-15)x(38-7)=12×31=372个窗口(更正于:2018-04-15)。现在提取每个窗口的HOG特征,则可得到105×36=3780HOG特征向量。

        将这3303780维的HOG特征当做测试样本,用支持向量机(SVM)分类器来判别出,这些窗口的HOG特征是否有行人,有行人的用矩形框标记起来。HOG行人特征及所对应的SVM分类器的参数,在opencv中已经训练好了,我们只需要得到HOG特征,然后调用SVM即可得到判别结果。

以上是个人对HOG算法的理解,若理解不到位或者有误的,请多多指教!

代码:

/* Copyright (c) 2015 Jingshuang Hu @filename:demo.cpp @datetime:2015.08.06 @author:HJS @e-mail: @blog:http://blog.csdn.net/hujingshuang */ #include 
  
    #include 
   
     using namespace cv; using namespace std; int main() { Mat image = imread("test.jpg"); // 1. 定义HOG对象 HOGDescriptor hog(Size(64,128),Size(16,16),Size(8,8),Size(8,8),9);//HOG检测器,用来计算HOG描述子的 // 2. 设置SVM分类器 hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); // 采用已经训练好的行人检测分类器 // 3. 在测试图像上检测行人区域 vector 
    
      regions; hog.detectMultiScale(image, regions, 0, Size(8,8), Size(32,32), 1.05, 1); // 显示 for (size_t i = 0; i < regions.size(); i++) { rectangle(image, regions[i], Scalar(0,0,255), 2); } imshow("HOG行人检测", image); waitKey(); return 0; } 
     
    
  

结果:

【特征检测】HOG特征算法

【特征检测】HOG特征算法

从图中可以看出,依然是有漏检的情况。

源码分析:

1、opencv源码解析之(6):hog源码分析

2、目标检测学习_1(用opencv自带hog实现行人检测)

3、HOG:从理论到OpenCV实践

4、opencv之HOG源代码注释

5、opencv之HOG源代码分析

参考资料:

1、维基百科:Histogram of oriented gradients

2、原论文:Histograms of Oriented Gradients for Human Detection

3、基于多特征的粒子滤波行人跟踪算法研究[M],张广西,2013.

4、基于HOG特征的人脸识别系统研究[M],穆春雷,2013.

5、基于HOG特征的目标识别算法研究[M],尚俊,2012.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201909.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午8:20
下一篇 2026年3月20日 上午8:20


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号