基于方向梯度直方图(HOG)/线性支持向量机(SVM)算法的行人检测方法中存在检测速度慢的问题,如下图所示,对一张400*490像素的图片进行检测要接近800毫秒,所以hog+svm的方法放在视频中进行行人检测时,每秒只能检测1帧图片,1帧/s根本不能达到视频播放的流畅性。

本文采用先从视频每帧的图像中提取出物体的轮廓(也可以对前后两针图片做差,只对有变化的部分进行检测,其目的一样,都是减少运算的面积),再对每个轮廓进行HOG+SVM检测,判断是否为行人。可以大大的缩减HOG+SVM的面积,经实测,检测速度可以达到10帧/S,可以勉强达到视频流畅的要求。

轮廓的提取用的是cv::findContours的API,感兴趣的可以自己去查看相关资料

首先介绍下方向梯度直方图。

在图像或者视频帧中,边缘方向密度分布可以很好地描述局部目标的形状和表象,也就是说通过 HOG特征,可以有效地将人体和复杂背景区分出来。对于行人检测中 HOG 特征提取的具体实现方法是: 将视频中的每一帧通过滑动窗口切割成很小的区域( Cell) ,通过计算每个区域面的方向梯度特征,得到每个区域的方向特征直方图,小区域再组成更大的区域,通过将区域的方向梯度特征组合起来并在块单元中进行归一化处理,就形成了一个 Block 内 HOG 描述子,遍历搜索所有的方向特征从而最终构成一个帧的 HOG 描述特征向量。算法的过程[3]分为:
①将一个视频的每一帧进行灰度化处理。把视频的每一帧彩色空间变成灰度空间,因为 HOG 中不需要彩色信息的帮助。
②对输入的视频的每一帧进行颜色空间的归一化。由于视频中人信息的复杂性,背影的灰暗程度以及光照的影响都对检测器的鲁棒性有一定的影响,归一化可以很大程度上降低这些的影响。这 里 使 用gamma 校正: 对像素值求其平方根( 降低数值大小) 。
③计算像素梯度。这是 HOG 特征检测中最重要的一个环节,通过像素的梯度方向直方图来描述像素的特征。特别注意的是我们不需要做平滑处理,因为平滑处理的本质就是迷糊图像,降低了像素边缘信息,因而就不能很好地提取边缘信息来表达特征。

④将图像划分成小 cell。这一步我们需要为计算梯度,建立梯度方向直方图定义一个载体,因此这里把图像分割成很小的区域,这里称为细胞单元,实验表明6 × 6 像素的细胞单元效果最佳。接着采用 9 个直方图来统计一个细胞单元里面的特征信息。360°不考虑
正负方向,把方向分成 9 份,如图 1 所示,称为 bin,也就是每一个 bin 对应 20°,这样就把梯度方向映射到直方图里面,9 个方向特征向量代表 9 个 bin,增幅就代表每一个 bin 的权值。

⑤统计每个 cell 的梯度直方图即可形成每个 cell的 descriptor。

⑥将每几个 cell 组成一个 block,一个 block 内所有 cell 的特征串联起来,便得到该 block 的 HOG 特征descriptor。

⑦将图像内所有 block 的 HOG 特征收集起来就可得到该图像特征向量。

支持向量机

支持向量机( Support Vector Machine) 就是风险降低到最小程度上,寻找最优的解决方案。视频检测特征分类中,就是针对低维空间的线性不可分问题,通过核函数映射到高维空间达到线性可分,再进行线性分割实现特征分类。
SVM 具有以下几个特点:
( 1) 小样本。
( 2) 非 线 性 问 题。即针对线性的不可分问题,SVM 通过松弛变量以及核函数进行解决。
( 3) 高维模式识别。在某些样本,例如密集型特征,可以达到几万甚至十几万的维数,如果不对样本进行降维,SVM 也能够找出支持向量样本,对这些特征训练出优秀的分类器。

视频检测代码:

void video_test() {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<float>(str));}
*/vector<Rect> people;VideoCapture capture(VideotestPath);/*if (!capture.isOpened())return -1;*/Mat frame, foreground;int num = 0; Ptr<BackgroundSubtractorMOG2> mod = createBackgroundSubtractorMOG2();while (true){vector<Rect> rect6;if (!capture.read(frame))break;mod->apply(frame, foreground, 0.01);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()<<endl;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();
}

提取轮廓的代码:

void display(Mat gray_diff, vector<Rect>& rect)
{//Mat res = src.clone();vector<vector<Point>> cts;  //定义轮廓数组findContours(gray_diff, cts, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); //查找轮廓,,模式为只检测外轮廓,并存储所有的轮廓点//vector<Rect> rect; //定义矩形边框for (int i = 0; i < cts.size(); i++){if (contourArea(cts[i])>th_area)       //计算轮廓的面积,排除小的干扰轮廓//查找外部矩形边界  rect.push_back(boundingRect(cts[i]));   //计算轮廓的垂直边界最小矩形}cout << rect.size() << endl;     //输出轮廓个数
}

检测效果:

进行HOG+SVM的四个顶点像素坐标。可以看到每次运算的面积小了很多。

