opencv之GPUvsCPU

2019-04-14 18:20发布

 在使用cuda进行编程之前,我们不妨再来看看OpenCV中的效果是什么样子的,那么这一次,我将使用OpenCV来进行HOG+SVM的行人检测。 事实上,HOG+SVM在行人检测上的应用在网上已经有了非常丰富的资料,可以说,这个技术相对来说是比较成熟的,那么此次应用OpenCV进行行人检测的实现主要目的如下: 1.了解HOG+SVM在行人检测上的实际效果,并借此熟悉OpenCV中相关程序的编写 2.比较CPU与GPU的运行差别 3.引入我对HOG以及SVM的原理性学习 事实上,我们可以参考http://docs.opencv.org/2.4.9/modules/refman.html(即OpenCV的API档案)来学习OpenCV,并查找你需要的函数,了解各个参数的含义以及使用要求!这次我们调用的是OpenCV中关于gpu detect部分,于是我们可以参考如下:http://docs.opencv.org/2.4.9/modules/gpu/doc/object_detection.html 比如说detectMultiScale函数,如下图所示:

 这里要注意padding要是(0,0)! 这里废话就不多说,直接上程序(这里只上gpu程序,普通的cv程序,大家应该都懂)   C代码   收藏代码
  1. #include "stdio.h"  
  2. #include "opencv2/core/core.hpp"  
  3. #include "opencv2/highgui/highgui.hpp"  
  4. #include "opencv2/imgproc/imgproc.hpp"  
  5. #include "opencv2/gpu/gpu.hpp"  
  6. #include "opencv2/ml/ml.hpp"  
  7. #include "cuda.h"  
  8. #include "cuda_runtime_api.h"  
  9. using namespace std;  
  10. using namespace cv;  
  11. using namespace cv::gpu;  
  12. int main(int argc, char** argv)    
  13. {  
  14.     cudaSetDevice(0);  
  15.     cudaFree(0);        
  16.     size_t j = 0;  
  17.     int k = 0;  
  18.     int count = 0;  
  19.     int avrTime = 0;  
  20.     for (j = 0; j < 100; ++ j)  
  21.     {  
  22.         cout << count << endl;   
  23.         char img[100] = "";  
  24.            sprintf(img, "./temp/image%d.jpg", count+1);  
  25.         cv::Mat image = cv::imread(img);    
  26.            
  27.         if (image.empty())    
  28.         {    
  29.         std::cout<<"read image failed"<
  30.         }    
  31.         double start = (double)getTickCount();  
  32.         gpu::GpuMat image_gpu(image);   
  33.         GpuMat gray_gpu;  
  34.         gpu::cvtColor(image_gpu, gray_gpu, COLOR_BGR2GRAY);  
  35.             //Mat gray;  
  36.         //cvtColor(image, gray, COLOR_BGR2GRAY);  
  37.         // 1. 定义HOG对象    
  38.         cv::gpu::HOGDescriptor hog; // 采用默认参数    
  39.        
  40.         // 2. 设置SVM分类器    
  41.         hog.setSVMDetector(cv::gpu::HOGDescriptor::getDefaultPeopleDetector());   // 采用已经训练好的行人检测分类器    
  42.         // 3. 在测试图像上检测行人区域    
  43.         std::vector regions;        
  44.         hog.detectMultiScale(gray_gpu, regions, 0, cv::Size(8,8), cv::Size(0,0), 1.05, 1);   
  45.         double t = ((double)getTickCount() - start)/getTickFrequency();  
  46.         // 显示    
  47.         for (size_t i = 0; i < regions.size(); i++)    
  48.         {    
  49.         cv::rectangle(image, regions[i], cv::Scalar(0,0,255), 2);    
  50.         }    
  51.   
  52.         cout << "时间: " << t * 1000 <<"ms"<< endl;   
  53.             avrTime = avrTime + t * 1000;  
  54.         //char result[100] = "";  
  55.            //sprintf(result, "./result/image%d.jpg", count+1);  
  56.             //imwrite(result, image);  
  57.         imshow("hog", image);    
  58.         waitKey(1);    
  59.         count ++;  
  60.   }   
  61.   cout << "time is : " << avrTime / 100 <<"ms"<< endl;   
  62.     return 0;    
  63.  }  
这里为了方便了解算法运行的具体时间,我把测试图(100张)的运行平均时间计算出来,以此为准   可以发现,gpu的运行时间:
若我们把程序改成普通cpu运行(就是把gpu有关的改成普通的函数和mat),运行时间:
  注意:上回书说道,第一次运行CUDA是慢的,这里我们把头两句话注释掉:     //cudaSetDevice(0);
    //cudaFree(0);  结果如下:
第一次时间果真是要长很多,所以说,这两句话还是必要的,目的是第一次开启CUDA连接,第二次开始速度将变得更快。
  这里我使用的训练样本是OpenCV自带的训练样本,HOG特征是其内部完成的,我使用的测试样本是100张连续的行人图片。已上传! 最后得到的结果


转:https://lps-683.iteye.com/blog/2281273