1.准备工作(需要用的软件安装)
1.1安装VS2015
CUDA是以VS为基础的,因此要先安装VS。安装CUDA的时候会自动检测VS的版本。安装步骤较简单,下载在线安装程序之后双击即可,配置栏有关C++的都勾上,其中最重要的一项为VC++,点击下一步安装。
1.2安装CUDA
解压和安装路径最好不要改,否则会出现找不到路径之类的不要麻烦。
CUDA解压完后会自动安装,出现检查系统兼容性的界面。如果你的显卡适用的版本比CUDA版本高,则会出现硬件找不到的错误,不必理会,下一步安装。
我的显卡是GTX1050,CUDA版本是9.1.126,而我安装的CUDA版本是9.1.85,因此会出现找不到硬件,不要紧,点击“继续”安装
同意并继续
选择“自定义”->“下一步”
只勾选"CUDA"
这里的安装位置不要改,按默认的就行,“下一步"
之后便是等待安装。。。。
安装完:
使用nvcc -V查看是否安装成功
1.3 安装Cmake
百度上下载一个,版本不要太低也不要太高,我用的是3.10.1,下一步安装就行,没特别的。
1.4 下载opencv源码
到opencv官网下载opencv源码。
2.编译opencv源码
安装好以上基础工具之后可以进入下一步编译opencv源码了。
打开Cmake。
1处为源代码路径,2处为Cmake配置后的路径。配置好之后点击configure。
选择“Visual Studio 14 2015 win64 ” 和 “use defalut native compilers" 后点击Finish,等待配置完毕。 如果你的CUDA安装正确会检测到你的CUDA版本。在配置过程中会联网下载点东西,如果这时候网络不好的话会报错,在Cmake编译的Log文件中有需要下载的文件和文件对应的网址,可以等网络好的时候再联网下载,将下载好的文件放入原位置即可。
配置完成之后点击生成(注意勾选WITH_CUDA)
生成完毕之后在 “ Configuring done"下面会出现”Generating done"。之后直接点击“Open Project",便会使用VS2015打开工程。
在 VS2015界面 点击 “ 生成”->“配置管理器”,在配置管理器中选择 “ALL_BUILD"和”INSTALL“ ,生成即可 。这个时候看电脑速度了,我电脑是I7-8750H ,GTX1050 编译了四个多小时。
编译成功后在自己选的Cmake的Build路径下会出现一个install文件夹,这个就是咱编译后生成的文件。
3.运行CUDA代码测试
3.1配置opencv运行环境
opencv运行环境配置不难,主要有两个步骤:
3.1.1 配置系统环境变量
按照下图顺序进入到环境变量对话框,添加生成bin路径。
3.1.2 VS2015包含库路径配置
按照自己的平台添加属性表,我的是Debug X64平台,因此在Debug|X64下添加一个“OpencvProjectySheet"。在“OpencvProjectySheet"中的”VC++“目录中添加包含目录和库目录。
在”链接器“中添加宏定义。
这些库文件全是自己通过VS2015编译出来的。这个也是检查自己编译是否成功的标准,如果编译不成功,则没有库文件;编译成功则有需要的库文件。
3.2测试例程(代码)
3.2.1测试代码
/*直接在cu文件中实现cuda与opencv混合编程*/
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/cudaobjdetect.hpp>
using namespace std;
using namespace cv;
using namespace cuda;
#ifdef _DEBUG
#pragma comment ( lib,"opencv_core340d.lib")
#pragma comment ( lib,"opencv_highgui340d.lib")
#pragma comment ( lib,"opencv_calib3d340d.lib")
#pragma comment ( lib,"opencv_imgcodecs340d.lib")
#pragma comment ( lib,"opencv_imgproc340d.lib")
#pragma comment ( lib,"opencv_cudaimgproc340d.lib")
#pragma comment ( lib,"opencv_cudaarithm340d.lib")
#pragma comment ( lib,"cudart.lib")
#else
#pragma comment ( lib,"opencv_core340.lib")
#pragma comment ( lib,"opencv_highgui340.lib")
#pragma comment ( lib,"opencv_calib3d340.lib")
#pragma comment ( lib,"opencv_imgcodecs340.lib")
#pragma comment ( lib,"opencv_imgproc340.lib")
#pragma comment ( lib,"opencv_cudaimgproc340.lib")
#pragma comment ( lib,"opencv_cudaarithm340.lib")
#pragma comment ( lib,"cudart.lib")
#endif
//出错处理函数
#define CHECK_ERROR(call){\
const cudaError_t err = call;\
if (err != cudaSuccess)\
{\
printf("Error:%s,%d,",__FILE__,__LINE__);\
printf("code:%d,reason:%s\n",err,cudaGetErrorString(err));\
exit(1);\
}\
}
int main(int argc, char **argv)
{
VideoCapture cap;
//cap.open("rtsp://admin:admin@192.168.1.108:80/cam/realmonitor?channel=1&subtype=0");
cap.open(0);
if(!cap.isOpened())
return -1;
Mat frame;
cuda::GpuMat cu_dst;
Ptr<cuda::CascadeClassifier> cascade_gpu = cuda::CascadeClassifier::create("D:\\opencv3_4_0\\sources\\data\\haarcascades_cuda\\haarcascade_frontalface_default.xml");
vector<Rect> faces;
while (1)
{
cap >> frame;
if (frame.empty())
break;
cuda::GpuMat image_gpu(frame);
cascade_gpu->detectMultiScale(image_gpu, cu_dst);
cascade_gpu->convert(cu_dst, faces);
for (int i = 0; i < faces.size(); ++i)
rectangle(frame, faces[i], Scalar(255));
imshow("faces", frame);
//等待用户按键
waitKey(1);
};
cap.release();
return 0;
/*以下代码是用 一张图片进行测试的*/
/*
Ptr<cuda::CascadeClassifier> cascade_gpu = cuda::CascadeClassifier::create("D:\\opencv3_4_0\\sources\\data\\haarcascades_cuda\\haarcascade_frontalface_default.xml");
Mat image_cpu = imread("D:\\opencv_work\\006.jpg");
imshow("image_cpu", image_cpu);
GpuMat image_gpu(image_cpu);
GpuMat objbuf;
cascade_gpu->detectMultiScale(image_gpu, objbuf);
std::vector<Rect> faces;
cascade_gpu->convert(objbuf, faces);
for (int i = 0; i < faces.size(); ++i)
cv::rectangle(image_cpu, faces[i], Scalar(255));
imshow("Faces", image_cpu);
waitKey(0);
destroyAllWindows();
return 0;
*/
}
3.2.2 实验结果
调用摄像头进行人脸识别,使用Opencv的CascadeClassifier分类器做运算量是及其大的,但从右侧可以看到CPU的占用率很低,说明主要的运算不在CPU,能快速执行这样大运算量的地方也只有GPU了。
可以用CPU执行同样的算法对比一下,右侧的CPU占用率极高。通过任务管理器看的话CPU占用会达到100%。
进一步对比,cuda的CascadeClassifier识别命中率不如CPU的CascadeClassifier。