在使用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);
第一次时间果真是要长很多,所以说,这两句话还是必要的,目的是第一次开启CUDA连接,第二次开始速度将变得更快。
这里我使用的训练样本是OpenCV自带的训练样本,HOG特征是其内部完成的,我使用的测试样本是100张连续的行人图片。已上传!
最后得到的结果
接下来,我将会进入到CUDA的学习