HOG检测简单原理
一、HOG
HOG(方向直方图特征)是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。HOG+SVM进行行人检测的方法是法国研究人员Dalal在2005年的CVPR上提出来的,到现在,虽然说有很多行人检测算法,但是这个确实使用起来最简单的,而且大部分的行人检测算法都是在这个的基础上进行改进。
二、HOG的实现过程(大体过程,简单易懂,不讲数学原理)
1.首先选取需要检测的目标或者一个需要检测的一个窗口。
2.对检测的图进行*灰度处理*(把这个图像看成为三维图像,x y z的三维图像)
3.使用Gamma矫正对输入图像进行归一化,目的就是,去除噪声,减少异常值的影响
4.计算每个像素上的梯度信息,包括大小和方向信息。主要就是为了捕捉轮廓信息。
5.将图像划分为小cell细胞单元。
6.统计每个cell的梯度直方图,生成每个cell的描述子
7.将没几个cell组合成大的block,cell得描述子串联起来便可以得到block的描述子。
8.最后再将image中block的HOG特征描述子串联起来,可以得到imgage的特征,就可以得到最终可以进行分类使用的特征向量
大体流程图:

代码
#include
#include using namespace std;
using namespace cv;void display(Mat gray_diff, vector<Rect>& rect)
{//Mat res = src.clone();vector<vector<Point>> cts; //定义轮廓数组findContours(gray_diff, cts, RETR_EXTERNAL, CHAIN_APPROX_NONE); //查找轮廓,,模式为只检测外轮廓,并存储所有的轮廓点//vector rect; //定义矩形边框 for (int i = 0; i < cts.size(); i++){if (contourArea(cts[i])>50) //计算轮廓的面积,排除小的干扰轮廓//查找外部矩形边界 rect.push_back(boundingRect(cts[i])); //计算轮廓的垂直边界最小矩形}cout << rect.size() << endl; //输出轮廓个数
}int main() {void display(Mat, vector<Rect>&);//void Crop_picture(); //void train();//void save_hard_example();//Crop_picture(); //裁切负样本图片,每张负样本图片随机裁成10张//train(); //训练正负样本//save_hardexample() //根据正负样本得到的检测子,对INRIAPerson/Train/neg/中的图片进行测试,并将错检的样本保存//train(); //训练正负样本及难例样本//加载svm分类器的系数HOGDescriptor hog; string str;vector<float> detector;/*ifstream fin("HOGDetectorForOpenCV.txt");while (getline(fin, str)){detector.push_back(stringToNum(str));}
*/ vector<Rect> people;VideoCapture capture("C:\\Users\\20435\\Desktop\\tu\\行人检测\\vtest01.avi");/*if (!capture.isOpened())return -1;*/Mat frame, foreground;int num = 0;//https://blog.csdn.net/ding_programmer/article/details/102881342 /*高斯混合分离模型/将图像分为3-5个高斯模型,一个像素点来了,如果该像素点离任何一个高斯模型的距离大于其2倍的标准差,则为前景即运动物体,否则则是背景步骤:第一步:初始各种参数第二步:使用T帧图像构造模型,对于第一个帧图像的第一个像素点,使用u1,σ1构造高斯模型第三步:对于一个新来的模型,如果该像素在高斯模型3*σ1内,则属于该高斯模型,对参数进行更新第四步:如果不满足该高斯模型,重新建立一个新的高斯模型*/Ptr<BackgroundSubtractorMOG2> mod = createBackgroundSubtractorMOG2();while (true){vector<Rect> rect6;if (!capture.read(frame))break;mod->apply(frame, foreground, 0.1);hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());//hog.setSVMDetector(detector);vector<Rect> rect5;display(foreground, rect5); //这里调用了vector<Rect> ret = rect5;for (auto i = 0; i != ret.size(); i++){Mat a = frame;if (ret[i].x > 50 && ret[i].y > 50 && ret[i].x + ret[i].width < 670 && ret[i].y + ret[i].height < 520){ret[i].x = ret[i].x - 50;ret[i].y = ret[i].y - 50; ret[i].width = ret[i].width + 100; ret[i].height = ret[i].height + 100;}Mat src(a(ret[i]));cout << ret[i].x << " " << ret[i].y << " " << ret[i].width << " " << ret[i].height << endl;// imshow("aa", src); waitKey(0);// cv::namedWindow("src", CV_WINDOW_NORMAL); if (ret[i].width >= 64 && ret[i].height >= 128)hog.detectMultiScale(src, people, 0, Size(4, 4), Size(0, 0), 1.07, 2);//cout << people.size()<for (size_t j = 0; j < people.size(); j++){people[j].x += ret[i].x; people[j].y += ret[i].y;rect6.push_back(people[j]);//rectangle(frame, people[j], cv::Scalar(0, 0, 255), 2);}//imshow(" ", frame); waitKey(0);}//因为多尺度检测得到的结果矩形框较大,按比例缩减矩形框for (auto h = 0; h != rect6.size(); h++){rect6[h].x += cvRound(rect6[h].width * 0.1);rect6[h].width = cvRound(rect6[h].width * 0.8);rect6[h].y += cvRound(rect6[h].height * 0.07);rect6[h].height = cvRound(rect6[h].height * 0.8);rectangle(frame, rect6[h], cv::Scalar(0, 0, 255), 1);//rect2[h] = boundingRect(frame);}在这里插入图片描述imshow(" ", frame); waitKey(1);}waitKey();
}
代码测试截图:


参考链接:HOG详细原理
测试视频提取链接
提取码:wey1
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
