之前的文章中,给大家介绍了如何将OpenCV 2.2与CUDA 4.0的巧妙结合。今天尝试把CUDA 和 OpenCV 两者进行硬性结合。
建立一个 project,添加一个.cu 的文件。
按照之前的方法进行 OpenCV 和 CUDA 的配置:
我们看到.cu 文件的图标不好看,可以在属性中 File Type 项选择 C/C++ Code。
这样 .cu 就变成了我们熟悉的图标,当然这些都是无所谓的事情。
添加代码,我把之前用来测试 OpenCV 和 CUDA 的代码放到了一起:
#include <iostream>
#include <highgui.h>
using namespace ::std;
///////////////////////////////////////////////////////////////////////////
#include <cv.h>
#include <highgui.h>
#pragma comment(lib, "ml.lib")
#pragma comment(lib, "cv.lib")
#pragma comment(lib, "cvaux.lib")
#pragma comment(lib, "cvcam.lib")
#pragma comment(lib, "cxcore.lib")
#pragma comment(lib, "cxts.lib")
#pragma comment(lib, "highgui.lib")
#pragma comment(lib, "cvhaartraining.lib")
///////////////////////////////////////////////////////////////////////////
__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);
}
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;
}
直接用 Debug 运行出错加一堆 warning,难道这样硬生生搬到一起就不行吗?
后来,同学用 OpenCV 1.0 和 CUDA 4.0 的组合顺利通过。
或者参考http://www.ademiller.com/blogs/tech/2011/03/using-cuda-and-thrust-with-visual-studio-2010/
再后来,用 Release 运行竟然通过了,而且结果正确,神了个奇,但是 warning 依然很多,看来不是个好方法。
但起码出结果了,我很不理解,看来我对 Debug 和 Release 的机制还不了解,以后再说。
顺便一提,这时图片路径使用绝对路径竟然就可以了。