cuda跟opencv的混合編程,注意opencv須要從新編譯

編譯的辦法參見:ios

http://blog.csdn.net/wangyaninglm/article/details/39997113c++

 

如下是程序代碼,網上搜的例子:多線程

注意事項:32位工程添加64位的支持,配置好cuda的項目路徑include,添加函數

//swap.cu


#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <opencv2/core/cuda_devptrs.hpp>
using namespace cv;
using namespace cv::gpu;

//自定義內核函數
__global__ void swap_rb_kernel(const PtrStepSz<uchar3> src,PtrStep<uchar3> dst)
{
    int x = threadIdx.x + blockIdx.x * blockDim.x;
    int y = threadIdx.y + blockIdx.y * blockDim.y;

    if(x < src.cols && y < src.rows)
    {
        uchar3 v = src(y,x);
        dst(y,x) = make_uchar3(v.z,v.y,v.x);
    }
}

extern "C" void swap_rb_caller(const PtrStepSz<uchar3>& src,PtrStep<uchar3> dst,cudaStream_t stream)
{
    dim3 block(32,8);
    dim3 grid((src.cols + block.x - 1)/block.x,(src.rows + block.y - 1)/block.y);

    swap_rb_kernel<<<grid,block,0,stream>>>(src,dst);
    if(stream == 0)
        cudaDeviceSynchronize();
}


 

 

//swap.cpp



#include <opencv2/gpu/gpu.hpp>
#include <opencv2/gpu/stream_accessor.hpp>


using namespace cv;
using namespace cv::gpu;

extern "C" void swap_rb_caller(const PtrStepSz<uchar3>& src,PtrStep<uchar3> dst,cudaStream_t stream);

extern "C" void swap_rb(const GpuMat& src,GpuMat& dst,Stream& stream = Stream::Null())
{
	CV_Assert(src.type() == CV_8UC3);
	dst.create(src.size(),src.type());
	cudaStream_t s = StreamAccessor::getStream(stream);
	swap_rb_caller(src,dst,s);
}


 

//main.cpp

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/gpu/gpu.hpp>

#pragma comment(lib,"opencv_gpu2410d.lib")
#pragma comment(lib,"opencv_core2410d.lib")
#pragma comment(lib,"opencv_highgui2410d.lib")

using namespace cv;
using namespace cv::gpu;

extern "C" void swap_rb(const GpuMat& src,GpuMat& dst,Stream& stream = Stream::Null());

int main()
{
	Mat image = imread("lena.jpg");
	imshow("src",image);
	GpuMat gpuMat,output;

	gpuMat.upload(image);
	swap_rb(gpuMat,output);
	output.download(image);

	imshow("gpu",image);
	getchar();
	waitKey(0);
	return 0;
}


 

 

 

 實現效果:ui

 

 

網上找的注意事項:spa

 

 

假設有兩個工程:CUDA工程TestCuda;C++工程CallCuda.net

1. 在CUDA工程TestCuda中,線程

(1).cpp文件(類成員函數定義)調用.cu文件下的函數code

例如.cu文件下的函數void run_kernel(); 其前面必須用 extern 「C」 修飾。blog

而.cpp文件(類成員函數定義)下的類成員函數,如,void cpp_run();

若是它想調用 run_kernel(),則首先可在.h文件(類定義)中的類定義的外面先聲明.cu文件下的C函數,例如,extern 「C」 void run_kernel();


(2)CUDA工程屬性-->常規中,選擇配置類型爲「靜態庫(.lib)」-->應用;

同時在工程屬性下的庫管理器-->常規項下的附加依賴項中,添加CUDA庫:cudart.lib,curand.lib等;在附加庫目錄添加相應的庫所在目錄。


2.另外的C++工程CallCuda

在CallCuda工程屬性下,找到附加依賴項,添加:CUDA庫(cudart.lib等)和TestCuda生成的靜態庫(TestCuda.lib);以及添加附加庫目錄。

至此,該工程下的.cpp文件下的函數,就能夠調用CUDA工程下的cpp_run()函數了,不過首先要實例化類。


1.將example.cu添加到工程中。在已有工程上右鍵單擊,選擇添加已有項。 2.添加編譯規則。右鍵單擊工程文件,選擇「自定義生成規則」,在彈出的對話框中選擇CUDA Build Rule x.x。 3.修改.cu文件的編譯器。右鍵單擊.cu文件,單擊屬性,修改編譯規則,選擇剛纔添加的CUDA編譯器。 4.添加包含目錄。在項目屬性-》C++->常規->附加包含目錄中添加CUDA SDK的目錄。例如"C:\Program Files\NVIDIA Corporation\NVIDIA GPU Computing SDK 3.2\C\common\inc";"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.0\include" 5.添加.lib文件。在連接器-》輸入中添加cudart.lib cutil32D.lib 6.修改代碼生成爲多線程(/MT)方式。 7.Done. 以上是工程配置。 除此以外,還要把調用cuda代碼的c++函數在.cu文件中用extern "C" 包含起來。而且在調用文件.cpp中用extern "C"聲明該函數,而後調用。 
相關文章
相關標籤/搜索