实现图像的反转并不难,小编在opencv篇中已经把代码贴出。本文却又旧事重提,主要为了用CUDA实现并行处理反转过程,代码难度并不大,但是却是对opencv+CUDA结合起来的一个应用,给以后一些运算量大的图像算法用CUDA并行运算实现提供一个现实参考,好了,废话不多说,先贴上代码:
/*****************************************************************************************************
* File name: cudaCppMain.cpp
* Author: source code by RamiYim
* Version: cs-hhu-cn0.0
* Date: 2014.08.12
* Description: 测试cuda与opencv相结合
* Others:
* Function List: main functions and its function
* History:<rami>,<20140819>,<添加相关函数>,<desc>
<rami>,<20140812>,<创建文件>,<desc>
******************************************************************************************************/
#include "reverseImage.h"
int main()
{
reverseImage(cvLoadImage("D:/lena.jpg"));
return 0;
}
/*****************************************************************************************************
* File name: reverseImage.h
* Author: source code by RamiYim
* Version: cs-hhu-cn0.0
* Date: 2014.08.12
* Description: 测试cuda与opencv相结合
* Others:
* Function List: main functions and its function
* History:<rami>,<20140819>,<添加相关函数>,<desc>
<rami>,<20140812>,<创建文件>,<desc>
******************************************************************************************************/
#include "cv.h"
#include "highgui.h"
void reverseImage(IplImage *);
/*****************************************************************************************************
* File name: reverseImage.cpp
* Author: source code by RamiYim
* Version: cs-hhu-cn0.0
* Date: 2014.08.12
* Description: 测试cuda与opencv相结合
* Others:
* Function List: 实现reverseImage函数
* History:<rami>,<20140819>,<添加相关函数>,<desc>
* <rami>,<20140812>,<创建文件>,<desc>
******************************************************************************************************/
#include "reverseImage.h"
#include "cv.h"
extern "C" int revImg(const char *, int size);
void reverseImage(IplImage *sourceImage){
cvNamedWindow("sourceImage");
cvShowImage("sourceImage", sourceImage);
cvWaitKey(0);
int width, height, channels, width_step;
width = sourceImage -> width;
height = sourceImage -> height;
channels = sourceImage -> nChannels;
width_step = sourceImage -> widthStep;
const char *data = sourceImage -> imageData;
int size = width * height * channels;
revImg(data, size);
cvShowImage("reversedImage", sourceImage);
cvWaitKey(0);
cvDestroyWindow("sourceImage");
cvDestroyWindow("reversedImage");
}
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include "cv.h"
#include "highgui.h"
cudaError_t addWithCuda(char *data, int size);
__global__ void revImg(char *dev_c)
{
int bid = blockIdx.x * gridDim.x + blockIdx.y; //gridDim.x为固定值400,blockIdx.x取值范围为0~399
int tid = bid * blockDim.x + threadIdx.x; //blockDim.x为定值3,threadIdx.x取值范围为0~2
dev_c[tid] = 255 - dev_c[tid]; //实现反转主体功能
}
extern "C" void revImg(char *data, int size)
{
cudaError_t cudaStatus = addWithCuda(data, size);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "addWithCuda failed!");
}
}
cudaError_t addWithCuda(char *data, int size) {
char *dev_c = 0;
cudaError_t cudaStatus;
// Choose which GPU to run on, change this on a multi-GPU system.
cudaStatus = cudaSetDevice(0);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaSetDevice failed! Do you have a CUDA-capable GPU installed?");
goto Error;
}
// Allocate GPU buffers for dev_c
cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(char));
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMalloc failed!");
goto Error;
}
// Copy input vectors from host memory to GPU buffers.
cudaStatus = cudaMemcpy(dev_c, data, size * sizeof(char), cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMemcpy failed!");
goto Error;
}
// Launch a kernel on the GPU with one thread for each element.
dim3 dimGrid(400, 400);
dim3 dimBlock(3, 1); //1行3列
revImg<<<dimGrid, dimBlock>>>(dev_c); //调用内核函数
// Check for any errors launching the kernel
cudaStatus = cudaGetLastError();
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus));
goto Error;
}
// cudaDeviceSynchronize waits for the kernel to finish, and returns
// any errors encountered during the launch.
cudaStatus = cudaDeviceSynchronize();
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
goto Error;
}
// Copy output vector from GPU buffer to host memory.
cudaStatus = cudaMemcpy(data, dev_c, size * sizeof(char), cudaMemcpyDeviceToHost);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMemcpy failed!");
goto Error;
}
Error:
cudaFree(dev_c);
return cudaStatus;
}
以上即为函数的主体功能,结果如下图:
PS:CUDA环境配置见本人博客,地址为:http://blog.youkuaiyun.com/a2112233445566/article/details/38420567
OpenCV环境配置件本人博客,地址为:http://blog.youkuaiyun.com/a2112233445566/article/details/38540389