闵大荒之旅(三)---- 抄抄改改opencv之GPUvsCPU

 在使用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程序,大家应该都懂)

 

#include "stdio.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/gpu/gpu.hpp"
#include "opencv2/ml/ml.hpp"
#include "cuda.h"
#include "cuda_runtime_api.h"
using namespace std;
using namespace cv;
using namespace cv::gpu;
int main(int argc, char** argv)  
{
    cudaSetDevice(0);
    cudaFree(0);      
    size_t j = 0;
    int k = 0;
    int count = 0;
    int avrTime = 0;
    for (j = 0; j < 100; ++ j)
    {
        cout << count << endl; 
        char img[100] = "";
           sprintf(img, "./temp/image%d.jpg", count+1);
        cv::Mat image = cv::imread(img);  
         
        if (image.empty())  
        {  
        std::cout<<"read image failed"<<std::endl;  
        }  
        double start = (double)getTickCount();
        gpu::GpuMat image_gpu(image); 
        GpuMat gray_gpu;
        gpu::cvtColor(image_gpu, gray_gpu, COLOR_BGR2GRAY);
            //Mat gray;
        //cvtColor(image, gray, COLOR_BGR2GRAY);
        // 1. 定义HOG对象  
        cv::gpu::HOGDescriptor hog; // 采用默认参数  
     
        // 2. 设置SVM分类器  
        hog.setSVMDetector(cv::gpu::HOGDescriptor::getDefaultPeopleDetector());   // 采用已经训练好的行人检测分类器  
        // 3. 在测试图像上检测行人区域  
        std::vector<cv::Rect> regions;      
        hog.detectMultiScale(gray_gpu, regions, 0, cv::Size(8,8), cv::Size(0,0), 1.05, 1); 
        double t = ((double)getTickCount() - start)/getTickFrequency();
        // 显示  
        for (size_t i = 0; i < regions.size(); i++)  
        {  
        cv::rectangle(image, regions[i], cv::Scalar(0,0,255), 2);  
        }  

        cout << "时间: " << t * 1000 <<"ms"<< endl; 
            avrTime = avrTime + t * 1000;
        //char result[100] = "";
           //sprintf(result, "./result/image%d.jpg", count+1);
            //imwrite(result, image);
        imshow("hog", image);  
        waitKey(1);  
        count ++;
  } 
  cout << "time is : " << avrTime / 100 <<"ms"<< endl; 
    return 0;  
 }

这里为了方便了解算法运行的具体时间,我把测试图(100张)的运行平均时间计算出来,以此为准

 

可以发现,gpu的运行时间:

若我们把程序改成普通cpu运行(就是把gpu有关的改成普通的函数和mat),运行时间:

 

注意:上回书说道,第一次运行CUDA是慢的,这里我们把头两句话注释掉:

    //cudaSetDevice(0);
    //cudaFree(0);

 结果如下:
闵大荒之旅(三)---- 抄抄改改opencv之GPUvsCPU_第1张图片

第一次时间果真是要长很多,所以说,这两句话还是必要的,目的是第一次开启CUDA连接,第二次开始速度将变得更快。
 

这里我使用的训练样本是OpenCV自带的训练样本,HOG特征是其内部完成的,我使用的测试样本是100张连续的行人图片。已上传!

最后得到的结果

 

 
 接下来,我将会进入到CUDA的学习
 
 

你可能感兴趣的:(闵大荒之旅(三)---- 抄抄改改opencv之GPUvsCPU)