Advertisement
phystota

histogram_2

Oct 29th, 2024
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.64 KB | None | 0 0
  1. // Histogram Equalization
  2.  
  3. #include <wb.h>
  4. #include <iostream>
  5. #include <string.h>
  6.  
  7. #define HISTOGRAM_LENGTH 256
  8.  
  9. //@@ insert code here
  10.  
  11. #define wbCheck(stmt)                                                     \
  12.   do {                                                                    \
  13.     cudaError_t err = stmt;                                               \
  14.     if (err != cudaSuccess) {                                             \
  15.       wbLog(ERROR, "Failed to run stmt ", #stmt);                         \
  16.       wbLog(ERROR, "Got CUDA error ...  ", cudaGetErrorString(err));      \
  17.       return -1;                                                          \
  18.     }                                                                     \
  19.   } while (0)
  20.  
  21. __global__ void FloattoUChar(float *Pin, unsigned char *Pout, int imgsize){
  22.   unsigned int t = blockIdx.x*blockDim.x + threadIdx.x;
  23.   if (t < imgsize){
  24.     Pout[t] =  (unsigned char) ((HISTOGRAM_LENGTH - 1) * Pin[t]);
  25.   }
  26. }
  27.  
  28. __global__ void ColortoGray(unsigned char *Pin, unsigned char *Pout, int imgSize){
  29.   unsigned int t = blockIdx.x*blockDim.x + threadIdx.x;
  30.   if(t < imgSize){
  31.     uint8_t red, grn, blu;
  32.  
  33.     red = Pin[t * 3];
  34.     grn = Pin[t * 3 + 1];
  35.     blu = Pin[t * 3 + 2];
  36.  
  37.     Pout[t] = (unsigned char) ((0.21 * red) + (0.07 * blu) + (0.71 * grn));
  38.   }
  39. }
  40.  
  41. __global__ void GraytoHist(unsigned char *Pin, unsigned int *Pout, int imgsize){
  42.   __shared__ unsigned int hist[HISTOGRAM_LENGTH];
  43.  
  44.   unsigned int t = blockIdx.x*blockDim.x + threadIdx.x;
  45.   if (threadIdx.x < HISTOGRAM_LENGTH){ // set histogram initial values to zero
  46.     hist[threadIdx.x] = 0;
  47.   }
  48.   __syncthreads();
  49.  
  50.   if (t < imgsize){     // feeding the histogram, Pin[t] always from 0 to 255, so hist[Pin[t]] matches
  51.     atomicAdd(&hist[Pin[t]], 1);
  52.   }
  53.   __syncthreads();
  54.  
  55.   if (threadIdx.x < HISTOGRAM_LENGTH){    // adding results from different block to the output
  56.     atomicAdd(&Pout[threadIdx.x], hist[threadIdx.x]);
  57.   }
  58. }
  59.  
  60. __global__ void HistScanCDF(unsigned int *Pin, float *Pout, int imgsize){
  61.   __shared__ float Scan[HISTOGRAM_LENGTH];
  62.   unsigned int t = threadIdx.x;
  63.   if (t < HISTOGRAM_LENGTH){
  64.     Scan[t] = Pin[t];
  65.   }
  66.   __syncthreads();
  67.  
  68.   for (unsigned int stride = 1; stride < blockDim.x; stride *= 2){
  69.     __syncthreads();
  70.     if (t >= stride) Scan[t] += Scan[t - stride];
  71.   }
  72.   __syncthreads();
  73.   Pout[t] = Scan[t]/imgsize;
  74. }
  75. __global__ void Equalizer(unsigned char* Pin, float* Pout, float* CDF, int imgsize) {
  76.  
  77.   unsigned int t = blockIdx.x * blockDim.x + threadIdx.x;
  78.  
  79.   if(t < imgsize){
  80.     float val = 255 * (CDF[Pin[t]] - CDF[0]) / (1 - CDF[0]) / (HISTOGRAM_LENGTH - 1);
  81.  
  82.     Pout[t] = (float) min(max(val, 0.0), 255.0);
  83.   }
  84. }
  85.  
  86.  
  87. int main(int argc, char **argv) {
  88.   wbArg_t args;
  89.   int imageWidth;
  90.   int imageHeight;
  91.   int imageChannels;
  92.   wbImage_t inputImage;
  93.   wbImage_t outputImage;
  94.   float *hostInputImageData;
  95.   float *hostOutputImageData;
  96.   const char *inputImageFile;
  97.  
  98.   float *deviceInput;
  99.   unsigned char *deviceUChar;
  100.   unsigned char *deviceGray;
  101.   unsigned int *deviceHist;
  102.   float *deviceCDF;
  103.   float *deviceOutput;
  104.   unsigned int *hostHist;
  105.   unsigned char *hostGray;
  106.   float *hostCDF;
  107.  
  108.  
  109.  
  110.   args = wbArg_read(argc, argv); /* parse the input arguments */
  111.  
  112.   inputImageFile = wbArg_getInputFile(args, 0);
  113.  
  114.   //Import data and create memory on host
  115.   inputImage = wbImport(inputImageFile);
  116.   imageWidth = wbImage_getWidth(inputImage);
  117.   imageHeight = wbImage_getHeight(inputImage);
  118.   imageChannels = wbImage_getChannels(inputImage);
  119.   outputImage = wbImage_new(imageWidth, imageHeight, imageChannels);
  120.  
  121.   hostInputImageData = wbImage_getData(inputImage);
  122.   hostOutputImageData = wbImage_getData(outputImage);
  123.  
  124.   hostHist = (unsigned int *)malloc(HISTOGRAM_LENGTH * sizeof(unsigned int));
  125.   hostGray = (unsigned char *)malloc(imageWidth*imageHeight * sizeof(unsigned char));
  126.   hostCDF = (float *)malloc(HISTOGRAM_LENGTH * sizeof(float));
  127.  
  128.   int imgsize = imageWidth*imageHeight*imageChannels;
  129.  
  130.   wbCheck(cudaMalloc((void**)&deviceInput, imgsize * sizeof(float)));
  131.   wbCheck(cudaMalloc((void**)&deviceUChar, imgsize * sizeof(unsigned char)));
  132.   wbCheck(cudaMalloc((void**)&deviceGray,  imageWidth*imageHeight* sizeof(unsigned char)));  
  133.   wbCheck(cudaMalloc((void**)&deviceHist, HISTOGRAM_LENGTH * sizeof(unsigned int)));
  134.   wbCheck(cudaMalloc((void**)&deviceCDF, HISTOGRAM_LENGTH * sizeof(float)));
  135.   wbCheck(cudaMalloc((void**)&deviceOutput, imgsize * sizeof(float)));
  136.  
  137.   wbCheck(cudaMemcpy(deviceInput, hostInputImageData, imgsize * sizeof(float), cudaMemcpyHostToDevice));
  138.   wbCheck(cudaMemset((void *) deviceHist, 0, HISTOGRAM_LENGTH * sizeof(unsigned int)));
  139.   wbCheck(cudaMemset((void *) deviceCDF, 0, HISTOGRAM_LENGTH * sizeof(float)));
  140.   memset(hostHist, 0, HISTOGRAM_LENGTH * sizeof(unsigned int));
  141.  
  142.  
  143.  
  144.   dim3 DimGrid(ceil(1.0*imgsize/(HISTOGRAM_LENGTH)), 1, 1);
  145.   dim3 DimGrid_CDF(1,1,1);
  146.   dim3 DimBlock(HISTOGRAM_LENGTH, 1, 1);
  147.  
  148.   FloattoUChar <<<DimGrid, DimBlock>>>(deviceInput, deviceUChar, imgsize);
  149.   cudaDeviceSynchronize();
  150.   ColortoGray <<<DimGrid, DimBlock>>>(deviceUChar, deviceGray, imageWidth*imageHeight*imageChannels);
  151.   cudaDeviceSynchronize();
  152.  
  153.   // wbCheck(cudaMemcpy(hostGray, deviceGray, imageWidth*imageHeight * sizeof(unsigned char), cudaMemcpyDeviceToHost));
  154.  
  155.   // for (int i = 0; i < imageWidth*imageHeight; i++){
  156.   //   printf("%hhu\n", hostGray[i]);
  157.   // }  
  158.  
  159.   GraytoHist <<<DimGrid, DimBlock>>>(deviceGray, deviceHist, imageWidth*imageHeight);
  160.   cudaDeviceSynchronize();
  161.  
  162.   // wbCheck(cudaMemcpy(hostHist, deviceHist, HISTOGRAM_LENGTH * sizeof(unsigned int), cudaMemcpyDeviceToHost));
  163.  
  164.   // for (int i = 0; i < HISTOGRAM_LENGTH; i++){
  165.   //   printf("%u\n", hostHist[i]);
  166.   // }
  167.  
  168.   HistScanCDF <<<DimGrid_CDF, DimBlock>>>(deviceHist, deviceCDF, imageWidth*imageHeight);
  169.   cudaDeviceSynchronize();
  170.  
  171.   // wbCheck(cudaMemcpy(hostCDF, deviceCDF, HISTOGRAM_LENGTH * sizeof(float), cudaMemcpyDeviceToHost));
  172.  
  173.   // for (int i = 0; i < HISTOGRAM_LENGTH; i++){
  174.   //   printf("%lf\n", hostCDF[i]);
  175.   // }  
  176.  
  177.   Equalizer <<<DimGrid, DimBlock>>>(deviceUChar, deviceOutput, deviceCDF, imgsize);
  178.   cudaDeviceSynchronize();
  179.  
  180.   wbCheck(cudaMemcpy(hostOutputImageData, deviceOutput, imgsize * sizeof(float), cudaMemcpyDeviceToHost));
  181.  
  182.   wbImage_setData(outputImage, hostOutputImageData);
  183.  
  184.   wbSolution(args, outputImage);
  185.  
  186.   cudaFree(deviceInput);
  187.   cudaFree(deviceUChar);
  188.   cudaFree(deviceGray);
  189.   cudaFree(deviceHist);
  190.   cudaFree(deviceCDF);
  191.   cudaFree(deviceOutput);
  192.  
  193.   free(hostCDF);
  194.   free(hostGray);
  195.   free(hostHist);
  196.   free(hostInputImageData);
  197.   free(hostOutputImageData);
  198.  
  199.   return 0;
  200. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement