文章目录

    • 背景
    • HOG特征描述符
    • 方法概述
    • HOG算法优缺点
    • 实例讲解
  • 参考资料

背景

  梯度直方图HOG(Histogram of Oriented Gradients)是法国人Dalal在2005年CVPR会议上提出的特征提取算法,并将其与 SVM 配合,用于行人检测。(论文地址:Histograms of oriented gradients for human detection。)

HOG特征在图像手工特征提取方面具有里程碑式的意义,当时在行人检测领域获得了极大成功。

HOG特征描述符

  在一副图像中,局部目标的外表和形状(appearance and shape)局部梯度的分布很好的描述,即使我们不知道对应的梯度和边缘的位置(本质:梯度的统计信息,梯度主要存在于边缘edge或角落corner的地方)。

  特征描述符就是通过提取图像的有用信息,并且丢弃无关信息来简化图像的表示。HOG特征描述符可以将3通道的彩色图像转换成一定长度的特征向量。

  在HOG特征描述符中,梯度方向的分布,也就是梯度方向的直方图被视作特征。图像的梯度(x和y导数)非常有用,因为边缘和拐角(强度突变的区域)周围的梯度幅度很大,并且边缘和拐角比平坦区域包含更多关于物体形状的信息。

  HOG算法的主要目的是对图像进行梯度计算,统计图像的梯度方向和梯度大小。 他提取的边缘和梯度特征能够很好的抓住局部形状的特点,并且因为对图像做了Gamma校正和采用cell方式进行归一化处理,对几何和光学变化都有很好的不变性,变换或旋转对于足够小的区域影响很小。

方法概述

  基本思路是将图像划分为很多小的连通区域,即细胞单元Cell,然后对Cell的梯度幅值和方向进行投票统计,形成基于梯度特性的直方图。把直方图在图像更大的范围内(又名区间或者Block)进行归一化。归一化的块描述符叫做HOG描述子(feature descriptor)。将检测窗口中的所有块的HOG描述子组合成最终的特征向量。然后使用SVM分类器进行目标和非目标的二分类(检测)。


HOG算法优缺点

优点

  • 核心思想是所检测的局部物体外形能够被梯度或边缘方向的分布所描述,HOG能较好地捕捉局部形状信息,对几何和光学变化都有很好的不变性;

  • HOG是在密集采样的图像块中求取的,在计算得到的HOG特征向量中隐含了该块与检测窗口之间的空间位置关系。

缺点

  • 特征描述子获取过程复杂,维数较高,导致实时性差;

  • 很难处理遮挡问题,人体姿势动作幅度过大或物体方向改变也不易检测(这个问题后来在DPM中采用可变形部件模型的方法得到了改善);

  • 跟SIFT相比,HOG没有选取主方向,也没有旋转梯度方向直方图,因而本身不具有旋转不变性(较大的方向变化),其旋转不变性是通过采用不同旋转方向的训练样本来实现的;

  • 跟SIFT相比,HOG本身不具有尺度不变性,其尺度不变性是通过缩放检测窗口图像的大小来实现的;

  • 由于梯度的性质,HOG对噪点相当敏感,在实际应用中,在block和Cell划分之后,对于得到各个区域,有时候还会做一次高斯平滑去除噪点。

实例讲解

以下面这张图片为例(宽高为100x200),进行计算HOG特征描述符的具体步骤。

图像预处理

  预处理包括灰度化和Gamma变换。灰度处理是可选操作,因为灰度图像和彩色图像都可以用于计算梯度图。
  对于彩色图像,先对三通道颜色值分别计算梯度,然后取梯度值最大的那个作为该像素的梯度。然后进行伽马矫正,调节图像对比度,减少光照对图像的影响(包括光照不均和局部阴影),使过曝或者欠曝的图像恢复正常,更接近人眼看到的图像。

梯度计算

为了得到梯度直方图,那么首先需要计算图像水平方向和垂直方向梯度。可以通过使用以下内核过滤图像实现,分别用于计算水平梯度和垂直梯度。
一般使用特定的卷积核对图像滤波实现,可选用的卷积模板有:sobel算子、Prewitt算子、Roberts模板等等。

可以使用内核大小为1的sobel算子获取相同结果,OpenCV也是如此。利用sobel水平和垂直算子与输入图像卷积计算 ,进一步得到图像梯度的幅值.

图像梯度的方向:

θM=arctan(dy/dx)\theta_M = arctan(d_y/d_x) θM​=arctan(dy​/dx​)

注意的是:梯度方向和图像边缘方向是互相正交的。


import cv2
import numpy as np# Read image
img = cv2.imread('*.jpg')
img = np.float32(img) / 255.0  # 归一化# 计算x和y方向的梯度
gx = cv2.Sobel(img, cv2.CV_32F, 1, 0, ksize=1)
gy = cv2.Sobel(img, cv2.CV_32F, 0, 1, ksize=1)# 计算合梯度的幅值和方向(角度)mag, angle = cv2.cartToPolar(gx, gy, angleInDegrees=True)

梯度图

第一个图:x-梯度的绝对值,第二个图:y梯度的绝对值 ,第三个图:梯度的幅值,第四个图:角度。

注意:x-梯度在垂直线触发,y-梯度在水平线触发。梯度的幅值在有密集的剧烈改变时触发。当区域很平缓时,梯度没有明显变化。梯度图除去了很多不必要的信息(例如有颜色的背景),强调凸显线条。当你看到梯度图像,很容易想到这张图片有一个人。
在每个像素点,梯度有一个幅值和方向。对于有颜色的图像,计算三通道的梯度(如上图所示)。一个像素点的梯度的幅值是三通道中梯度幅值最大的值,角度也是最大梯度对应的角度。

计算梯度直方图

此时,每一个像素点具有两个值:梯度幅值和梯度方向。

在这一步中,图像被分成若干个8×8的Cell,如下图所示,例如我们将图像resize至64x128的大小,那么这幅图像就被划分为8x16个8x8的Cell单元,并为每个8×8的Cell计算梯度直方图。当然,Cell的划分也可以是其他值:16x16,8x16等,根据具体的场景确定。

为什么要把图像分为若干个Cell?

这是因为如果对一整张梯度图逐像素计算,其中的有效特征是非常稀疏的,不但运算量大,而且会受到一些噪声干扰。使用特征描述符便提供了紧凑的表示。一个8x8的图像块包含8x8x3=192个像素值。一个8x8的Cell包含了8x8x2 = 128个值(每个像素包括梯度的大小和方向)。128个值将由9-bin的直方图(存储9个值的向量,想想坐标应该就明白了)。同时,计算Cell上的梯度直方图更具鲁棒性。逐像素计算梯度会产生噪音,直方图表示对噪音更不敏感。

在HOG中,每个8x8的Cell的梯度直方图本质是一个由9个数值组成的向量, 对应于0、20、40、60…160的梯度方向(角度)。那么原本Cell中8x8x2 = 128个值就由长度为9的向量来表示,用这种梯度直方图的表示方法,大大降低了计算量,同时又对光照等环境变化更加地鲁棒。

如下图所示,左图是衣服64x128的图像,被划分为8x16个8x8的Cell;中间的图像表示一个Cell中的梯度矢量,箭头朝向代表梯度方向,箭头长度代表梯度大小。

右图是 8×8 的Cell中表示梯度的原始数值,注意角度的范围介于0到180度之间,而不是0到360度, 这被称为“无符号”梯度,因为两个完全相反的方向被认为是相同的。 和 是相同的。(经验表明这样处理对于行人检测效果更好。)

接下来,计算Cell中像素的梯度直方图,将0-180度分成9等份,称为9个bins,分别是0,20,40…160。然后对每个bin中梯度的贡献进行统计:

这里采用加权投票统计,比如上面方向图中蓝圈包围的像素,角度为80度,这个像素对应的幅值为2,所以在直方图80度对应的bin加上2。红圈包围的像素,角度为10度,介于0度和20度之间,其幅值为4,那么这个梯度值就被按比例分给0度和20度对应的bin,也就是各加上2。


再比如:(如上图所示)某像素的梯度幅值为13.6,方向为36,36度两侧的角度bin分别为20度和40度,那么按一定加权比例分别在20度和40度对应的bin加上梯度值,加权公式为:

  • 20度对应的bin:((40-36)/20) x13.6,分母的20表示20等份,其中4份给20度对应的bin;

  • 40度对应的bin:((36-20)/20) x13.6,分母的20表示20等份,其中16份给20度对应的bin;

还有一个细节需要注意,如果某个像素的梯度角度大于160度,也就是在160度到180度之间,那么把这个像素对应的梯度值按比例分给0度和160度对应的bin。如左下图绿色圆圈中的角度为165度,幅值为85,则按照同样的加权方式将85分别加到0度和160度对应的bin中。

