【问题标题】:How to include and use OpenCv3.1.0 library to CUDA file(.cu)?如何在 CUDA 文件(.cu)中包含和使用 OpenCv3.1.0 库?
【发布时间】:2016-11-06 05:19:56
【问题描述】:

我试图用我自己的内核实现中值滤波器,就像这个伪代码:

//main.cpp
#include "opencv2/opencv.hpp"
cv::Mat inputMat = cv::imread()
cudaMedianCaller (inputMat, kernelMat)

//medianFilter.h
#include "opencv2/opencv.hpp"
cudaMedianCaller (const cv::Mat& inputMat, cv::Mat& kernelMat);

//medianFilter.cu
cudaMedianCaller (const cv::Mat& inputMat, cv::Mat& kernelMat)
{
    kernelMedianFilter<<< , >>> (uchar3* d_inputMat, uchar* d_kernelMat)
}

__global__ void kernelMedianFilter (uchar3* d_inputMat, uchar* d_kernelMat)
{

}

我得到编译错误:

C1083:无法打开包含文件:'opencv2/opencv.hpp':没有这样的文件或 目录

我知道 .cu 文件使用 nvcc 编译,无法编译 OpenCV 头文件。

1) 如何将 OpenCV3.1.0 库包含到 .cu 文件中?

【问题讨论】:

    标签: opencv cuda gpu opencv3.1


    【解决方案1】:

    您不需要在 .cu 文件中包含 OpenCV。您需要一个以原始指针和基本数据类型作为参数的调用方 API。

    main.cpp

    #include "opencv2/opencv.hpp"
    #include "medianFilter.h"
    
    int main() {
      cv::Mat inputMat = cv::imread();
      .....
      cudaMedianCaller (d_inputMat, d_kernelMat);
      .....
      return 0;
    }
    

    medianFilter.h

    cudaMedianCaller (uchar3* d_inputMat, uchar* d_kernelMat);
    

    medianFilter.cu

    cudaMedianCaller (uchar3* d_inputMat, uchar* d_kernelMat)
    {
        kernelMedianFilter<<< , >>> (uchar3* d_inputMat, uchar* d_kernelMat)
    }
    
    __global__ void kernelMedianFilter (uchar3* d_inputMat, uchar* _kernelMat)
    {
    
    }
    

    【讨论】:

    • 非常感谢。我用我的代码测试你的文件,然后向你报告。
    【解决方案2】:

    尽管另一个很好的答案建议将 C++ 和 CUDA 分开,但还有另一种方法可以将 OpenCV 容器包含在 .cu 文件中:

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.8)
    project(test LANGUAGES CXX CUDA)
    find_package(OpenCV 3.0 REQUIRED)
    
    # compile the target
    add_executable(test_app main.cpp medianFilter.cu)
    target_link_libraries(test_app PRIVATE cudart ${OpenCV_LIBS})
    

    main.cpp

    #include "opencv2/opencv.hpp"
    #include "medianFilter.h"
    
    int main()
    {
        // input data
        cv::Mat inputMat(cv::Size(128, 128), CV_8UC3, cv::Scalar(100));
        cv::Mat kernelMat(cv::Size(16, 16), CV_8UC1, cv::Scalar(1));
    
        // call CUDA
        cudaMedianCaller(inputMat, kernelMat);
        return 0;
    }
    

    medianFilter.cu

    #include "medianFilter.h"
    __global__ void kernelMedianFilter(uchar3* d_inputMat, uchar* d_kernelMat)
    {
        return;
    }
    void cudaMedianCaller(const cv::Mat& inputMat, cv::Mat& kernelMat)
    {
        // allocate device pointers
        uchar3 *d_inputMat;
        uchar  *d_kernelMat;
        cudaMalloc(&d_inputMat,  inputMat.total() * sizeof(uchar3));
        cudaMalloc(&d_kernelMat, kernelMat.total() * sizeof(uchar));
    
        // copy from host to device
        cudaMemcpy(d_inputMat, inputMat.ptr<uchar3>(0), inputMat.total() * sizeof(uchar3), cudaMemcpyHostToDevice);
        cudaMemcpy(d_kernelMat, kernelMat.ptr<uchar>(0), kernelMat.total() * sizeof(uchar), cudaMemcpyHostToDevice);
    
        // call CUDA kernel
        kernelMedianFilter <<<1, 1>>> (d_inputMat, d_kernelMat);
    
        // free
        cudaFree(d_inputMat);
        cudaFree(d_kernelMat);
    }
    

    medianFilter.h

    #include "opencv2/opencv.hpp"
    void cudaMedianCaller (const cv::Mat& inputMat, cv::Mat& kernelMat);
    

    要运行二进制应用程序,您可能需要将一些必需的.dll 复制到二进制文件夹。对我来说,我将opencv_core343.dllC:\Program Files\OpenCV\x64\vc15\bin 复制到test_app.exe 所在的文件夹中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-07
      • 2023-03-23
      • 2013-05-09
      • 2018-02-17
      • 1970-01-01
      • 2018-02-17
      • 2021-06-14
      相关资源
      最近更新 更多