本文主要参考博客:1.https://www.cnblogs.com/panchuangai/p/12567973.html

2.https://blog.csdn.net/weixin_38367817/article/details/83153954

3.https://blog.csdn.net/weixin_44947897/article/details/107165653

4.https://www.jianshu.com/p/395f0582c5f7

5.https://blog.csdn.net/qq_27396861/article/details/88374215

6.https://blog.csdn.net/akadiao/article/details/79685323

7.https://blog.csdn.net/u012762410/article/details/78846085

8.https://blog.csdn.net/sinat_26917383/article/details/69666371

9.https://blog.csdn.net/zhazhiqiang/article/details/21047207

特征描述子是图像的简化表示,仅包含图像的最重要信息。本博客将介绍几种常用的特征描述子,包括HOG、SIFT、SURF、ORB.

原来在另一篇博客简单介绍过该特征的一点关键知识,此处更加详细的总结一下,附上原来链接

https://blog.csdn.net/u013972657/article/details/110631959

目录

1. HOG(Histogram of Oriented Gradients,方向梯度直方图)

1.1主要思想

1.2适用领域

1.3计算方向梯度直方图的过程

1.4opencv hog特征描述子的调用及计算

1.5 行人检测


1. HOG(Histogram of Oriented Gradients,方向梯度直方图)

1.1主要思想

在一副图像中,局部目标的表象和形状(appearance and shape)能够被梯度或边缘的方向密度分布很好地描述。(本质:梯度的统计信息,而梯度主要存在于边缘的地方)。它与图像边缘特征的主要区别是图像边缘特征只识别像素是否是边缘(只计算梯度),而HOG特征还计算边缘(梯度)的方向。

1.2适用领域

hog是一种在计算机视觉和图像处理中用来对物体检测的特征描述子,Hog特征结合SVM分类器已经被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功。

1.3计算方向梯度直方图的过程

输入图像-》图像灰度化-》Gamma校正-》计算图像梯度-》计算cell的描述子-》将cell组合为block,block内特征归一化-》将block串联起来,得到图像描述子

描述步骤之前,先总体介绍一些预备知识:

(1)在原论文中处理图像时,图像的尺寸缩放为64*128(64为宽,128为高),这个大小是为了方便之后划分为cell以及block。

(2)将图像划分为8*8的cell(对于8*8的网格已经足够大来表示有用的特征比如脸,头等等)
(3)每个cell都要计算一个直方图,该直方图是对幅值magnitude和方向direction的统计(每个像素都有一个幅值和方向),方向范围是0~180度,使用的是无符号梯度,此时一个梯度和它的负数是用同一个数字表示的,也就是说一个梯度的箭头以及它旋转180度之后的箭头方向被认为是一样的。那为什么不用0-360度的表示呢?在事件中发现unsigned gradients比signed gradients在行人检测任务中效果更好。

(4)block(16*16):由于局部光照的变化以及前景-背景对比度的变化,使得梯度强度的变化范围非常大。这就需要对梯度强度做归一化。在block内归一化是为了增强描述子对光照、阴影和边缘变化的鲁棒性。它能进一步对光照、阴影和边缘进行压缩。一个block内所有cell的特征向量串联起来便得到该block的HOG特征。这些区间是互有重叠的,这就意味着:每一个单元格的特征会以不同的结果多次出现在最后的特征向量中。

各步骤关键:

1.图像灰度化是可选操作,因为灰度图像和彩色图像都可以用于计算梯度图。对于彩色图像,先对三通道颜色值分别计算梯度,然后取梯度值最大的那个作为该像素的梯度。但在计算机视觉处理中一般都以灰度图作为处理对象(不包括深度学习)。

2.Gamma校正:调节图像对比度,减少光照对图像的影响,使过曝或者欠曝的图像恢复正常,更接近人眼看到的图像。

3.计算梯度:计算一个像素的x方向梯度及y方向的梯度。根据它们确定每个像素的大小和方向

梯度方向(角度的值):atan()

梯度幅值为:

4.计算cell描述子:

按照角度不同,直方图分为9个bin,代表角度0,20,40,60,80,100,120,140,160;根据方向确定选择哪个bin,根据幅值确定bin的大小,如果角度值为介于上边9个值的值,那么需要根据距离9个值左右值的远近在幅值上分别乘以比例来确定在这两个bin上的大小。如下图(改图截取自参考博客1,为便于理解放于此处,如有侵权,联系笔者删除):

5.组合为block并且归一化

一个block是由四个cell组成的,将每个cell的的9个Bin的直方图(即9*1的向量)组合成一个36*1的向量,之后对其归一化,接着,窗口再朝后面挪8个像素(看动图)。重复这个过程把整张图遍历一遍。如下图(该图源于参考链接4,为便于理解放于此处,如有侵权,联系笔者删除)

