opencv+CUDA9.1+vs2015环境搭建,编译opencv库,调用GPU加速运算

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:[email protected]: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。

猜你喜欢

转载自blog.csdn.net/qq_30623591/article/details/82084113