对整个Cell进行投票统计,最终得到9-bin直方图:

Block归一化
HOG特征将8×8的一个局部区域作为一个Cell,再以2×2个Cell作为一组,称为一个block,也就是说一个block表示16x16的区域。

由于每个Cell有9个值,一个block(2×2个Cell)则有36个值,HOG是通过滑动窗口的方式来得到block的,如下图所示:


为什么需要分Block呢?

我们已经为图像的8×8单元构造了基于梯度的直方图,但是图像的梯度对整体光照很敏感。这意味着对于特定的图像,图像的某些部分与其他部分相比会非常明亮。虽然不能从图像中完全消除,但是可以通过使用16×16个块来对梯度进行归一化来减少这种光照变化的影响。比如通过将所有像素值除以2来使图像变暗,那么梯度幅值将减小一半,因此直方图中的值也将减小一半。

接下来对Block进行归一化。(再再再一次强调,归一化的目的是为了降低光照/迁移的影响):

归一化的方法有很多:L1-norm、L2-norm、max/min等等,一般选择L2-norm。

例如对于一个[128,64,32]的三维向量来说,模长是:
1282+642+322=146.64\sqrt{128^2+64^2+32^2 } = 146.64 1282+642+322​=146.64

这叫做向量的L2范数。将这个向量的每个元素除以146.64就得到了归一化向量 [0.87, 0.43, 0.22]。
现在有一个新向量,是第一个向量的2倍 [128x2, 64x2, 32x2],也就是 [256, 128, 64],我们将这个向量进行归一化,你可以看到归一化后的结果与第一个向量归一化后的结果相同。所以,对向量进行归一化可以消除整体光照的影响。
知道了如何归一化,现在来对block的梯度直方图进行归一化(注意不是Cell),一个block有4个直方图,将这4个直方图拼接成长度为36的向量,然后对这个向量进行归一化。
因为使用的是滑动窗口,滑动步长为8个像素,一个Cell大小,每滑动一次,就在这个窗口上进行归一化计算得到长度为36的向量,并重复这个过程。如上图所示。

获得HOG描述子
每一个16x16大小的block将会得到一个长度为36x1的特征向量,并进行归一化。那会得到多大的特征向量呢?
对于上图被划分8 x16个Cell ,每个block有2x2个Cell的话,那么Cell的个数为:(8-1)x(16-1)=105。

每个16x16 block由36x1维向量,合并所有105个block的特征,最终得到由36 x105=3780维向量表示的特征描述符。

获得HOG特征向量,就可以用来可视化和分类了。对于多维的HOG特征,SVM就可以排上用场了。

介绍以下Dalal等人的训练方法:

  1. 提取正负样本的HOG特征;

  2. 用正负样本训练一个初始的分类器,然后由分类器生产检测器;

  3. 然后用初始分类器在负样本原图上进行行人检测,检测出来的矩形区域自然都是分类错误的负样本,这就是所谓的难例(hard examples);

  4. 提取难例的HOG特征并结合第一步中的特征,重新训练,生成最终的检测器

这种二次训练的处理过程显著提高了每个检测器的表现,一般可以使得每个窗口的误报率(FPPW False Positives Per Window)下降5%。

使用HOG特征数据
HOG特征本身是不支持旋转不变性与多尺度检测的,但是通过构建高斯金字塔实现多尺度的开窗检测就会得到不同分辨率的多尺度检测支持,如下图所示。


参考资料

  1. Histograms of oriented gradients for human detection
  2. Finding people in images and videos
  3. Fast human detection using a cascade of histograms of oriented gradients
  4. HOG特征(Histogram of Gradient)学习总结
  5. 图像学习-HOG特征
  6. SVM算法在项目实践中的应用

(二)目标检测之 HOG+SVM 算法相关推荐

  1. OpenCV学习笔记(二十六)——小试SVM算法ml OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect OpenCV学习笔记(二十八)——光流法对运动目标跟踪Video Ope

    OpenCV学习笔记(二十六)--小试SVM算法ml 总感觉自己停留在码农的初级阶段,要想更上一层,就得静下心来,好好研究一下算法的东西.OpenCV作为一个计算机视觉的开源库,肯定不会只停留在数字图 ...

  2. matlab corner 舍弃,CornerNet为什么有别于其他目标检测领域的主流算法?

    原标题:CornerNet为什么有别于其他目标检测领域的主流算法? 这篇文章为大家解读由密歇根大学 Hei Law 团队在 ECCV 2018发布的论文,一种新的目标检测算法. 目标检测算法在诸如自动 ...

  3. CVPR目标检测与实例分割算法解析:FCOS(2019),Mask R-CNN(2019),PolarMask(2020)

    CVPR目标检测与实例分割算法解析:FCOS(2019),Mask R-CNN(2019),PolarMask(2020) 目标检测:FCOS(CVPR 2019) 目标检测算法FCOS(FCOS: ...

  4. 论文推荐 | 目标检测中不平衡问题算法综述

    (图片付费下载于视觉中国) 作者 | CV君 来源 | 我爱计算机视觉(ID:aicvml) 今天跟大家推荐一篇前几天新出的投向TPAMI的论文:Imbalance Problems in Objec ...

  5. 【小白目标检测】手把手教你做视频中的实时目标检测(基于Pelee算法)

    手把手教你做视频中的实时目标检测(基于Pelee算法) 0. 先看效果: 1. 算法详解: 2. 下载源码: 3. 运行检测: 有需求的大佬欢迎加入我的接单群,需求详情请群里戳群主 获取源码或数据集: ...

  6. 用于目标检测的Faster R-CNN算法的实际实现

    Introduction 您使用哪种算法进行对象检测任务? 为了在最短的时间内构建最精确的模型,我尝试了其中的一些. 这个跨越多个黑客马拉松和现实世界数据集的旅程通常总是让我进入R-CNN系列算法. ...

  7. CVPR2005【行人检测】HOG+SVM用于人体检测的梯度方向直方图

    目录 CVPR2005-用于人体检测的梯度方向直方图 Histograms of Oriented Gradients for Human Detection 使用的数据集 研究方法 数据 流程 双对 ...

  8. 【目标检测】Fast RCNN算法详解

    转载自:http://blog.csdn.net/shenxiaolu1984/article/details/51036677 Girshick, Ross. "Fast r-cnn.&q ...

  9. 人工智能目标检测模型总结(二)——目标检测two-stage模型汇总

    two-stage模型:R-CNN.Fast R-CNN.Faster R-CNN 三个模型都是Ross Girshick教授分别在2014.2015年提出来的,在PASCAL VOC 2007数据集 ...

最新文章

  1. php mysql 读取中文数据的函数_php读取mysql中文数据出现乱码的解决方法
  2. python自动化--语言基础一数据类型及类型转换
  3. eclipse下安装PyDev不显示问题
  4. Python 爬虫知识点 - 淘宝商品检索结果抓包分析(续一)
  5. LeetCode之Intersection of Two Arrays
  6. anaconda和python有什么不一样_黄山毛峰的味道为什么会不一样?
  7. 昨天刚招到一个程序员,第一天入职就离职了....因为不加班
  8. Exsi 5.0 物理端口捆绑+VRRP+DvSwitch配置
  9. 手机游戏开发 - 究竟要做什么、怎么做(中)
  10. 【CCCC】L3-009 长城 (30分),计算几何+凸包,极角排序
  11. Java 语法 索引 ----- 继承(Inheritance) 和重写(Overriding)
  12. AD元件库安装与使用
  13. 微信小程序服务通知开发
  14. Word删除指定一页的页码
  15. 读庄子-万物齐一和自然无为
  16. wordpress调用the_excerpt()不带p标签
  17. 【Django】 视图层说明
  18. 【数据库课程】研讨02
  19. 记free 多次引发的内存踩踏事件
  20. 【论文翻译】小样本学习(Few-Shot Learning)背景和主要方向简介

热门文章

  1. 从 我爱你 到 我爱钱
  2. 软件工程作业 第一周
  3. js 访问剪贴板粘贴
  4. 头像裁剪框html css,js头像裁剪实现——canvas+Jcrop+jQuery
  5. 世界是由什么组成的java_世界的万物到底是由什么构成的?答案竟然是:什么都没有?...
  6. html的marquee标签,marquee 标签参数详细说明
  7. 企业微信的可以用的管理工具有哪些?
  8. webapp开发完整版
  9. 内网服务器自建 yum、epel 源仓库
  10. OSChina 周四乱弹 —— 玩手机会变丑?