Opencv实现行人检测(HOG + SVM)

1. 理论基础

使用OpenCv进行行人检测的主要思想: HOG + SVM
HOG: 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。HOG特征通过计算和统计图像局部区域的梯度方向直方图来构成特征.
SVM: (Support Vector Machine)指的是支持向量机,是常见的一种判别方法。在机器学习领域,是一个有监督的学习模型,通常用来进行模式识别、分类以及回归分析, 在行人检测中可以用作区分行人和非行人的分类器。

在使用HOG + SVM进行行人检测时, 采集HOG特征的主要思想是通过对一幅图像进行分析, 局部目标的表象和形状可以被剃度或者边缘密度方向分布很好的好的描述. 我们对图像的各个像素点采集土堆或者边缘的方向直方图, 根据直方图的信息就可以描述图片的特征. 好在OpenCv 中已经提供了计算HOG特征的方法, 根据采集到的HOG特征向量, 供SVM分类使用. SVM简单来说就是一个分类器, 在行人检测中就可以转化为行人与非行人的两类分类问题, 在OpenCv中运用到的是基于网格法的SVM.使用采集到的正样本(行人)和负样本(非行人, 可以是汽车, 树木, 路灯等等)的HOG特征, 然后使用SVM分类器进行训练, 得到行人检测模型, 进行行人检测.

2. 训练和测试

分为以下几个过程:
1. 准备训练样本集合: 包括正样本集合和负样本集合.
2. 对训练样本进行处理, 根据法国国家信息与自动化研究所行人数据库(INRIA Person DataBase)给出的样本集和图像信息, 进行样本采集.(Tools类中的 ImgCut() 函数)(这里进行处理的主要作用是对样本进行归一化, 将其归一到一个尺度(64*120))
3. 提取正样本的HOG特征.
4. 提取负样本的HOG特征.
5. 对正负样本进行标记, 正样本为1, 负样本为0.
6. 将正负样本的HOG特征及正负样本的标签输入 SVM 进行训练.
7. 训练后SVM 的结果保存在 Pedestrian.xml文件中.
8. 对得到的Pedestrian.xml文件输入进SVM得到行人检测分类器, 进行行人检测, 行人检测的主要会应用于智能交通, 此程序不仅可以对图片处理,还可以对视频进行处理, 并且是一个可视化的过程, 这里的视频数据来自加州理工行人检测基准数据(Caltech Pedestrian Detection Benchmark).
9. 对于难例的处理, 所谓的难例就是第一次训练出的分类器负样本原图中检测到的有行人的样本, 这些误报使得行人检测的分类器不是那么准确, 所以可以将误报的矩形框保存为新的负样本, 对新的负样本进行二次训练, 实现难例的处理.
注: 训练和测试数据集见附录, 结果见附件.

3. 模型及结果优缺点分析.

(1)此HOG + SVM进行行人检测的模型的分辨特征有以下几个:
1. 对于特征明显行人分辨能力强.
2. 目标单一时分辨能力强.
3. 干扰较少时分辨能力强.
(2)不足:
对于人群较多的图片和人物特征不明显的图片分辨能力较差.
(3)对于不足的改进:
1. 使用更多的样本进行训练.
2. 对于分辨错误的难例进行二次训练.

4. 模型建立中发现的问题及改进方法

在进行HOG + SVM进行行人检测时, 时间消耗较长.对于训练的2416个正样本和12180个负样本进行两次训练共使用了595.919秒.
改进方法可以是进行CPU 并行优化, 可以分为三个线程, 确保每一个CPU核心都是满载.
1. 图像的预处理.
2. 提取HOG特征.
3. 使用SVM训练.

5. 行人检测OpenCv 代码(C++)

 1. Tools类(处理图片)
#include "opencv2/core/core.hpp"    
#include "opencv2/objdetect.hpp"  
#include "opencv2/core/cuda.hpp"  
#include "opencv2/highgui/highgui.hpp"    
#include "opencv2/imgproc/imgproc.hpp"    
#include "opencv2/video/video.hpp"    
#include "opencv2/ml.hpp"  
#include "opencv2/opencv.hpp"  
#include <opencv2/objdetect/objdetect.hpp>    
#include <opencv2/imgcodecs.hpp>  
#include <stdlib.h>  
#include <time.h>  
#include <algorithm>  
#include <math.h>  
#include <iostream>    
#include <vector>  
#include <fstream>  
#include <cstdlib>
using namespace std;
using namespace cv;
using namespace cv::ml;

class Tools
{
public:
    Tools();
    int CropImageCount = 0; //裁剪出来的负样本图片个数    
    void ImgCut()
    {
        Mat src;
        string ImgName;

        char saveName[256];//裁剪出来的负样本图片文件名    
        ifstream fin("E:\\Program\\Vstudio\\OpenCv\\picture\\INRIAPerson\\Train\\neg.lst");//打开原始负样本图片文件列表    

        //一行一行读取文件列表    
        while (getline(fin, ImgName))
        {
            cout << "处理:" << ImgName << endl;
            ImgName = "E:\\Program\\Vstudio\\OpenCv\\picture\\INRIAPerson\\" + ImgName;

            src = imread(ImgName, 1);//读取图片    
                                 //cout<<"宽:"<<src.cols<<",高:"<<src.rows<<endl;    
//图片大小应该能能至少包含一个64*128的窗口    
            if (src.cols >= 64 && src.rows >= 128)
            {
                srand(time(NULL));//设置随机数种子  time(NULL)表示当前系统时间  

                                  //从每张图片中随机采样10个64*128大小的不包含人的负样本    
                for (int i = 0; i<10; i++)
                {
                    int x = (rand() % (src.cols - 64)); //左上角x坐标    
                    int y = (rand() % (src.rows - 128)); //左上角y坐标    
                                                         //cout<<x<<","<<y<<endl;    
                    Mat imgROI = src(Rect(x, y, 64, 128));
                    sprintf(saveName, "E:\\Program\\Vstudio\\OpenCv\\picture\\INRIAPerson\\negphoto\\noperson%06d.jpg", ++CropImageCount);//生成裁剪出的负样本图片的文件名    
                    imwrite(saveName, imgROI);//保存文件    
                }
            }
        }
    }
    ~Tools();
};
2. Pedestrian类(行人检测)
主要包括以下函数:
(1) 取得SVM分类器
void get_svm_detector(const Ptr< SVM >& svm, vector< float > & hog_detector)
(2) 转化OpenCv机器学习算法所使用的训练和样本集
void convert_to_ml(const vector< Mat > & train_samples, Mat& trainData)
(3) 载入目录的图片样本
void load_images(const String & dirname, vector< Mat > & img_lst, bool showImages = false)
(4) 计算HOG特征
void computeHOGs(const Size wsize, const vector< Mat > & img_lst, vector< Mat > & gradient_lst)
(5) 测试已经训练的分类器
int test_trained_detector(String obj_det_filename, String test_dir, String videofilename)
#include "opencv2/core/core.hpp"    
#include "opencv2/objdetect.hpp"  
#include "opencv2/core/cuda.hpp"  
#include "opencv2/highgui/highgui.hpp"    
#include "opencv2/imgproc/imgproc.hpp"    
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值