Advertisement
phystota

histogram_final

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