图像特征描述子(一)——HOG-程序员宅基地

技术标签: opencv图像处理  图像特征描述  计算机视觉  图像知识  opencv  

本文主要参考博客: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方向梯度_{Gx}及y方向的梯度_{Gy}。根据它们确定每个像素的大小和方向

梯度方向(角度的值):atan(_{Gy/Gx})

梯度幅值为:\sqrt{Gx^{2}+Gy^{2}}

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=\sqrt{(a1)^{2}*(a2)^{2}*(a3)^{2}...*(a36)^{2}}

并将向量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;
}

测试结果:

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013972657/article/details/118294795

智能推荐

Docker 快速上手学习入门教程_docker菜鸟教程-程序员宅基地

文章浏览阅读2.5w次,点赞6次,收藏50次。官方解释是,docker 容器是机器上的沙盒进程,它与主机上的所有其他进程隔离。所以容器只是操作系统中被隔离开来的一个进程,所谓的容器化,其实也只是对操作系统进行欺骗的一种语法糖。_docker菜鸟教程

电脑技巧:Windows系统原版纯净软件必备的两个网站_msdn我告诉你-程序员宅基地

文章浏览阅读5.7k次,点赞3次,收藏14次。该如何避免的,今天小编给大家推荐两个下载Windows系统官方软件的资源网站,可以杜绝软件捆绑等行为。该站提供了丰富的Windows官方技术资源,比较重要的有MSDN技术资源文档库、官方工具和资源、应用程序、开发人员工具(Visual Studio 、SQLServer等等)、系统镜像、设计人员工具等。总的来说,这两个都是非常优秀的Windows系统镜像资源站,提供了丰富的Windows系统镜像资源,并且保证了资源的纯净和安全性,有需要的朋友可以去了解一下。这个非常实用的资源网站的创建者是国内的一个网友。_msdn我告诉你

vue2封装对话框el-dialog组件_<el-dialog 封装成组件 vue2-程序员宅基地

文章浏览阅读1.2k次。vue2封装对话框el-dialog组件_

MFC 文本框换行_c++ mfc同一框内输入二行怎么换行-程序员宅基地

文章浏览阅读4.7k次,点赞5次,收藏6次。MFC 文本框换行 标签: it mfc 文本框1.将Multiline属性设置为True2.换行是使用"\r\n" (宽字符串为L"\r\n")3.如果需要编辑并且按Enter键换行,还要将 Want Return 设置为 True4.如果需要垂直滚动条的话将Vertical Scroll属性设置为True,需要水平滚动条的话将Horizontal Scroll属性设_c++ mfc同一框内输入二行怎么换行

redis-desktop-manager无法连接redis-server的解决方法_redis-server doesn't support auth command or ismis-程序员宅基地

文章浏览阅读832次。检查Linux是否是否开启所需端口,默认为6379,若未打开,将其开启:以root用户执行iptables -I INPUT -p tcp --dport 6379 -j ACCEPT如果还是未能解决,修改redis.conf,修改主机地址:bind 192.168.85.**;然后使用该配置文件,重新启动Redis服务./redis-server redis.conf..._redis-server doesn't support auth command or ismisconfigured. try

实验四 数据选择器及其应用-程序员宅基地

文章浏览阅读4.9k次。济大数电实验报告_数据选择器及其应用

随便推点

灰色预测模型matlab_MATLAB实战|基于灰色预测河南省社会消费品零售总额预测-程序员宅基地

文章浏览阅读236次。1研究内容消费在生产中占据十分重要的地位,是生产的最终目的和动力,是保持省内经济稳定快速发展的核心要素。预测河南省社会消费品零售总额,是进行宏观经济调控和消费体制改变创新的基础,是河南省内人民对美好的全面和谐社会的追求的要求,保持河南省经济稳定和可持续发展具有重要意义。本文建立灰色预测模型,利用MATLAB软件,预测出2019年~2023年河南省社会消费品零售总额预测值分别为21881...._灰色预测模型用什么软件

log4qt-程序员宅基地

文章浏览阅读1.2k次。12.4-在Qt中使用Log4Qt输出Log文件,看这一篇就足够了一、为啥要使用第三方Log库,而不用平台自带的Log库二、Log4j系列库的功能介绍与基本概念三、Log4Qt库的基本介绍四、将Log4qt组装成为一个单独模块五、使用配置文件的方式配置Log4Qt六、使用代码的方式配置Log4Qt七、在Qt工程中引入Log4Qt库模块的方法八、获取示例中的源代码一、为啥要使用第三方Log库,而不用平台自带的Log库首先要说明的是,在平时开发和调试中开发平台自带的“打印输出”已经足够了。但_log4qt

100种思维模型之全局观思维模型-67_计算机中对于全局观的-程序员宅基地

文章浏览阅读786次。全局观思维模型,一个教我们由点到线,由线到面,再由面到体,不断的放大格局去思考问题的思维模型。_计算机中对于全局观的

线程间控制之CountDownLatch和CyclicBarrier使用介绍_countdownluach于cyclicbarrier的用法-程序员宅基地

文章浏览阅读330次。一、CountDownLatch介绍CountDownLatch采用减法计算;是一个同步辅助工具类和CyclicBarrier类功能类似,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。二、CountDownLatch俩种应用场景: 场景一:所有线程在等待开始信号(startSignal.await()),主流程发出开始信号通知,既执行startSignal.countDown()方法后;所有线程才开始执行;每个线程执行完发出做完信号,既执行do..._countdownluach于cyclicbarrier的用法

自动化监控系统Prometheus&Grafana_-自动化监控系统prometheus&grafana实战-程序员宅基地

文章浏览阅读508次。Prometheus 算是一个全能型选手,原生支持容器监控,当然监控传统应用也不是吃干饭的,所以就是容器和非容器他都支持,所有的监控系统都具备这个流程,_-自动化监控系统prometheus&grafana实战

React 组件封装之 Search 搜索_react search-程序员宅基地

文章浏览阅读4.7k次。输入关键字,可以通过键盘的搜索按钮完成搜索功能。_react search