OpenCV3 比較CPU, OpenCL,cuda效能
阿新 • • 發佈:2018-12-12
#include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/core/ocl.hpp> #include <opencv2/core/cuda.hpp> #include <opencv2/cudaobjdetect.hpp> #include <opencv2/cudaimgproc.hpp> int main(int argc, char**argv) { std::cout << "OpenCV version=" << std::hex << CV_VERSION << std::dec << std::endl; cv::Mat frame; cv::UMat uframe, uFrameGray; cv::cuda::GpuMat image_gpu, image_gpu_gray; cv::VideoCapture capture("path_to_the_video"); bool useOpenCL = (argc == 2); std::cout << "Use OpenCL=" << useOpenCL << std::endl; cv::ocl::setUseOpenCL(useOpenCL); bool useCuda = (argc == 3); std::cout << "Use CUDA=" << useCuda << std::endl; cv::Ptr<cv::CascadeClassifier> cascade = cv::makePtr<cv::CascadeClassifier>("data/lbpcascades/lbpcascade_frontalface_at.xml"); cv::Ptr<cv::cuda::CascadeClassifier> cascade_gpu = cv::cuda::CascadeClassifier::create("data/lbpcascades/lbpcascade_frontalface_at.xml"); double time = 0.0; int nb = 0; if(capture.isOpened()) { for(;;) { capture >> frame; if(frame.empty() || nb >= 1000) { break; } std::vector<cv::Rect> faces; double t = 0.0; if(!useCuda) { t = (double) cv::getTickCount(); frame.copyTo(uframe); cv::cvtColor(uframe, uFrameGray, CV_BGR2GRAY); cascade->detectMultiScale(uFrameGray, faces); t = ((double) cv::getTickCount() - t) / cv::getTickFrequency(); } else { t = (double) cv::getTickCount(); image_gpu.upload(frame); cv::cuda::cvtColor(image_gpu, image_gpu_gray, CV_BGR2GRAY); cv::cuda::GpuMat objbuf; cascade_gpu->detectMultiScale(image_gpu_gray, objbuf); cascade_gpu->convert(objbuf, faces); t = ((double) cv::getTickCount() - t) / cv::getTickFrequency(); } time += t; nb++; for(std::vector<cv::Rect>::const_iterator it = faces.begin(); it != faces.end(); ++it) { cv::rectangle(frame, *it, cv::Scalar(0,0,255)); } std::stringstream ss; ss << "FPS=" << (nb / time); cv::putText(frame, ss.str(), cv::Point(30, 30), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0,0,255)); cv::imshow("Frame", frame); char c = cv::waitKey(30); if(c == 27) { break; } } } std::cout << "Mean time=" << (time / nb) << " s" << " ; Mean FPS=" << (nb / time) << " ; nb=" << nb << std::endl; system("pause"); return 0; }
lbpcascade_frontalface_at.xml 檔案可以百度搜索就能下載到,是一個級聯分類器訓練好的模型,用於識別人臉正面,很常用。具體資料可以參考http://blog.csdn.net/yang_xian521/article/details/6973667
只需要將
cv::VideoCapture capture("path_to_the_video"); cv::Ptr<cv::CascadeClassifier> cascade = cv::makePtr<cv::CascadeClassifier>("data/lbpcascades/lbpcascade_frontalface_at.xml"); cv::Ptr<cv::cuda::CascadeClassifier> cascade_gpu = cv::cuda::CascadeClassifier::create("data/lbpcascades/lbpcascade_frontalface_at.xml");
結果很意外,opencl基本沒有加速效果,而cuda加速效果很明顯
OpenCV3的GPU模組需要手動重新編譯才可以使用。本文介紹了編譯OpenCV3.2.0+ GPU模組的方法
Reference: