Advertisement

(二)OpenCV特征提取与检测_08_HOG特征检测

阅读量:

HOG特征描述子提取:
①灰度图像转换(1:2)
cvtColor(gray = R 0.3 + 0.59 G + 0.11 _B)
②梯度计算
③分网格的梯度方向直方图
分割为8_8=64像素的Cell网格
对每个Cell求取方向直方图 (Orientation Hist)
分为9个Bin,角度取值范围为-180180之间,对-1800之间的加上180取正数,对应的值为梯度值。方向为Bin数组0~9的Index
④块描述子
将2x2的网格单元组合成为一个大的块(Block)
对每个块之间有1/2部分是重叠区域
主要是将每个Cell的直方图合并为一个大的直方图(Bin索引不变[0~9]之间)
⑤块描述子归一化
⑥特征数据与检测窗口
正样本(用于特征识别)、负样本(干扰因素)
最终获得HOG描述算子(特征数据)
对于64x128的像素块,可以分为8x16个Cell分为7x15个块(R-HOG)
总计的直方图向量数为:7x15x2x2x9 = 3780个向量数组(64-16)/8+1个水平块,(128-16)/8+1个垂直块)个16x16块扫描窗口,每个块有2x2个cell,9表示9-bins直方图)用来存储每个像素的梯度大小和梯度方向
初步测试、开窗检测
⑦匹配方法
(HOG + SVM 实行行人检测)

复制代码
    HOGDescriptor(
    Size winSize,//(64, 128) 
    Size blockSize,//(16, 16)
    Size blockStride,//(8, 8)
    Size cellSize,//(8, 8)
    int  nbins);//9)
复制代码
    #include <opencv2/opencv.hpp>
    #include <iostream>
    
    using namespace std;
    using namespace cv;
    
    int main(int argc, char** argv)
    {
    	Mat src,gray,dst;
    	src = imread("../path.jpg");
    	if (src.empty())
    	{
    		cout << "could not load image..." << endl;
    		return -1;
    	}
    
    	namedWindow("src", WINDOW_AUTOSIZE);
    	imshow("src", src);
    
    	/*
    	//详解https://www.cnblogs.com/zhazhiqiang/p/3595266.html
    	resize(src, gray, Size(64, 128));
    	//灰度图像转换
    	cvtColor(gray, gray, COLOR_BGR2GRAY);
    
    	Size winSize = Size(64, 128);//检测窗口大小
    	Size blockSize = Size(16, 16);//块大小,目前只支持Size(16, 16)
    	Size blockStride = Size(8, 8);//块的滑动步长,大小只支持是单元格cell_size大小的倍数
    	Size cellSize = Size(8, 8);//单元格的大小,目前只支持Size(8, 8)
    	int	 bins = 9;//直方图bin的数量(投票箱的个数),目前每个单元格Cell只支持9个
    
    	//创造一个HOG描述子和检测器detector
    	HOGDescriptor detector(winSize, blockSize, blockStride, cellSize, bins);
    	vector<float> descriptors;
    	vector<Point> locations;
    	//计算HOG特征向量
    	detector.compute(gray,//源图像,只支持CV_8UC1和CV_8UC4数据类型
    		descriptors, //返回的HOG特征向量,descriptors.size是HOG特征的维数
    		Size(0, 0), //窗口移动步长
    		Size(0, 0), //扩充像素数
    		locations); //对于正样本可以直接取(0,0),负样本为随机产生合理坐标范围内的点坐标
    	
    	//OpenCV中一个Hog描述子是针对一个检测窗口而言的,
    	//一个检测窗口有((128 - 16) / 8 + 1)*((64 - 16) / 8 + 1) = 105个Block,
    	//一个Block有4个Cell,一个Cell的Hog描述子向量的长度是9,
    	//所以一个检测窗口的Hog描述子的向量长度是105 * 4 * 9 = 3780维
    	cout << "number of HOG descriptors: " << descriptors.size() << endl;
    	*/
    
    	//HOG + SVM 行人检测
    	HOGDescriptor hog = HOGDescriptor();
    	//设置线性SVM分类器的系数
    	hog.setSVMDetector(hog.getDefaultPeopleDetector());//getDefaultPeopleDetector()获取行人分类器(默认检测窗口大小)的系数(获得3780维检测算子)
    
    	vector<Rect> foundLocations;
    	//用多尺度的窗口进行物体检测,需有setSVMDetector
    	hog.detectMultiScale(src,//源图像,只支持CV_8UC1和CV_8UC4数据类型
    		foundLocations, //检测出的物体的边缘
    		0, //特征向量和SVM划分超平面的阀值距离(通常它为0,并应由检测器系数决定)
    		Size(8, 8),//窗口步长,必须是块步长的整数倍
    		Size(0,0), //模拟参数,使得CUP能兼容(目前必须是(0, 0))
05,//检测窗口增长参数
    		2);//调节相似性系数的阈值(检测到时,某些对象可以由许多矩形覆盖),0表示不进行分组
    	
    	dst = src.clone();
    	//画长方形,框出行人
    	for (size_t t = 0; t < foundLocations.size(); t++) 
    	{
    		rectangle(dst, foundLocations[t], Scalar(0, 0, 255), 2, 8, 0);
    	}
    	namedWindow("HOG SVM Detector检测行人", WINDOW_AUTOSIZE);
    	imshow("HOG SVM Detector检测行人", dst);
    	
    	waitKey(0);
    	return 0;
    }

src为:(网络图片)

在这里插入图片描述

输出结果:

在这里插入图片描述

全部评论 (0)

还没有任何评论哟~