当然 ,是可以优化,比如每两帧图片检测一次,下一帧图片保持上一帧的检测结果。比如轮廓区域的面积怎么去合适的框起来,如何设定合适的阈值去滤掉小框,两个框重叠时,怎么去优化,减小进行运算的面积。本文只是给个思路,具体读者可以自己去实现。

贴下github  有兴趣的可以去读下 ,样本集用的INRIA行人检测数据集,训练过程就不详述了。

github:https://github.com/ttttthub/pedestrian-detection.git

基于opencv的行人检测(支持图片,视频)相关推荐

  1. 基于opencv的人脸检测(图片、视频、摄像头)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一.检测图片中的人脸 二.检测视频与摄像头中的人脸 总结 前言 人脸检测识别一直是个热门的研究问题,同时也是opencv中 ...

  2. opencv canny源码解析_行人检测 基于 OpenCV 的人体检测

    原文链接 行人检测 基于 OpenCV 的人体检测 - 热分享​hotdog29.com 在 2019年8月1日 上张贴 由 hotdog发表回复 行人检测 基于 OpenCV 的人体检测 我们都知道 ...

  3. pythonopencv检测行人_行人检测 基于 OpenCV 的人体检测

    原文链接行人检测 基于 OpenCV 的人体检测 - 热分享​hotdog29.com 行人检测 基于 OpenCV 的人体检测 我们都知道,无论性别,种族或种族如何,我们的身体都具有相同的基本结构. ...

  4. python行人检测_行人检测 基于 OpenCV 的人体检测

    原文链接行人检测 基于 OpenCV 的人体检测 - 热分享​hotdog29.com 行人检测 基于 OpenCV 的人体检测 我们都知道,无论性别,种族或种族如何,我们的身体都具有相同的基本结构. ...

  5. 基于OpenCV的火焰检测(二)——RGB颜色判据

    上文跟大家分享了在做火焰检测中常用到的图像预处理方法,从这一篇博文开始,我将向大家介绍如何一步一步地检测出火焰区域.火焰提取要用 到很多判据,今天我要向大家介绍的是最简单的但是很有效的判据--RGB判 ...

  6. python运动目标检测与跟踪_基于OpenCV的运动目标检测与跟踪

    尹俊超,刘直芳:基于 OpenCV 的运动目标检测与跟踪 2011, V ol.32, No.8 2817 0 引 言 运动目标检测跟踪技术在航空航天遥感. 生物医学. 工业 自动化生产. 军事公安目 ...

  7. 基于opencv实现人脸检测

    基于opencv实现人脸检测 opencv简述 opencv是一个开源的计算机视觉库,它有着C++,Python,Java等接口,支持Windows,Linux,Mac OS,IOS 和 Androi ...

  8. 基于OpenCV的火焰检测(三)——HSI颜色判据

    上文向大家介绍了如何用最简单的RGB判据来初步提取火焰区域,现在我要给大家分享的是一种更加直观的判据--HSI判据.为什么说HSI判据是更加直观的判据呢?老规矩,先介绍一下HSI色彩模型:HSI颜色模 ...

  9. Python基于OpenCV高空抛物检测系统[完整源码&部署教程]

    1.视频演示: [项目分享]Python基于OpenCV高空抛物检测系统[完整源码&部署教程]_哔哩哔哩_bilibili 2.图片演示: 3.算法原理: 参考该博客提出的移动侦测法,即是根据 ...

最新文章

  1. .NET : 针对Oracle的LOB数据访问
  2. VUE的本地应用-V- on
  3. C++_typedef名字
  4. 深入理解JavaScript的变量作用域
  5. 仁慈型dea matlab程序,数据包络分析(DEA)方法..docx
  6. .NET5来了你别慌
  7. 阅读《Google成功七堂课》
  8. 开始深入的学习javascript
  9. jieba源码分析(二)
  10. Java动态代理实现(转载\整理)
  11. 深入理解JavaScript系列
  12. for循环的类型以及while循环
  13. vi-vim (十五):显示与设置选项
  14. 计算机通过注册表修改摄像机设备的名称
  15. 免费的录屏软件Capture
  16. 色散方程用matlab编译,急切求助用matlab曲线拟合色散方程 - 程序语言 - 小木虫 - 学术 科研 互动社区...
  17. 【接力题典1800记录】不定积分
  18. 加快二代支付系统建设改进央行支付清算服务
  19. 两年软件开发工作总结及未来展望
  20. 如何使用微软提供的TCHAR.H头文件

热门文章

  1. 【论文笔记】基于Control Barrier Function的二次规划(QP)控制
  2. Java学生成绩管理系统(含源码+论文+答辩PPT等)
  3. Java基础知识强化之网络编程笔记03:UDP之UDP协议发送数据 和 接收数据
  4. Linux Audio驱动系列(技巧篇) - tingmix调试抓Log
  5. 基于Huffman树的文件压缩(详细)
  6. 王者荣耀:达摩长头发了?星座皮肤再添大将,后羿CP皮肤来袭!
  7. 退出计算机二级培训的申请书,退出培训的申请怎么写
  8. 计算机工程与应用发票,计算机工程与应用
  9. HDU ACM Steps 攻略
  10. win7下安装Ubuntu16.04系统