Advertisement
phystota

histogram_2_1

Oct 31st, 2024
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.76 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.71 * grn) + (0.07 * blu));
  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.  
  76. __global__ void Equalizer(unsigned char* Pin, float* Pout, float* CDF, int imgsize) {
  77.  
  78.   unsigned int t = blockIdx.x * blockDim.x + threadIdx.x;
  79.  
  80.   if(t < imgsize){
  81.     float val = (float) (255 * (CDF[Pin[t]] - CDF[0]) / (1.0 - CDF[0])) / (HISTOGRAM_LENGTH - 1.0);
  82.  
  83.     Pout[t] = (float) min(max(val, 0.0), 255.0);
  84.   }
  85. }
  86.  
  87.  
  88. int main(int argc, char **argv) {
  89.   wbArg_t args;
  90.   int imageWidth;
  91.   int imageHeight;
  92.   int imageChannels;
  93.   wbImage_t inputImage;
  94.   wbImage_t outputImage;
  95.   float *hostInputImageData;
  96.   float *hostOutputImageData;
  97.   const char *inputImageFile;
  98.  
  99.   float *deviceInput;
  100.   unsigned char *deviceUChar;
  101.   unsigned char *deviceGray;
  102.   unsigned int *deviceHist;
  103.   float *deviceCDF;
  104.   float *deviceOutput;
  105.   unsigned int *hostHist;
  106.   unsigned char *hostGray;
  107.   float *hostCDF;
  108.  
  109.  
  110.  
  111.   args = wbArg_read(argc, argv); /* parse the input arguments */
  112.  
  113.   inputImageFile = wbArg_getInputFile(args, 0);
  114.  
  115.   //Import data and create memory on host
  116.   inputImage = wbImport(inputImageFile);
  117.   imageWidth = wbImage_getWidth(inputImage);
  118.   imageHeight = wbImage_getHeight(inputImage);
  119.   imageChannels = wbImage_getChannels(inputImage);
  120.   outputImage = wbImage_new(imageWidth, imageHeight, imageChannels);
  121.  
  122.   hostInputImageData = wbImage_getData(inputImage);
  123.   hostOutputImageData = wbImage_getData(outputImage);
  124.  
  125.   hostHist = (unsigned int *)malloc(HISTOGRAM_LENGTH * sizeof(unsigned int));
  126.   hostGray = (unsigned char *)malloc(imageWidth*imageHeight * sizeof(unsigned char));
  127.   hostCDF = (float *)malloc(HISTOGRAM_LENGTH * sizeof(float));
  128.  
  129.   int imgsize = imageWidth*imageHeight*imageChannels;
  130.  
  131.   wbCheck(cudaMalloc((void**)&deviceInput, imgsize * sizeof(float)));
  132.   wbCheck(cudaMalloc((void**)&deviceUChar, imgsize * sizeof(unsigned char)));
  133.   wbCheck(cudaMalloc((void**)&deviceGray,  imageWidth*imageHeight* sizeof(unsigned char)));  
  134.   wbCheck(cudaMalloc((void**)&deviceHist, HISTOGRAM_LENGTH * sizeof(unsigned int)));
  135.   wbCheck(cudaMalloc((void**)&deviceCDF, HISTOGRAM_LENGTH * sizeof(float)));
  136.   wbCheck(cudaMalloc((void**)&deviceOutput, imgsize * sizeof(float)));
  137.  
  138.   wbCheck(cudaMemcpy(deviceInput, hostInputImageData, imgsize * sizeof(float), cudaMemcpyHostToDevice));
  139.   wbCheck(cudaMemset((void *) deviceHist, 0, HISTOGRAM_LENGTH * sizeof(unsigned int)));
  140.   wbCheck(cudaMemset((void *) deviceCDF, 0, HISTOGRAM_LENGTH * sizeof(float)));
  141.   memset(hostHist, 0, HISTOGRAM_LENGTH * sizeof(unsigned int));
  142.  
  143.  
  144.  
  145.   dim3 DimGrid(ceil(1.0*imgsize/(HISTOGRAM_LENGTH)), 1, 1);
  146.   dim3 DimGrid_CDF(1,1,1);
  147.   dim3 DimBlock(HISTOGRAM_LENGTH, 1, 1);
  148.  
  149.   FloattoUChar <<<DimGrid, DimBlock>>>(deviceInput, deviceUChar, imgsize);
  150.   cudaDeviceSynchronize();
  151.  
  152.   ColortoGray <<<DimGrid, DimBlock>>>(deviceUChar, deviceGray, imageWidth*imageHeight*imageChannels);
  153.   cudaDeviceSynchronize();
  154.  
  155.   // wbCheck(cudaMemcpy(hostGray, deviceGray, imageWidth*imageHeight * sizeof(unsigned char), cudaMemcpyDeviceToHost));
  156.  
  157.   // for (int i = 0; i < imageWidth*imageHeight; i++){
  158.   //   printf("%hhu\n", hostGray[i]);
  159.   // }  
  160.  
  161.   GraytoHist <<<DimGrid, DimBlock>>>(deviceGray, deviceHist, imageWidth*imageHeight);
  162.   cudaDeviceSynchronize();
  163.  
  164.   // wbCheck(cudaMemcpy(hostHist, deviceHist, HISTOGRAM_LENGTH * sizeof(unsigned int), cudaMemcpyDeviceToHost));
  165.  
  166.   // for (int i = 0; i < HISTOGRAM_LENGTH; i++){
  167.   //   printf("%u\n", hostHist[i]);
  168.   // }
  169.  
  170.   HistScanCDF <<<DimGrid_CDF, DimBlock>>>(deviceHist, deviceCDF, imageWidth*imageHeight);
  171.   cudaDeviceSynchronize();
  172.  
  173.   // wbCheck(cudaMemcpy(hostCDF, deviceCDF, HISTOGRAM_LENGTH * sizeof(float), cudaMemcpyDeviceToHost));
  174.  
  175.   // for (int i = 0; i < HISTOGRAM_LENGTH; i++){
  176.   //   printf("%lf\n", hostCDF[i]);
  177.   // }  
  178.  
  179.   Equalizer <<<DimGrid, DimBlock>>>(deviceUChar, deviceOutput, deviceCDF, imgsize);
  180.   cudaDeviceSynchronize();  
  181.  
  182.   wbCheck(cudaMemcpy(hostOutputImageData, deviceOutput, imgsize * sizeof(float), cudaMemcpyDeviceToHost));
  183.  
  184.   // for (int i = 0; i < imgsize; i++){
  185.   //   printf("%lf\n", hostOutputImageData[i]);
  186.   // }  
  187.  
  188.   wbImage_setData(outputImage, hostOutputImageData);
  189.  
  190.   wbSolution(args, outputImage);
  191.  
  192.   cudaFree(deviceInput);
  193.   cudaFree(deviceUChar);
  194.   cudaFree(deviceGray);
  195.   cudaFree(deviceHist);
  196.   cudaFree(deviceCDF);
  197.   cudaFree(deviceOutput);
  198.  
  199.   free(hostCDF);
  200.   free(hostGray);
  201.   free(hostHist);
  202.   free(hostInputImageData);
  203.   free(hostOutputImageData);
  204.  
  205.   return 0;
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement