OpenCV 2.2与CUDA 4.0的巧妙结合

间隙填充
正睿科技  发布时间:2011-09-21 09:17:21  浏览数:3836
本文将为大家介绍如何将OpenCV 2.2与CUDA 4.0的巧妙结合。以下是文章内容:

  主要思想是:并行的程序写在.cu文件中,编译成.dll的形式,之后用.cpp文件直接调用.dll文件,完成两者结合。

  1)首先建立一个 Win32 Console Application,并添加源文件*.cpp。

  2)在同一个 Solution 下面,再建立一个 Win32 DLL,添加 CUDA 头文件*.cuh 和 CUDA 文件*.cu。

  3)按照之前的方法,分别对两个 project 进行 OpenCV 和 CUDA 的配置。

OpenCV2.2与CUDA4.0的巧妙结合

  这时需要做一些配置将两个 project 关联到一起。

  对.cpp 文件所在的 project 做如下配置。

  4)打开其属性页,在 Linker | General | Additional Libraries Directories 中添加:

  ..\$(Configuration) 以及 $(CUDA_PATH_V4_0)\lib\$(Platform)

OpenCV2.2与CUDA4.0的巧妙结合

  5)打开属性页,在 Linker | Input | Additional Dependencies 中添加:

  cudart.lib 以及 OpenCVwithCUDAdll.lib(根据第二个 project 的名字而定)。

  6)打开属性页,在 C/C++ | General | Additional Include Directories 中添加目录:

  ..\OpenCVwithCUDAdll\(视第二个 project 的名字而定)以及 $(CUDA_PATH_V4_0)\Include。

OpenCV2.2与CUDA4.0的巧妙结合

  下面对 Solution 进行配置。

  7)打开其属性页,在 Project Dependencies 中勾选两个 project 的以来关系。

  使 Win32 Application project 依附于 CUDA project。

OpenCV2.2与CUDA4.0的巧妙结合


  8)配置完成,填写代码:

  main.cpp

#include <iostream>
#include
<highgui.h>
#include
"CUDAdll.cuh"
using namespace ::std;


int main()
{
IplImage
*img = cvLoadImage("E:\lena.jpg");
cvShowImage(
"Image:",img);


float M[3][3] = {
{
1.0, 2.0, 3.0},
{
4.0, 5.0, 6.0},
{
7.0, 8.0, 9.0}
};
float N[3][3] = {
{
1.0, 2.0, 3.0},
{
4.0, 5.0, 6.0},
{
7.0, 8.0, 9.0}
};
float P[3][3] = {0.0};


float* m = &M[0][0];
float* n = &N[0][0];
float* p = &P[0][0];


int Width = 3;


MatrixMulOnDevice(m, n, p, Width);


for (int i = 0;i < Width;i++)
{
for (int j = 0;j < Width;j++)
{
cout
<<P[i][j]<<" ";
}
cout
<<endl;
}


cvWaitKey();
return 0;
}

    CUDAdll.cuh

#ifdef mydll_api
#else
#define mydll_api _declspec(dllimport)
#endif
mydll_api
void MatrixMulOnDevice(float* M, float* N, float* P, int Width);
mydll_api
void MatrixMulKernel(float* Md, float* Nd, float* Pd, int Width);

    CUDAdll.cu

#define mydll_api _declspec(dllexport)
#include
"CUDAdll.cuh"


__global__
void MatrixMulKernel(float* Md, float* Nd, float* Pd, int Width)
{
int tx = threadIdx.x;
int ty = threadIdx.y;


float Pvalue = 0.0;


for(int k = 0; k < Width; k++)
{
float Melement = Md[ty *Width + k];
float Nelement = Nd[k *Width + tx];
Pvalue
+= Melement * Nelement;
}
Pd[ty
*Width + tx] = Pvalue;
}


void MatrixMulOnDevice(float* M, float* N, float* P, int Width)
{
int size = Width * Width * sizeof(float);
float* Md;
float* Nd;
float* Pd;


cudaMalloc(
&Md, size);
cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice);


cudaMalloc(
&Nd, size);
cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice);


cudaMalloc(
&Pd, size);


dim3 dimBlock(Width, Width);
dim3 dimGrid(
1,1);


MatrixMulKernel
<<<dimGrid, dimBlock>>>(Md, Nd, Pd, Width);


cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost);


cudaFree(Md);
cudaFree(Nd);
cudaFree(Pd);
}

  cuda做的是矩阵乘法,opencv输出图像:

OpenCV2.2与CUDA4.0的巧妙结合

  就是这个图片路径弄不清怎么回事,有时候绝对路径就不能显示图片。