CUDA和OpenCV实现的图像GAMMA变换

[cpp]  view plain copy
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include "cutil_inline.h"  
  6.   
  7. #define GAMMA 0.4  
  8.   
  9. void runTest(int argc, char** argv);  
  10.   
  11. __global__ void testKernel(float* d_idata, float* d_odata, int width, int height, float gamma)  
  12. {  
  13.  unsigned int tid_in_grid_x = blockDim.x*blockIdx.x + threadIdx.x;  
  14.  unsigned int tid_in_grid_y = blockDim.y*blockIdx.y + threadIdx.y;  
  15.  unsigned int tid_in_grid = tid_in_grid_y*width + tid_in_grid_x;  
  16.   
  17.  d_odata[tid_in_grid] = powf(d_idata[tid_in_grid], gamma);   
  18. }  
  19.   
  20. int main(int argc, char** argv)  
  21. {  
  22.  runTest(argc, argv);  
  23.  CUT_EXIT(argc, argv);  
  24. }  
  25.   
  26. void runTest(int argc, char** argv)  
  27. {  
  28.  if( cutCheckCmdLineFlag(argc, (const char**)argv, "device") )     //设备初始化并设定计时器。  
  29.   cutilDeviceInit(argc, argv);  
  30.  else  
  31.   cudaSetDevice(cutGetMaxGflopsDeviceId() );  
  32.   
  33.  unsigned int timer = 0;  
  34.     cutilCheckError(cutCreateTimer(&timer));  
  35.     cutilCheckError(cutStartTimer(timer));  
  36.   
  37.  IplImage* pImg;   
  38.  if((pImg = cvLoadImage("lena_gray.jpg", CV_LOAD_IMAGE_GRAYSCALE)) != 0 )  
  39.     {  
  40.         cvNamedWindow("Image", 1);  
  41.         cvShowImage("Image", pImg);  
  42.   
  43.   unsigned int num_blocks_x = pImg->width/16;  
  44.   unsigned int num_blocks_y = pImg->height/16;  
  45.   
  46.   unsigned int mem_size = sizeof(float)*pImg->widthStep*pImg->height;  
  47.   
  48.   float* h_idata = (float*)malloc(mem_size);  
  49.   float* h_odata = (float*)malloc(mem_size);  
  50.   
  51.   float* d_idata;  
  52.   CUDA_SAFE_CALL(cudaMalloc((void**)&d_idata, mem_size));  
  53.   float* d_odata;  
  54.   CUDA_SAFE_CALL(cudaMalloc((void**)&d_odata, mem_size));  
  55.   
  56.   for(int i = 0; i < pImg->widthStep*pImg->height; i++)  //从图像中复制数据时要特别注意变量类型,char类型的数据计算精度     
  57.   
  58.  h_idata[i] = ((uchar)pImg->imageData[i])/255.0;           //太低,但是图像中只能存储char类型,所以要进行转换  
  59.   
  60.   CUDA_SAFE_CALL(cudaMemcpy(d_idata, h_idata, mem_size, cudaMemcpyHostToDevice));  
  61.   
  62.   dim3 grid(num_blocks_x, num_blocks_y, 1);  
  63.   dim3 threads(16, 16, 1);  
  64.   
  65.   testKernel<<>>(d_idata, d_odata, pImg->width, pImg->height, GAMMA);  
  66.   
  67.   CUT_CHECK_ERROR("Kernel execution failed");  
  68.   
  69.   CUDA_SAFE_CALL(cudaMemcpy(h_odata, d_odata, mem_size, cudaMemcpyDeviceToHost));  
  70.   
  71.   IplImage* oImg = cvCreateImage(cvSize(pImg->width,pImg->height), IPL_DEPTH_8U, 1);  
  72.   for(int i = 0; i < pImg->widthStep*pImg->height; i++)  
  73.    oImg->imageData[i] = (uchar)(int)(h_odata[i]*255);  
  74.   
  75.   cvNamedWindow("Result", CV_WINDOW_AUTOSIZE);  
  76.         cvShowImage("Result", oImg);  
  77. //  cvSaveImage("result.jpg", oImg);  
  78.   
  79.   cutilCheckError( cutStopTimer( timer));  
  80.   printf( "Processing time: %f (ms)/n", cutGetTimerValue( timer));  
  81.   cutilCheckError( cutDeleteTimer( timer));  
  82.   
  83.   cvWaitKey(0);  
  84.   cvDestroyWindow("Image");  
  85.         cvReleaseImage(&pImg);  
  86.   cvDestroyWindow("Result");  
  87.         cvReleaseImage(&oImg);  
  88.   
  89.   free(h_idata);  
  90.   free(h_odata);  
  91.   CUDA_SAFE_CALL(cudaFree(d_idata));  
  92.   CUDA_SAFE_CALL(cudaFree(d_odata));  
  93.   
  94.     }  
  95. }   

你可能感兴趣的:(thread,nvidia,cuda,opencv)