精华内容
下载资源
问答
  • 1000张行人检测负样本,分辨率为320X240,可用于训练行人检测分类器,本人已使用样本训练出.xml分类器,检测效果良好。另外正样本(POS)如需要请见另一个资源(负样本也很多,正负样本上传容量受限)。
  • 结合k-均值聚类缓解行人检测正负样本不平衡问题.pdf
  • 2400多张行人检测的正样本,分辨率为96X160,可用于训练行人检测分类器,本人已使用样本训练出.xml分类器,检测效果良好。另外负样本(NEG)如需要请见另一个资源(负样本也很多,正负样本上传容量受限)。
  • 在2005年CVPR上,来自法国的研究人员Navneet Dalal 和Bill Triggs提出利用Hog进行特征提取,利用线性SVM作为分类器,从而实现行人检测。而这两位也通过大量的测试发现,Hog+SVM是速度和效果综合平衡性能较好的一...

     在2005年CVPR上,来自法国的研究人员Navneet Dalal 和Bill Triggs提出利用Hog进行特征提取,利用线性SVM作为分类器,从而实现行人检测。而这两位也通过大量的测试发现,Hog+SVM是速度和效果综合平衡性能较好的一种行人检测方法。后来,虽然很多研究人员也提出了很多改进的行人检测算法,但基本都以该算法为基础框架。因此,Hog+SVM也成为一个里程表式的算法被写入到OpenCV中。在OpenCV2.0之后的版本,都有Hog特征描述算子的API,而至于SVM,早在OpenCV1.0版本就已经集成进去了;OpenCV虽然提供了Hog和SVM的API,也提供了行人检测的sample,遗憾的是,OpenCV并没有提供样本训练的sample。这也就意味着,很多人只能用OpenCV自带的已经训练好的分类器来进行行人检测。然而,OpenCV自带的分类器是利用Navneet Dalal和Bill Triggs提供的样本进行训练的,不见得能适用于你的应用场合。因此,针对你的特定应用场景,很有必要进行重新训练得到适合你的分类器。本文的目的,正在于此。

    重新训练行人检测的流程:

    (1)准备训练样本集合;包括正样本集和负样本集;根据机器学习的基础知识我们知道,要利用机器学习算法进行样本训练,从而得到一个性能优良的分类器,训练样本应该是无限多的,而且训练样本应该覆盖实际应用过程中可能发生的各种情况。(很多朋友,用10来个正样本,10来个负样本进行训练,之后,就进行测试,发现效果没有想象中的那么好,就开始发牢骚,抱怨。。。对于这些人,我只能抱歉的说,对于机器学习、模式识别的认识,你还处于没有入门的阶段);实际应用过程中,训练样本不可能无限多,但无论如何,三五千个正样本,三五千个负样本,应该不是什么难事吧?(如果连这个都做不到,建议你别搞机器学习,模式识别了;训练素材都没有,怎么让机器学习到足够的信息呢?)

    (2)收集到足够的训练样本之后,你需要手动裁剪样本。例如,你想用Hog+SVM来对商业步行街的监控画面中进行行人检测,那么,你就应该用收集到的训练样本集合,手动裁剪画面中的行人(可以写个简单程序,只需要鼠标框选一下,就将框选区域保存下来)。

    (3)裁剪得到训练样本之后,将所有正样本放在一个文件夹中;将所有负样本放在另一个文件夹中;并将所有训练样本缩放到同样的尺寸大小。OpenCV自带的例子在训练时,就是将样本缩放为64*128进行训练的;

    (4)提取所有正样本的Hog特征;

    (5)提取所有负样本的Hog特征;

    (6)对所有正负样本赋予样本标签;例如,所有正样本标记为1,所有负样本标记为0;

    (7)将正负样本的Hog特征,正负样本的标签,都输入到SVM中进行训练;Dalal在论文中考虑到速度问题,建议采用线性SVM进行训练。这里,不妨也采用线性SVM;

    (8)SVM训练之后,将结果保存为文本文件。

    (9)线性SVM进行训练之后得到的文本文件里面,有一个数组,叫做support vector,还有一个数组,叫做alpha,有一个浮点数,叫做rho;将alpha矩阵同support vector相乘,注意,alpha*supportVector,将得到一个列向量。之后,再该列向量的最后添加一个元素rho。如此,变得到了一个分类器,利用该分类器,直接替换opencv中行人检测默认的那个分类器(cv::HOGDescriptor::setSVMDetector()),就可以利用你的训练样本训练出来的分类器进行行人检测了。

    下面给出样本训练的参考代码:

    class Mysvm: public CvSVM  
    {  
    public:  
        int get_alpha_count()  
        {  
            return this->sv_total;  
        }  
      
        int get_sv_dim()  
        {  
            return this->var_all;  
        }  
      
        int get_sv_count()  
        {  
            return this->decision_func->sv_count;  
        }  
      
        double* get_alpha()  
        {  
            return this->decision_func->alpha;  
        }  
      
        float** get_sv()  
        {  
            return this->sv;  
        }  
      
        float get_rho()  
        {  
            return this->decision_func->rho;  
        }  
    };  
      
    void Train()  
    {  
        char classifierSavePath[256] = "c:/pedestrianDetect-peopleFlow.txt";  
      
        string positivePath = "E:\\pictures\\train1\\pos\\";  
        string negativePath = "E:\\pictures\\train1\\neg\\";  
      
        int positiveSampleCount = 4900;  
        int negativeSampleCount = 6192;  
        int totalSampleCount = positiveSampleCount + negativeSampleCount;  
      
        cout<<"//"<<endl;  
        cout<<"totalSampleCount: "<<totalSampleCount<<endl;  
        cout<<"positiveSampleCount: "<<positiveSampleCount<<endl;  
        cout<<"negativeSampleCount: "<<negativeSampleCount<<endl;  
      
        CvMat *sampleFeaturesMat = cvCreateMat(totalSampleCount , 1764, CV_32FC1);  
        //64*128的训练样本,该矩阵将是totalSample*3780,64*64的训练样本,该矩阵将是totalSample*1764  
        cvSetZero(sampleFeaturesMat);    
        CvMat *sampleLabelMat = cvCreateMat(totalSampleCount, 1, CV_32FC1);//样本标识    
        cvSetZero(sampleLabelMat);    
      
        cout<<"************************************************************"<<endl;  
        cout<<"start to training positive samples..."<<endl;  
      
        char positiveImgName[256];  
        string path;  
        for(int i=0; i<positiveSampleCount; i++)    
        {    
            memset(positiveImgName, '\0', 256*sizeof(char));  
            sprintf(positiveImgName, "%d.jpg", i);  
            int len = strlen(positiveImgName);  
            string tempStr = positiveImgName;  
            path = positivePath + tempStr;  
      
            cv::Mat img = cv::imread(path);  
            if( img.data == NULL )  
            {  
                cout<<"positive image sample load error: "<<i<<" "<<path<<endl;  
                system("pause");  
                continue;  
            }  
      
            cv::HOGDescriptor hog(cv::Size(64,64), cv::Size(16,16), cv::Size(8,8), cv::Size(8,8), 9);  
            vector<float> featureVec;   
      
            hog.compute(img, featureVec, cv::Size(8,8));    
            int featureVecSize = featureVec.size();  
      
            for (int j=0; j<featureVecSize; j++)    
            {         
                CV_MAT_ELEM( *sampleFeaturesMat, float, i, j ) = featureVec[j];   
            }    
            sampleLabelMat->data.fl[i] = 1;  
        }  
        cout<<"end of training for positive samples..."<<endl;  
      
        cout<<"*********************************************************"<<endl;  
        cout<<"start to train negative samples..."<<endl;  
      
        char negativeImgName[256];  
        for (int i=0; i<negativeSampleCount; i++)  
        {    
            memset(negativeImgName, '\0', 256*sizeof(char));  
            sprintf(negativeImgName, "%d.jpg", i);  
            path = negativePath + negativeImgName;  
            cv::Mat img = cv::imread(path);  
            if(img.data == NULL)  
            {  
                cout<<"negative image sample load error: "<<path<<endl;  
                continue;  
            }  
      
            cv::HOGDescriptor hog(cv::Size(64,64), cv::Size(16,16), cv::Size(8,8), cv::Size(8,8), 9);    
            vector<float> featureVec;   
      
            hog.compute(img,featureVec,cv::Size(8,8));//计算HOG特征  
            int featureVecSize = featureVec.size();    
      
            for ( int j=0; j<featureVecSize; j ++)    
            {    
                CV_MAT_ELEM( *sampleFeaturesMat, float, i + positiveSampleCount, j ) = featureVec[ j ];  
            }    
      
            sampleLabelMat->data.fl[ i + positiveSampleCount ] = -1;  
        }    
      
        cout<<"end of training for negative samples..."<<endl;  
        cout<<"********************************************************"<<endl;  
        cout<<"start to train for SVM classifier..."<<endl;  
      
        CvSVMParams params;    
        params.svm_type = CvSVM::C_SVC;    
        params.kernel_type = CvSVM::LINEAR;    
        params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, FLT_EPSILON);  
        params.C = 0.01;  
      
        Mysvm svm;  
        svm.train( sampleFeaturesMat, sampleLabelMat, NULL, NULL, params ); //用SVM线性分类器训练  
        svm.save(classifierSavePath);  
      
        cvReleaseMat(&sampleFeaturesMat);  
        cvReleaseMat(&sampleLabelMat);  
      
        int supportVectorSize = svm.get_support_vector_count();  
        cout<<"support vector size of SVM:"<<supportVectorSize<<endl;  
        cout<<"************************ end of training for SVM ******************"<<endl;  
      
        CvMat *sv,*alp,*re;//所有样本特征向量   
        sv  = cvCreateMat(supportVectorSize , 1764, CV_32FC1);  
        alp = cvCreateMat(1 , supportVectorSize, CV_32FC1);  
        re  = cvCreateMat(1 , 1764, CV_32FC1);  
        CvMat *res  = cvCreateMat(1 , 1, CV_32FC1);  
      
        cvSetZero(sv);  
        cvSetZero(re);  
        
        for(int i=0; i<supportVectorSize; i++)  
        {  
            memcpy( (float*)(sv->data.fl+i*1764), svm.get_support_vector(i), 1764*sizeof(float));      
        }  
      
        double* alphaArr = svm.get_alpha();  
        int alphaCount = svm.get_alpha_count();  
      
        for(int i=0; i<supportVectorSize; i++)  
        {  
            alp->data.fl[i] = alphaArr[i];  
        }  
        cvMatMul(alp, sv, re);  
      
        int posCount = 0;  
        for (int i=0; i<1764; i++)  
        {  
            re->data.fl[i] *= -1;  
        }  
      
        FILE* fp = fopen("c:/hogSVMDetector-peopleFlow.txt","wb");  
        if( NULL == fp )  
        {  
            return 1;  
        }  
        for(int i=0; i<1764; i++)  
        {  
            fprintf(fp,"%f \n",re->data.fl[i]);  
        }  
        float rho = svm.get_rho();  
        fprintf(fp, "%f", rho);  
        cout<<"c:/hogSVMDetector.txt 保存完毕"<<endl;//保存HOG能识别的分类器  
        fclose(fp);  
      
        return 1;  
    }  

     

    展开全文
  • 人脸识别正负样本集,负样本2500多,且为处理后灰度图;正样本1000多张,且为归一化后的图片;同时负样本也是适应于车辆识别,车牌识别,行人检测
  • 人脸识别正负样本集,负样本2500多,且为处理后灰度图;正样本1000多张,且为归一化后的图片;同时负样本也是适应于车辆识别,车牌识别,行人检测
  • 有哪位大侠有行人检测分类器训练用的正负样本啊,给我发一份感激不尽!谢谢
  • /********************************* 随机剪裁负样本 *******************************************/ void crop_negsample_random() { string imgName; char saveName[200]; //读入文件txt名 ifstream fileNeg(...

    1,示例代码

    #include <iostream>
    #include <fstream>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/objdetect/objdetect.hpp>
    #include <opencv2/ml/ml.hpp>
    #include <sys/time.h>
    
    using namespace std;
    using namespace cv;
    using namespace cv::ml;
    
    
    #define PosSamNO 2416  //原始正样本数
    #define NegSamNO 6070 // 剪裁后的负样本数6070
    #define cropNegNum 1214  //原始负样本数
    
    #define HardExampleNO 10896 // hard negative num//10896
    #define AugPosSamNO 0 //Aug positive num
    
    #define TRAIN true //是否进行训练,true表示重新训练,false表示读取xml文件中的SVM模型
    #define CENTRAL_CROP true //true:训练时,对96*160的INRIA正样本图片剪裁出中间的64*128大小人体
    #define crop_negsample true //随机剪裁负样本数的开关
    
    /*********************************    随机剪裁负样本   *******************************************/
    void crop_negsample_random()
    {
        string imgName;
        char saveName[200];
        //读入文件txt名
        ifstream fileNeg("/Users/macbookpro/CLionProjects/pedestrian_detection/img_dir/sample_neg.txt");
    
        int num=0;
        //如果文件存在,则先删除该文件
        //写入文件txt名
        ofstream fout("/Users/macbookpro/CLionProjects/pedestrian_detection/img_dir/sample_new_neg.txt",ios::trunc);//加路径
    
        //读取负样本
        //当i小于负样本数量,进行循环,同时读入文件fileNeg中值到imgName中
        for (int i = 0;i < cropNegNum && getline(fileNeg, imgName); i++)
        {
            imgName = "/Users/macbookpro/CLionProjects/pedestrian_detection/normalized_images/train/neg/" + imgName;
            //IMREAD_UNCHANGED :不进行转化,比如保存为了16位的图片,读取出来仍然为16位。
            Mat img = imread(imgName, IMREAD_UNCHANGED);
            //Linux时间函数
            //tv_sec;        /* Seconds. */
            //tv_usec;  /* Microseconds. */
            struct timeval tv;
            if (img.empty())//如果图片不存在,则输出
            {
                cout << "can not load the image:" << imgName << endl;
                continue;
            }
            if (img.cols >= 64 && img.rows >= 128)//如果图片尺寸大于64或者128时
            {
                num = 0;
                //从每张图片中随机剪裁5(10)张64*128的负样本
                for (int j = 0;j < 5;j++)
                {
    
                    //gettimeofday()会把目前的时间用tv 结构体返回
                    gettimeofday(&tv,NULL);
                    srand(tv.tv_usec);//利用系统时间(微妙),设置随机数种子
    
                    int x = rand() % (img.cols - 64); //左上角x, 范围为[0,cols - 64)
                    int y = rand() % (img.rows - 128); //左上角y, 范围为[0,rows - 64)
                    cout << "x:" << x << "y:" << y <<endl;
                    Mat src = img(Rect(x, y, 64, 128));//Rect(x,y,64,128)从左上角坐标为(x,y)位置剪裁一个宽64,高128的矩形
                    //把剪裁后的图片名称存入svaeName变量中
                    sprintf(saveName, "/Users/macbookpro/CLionProjects/pedestrian_detection/normalized_images/train/new_neg/neg%dCropped%d.png",i, num);
                    //把剪裁后的图片src,另存为名字为svaeName的图片
                    imwrite(saveName,src);
    
                    //保存裁剪得到的图片名称到txt文件,换行分隔
                    if(i<(cropNegNum-1)){
                        fout <<"neg" << i << "Cropped"<< num++ << ".png"<< endl;
                    }
                    else if(i==(cropNegNum-1) && j<4){
                        fout <<"neg" << i << "Cropped"<< num++ << ".png"<< endl;
                    }
                    else{
                        fout <<"neg" << i << "Cropped"<< num++ << ".png";
                    }
                }
            }
        }
        fout.close();//关闭文件
        cout << "crop ok!" << endl;
    }
    
    int main()
    {
        if(crop_negsample){
            // crop_negsample_random(); //裁剪负样本
        }
        //检测窗口(64,128),块尺寸(16,16),块步长(8,8),cell尺寸(8,8),直方图bin个数9
        HOGDescriptor hog(Size(64,128),Size(16,16),Size(8,8),Size(8,8),9);
        int DescriptorDim;//HOG描述子的维数,由图片大小、检测窗口大小、块大小、细胞单元中直方图bin个数决定
        Ptr<SVM> svm = SVM::create();// 创建分类器
    
        if(TRAIN)//若TRAIN为true,重新训练分类器
        {
            string ImgName;//图片名(绝对路径)
            //正样本图片的文件名列表
            ifstream finPos("/Users/macbookpro/CLionProjects/pedestrian_detection/img_dir/sample_pos.txt");
            // ifstream finNeg("../sample_neg.txt");
            //负样本图片的文件名列表
            ifstream finNeg("/Users/macbookpro/CLionProjects/pedestrian_detection/img_dir/sample_new_neg.txt");
            //HardExample负样本的文件名列表
            ifstream finHardNeg("/Users/macbookpro/CLionProjects/pedestrian_detection/img_dir/hard_neg.txt");
    
            //if (!finPos || !finNeg || !finHardNeg)
            if (!finPos || !finNeg)
            {
                cout << "Pos/Neg/hardNeg imglist reading failed..." << endl;
                return 1;
            }
    
            Mat sampleFeatureMat;
            Mat sampleLabelMat;
    
            //loading original positive examples...
            for(int num=0; num < PosSamNO && getline(finPos,ImgName); num++)
            {
                cout <<"Now processing original positive image: " << ImgName << endl;
                ImgName = "/Users/macbookpro/CLionProjects/pedestrian_detection/normalized_images/train/pos/" + ImgName;
                Mat src = imread(ImgName);//读取图片
    
                if(CENTRAL_CROP)//true:训练时,对96*160的INRIA正样本图片剪裁出中间的64*128大小人体
                    if(src.cols >= 96 && src.rows >= 160)
                    //resize(src,src,Size(64,128));
                        src = src(Rect(16,16,64,128));
                   // else cout << "error" << endl; //测试
    
                vector<float> descriptors;//HOG描述子向量
                hog.compute(src, descriptors, Size(8,8));//计算HOG描述子,检测窗口移动步长(8,8)
                //cout<<"描述子维数:"<<descriptors.size()<<endl;
    
    
                //处理第一个样本时初始化特征向量矩阵和类别矩阵,因为只有知道了特征向量的维数才能初始化特征向量矩阵
                if(num == 0 )
                {
                    DescriptorDim = descriptors.size();//HOG描述子的维数
                    //初始化所有训练样本的特征向量组成的矩阵,行数等于所有样本的个数,列数等于HOG描述子维数sampleFeatureMat
                    sampleFeatureMat = Mat::zeros(PosSamNO +AugPosSamNO +NegSamNO +HardExampleNO, DescriptorDim, CV_32FC1);//CV_32FC1:CvMat数据结构参数
                    //初始化训练样本的类别向量,行数等于所有样本的个数,列数等于1;1表示有人,0表示无人
                    sampleLabelMat = Mat::zeros(PosSamNO +AugPosSamNO +NegSamNO +HardExampleNO, 1, CV_32SC1);//sampleLabelMat的数据类型必须为有符号整数型
                }
    
                //将计算好的HOG描述子复制到样本特征矩阵sampleFeatureMat
                for(int i=0; i<DescriptorDim; i++)
                    sampleFeatureMat.at<float>(num,i) = descriptors[i];//第num个样本的特征向量中的第i个元素
                sampleLabelMat.at<int>(num,0) = 1;//正样本类别为1,有人
            }
            finPos.close();
    
    
            //依次读取负样本图片,生成HOG描述子
            for(int num = 0; num < NegSamNO && getline(finNeg,ImgName); num++)
            {
                cout<<"Now processing original negative image: "<<ImgName<<endl;
                // ImgName = "../normalized_images/train/neg/" + ImgName;
                //加上负样本的路径名
                ImgName = "/Users/macbookpro/CLionProjects/pedestrian_detection/normalized_images/train/new_neg/" + ImgName;
                Mat src = imread(ImgName);//读取图片
    
                vector<float> descriptors;//HOG描述子向量
                hog.compute(src,descriptors,Size(8,8));//计算HOG描述子,检测窗口移动步长(8,8)
    
                //将计算好的HOG描述子复制到样本特征矩阵sampleFeatureMat
                for(int i=0; i<DescriptorDim; i++)
                    sampleFeatureMat.at<float>(num+PosSamNO+AugPosSamNO,i) = descriptors[i];//第PosSamNO+num个样本的特征向量中的第i个元素
                sampleLabelMat.at<int>(num +PosSamNO +AugPosSamNO, 0) = -1;//负样本类别为-1,无人
    
            }
            finNeg.close();
    
            //依次读取HardExample负样本图片,生成HOG描述子
            for(int num = 0; num < HardExampleNO && getline(finHardNeg,ImgName); num++)
            {
                cout<<"Now processing original hard negative image: "<<ImgName<<endl;
                // ImgName = "../normalized_images/train/neg/" + ImgName;
                //加上负样本的路径名
                ImgName = "/Users/macbookpro/CLionProjects/pedestrian_detection/normalized_images/train/hard_neg/" + ImgName;
                Mat src = imread(ImgName);//读取图片
    
                vector<float> descriptors;//HOG描述子向量
                hog.compute(src,descriptors,Size(8,8));//计算HOG描述子,检测窗口移动步长(8,8)
                //cout<<"描述子维数:"<<descriptors.size()<<endl;
    
                //将计算好的HOG描述子复制到样本特征矩阵sampleFeatureMat
                for(int i=0; i<DescriptorDim; i++)
                    sampleFeatureMat.at<float>(num+ PosSamNO + NegSamNO + AugPosSamNO,i) = descriptors[i];//第PosSamNO+num个样本的特征向量中的第i个元素
                sampleLabelMat.at<int>(num + PosSamNO + NegSamNO + AugPosSamNO, 0) = -1;//负样本类别为-1,无人
    
            }
            finHardNeg.close();
    
    
    
            svm ->setType(SVM::C_SVC);
            svm ->setC(0.01);
            svm ->setKernel(SVM::LINEAR);
            // svm ->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 3000, 1e-6));
            svm ->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-3));
    
            cout<<"Starting training..."<<endl;
            svm ->train(sampleFeatureMat, ROW_SAMPLE, sampleLabelMat);
            cout<<"Finishing training..."<<endl;
    
            svm ->save("/Users/macbookpro/CLionProjects/pedestrian_detection/data/SVM_HOG.xml");
    
        }
        else {
            svm = SVM::load( "/Users/macbookpro/CLionProjects/pedestrian_detection/data/SVM_HOG_2.xml" );
        }
        cout << "loaded SVM_HOG.xml file"  << endl;
    
        int svdim = svm ->getVarCount();//特征向量的维数,即HOG描述子的维数
        //支持向量的个数
        Mat svecsmat = svm ->getSupportVectors();//svecsmat元素的数据类型为float
        int numofsv = svecsmat.rows;
    
        // Mat alphamat = Mat::zeros(numofsv, svdim, CV_32F);//alphamat和svindex必须初始化,否则getDecisionFunction()函数会报错
        Mat alphamat = Mat::zeros(numofsv, svdim, CV_32F);
        Mat svindex = Mat::zeros(1, numofsv,CV_64F);
        cout << "after initialize the value of alphamat is  " << alphamat.size()  << endl;
    
        Mat Result;
        double rho = svm ->getDecisionFunction(0, alphamat, svindex);
    
        cout << "the value of rho is  " << rho << endl;
        alphamat.convertTo(alphamat, CV_32F);//将alphamat元素的数据类型重新转成CV_32F
        cout << "the value of alphamat is  " << alphamat << endl;
        cout << "the size of alphamat is  " << alphamat.size() << endl;
        cout << "the size of svecsmat is  " << svecsmat.size() << endl;
    
        //计算-(alphaMat * supportVectorMat),结果放到resultMat中
        Result = -1 * alphamat * svecsmat;//float
    
        cout << "the value of svdim is  " << svdim << endl;
    
        //得到最终的setSVMDetector(const vector<float>& detector)参数中可用的检测子
        vector<float> vec;
        //将resultMat中的数据复制到数组vec中
        for (int i = 0; i < svdim; ++i)
        {
            vec.push_back(Result.at<float>(0, i));
        }
        vec.push_back(rho);
    
        cout << "going to write the HOGDetectorForOpenCV.txt file"  << endl;
        //saving HOGDetectorForOpenCV.txt
        ofstream fout("/Users/macbookpro/CLionProjects/pedestrian_detection/data/HOGDetectorForOpenCV.txt");
        for (int i = 0; i < vec.size(); ++i)
        {
            fout << vec[i] << endl;
        }
        fout.close();//关闭文件
    
    
        /*********************************Testing**************************************************/
        HOGDescriptor hog_test;
        hog_test.setSVMDetector(vec);
    
        // Mat src = imread("../person_and_bike_177b.png");
        Mat src = imread("/Users/macbookpro/CLionProjects/pedestrian_detection/data/Test.jpg");
        vector<Rect> found, found_filtered;
        hog_test.detectMultiScale(src, found, 0, Size(8,8), Size(32,32), 1.05, 2);
    
        cout<<"found.size : "<<found.size()<<endl;
    
        //找出所有没有嵌套的矩形框r,并放入found_filtered中,如果有嵌套的话,则取外面最大的那个矩形框放入found_filtered中
        for(int i=0; i < found.size(); i++)
        {
            Rect r = found[i];
            int j=0;
            for(; j < found.size(); j++)
                if(j != i && (r & found[j]) == r)
                    break;
            if( j == found.size())
                found_filtered.push_back(r);
        }
    
    
        //画矩形框,因为hog检测出的矩形框比实际人体框要稍微大些,所以这里需要做一些调整
        for(int i=0; i<found_filtered.size(); i++)
        {
            Rect r = found_filtered[i];
            r.x += cvRound(r.width*0.1);
            r.width = cvRound(r.width*0.8);
            r.y += cvRound(r.height*0.07);
            r.height = cvRound(r.height*0.8);
            rectangle(src, r.tl(), r.br(), Scalar(0,255,0), 3);
        }
    
        imwrite("ImgProcessed.jpg",src);
        namedWindow("src",0);
        imshow("src",src);
        waitKey(0);
    
        /******************读入单个64*128的测试图并对其HOG描述子进行分类*********************/
        读取测试图片(64*128大小),并计算其HOG描述子
        //Mat testImg = imread("person014142.jpg");
        //Mat testImg = imread("noperson000026.jpg");
        //vector<float> descriptor;
        //hog.compute(testImg,descriptor,Size(8,8));//计算HOG描述子,检测窗口移动步长(8,8)
        //Mat testFeatureMat = Mat::zeros(1,3780,CV_32FC1);//测试样本的特征向量矩阵
        //将计算好的HOG描述子复制到testFeatureMat矩阵中
        //for(int i=0; i<descriptor.size(); i++)
        //	testFeatureMat.at<float>(0,i) = descriptor[i];
    
        //用训练好的SVM分类器对测试图片的特征向量进行分类
        //int result = svm.predict(testFeatureMat);//返回类标
        //cout<<"分类结果:"<<result<<endl;
    
        return 0;
    }
    
    
    

     

    展开全文
  • 行人检测训练库

    热门讨论 2016-12-14 14:44:23
    行人检测训练库,负样本12000,正样本2400.
  • hog+svm负样本处理

    热门讨论 2014-11-24 17:26:38
    hog特征+svm分类器行人检测训练的负样本处理程序,千万注意路径问题
  • 难例(或叫做难样本,Hard Example,Hard Negative,Hard Instance)是指利用第一次训练的分类器在负样本原图(肯定没有人体)上进行行人检测时所有检测到的矩形框,这些矩形框区域很明显都是误报,把这些误报的矩形框...

    难例(或叫做难样本,Hard Example,Hard Negative,Hard Instance)是指利用第一次训练的分类器在负样本原图(肯定没有人体)上进行行人检测时所有检测到的矩形框,这些矩形框区域很明显都是误报,把这些误报的矩形框保存为图片,加入到初始的负样本集合中,重新进行SVM的训练,可显著减少误报。这种方法叫做自举法(Bootstrap),自举法首先使用初始负样本集来训练一个模型,然后收集被这个初始模型错误分类的负样本来形成一个负样本难例集。用此负样本难例集训练新的模型,此过程可以重复多次。

    比如典型的误报如下:



    上图中将树干误认为是人体,这些就是Hard Example,将这些矩形框保存为64*128的图片文件,加入到负样本集合中。

    也就是说,难例就是分错类的负样本,将难例加入负样本集合进行二次训练就是告诉分类器:“这些是你上次分错类的,要吸取教训,改正错误”

    初次训练SVM+HOG分类器见:自己训练SVM分类器进行HOG行人检测

    Navneet Dalal在CVPR2005上的HOG原论文翻译见:http://blog.csdn.net/masibuaa/article/details/14056807


    #include <iostream>
    #include <fstream>
    #include <string>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/objdetect/objdetect.hpp>
    #include <opencv2/ml/ml.hpp>
    
    using namespace std;
    using namespace cv;
    
    int hardExampleCount = 0; //hard example计数
    
    int main()
    {
    	Mat src;
    	char saveName[256];//剪裁出来的hard example图片的文件名
    	string ImgName;
    	ifstream fin_detector("HOGDetectorForOpenCV_2400PosINRIA_12000Neg.txt");//打开自己训练的SVM检测器文件
    	ifstream fin_imgList("INRIANegativeImageList.txt");//打开原始负样本图片文件列表
    	//ifstream fin_imgList("subset.txt");
    
    	//从文件中读入自己训练的SVM参数
    	float temp;
    	vector<float> myDetector;//3781维的检测器参数
    	while(!fin_detector.eof())
    	{
    		fin_detector >> temp;
    		myDetector.push_back(temp);//放入检测器数组
    	}
    	cout<<"检测子维数:"<<myDetector.size()<<endl;
    
    	//namedWindow("src",0);
    	HOGDescriptor hog;//HOG特征检测器
    	hog.setSVMDetector(myDetector);//设置检测器参数为自己训练的SVM参数
    
    	//一行一行读取文件列表
    	while(getline(fin_imgList,ImgName))
    	{
    		cout<<"处理:"<<ImgName<<endl;
    		string fullName = "D:\\DataSet\\INRIAPerson\\INRIAPerson\\Train\\neg\\" + ImgName;//加上路径名
    		src = imread(fullName);//读取图片
    		Mat img = src.clone();//复制原图
    
    		vector<Rect> found;//矩形框数组
    		//对负样本原图进行多尺度检测,检测出的都是误报
    		hog.detectMultiScale(src, found, 0, Size(8,8), Size(32,32), 1.05, 2);
    
    		//遍历从图像中检测出来的矩形框,得到hard example
    		for(int i=0; i < found.size(); i++)
    		{
    			//检测出来的很多矩形框都超出了图像边界,将这些矩形框都强制规范在图像边界内部
    			Rect r = found[i];
    			if(r.x < 0)
    				r.x = 0;
    			if(r.y < 0)
    				r.y = 0;
    			if(r.x + r.width > src.cols)
    				r.width = src.cols - r.x;
    			if(r.y + r.height > src.rows)
    				r.height = src.rows - r.y;
    
    			//将矩形框保存为图片,就是Hard Example
    			Mat hardExampleImg = src(r);//从原图上截取矩形框大小的图片
    			resize(hardExampleImg,hardExampleImg,Size(64,128));//将剪裁出来的图片缩放为64*128大小
    			sprintf(saveName,"hardexample%09d.jpg",hardExampleCount++);//生成hard example图片的文件名
    			imwrite(saveName, hardExampleImg);//保存文件
    
    
    			//画矩形框,因为hog检测出的矩形框比实际人体框要稍微大些,所以这里需要做一些调整
    			//r.x += cvRound(r.width*0.1);
    			//r.width = cvRound(r.width*0.8);
    			//r.y += cvRound(r.height*0.07);
    			//r.height = cvRound(r.height*0.8);
    			rectangle(img, r.tl(), r.br(), Scalar(0,255,0), 3);
    
    		}
    		//imwrite(ImgName,img);
    		//imshow("src",src);
    		//waitKey(100);//注意:imshow之后一定要加waitKey,否则无法显示图像
    
    	}
    
    	system("pause");
    }


    源码下载,环境为VS2010 + OpenCV2.4.4

    http://download.csdn.net/detail/masikkk/6549325



    from: http://blog.csdn.net/masibuaa/article/details/16113373

    展开全文
  • 一文读懂行人检测算法1引言行人检测可定义为判断输入图片或视频帧是否包含行人,如果有将其检测出来,并输出bounding box 级别的结果。由于行人兼具刚性和柔性物体的特性 ,外观易受穿着、尺度、遮挡、姿态和视角等...

    原标题:干货!一文读懂行人检测算法

    1引言

    行人检测可定义为判断输入图片或视频帧是否包含行人,如果有将其检测出来,并输出bounding box 级别的结果。由于行人兼具刚性和柔性物体的特性 ,外观易受穿着、尺度、遮挡、姿态和视角等影响,使得行人检测成为计算机视觉领域中一个既具有研究价值同时又极具挑战性的热门课题。

    行人检测系统的研究起始于二十世纪九十年代中期,是目标检测的一种。从最开始到2002 年,研究者们借鉴、引入了一些图像处理、模式识别领域的成熟方法,侧重研究了行人的可用特征、简单分类算法。自2005 年以来,行人检测技术的训练库趋于大规模化、检测精度趋于实用化、检测速度趋于实时化。随着高校、研究所以及汽车厂商的研究持续深入,行人检测技术得到了飞速的发展。本文主要介绍行人检测的特征提取、分类器的发展历程以及行人检测的现状。

    2特征提取2.12001~2005 特征提取

    在早期的 PDS 中,在早期的 PDS 中 ,大多数工作仅使用一种外观 特征或者一种运动特征,外观特征主要有原始灰度 和轮廓 ,也有少量工作使用了颜色. 由于每种特征的针对性不同 ,只使用一种特征的PDS 都难以获得较好的检测性能。

    随着时间的发展,出现了俩种不同的研究趋势,一种是对人的外观特征和运动特性更具针对性。

    (a)新的外观特征:

    ( Ⅰ) Amnon 等提出了基于人体的 9 个关键部位及其相对位置关系构成的 13 个关键特征 ;

    (Ⅱ) Havasi 提出了基于人腿的三次对称性特征

    (b) 新的运动特征: Ran 等提出了人腿形态周期性特征。

    (c)新的抽象特征:Lowe 提出来SIFT 特(一种计算机视觉的算法,用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量),它具有尺度不变的良好特征;Amnon 也将在这一特征引入到起 PDS 用于形状特征的表示。

    另一种是使用多种特征综合的表示方法.Viola在2003年提出综合使用外观和运动特征的特征联合表示方法,使用结合串联的组合分类机制。

    此外,在一些工作中,也开始实行在全局特征中加入局部特征作为补充,此种方法可以提高检测率,降低误差率,部分解决障碍物的遮挡问题。

    2.2 2005~2011 特征提取2.2.1行人特征

    a564d7eeea12d817aea11453467d22f8.png

    随着行人特征提取类型 逐渐发展,提取类型不仅仅只是外观和运动特征,慢慢增加,可分为三类:底层特征,基于学习的特征,以及混合特征。

    2.2.2底层特征 基于学习的特征 混合特征

    b4d95d288a43370d8c094e781f16ee24.png

    注:0 底层特征 1 基于学习的特征 2 混合特征

    3行人检测的进程3.1行人检测方法

    (1)以Gavrila 为代表的全局模板方法:基于轮廓的分层匹配算法,构造了将近 2500 个轮廓模板对行人进行匹配, 从而识别出行人。为了解决模板数量众多而引起的速度下降问题,采用了由粗到细的分层搜索策略以加快搜索速度。另外,匹配的时候通过计算模板与待检测窗口的距离变换来度量两者之间的相似性。

    (2)以Broggi 为代表的局部模板方法:利用不同大小的二值图像模板来对人头和肩部进行建模,通过将输入图像的边缘图像与该二值模板进行比较从而识别行人,该方法被用到意大利 Parma 大学开发的ARGO 智能车中。

    (3)以Lipton 为代表的光流检测方法:计算运动区域内的残余光流;

    (4)以Heisele 为代表的运动检测方法:提取行人腿部运动特征;

    (5)以Wohler 为代表的神经网络方法:构建一个自适应时间延迟神经网络来判断是否是人体的运动图片序列;

    以上方法,存在速度慢、检测率低、误报率高的特点。

    3.2分类器

    分类器的构造和实施大体会经过以下几个步骤:

    选定样本(包含正样本和负样本),将所有样本分成训练样本和测试样本两部分。

    在训练样本上执行分类器算法,生成分类模型。

    在测试样本上执行分类模型,生成预测结果。

    根据预测结果,计算必要的评估指标,评估分类模型的性能。

    4行人检测的现状4.1 基于背景建模

    背景建模方法,提取出前景运动的目标,在目标区域内进行特征提取,然后利用分类器进行分类,判断是否包含行人; 背景建模目前主要存在的问题:必须适应环境的变化(比如光照的变化造成图像色度的变化),机抖动引起画面的抖动(比如手持相机拍照时候的移动),图像中密集出现的物体(比如树叶或树干等密集出现的物体,要正确的检测出来),必须能够正确的检测出背景物体的改变(比如新停下的车必须及时的归为背景物体,而有静止开始移动的物体也需要及时的检测出来),以及物体检测中往往会出现Ghost 区域。

    4.2 基于统计学习的方法

    这也是目前行人检测最常用的方法,根据大量的样本构建行人检测分类器。提取的特征主要有目标的灰度、边缘、纹理、颜色、梯度直方图等信息。分类器主要包括神经网络、SVM、adaboost 以及现在被计算机视觉视为宠儿的深度学习。

    统计学习目前存在的难点:

    (a)行人的姿态、服饰各不相同、复杂的背景、不同的行人尺度以及不同的关照环境。

    (b)提取的特征在特征空间中的分布不够紧凑;

    (c)分类器的性能受训练样本的影响较大;

    (d)离线训练时的负样本无法涵盖所有真实应用场景的情况;目前的行人检测基本上都是基于法国研究人员 Dalal 在 2005 的

    CVPR 发表的HOG+SVM 的行人检测算法。HOG+SVM 作为经典算法也别集成到OpenCV 里面去了,可以直接调用实现行人检测为了解决速度问题可以采用背景差分法的统计学习行人检测,前提是背景建模的方法足够有效(即效果好速度快),目前获得比较好的检测效果的方法通常采用多特征融合的方法以及级联分类器。(常用的特征有Harry-like、Hog 特征、LBP 特征、Edgelet 特征、CSS 特征、COV 特征、积分通道特征以及CENTRIST 特征。

    2f2d6b7e27c08f3f274b2a23c37113ba.png

    图:基于场景模拟与统计学习的行人检测框架

    5关于Faster R-CNN 的行人检测5.1 Faster R-CNN 的缺点及处理方法

    Faster R-CNN 在目标检测上准确,但在行人检测上效果一般, Faster R-CNN 用于行人检测效果不好的原因有两个:

    (1)行人在图像中的尺寸较小,对于小物体, 提出的特征没有什么区分能力。

    针对该情况,可以浅层池化,通过hole algorithm(“ a trous”or filter rarefaction )来增加特征图的尺寸。

    (2)行人检测中的误检主要是背景的干扰,广义物体检测主要受多种类影响,存在大量困难负样本。 可以使用 cascaded Boosted Forest 来提取困难负样本,然后对样本进行赋予权重。直接训练 RPN 提出的深度卷积特征。

    5.2 方法

    通过RPN 生成卷积特征图和候选框,Faster R-CNN 的RPN 主要是用于在多类目标检测场景中解决多类推荐问题,因此可以简化 RPN 来进行单一问题检测。 通过Boosted Forest 作为分类器来提取卷积特征,从RPN 提取的区域,我们使用RoI 池化提取固定长度的特征。在此时要注意的是,不同于以前方法中会 fine-tune 膨胀之后的卷积核,只是来提取特征而不进行fine-tune(在这里有可能fine-tune之后RPN的整体效果下降了,但是可能提取高分辨特征的能力提升了),接下来实现细节。

    6总结

    本文通过从特征提取和分类器等来简单介绍行人检测的发展进程,同时也大致介绍了行人检测的现状以及较为详细的叙述了关于Faster R-cnn 的行人检测一些问题的处理方法和

    原文链接:https://blog.csdn.net/qq_37572875/article/details/77915348?locationNum=11&fps=1返回搜狐,查看更多

    责任编辑:

    展开全文
  • 基于HOG adaboost行人检测

    热门讨论 2011-07-29 09:52:11
    全套HOG+adaboost行人检测代码,包括adaboost分类器训练以及检测代码,能显示最终分类结果,其中pos和neg文件夹分别为正样本和负样本
  • 行人检测(上)-行人检测介绍

    千次阅读 2017-04-24 17:20:02
    行人检测具有极其广泛的应用:智能辅助驾驶,智能监控,行人分析以及智能机器人等领域。从2005年以来行人检测进入了一个快速的发展阶段,但是也存在很多问题还有待解决,主要还是在性能和速度方面还不能达到一个权衡...
  • 进行行人检测的分类器训练时,负样本是从完全不包含人体的图片中随机剪裁出来的,下面程序的目的就是这个: [cpp] view plain copy #include  #include  #inclu
  • HOG+adboost行人检测

    2018-09-13 16:30:12
    基于HOG+adboost的行人检测代码,HOG与adboost都是自己用代码写的,训练集用的是INRIA数据集,500个正样本与1000个负样本。图片数据的剪裁可以看我的博客,里面有如何将图片进行剪裁与重命名。训练用的图片大小为64*...
  • 行人检测

    千次阅读 2016-08-30 16:47:30
    行人检测1(总结) 最近一直在看行人检测的论文,对目前的行人检测做大概的介绍。 行人检测具有极其广泛的应用:智能辅助驾驶,智能监控,行人分析以及智能机器人等领域。从2005年以来行人检测进入了一个快速的...
  • 包含三个压缩包分别是: Pets2009行人检测数据集view1包含 pos-norm64x128:2514个正样本(64x128) neg:5000负样本 view_1(png):视频转换后的png格式源图片,由于上传大小限制,只上传100张。
  • 分类器在负样本原图(肯定没有人体)上进行行人检测时所有检测到的矩形框,这些矩形框区域很明显都是误报 ,“把这些误报的矩形框保存为图片”,这些误检的图片就是HardExample图片。 把HardExample图片加入到初始的...
  • 行人检测综述

    千次阅读 2019-03-26 18:04:33
    行人检测具有极其广泛的应用:智能辅助驾驶,智能监控,行人分析以及智能机器人等领域。从2005年以来行人检测进入了一个快速的发展阶段,但是也存在很多问题还有待解决,主要还是在性能和速度方面还不能达到一个权衡...
  • 行人检测简述

    千次阅读 2013-08-29 17:18:50
    申明,本文是笔者在阅读了几篇行人检测综述性文章之后,翻译、总结、归纳所得。方便自己了解行人检测的发展趋势,同时,也给打算从事行人检测研究的朋友们提供一些思路吧。 行人检测的历史: 早期以静态图像...
  • 行人检测资源

    千次阅读 2016-09-22 00:13:02
    行人检测资源(上)综述文献 http://www.cvrobot.net/pedestrian-detection-resource-1-summary-review-survey/ 行人检测资源(下)代码数据 http://www.cvrobot.net/pedestrian-detection-resource-2-code-a
  • HOG+SVM行人检测

    2018-07-04 10:39:41
    提取正负样本hog特征投入SVM分类器训练,得到model由model生成检测子利用检测子检测负样本,得到hardexample提取hardexample的hog特征并结合第一步的特征一起训练,得到最终检测子hardexample通俗的讲,支持向量机是...
  • 行人检测概述

    千次阅读 2018-12-06 21:41:24
    最近毕设选题的时候看到刘西洋教授有这样一个题目,自己在网上查了一下,看到一篇好文章,收藏一下。 转载自...   PART I ...行人检测具有极其广泛的应用:智能辅助驾驶,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,678
精华内容 1,071
关键字:

行人检测的负样本