归一化方法有L1-norm、L2-norm、L1-sqrt(L1-norm后在平方)。通常使用L2-norm.

L2-norm的计算方法如下:

对于cell组合成的36维向量v=[a1,a2,a3,...,a36];

计算平方和的根:k=

并将向量v中的每个值除以此值k:

归一化后的向量=(a1/k,a2/k,a3/k,...,a36/k)

6.图像特征描述子

以5中图示华东,64*128将有7*15个16*16大小的block,这105个块中每一个有36个向量作为特征,所以该64*128大小的图像描述子大小是105*36=3780。

1.4opencv hog特征描述子的调用及计算

HogDescriptor: 构建一个Hog描述子及检测器

cv::HOGDescriptor::HOGDescriptor( Size winSize=Size(64,128), Size blockSize=Size(16,16), Size blockStride=Size(8,8), Size cellSize=Size(8,8), int nbins=9,double winSigma = DEFAULT_WIN_SIGMA, double threshold_L2Hys = 0.2,bool gamma_Correction = true,int nlevels=DEFAULT_NLEVELS )参数解释:
<1>win_size:检测窗口大小。
<2>block_size:块大小,目前只支持Size(16, 16)。
<3>block_stride:块的滑动步长,大小只支持是单元格cell_size大小的倍数。
<4>cell_size:单元格的大小,目前只支持Size(8, 8)。
<5>nbins:直方图bin的数量(投票箱的个数),目前每个单元格Cell只支持9个。
<6>win_sigma:高斯滤波窗口的参数。
<7>threshold_L2hys:块内直方图归一化类型L2-Hys的归一化收缩率
<8>gamma_correction:是否gamma校正
<9>nlevels:检测窗口的最大数量

compute函数:计算hog特征

void HOGDescriptor:: compute(const Mat&  img, vector<float>&  descriptors,Size  winStride, Size  padding,const vector<Point>&  locations) const
(3)参数注释
<1> img:源图像。只支持CV_8UC1和CV_8UC4数据类型。
<2> descriptors:返回的HOG特征向量,descriptors.size是HOG特征的维数。
<3> winStride:窗口移动步长。
<4> padding:扩充像素数。
<5> locations:对于正样本可以直接取(0,0),负样本为随机产生合理坐标范围内的点坐标。

getDescriptorSize函数:获取一个检测窗口HOG特征向量的位数

对百度下载一幅图像截取出人形做测试:

计算hog描述子代码:

#include <opencv2/opencv.hpp>
#include <opencv2/objdetect.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{Mat srcImage = imread("oneperson.jpg");Mat grayImage, dstImage;cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);resize(grayImage, dstImage, Size(64, 128));HOGDescriptor dectector(Size(64, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9);cout <<"dectector.getDescriptorSize():"<< dectector.getDescriptorSize() << endl;// HOG的描述子vector<float> descriptors;vector<Point> locations;dectector.compute(dstImage, descriptors, Size(0, 0), Size(0, 0), locations);cout << "descriptors.size():" << descriptors.size() << endl;cout << "feature:" << endl;for (int j = 0; j < 3780; j++){cout << descriptors[j] << ' ';}cout << endl;system("pause");return 0;
}

结果显示:

1.5 行人检测

OpenCV中自己带的训练模板里面有行人检测,可以直接调用,主要用到下面三个函数

setSVMDetector 函数:设置线性SVM分类器的系数

getDefaultPeopleDetector 函数:获取行人分类器(默认检测窗口大小)的系数(获得3780维检测算子)

detectMultiScale 函数(前边需有setSVMDetector):用多尺度的窗口进行物体检测

void HOGDescriptor::detectMultiScale(const Mat& img, vector<Rect>& foundLocations, vector<double>& foundWeights,double hitThreshold, Size winStride, Size padding,double scale0, double finalThreshold, bool useMeanshiftGrouping)
参数注释
<1>img:源图像。
<2>foundlocations:检测出的物体的边缘。
<3>foundWeights: 检测窗口得分
<4>hit_threshold:阀值,特征向量和SVM划分超平面的距离,大于这个值的才作为目标返回。
<5>win_stride:窗口步长,必须是block步长的整数倍。
<6>padding:图片边缘补齐参数,gpu版本必须是(0,0)。
<7>scale0:检测窗口增长参数。
<8>finalThreshold:检测结果聚类参数
<9>useMeanshiftGrouping:聚类方式选择的参数

从百度图库下载一张行人的图像:

测试代码:

#include <opencv2/opencv.hpp>
#include <opencv2/objdetect.hpp>
#include <iostream>
using namespace std;
using namespace cv;int main()
{Mat src, dst;src = imread("people.jpg", 1);if (src.empty()){printf("load image error...\n");return -1;}dst = src.clone();vector<Rect> findrects, findrect;HOGDescriptor HOG;//SVM分类器HOG.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());//多尺度检测HOG.detectMultiScale(src, findrects, 0, Size(4, 4), Size(0, 0), 1.05, 2);//框选出检测结果for (int i = 0; i<findrects.size(); i++){RNG rng(i);Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));rectangle(dst, findrects[i].tl(), findrects[i].br(), color, 2);}imshow("src", src);imshow("dst", dst);waitKey();return 0;
}

