找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6950|回复: 4
打印 上一主题 下一主题
收起左侧

opencv+hog+svm行人检测自己训练

[复制链接]
跳转到指定楼层
楼主

PedestrianDetection-master
1.数据集的预处理\
2.分类器的训练\
3.检测算法的测试\
4.Kalman跟踪\
README.md

全部资料51hei下载地址:
PedestrianDetection-master.zip (76.17 KB, 下载次数: 40)



源码预览如下:
  1. #include <opencv2/core/core.hpp>
  2. #include <opencv2/objdetect/objdetect.hpp>
  3. #include <opencv2/highgui/highgui.hpp>
  4. #include <opencv2/video/tracking.hpp>
  5. #include <opencv2/video/video.hpp>
  6. #include <stdio.h>
  7. #include <iostream>
  8. #include <fstream>
  9. #include <vector>
  10. #include <algorithm>
  11. using namespace std;
  12. using namespace cv;

  13. //常量定义
  14. char IMG_PATH_TEXT[]="E:/INRIAPerson/color/img_path.txt";   //图像路径
  15. //char IMG_PATH_TEXT[]="E:/研究生课件/机器视觉/Project/Data/pictures";   //图像路径
  16. //const int START_FRAME=243;    //开始跟踪的帧243   ||   413
  17. //const int END_FRAME=290;      //结束跟踪的帧290   ||   480
  18. const int WINHEIGHT=180;      //图像高度
  19. const int WINWIDTH=320;       //图像宽度
  20. const int ROIWIDTH=160;       //ROI高度
  21. const int ROIHEIGHT=160;      //ROI宽度

  22. const Scalar green(0,255,0);
  23. const Scalar red(0,0,255);
  24. const Scalar blue(255,0,0);

  25. const string DETECT_WINNAME="Detect Window";
  26. const string TRACKER_WINNAME="Track Window";

  27. Mat img(WINHEIGHT,WINWIDTH,CV_8UC3);   //the Mat storage the image
  28. Mat blackboard(WINHEIGHT,WINWIDTH,CV_8UC3);
  29. const cv::Rect WHOLEIMG(0,0,WINWIDTH-2,WINHEIGHT-2);
  30. const int STATE_NUM=4;
  31. const int MEASURE_NUM=2;
  32. //使用HOG在img图像中检测行人位置
  33. //返回的矩阵vector为矩阵位置
  34. //返回检测时间
  35. void DetectPedestrian(vector<cv::Rect>& found_filtered,const HOGDescriptor& hog,
  36.                       double* time=NULL)
  37. {
  38.     found_filtered.clear ();
  39.     vector<cv::Rect> found;

  40.     //hog detector get the cv::Rect with pedestrian
  41.     if(time!=NULL)
  42.         *time=(double)getTickCount();
  43.    
  44.     hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
  45.    
  46.     if(time!=NULL)
  47.     {
  48.         *time=(double)getTickCount()-*time;
  49.         *time /= getTickFrequency();
  50.     }

  51.     //if the cv::Rect overlap
  52.     size_t i, j;
  53.     for( i = 0; i < found.size(); i++ )
  54.     {
  55.         cv::Rect r = found[i];
  56.         for( j = 0; j < found.size(); j++ )
  57.             if( j != i && (r & found[j]) == r)
  58.                 break;
  59.         if( j == found.size() )
  60.             found_filtered.push_back(r);
  61.     }
  62.     for( i = 0; i < found_filtered.size(); i++ )
  63.     {
  64.         cv::Rect r = found_filtered[i];
  65.         // the HOG detector returns slightly larger rectangles than the real objects.
  66.         // so we slightly shrink the rectangles to get a nicer output.
  67.         r.x += cvRound(r.width*0.1);
  68.         r.width = cvRound(r.width*0.8);
  69.         r.y += cvRound(r.height*0.07);
  70.         r.height = cvRound(r.height*0.8);
  71.         //found_filtered[i]=r;
  72.         cv::rectangle (img,r,green,3);
  73.     }
  74.     std::cout<<" Time : "<<*time<<std::endl;
  75. }

  76. //重载函数,在img的一个子区域中检测行人位置
  77. //该子区域由一个矩形确定
  78. //
  79. //返回的矩阵vector为矩阵位置
  80. //返回检测时间
  81. void DetectPedestrian(vector<cv::Rect>& found_filtered,const HOGDescriptor& hog,
  82.                       const cv::Rect& roi,double* time=NULL)
  83. {
  84.     //CV_Assert(WHOLEIMG.contains(roi.br()) && WHOLEIMG.contains(roi.tl()));
  85.     found_filtered.clear ();
  86.     vector<cv::Rect> found;

  87.     //hog detector get the cv::Rect with pedestrian
  88.     if(time!=NULL)
  89.         *time=(double)getTickCount();

  90.     hog.detectMultiScale(img(roi), found, 0, Size(8,8), Size(32,32), 1.05, 2);

  91.     if(time!=NULL)
  92.     {
  93.         *time=(double)getTickCount()-*time;
  94.         *time /= getTickFrequency();
  95.     }

  96.     Point pt=roi.tl();
  97.     //if the cv::Rect overlap
  98.     size_t i, j;
  99.     for( i = 0; i < found.size(); i++ )
  100.     {
  101.         found[i]+=pt;
  102.         cv::Rect r = found[i];
  103.         for( j = 0; j < found.size(); j++ )
  104.             if( j != i && (r & found[j]) == r)
  105.                 break;
  106.         if( j == found.size() )
  107.             found_filtered.push_back(r);
  108.     }
  109.     for( i = 0; i < found_filtered.size(); i++ )
  110.     {
  111.         cv::Rect r = found_filtered[i];
  112.         // the HOG detector returns slightly larger rectangles than the real objects.
  113.         // so we slightly shrink the rectangles to get a nicer output.
  114.         r.x += cvRound(r.width*0.1);
  115.         r.width = cvRound(r.width*0.8);
  116.         r.y += cvRound(r.height*0.07);
  117.         r.height = cvRound(r.height*0.8);
  118.         //found_filtered[i]=r;
  119.         cv::rectangle (img,r,green,3);
  120.     }

  121.     std::cout<<" Time : "<<*time<<std::endl;
  122. }

  123. void InitialKalmanFilter(KalmanFilter& kf,double x,double y,
  124.                           double delta_x,double delta_y)
  125. {
  126.     kf.transitionMatrix=(Mat_<float>(STATE_NUM, STATE_NUM) <<
  127.                                             1,0,1,0,
  128.                                             0,1,0,1,
  129.                                             0,0,1,0,
  130.                                             0,0,0,1 );
  131.     kf.statePost=(Mat_<float>(STATE_NUM,1)<<
  132.                                             x,
  133.                                             y,
  134.                                             delta_x,
  135.                                             delta_y );
  136.     kf.statePre=(Mat_<float>(STATE_NUM,1)<<
  137.                                             x,
  138.                                             y,
  139.                                             delta_x,
  140.                                             delta_y );
  141.     //setIdentity: 缩放的单位对角矩阵;
  142.     // !< measurement matrix (H) 观测模型
  143.     setIdentity(kf.measurementMatrix);
  144.     // !< process noise covariance matrix (Q)
  145.     // wk 是过程噪声,并假定其符合均值为零,协方差矩阵为Qk(Q)的多元正态分布;
  146.     setIdentity(kf.processNoiseCov,Scalar::all(25));
  147.     // !< measurement noise covariance matrix (R)
  148.     //vk 是观测噪声,其均值为零,协方差矩阵为Rk,且服从正态分布;
  149.     setIdentity(kf.measurementNoiseCov,Scalar::all(25));
  150.     // !< priori error estimate covariance matrix (P'(k)): P'(k)=A*P(k-1)*At + Q)
  151.     // A代表F: transitionMatrix
  152.     //预测估计协方差矩阵;
  153.     setIdentity(kf.errorCovPost,Scalar::all(25));
  154. }

  155. //获得矩形的质心坐标
  156. Point2f GetCentroid(const cv::Rect& r)
  157. {
  158.     Point tl=r.tl();
  159.     Point br=r.br();
  160.     return Point2f((float)((tl.x+br.x)/2.0),(float)((tl.y+br.y)/2.0));
  161. }

  162. string DescripRect(const cv::Rect r)
  163. {
  164.     char buf[128];
  165.     sprintf(buf,"This rectangle width: %d , height %d , tl: (%d,%d) ,br: (%d,%d)",
  166.             r.width,r.height,r.tl ().x,r.tl ().y,r.br ().x,r.br ().y);
  167.    
  168.     return string(buf);
  169. }

  170. cv::Rect GetROI(const Point2f& centroid)
  171. {
  172.     Point tl((int)(centroid.x-ROIWIDTH/2),(int)(centroid.y-ROIHEIGHT/2));       
  173.     return (cv::Rect(tl.x,tl.y,ROIWIDTH,ROIHEIGHT) & WHOLEIMG);
  174. }


  175. int main()
  176. {
  177.     double time;
  178.     ofstream fout("data_recorder.txt");
  179.     int count=0;         //frame count
  180.     string img_path;                // img path
  181.     ifstream fin(IMG_PATH_TEXT);    //the text storage the image path
  182.     vector<cv::Rect> pedestrian_location;
  183.    
  184.     HOGDescriptor hog;    //HoG detector
  185.     hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
  186.    
  187.     cv::Rect preFrame;
  188.     cv::Rect curFrame;
  189.     int count_tmp=-1;
  190.     bool start_track=false;    //是否开始跟踪?

  191.     int loss_frame=0;
  192.     KalmanFilter kf(STATE_NUM,MEASURE_NUM);
  193.     vector<Point2f> pedestrian_centroid;     //存储质心变化
  194.     vector<Point2f> pedestrian_centroid_pre;    //预测的质心变化
  195.     vector<Point2f> state_post;
  196.     //while(getline (fin,img_path) && count<=END_FRAME)
  197.    
  198.     const string video_name = "E:/研究生课件/机器视觉/Project/Data/VID_20141228_151213.mp4";
  199.     VideoCapture video(video_name);
  200.     Mat frame;

  201.     VideoWriter videowriter;
  202.     videowriter.open("Test_LX.avi",CV_FOURCC('M','J','P','G'),
  203.                       10,Size(WINWIDTH,WINHEIGHT),true);
  204.    
  205.     VideoWriter boardwriter;
  206.     boardwriter.open("Test_LX_board.avi",CV_FOURCC('M','J','P','G'),
  207.                       10,Size(WINWIDTH,WINHEIGHT),true);
  208.     while(1)
  209.     {               
  210.         //BEGIN !
  211.         //Read the image from disk
  212.         //img=imread (img_path,1);
  213.         video >> frame;
  214.         
  215.         if(frame.empty ())
  216.             break;

  217.         cv::resize (frame, img, Size(WINWIDTH,WINHEIGHT));
  218.         blackboard.setTo (0);

  219.         //绘制行人质心
  220.         for (size_t k=0;k<pedestrian_centroid.size ();k++)
  221.         {
  222.             cv::circle(blackboard ,pedestrian_centroid[k],3,green);
  223.             if(k!=0)
  224.                 cv::line(blackboard ,pedestrian_centroid[k],pedestrian_centroid[k-1],
  225.                         green,2);
  226.         }
  227.         
  228.         for (size_t k=0;k<pedestrian_centroid_pre.size ();k++)
  229.         {
  230.             cv::circle(blackboard ,pedestrian_centroid_pre[k],3,red);
  231.             if(k!=0)
  232.                 cv::line(blackboard ,pedestrian_centroid_pre[k],
  233.                                      pedestrian_centroid_pre[k-1],red,2);
  234.         }

  235.         for (size_t k=0;k<state_post.size ();k++)
  236.         {
  237.             cv::circle(blackboard ,state_post[k],4,blue,-1);
  238.             if(k!=0)
  239.                 cv::line(blackboard ,state_post[k],state_post[k-1],blue,2);
  240.         }
  241.         
  242.         char buf[128];
  243.         sprintf(buf,"frame: %3d",count);
  244. /*
  245.         putText (blackboard ,string(buf),cv::Point(10,20),
  246.             FONT_HERSHEY_SIMPLEX,0.2,Scalar::all(255));
  247.         putText (blackboard ,"Red Rectangle: ROI from Kalman",cv::Point(10,40),
  248.                 FONT_HERSHEY_SIMPLEX,0.2,Scalar::all(255));
  249.         putText(blackboard , "Red Circle: Centroid from Kalman",cv::Point(10,60),
  250.                 FONT_HERSHEY_SIMPLEX,0.2,Scalar::all(255));
  251.         putText(blackboard , "Green Rectangle: Pedestrian Rect from HOG",
  252.                                                  cv::Point(10,80),
  253.             FONT_HERSHEY_SIMPLEX,0.2,Scalar::all(255));
  254.         putText(blackboard , "Green Circle: Centroid from HoG",cv::Point(10,100),
  255.             FONT_HERSHEY_SIMPLEX,0.2,Scalar::all(255));
  256.         putText(blackboard , "Blue Circle: posteriori state estimate",cv::Point(10,120),
  257.             FONT_HERSHEY_SIMPLEX,0.2,Scalar::all(255));
  258.         */
  259.         if (!start_track && (count_tmp==-1))   //没有开始跟踪   
  260.         {
  261.             // HoG detection
  262.             //这里时候存在行人呢??
  263.             //如果没有行人,就接着读下一帧吧,直到找到
  264.             //如果有行人,就目标建立卡尔曼滤波器
  265.             DetectPedestrian(pedestrian_location,hog,&time);
  266.             if (pedestrian_location.size ()==0)    //在该帧没有找到行人
  267.             {
  268.                 cv::imshow (DETECT_WINNAME,img);
  269.                 waitKey(2);
  270.                 printf("Frame %d cannot find pedestrian! \n",count);
  271.                 count++;
  272.                 continue;
  273.             }
  274.             else    //在这帧找到了行人
  275.             {
  276.                 preFrame=pedestrian_location[0];
  277.                 //如果有多个矩形框的话,先进行取交集运算
  278.                 for (size_t j=1;j<pedestrian_location.size ();j++)
  279.                 {
  280.                     if (preFrame.area ()<pedestrian_location[j].area ())
  281.                     {
  282.                         preFrame=pedestrian_location[j];
  283.                     }
  284.                     //preFrame |= pedestrian_location[j];
  285.                 }
  286.                
  287.                 count_tmp = count;       ///tmp 赋值
  288.                 printf("Frame %d find pedestrian! \n",count);

  289.             }       
  290.             cv::imshow (DETECT_WINNAME,img);
  291.         }
  292.         else   //开始了跟踪
  293.         {
  294.             if (count==(count_tmp+1))    //利用相邻两帧数据建立卡尔曼滤波器
  295.             {
  296.                 cv::Rect roi(WINWIDTH/2,WINHEIGHT/2,WINWIDTH/2,WINHEIGHT/2);
  297.                 roi=(roi&WHOLEIMG);
  298.                 std::cout<<roi.tl ().x<<"   "<<roi.tl ().y<<endl;
  299.                 std::cout<<roi.br ().x<<"   "<<roi.br ().y<<endl;
  300.                 DetectPedestrian(pedestrian_location,hog,WHOLEIMG,&time);       

  301.                 if(pedestrian_location.size ()==0)   //没有找到
  302.                 {
  303.                     start_track = 0;
  304.                     count_tmp = -1;
  305.                     continue;
  306.                 }

  307.                 curFrame = pedestrian_location[0];   //获得了t+1帧的位置信息
  308.                 Point2f pt1=GetCentroid (preFrame);
  309.                 Point2f pt2=GetCentroid (curFrame);

  310.                 // 1. 初始化
  311.                 InitialKalmanFilter (kf,pt2.x,pt2.y,pt2.x-pt1.x,pt2.y-pt1.y);
  312.                
  313.                 state_post.push_back (pt2);
  314.                 pedestrian_centroid.push_back (pt2);
  315.                 pedestrian_centroid_pre.push_back (pt2);
  316.                
  317.                 cout<<"Start!"<<endl;
  318.                 fout<<"Kalman Initial Complete!"<<endl;
  319.                 cv::imshow (DETECT_WINNAME,img);
  320.             }       
  321.             else
  322.             {
  323.                 // 2.预测
  324.                 Mat predict=kf.predict ();
  325.                 Point2f predictPt(predict.at<float>(0),predict.at<float>(1));

  326.                 fout<<"This is the "<<count<<" frame, and the predict point is ( "<<
  327.                     predictPt.x<<" , "<<predictPt.y<<" )"<<endl;

  328.                 pedestrian_centroid_pre.push_back (predictPt);
  329.                
  330.                 //cv::circle(blackboard,predictPt,5,red);
  331.                 cv::rectangle (blackboard,GetROI (predictPt),red,3);
  332.                
  333.                 cv::circle (img,predictPt,5,red,5);
  334.                

  335.                 // 3.更新Update
  336.                 // 1) 使用HoG检测
  337.                 cv::Rect curroi=GetROI (predictPt);
  338.                 //cv::Rect curroi=WHOLEIMG;
  339.                 //fout<<"This is the "<<count<<" frame, and "<<DescripRect(curroi);

  340.                 DetectPedestrian (pedestrian_location,hog,curroi,&time);

  341.                 // 2)根据位置更新
  342.                 if (pedestrian_location.size ()!=0)
  343.                 {
  344.                     loss_frame=0;

  345.                     int len=pedestrian_location.size ();
  346.                     double *dis=new double[len];
  347.                     int _min=0;
  348.                     for (int j=0;j<len;j++)
  349.                     {
  350.                         Rect r=pedestrian_location[j];
  351.                         Point cen=GetCentroid (r);
  352.                         double distan=(cen.x-predictPt.x)*(cen.x-predictPt.x)+
  353.                                         (cen.y-predictPt.y)*(cen.y-predictPt.y);
  354.                         dis[j]=distan;
  355.                         if (distan<dis[_min])
  356.                             _min=j;
  357.                     }
  358.                     delete[] dis;   //释放内存

  359.                     cv::Rect detected=pedestrian_location[_min];
  360. #if 0
  361.                     for (size_t j=1;j<pedestrian_location.size ();j++)
  362.                     {
  363.                         if (detected.area ()<pedestrian_location[j].area ())
  364.                         {
  365.                             detected=pedestrian_location[j];
  366.                         }
  367.                         //detected |= pedestrian_location[j];
  368.                     }                       
  369. #endif
  370.                     Point2f curCentroid=GetCentroid (detected);

  371.                     pedestrian_centroid.push_back (curCentroid);
  372.                     
  373.                     cv::circle (blackboard,curCentroid,5,green);
  374.                     
  375.                     cv::rectangle (blackboard ,detected,green,3);
  376.                     
  377.                     cv::circle (img,curCentroid,5,green,5);

  378.                     fout<<"This is the "<<count<<" frame, and the true point is ( "<<
  379.                         curCentroid.x<<" , "<<curCentroid.y<<" )"<<endl;

  380.                     Mat measure=*(Mat_<float>(2,1)<<curCentroid.x,curCentroid.y);
  381.                     kf.correct (measure);
  382.                     Mat state=kf.statePost;
  383.                     Point2f stateP=Point2f(state.at<float>(0),state.at<float>(1));
  384.                     //circle (blackboard ,sta
  385.                     state_post.push_back (stateP);
  386.                 }
  387.                 else
  388.                     loss_frame++;

  389.                 if (loss_frame>=3)
  390.                 {
  391.                     printf("Lose the obj in frame %d\n.",count);
  392.                     
  393.                     // mark
  394.                     start_track = 0;
  395.                     count_tmp = -1;
  396.                     continue;
  397.                 }

  398.                 cv::imshow (DETECT_WINNAME,img);
  399.                
  400.             }
  401.             cv::imshow (TRACKER_WINNAME,blackboard );
  402.         }

  403.         count++;
  404.    
  405.         boardwriter << blackboard;
  406.         videowriter << img;
  407.         
  408.         /*
  409.         int c=waitKey();
  410.         while (c!=27)
  411.         {
  412.             c=waitKey ();
  413.         }
  414.         */      
  415.     }
  416.     std::cout<<"-----------------------------"<<endl;
  417.     std::cout<<"Complete!"<<endl;
  418.     fout.close ();
  419.     cv::waitKey();
  420.     return 0;
  421. }

复制代码

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:361324 发表于 2018-6-28 22:13 | 只看该作者
你好,请问你是用什么平台实现的?
是用得opencv哪个版本?
特别感谢,望你回复,希望您能上这个论坛并回答这个问题,多谢你。
回复

使用道具 举报

板凳
ID:361324 发表于 2018-6-28 22:27 | 只看该作者
回复

使用道具 举报

地板
ID:361324 发表于 2018-6-28 22:28 | 只看该作者
请问帖主是采用什么平台运行整个程序的,用的什么版本的opencv
回复

使用道具 举报

5#
ID:361324 发表于 2018-6-28 22:32 | 只看该作者
你好,请问帖主是在什么平台下运行的程序,用的opencv是什么版本的?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表