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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章