测试结果:

文中若有错误或不妥之处,还望指出!

图像特征描述子(一)——HOG相关推荐

  1. 图像特征描述子之BRISK

    原文站点:https://senitco.github.io/2017/07/12/image-feature-brisk/   BRISK(Binary Robust Invariant Scala ...

  2. 图像特征描述子——Susan

    1.Susan: SUSAN(Smallest Univalue Segment Assimilating NucleusSUSAN)算子的模板和常规卷积算法的正方形模板不同,它使用一种近似圆形的模板 ...

  3. image.merge图像有什么变化_图像特征工程:HOG特征描述子介绍

    介绍 在机器学习算法的世界里,特征工程是非常重要的.实际上,作为一名数据科学家,这是我最喜欢的方面之一!从现有特征中设计新特征并改进模型的性能,这就是我们进行最多实验的地方. 世界上一些顶级数据科学家 ...

  4. 局部图像特征描述概述

    局部图像特征描述概述 樊彬 中国科学院自动化研究所 模式识别国家重点实验室 (CASIA NLPR) 局部图像特征描述是计算机视觉的一个基本研究问题,在寻找图像中的对应点以及物体特征描述中有着重要的作 ...

  5. “局部图像特征描述概述”--樊彬老师

    原文链接:http://www.sigvc.org/bbs/thread-165-1-1.html 这次我们荣幸地邀请到中国科学院自动化研究所的樊彬老师为我们撰写图像特征描述符方面的最新综述.樊彬老师 ...

  6. 傅里叶描述子、HOG特征描述子原理及matlab代码

    一.傅里叶描述子 傅里叶描述子的作用是用来描述图像的轮廓信息,具有平移.旋转.尺度不变性特征. 对于一幅图像,通过傅里叶描述子获得其图像轮廓信息,其本质就是空间.频域变换问题.通过将图像中的像素点进行 ...

  7. 图像特征点及特征描述子总结

    参考博客 https://blog.csdn.net/qq_28193895/article/details/80845803 https://blog.csdn.net/u013989576/art ...

  8. BRIEF 特征描述子

    FROM:http://www.cnblogs.com/ronny/p/4081362.html Binary Robust Independent Elementary Features www.c ...

  9. 特征描述子提取公用接口

    OpenCV封装了一些特征描述子提取算法,使得用户能够解决该问题时候方便使用各种算法.这章用来计算的描述子提取被表达成一个高维空间的向量 vector.所有实现 vector 特征描述子子提取的部分继 ...

最新文章

  1. sql数据库系统表和mysql系统表
  2. Java——递归调用
  3. UVa - 11988 Broken Keyboard(数组模拟链表)
  4. 三年半Java后端面试经历
  5. exe文件怎么看源码_Java 反射机制你还不会?那怎么看 Spring 源码?
  6. JavaFX布局中图片在表格中无法被自适应缩小?
  7. 数据结构与算法(一):线性表、栈、树(二叉树,AVL树)、图
  8. mysql 存储过程 查询语句怎么写_mysql 查询数据库中的存储过程与函数的语句
  9. CTF攻防世界刷题51-
  10. Linux常用命令详解2
  11. java6_64.tar配置,Ubuntu 下Java-JDK6的安装与环境配置
  12. 【XJTUSE 计算机组成与结构笔记】第十四章 指令级并行性和超标量处理
  13. 今日头条视频消重工具 抖音短视频去水印在线解析工具
  14. 日语动词+动词类型+动词活用
  15. ThreadPoolExecutor(一)——简介
  16. php md5 file算法原理,MD5算法原理与实现
  17. 学习笔记2022.7.25-7.30
  18. 利用深度学习辅助皮肤病诊断
  19. matlab资源管理器,资源管理器怎么打开?打开资源管理器的5种方法
  20. layui自定义验证表单

热门文章

  1. 光流正负值的含义以及如何利用光流进行warping
  2. 【Devc++】迷宫小游戏1.0
  3. 华擎Deskmini 310黑苹果efi引导文件
  4. java中求素数的几种方法汇总及比较
  5. MySQL之初始化配置
  6. w10系统无法访问xp计算机名,xp系统用户无法访问win10电脑上共享资源的解决方法...
  7. Java关键字之finally
  8. Matlab 关于彩色图像的平移、旋转以及对称处理
  9. mysql auto position_MySQL内核月报 2015.01-MySQL · 捉虫动态· 设置 gtid_purged 破坏AUTO_POSITION复制协议-阿里云开发者社区...
  10. pycharm安装Translation翻译插件(中文翻译)