Advertisement
Guest User

Untitled

a guest
Mar 20th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.95 KB | None | 0 0
  1. #define _USE_MATH_DEFINES
  2. #include "iostream"
  3. #include <cmath>
  4. #include "cuda_runtime.h"
  5. #include "device_launch_parameters.h"
  6. #include <opencv2/opencv.hpp>
  7. #include <stdio.h>
  8. #include <string>
  9. #include <chrono>
  10.  
  11. #define CUDA_KC 32
  12. #define CUDA_BS 32
  13.  
  14. using namespace std;
  15. using namespace cv;
  16.  
  17. string imageinputPath;
  18. string imageOutputPath;
  19.  
  20. const int gaussFilterSize = 5;
  21. const double sigma = 1.5;
  22.  
  23. int imageCols;
  24. int imageRows;
  25. int imageChannels;
  26. size_t imageSizeInBytes;
  27.  
  28. double **matrix;
  29. double *matrix1D;
  30.  
  31. int loadParams(int argc, char** argv);
  32. Mat * loadImage();
  33. void compGaussianMatrix2D(int size, double sigma);
  34. void compGaussianMatrix1D(int size);
  35. __global__
  36. static void performGaussParrallel2(uint8_t* inputImage, uint8_t* outImgage, double *cudaMatrix, int imageCols, int imageRows, int imageChannels);
  37.  
  38. int main(int argc, char **argv)
  39. {
  40. cudaError_t err = cudaSuccess;
  41. loadParams(argc, argv); //loads params from CMD
  42.  
  43. //gets image data from file
  44. Mat * inputImage = loadImage();
  45. if (inputImage == NULL) {
  46. return 0;
  47. }
  48. //HOST orginal image data init
  49. uint8_t *hostOrginalImageData = (uint8_t*)inputImage->data;
  50.  
  51. compGaussianMatrix2D(gaussFilterSize, sigma);//computes gaussian matrix
  52. compGaussianMatrix1D(gaussFilterSize);//gaussian matrix as a vector
  53. imageCols = inputImage->cols;
  54. imageRows = inputImage->rows;
  55. imageChannels = inputImage->channels();
  56. imageSizeInBytes = imageCols * imageRows * imageChannels * sizeof(uint8_t);
  57.  
  58. //HOST Processed Image Data
  59. uint8_t *hostProcessedImageData = (uint8_t *)malloc(imageSizeInBytes);
  60. //CUDA processed image data alloc
  61. uint8_t *cudaProcessedImageData = NULL;
  62. err = cudaMalloc(&cudaProcessedImageData, imageSizeInBytes);
  63. if (err != cudaSuccess) {cout << "Error while malloc cudaProcessedImageData \n";exit(EXIT_FAILURE);}
  64.  
  65. //CUDA orginal image data alloc and memcpy from HOST
  66. uint8_t *cudaOrginalImageData = NULL;
  67. err = cudaMalloc(&cudaOrginalImageData, imageSizeInBytes);
  68. if (err != cudaSuccess) {cout << "Error while malloc cudaOrginalImageData \n";exit(EXIT_FAILURE);}
  69. err = cudaMemcpy(cudaOrginalImageData, hostOrginalImageData, imageSizeInBytes, cudaMemcpyHostToDevice);
  70. if (err != cudaSuccess) {cout << "Error while cudaMemcpy cudaOrginalImageData \n";exit(EXIT_FAILURE);}
  71.  
  72. //CUDA matrix alloc and memcpy from HOST
  73. double *cudaMatrix = NULL;
  74. size_t cudaMatrixSize = 5 * 5 * sizeof(double);
  75. err = cudaMalloc(&cudaMatrix, cudaMatrixSize);
  76. if (err != cudaSuccess) {cout << "Error while cudaMalloc cudaMatrix \n";exit(EXIT_FAILURE);}
  77. err = cudaMemcpy(cudaMatrix, matrix1D, cudaMatrixSize, cudaMemcpyHostToDevice);
  78. if (err != cudaSuccess) {cout << "Error while cudaMemcpy cudaMatrix \n";exit(EXIT_FAILURE);}
  79.  
  80. chrono::system_clock::time_point start;
  81. chrono::system_clock::time_point stop;
  82. start = chrono::high_resolution_clock::now();
  83.  
  84. performGaussParrallel2<<<CUDA_KC, CUDA_BS>>>(cudaOrginalImageData, cudaProcessedImageData, cudaMatrix, imageCols, imageRows, imageChannels);
  85.  
  86. stop = chrono::high_resolution_clock::now();
  87. cudaDeviceSynchronize();
  88. err = cudaGetLastError();
  89. if (err != cudaSuccess){cout << "Error while calling performGaussParrallel2! \n" << cudaGetErrorString(err);exit(EXIT_FAILURE);}
  90. chrono::duration<double> elapsed = stop - start;
  91. err = cudaMemcpy(hostProcessedImageData, cudaProcessedImageData, imageSizeInBytes, cudaMemcpyDeviceToHost);
  92. if (err != cudaSuccess) {cout << "Error while cudaMemcpy processedimage \n";exit(EXIT_FAILURE);}
  93. err = cudaFree(cudaProcessedImageData);
  94. if (err != cudaSuccess){fprintf(stderr, "Failed to free device vector A (error code %s)!\n", cudaGetErrorString(err));exit(EXIT_FAILURE);}
  95. err = cudaFree(cudaOrginalImageData);
  96. if (err != cudaSuccess){fprintf(stderr, "Failed to free device vector A (error code %s)!\n", cudaGetErrorString(err));exit(EXIT_FAILURE);}
  97.  
  98. Mat newImageMat = Mat(imageRows, imageCols, inputImage->type());
  99. try {
  100. newImageMat.data = hostProcessedImageData;
  101. imwrite(imageOutputPath, newImageMat);
  102. } catch (exception e) {
  103. cout << "Cant save image!";
  104. return 0;
  105. }
  106.  
  107.  
  108. cout << "Czas: " << elapsed.count();
  109. // system("pause");
  110. return 0;
  111. }
  112.  
  113. __global__
  114. static void performGaussParrallel2(uint8_t* inputImage, uint8_t* outImgage, double *cudaMatrix, int imageCols, int imageRows, int imageChannels) {
  115. const int tid = threadIdx.x;
  116. //const int bid = blockIdx.x;
  117. // int imageSizeInBytes = imageCols * imageRows * imageChannels * sizeof(uint8_t);
  118. int blockSize = (imageCols * imageRows) / 512;
  119. int startPoint = tid*blockSize * imageChannels * sizeof(uint8_t);
  120. int h, w;
  121. int currentPos = startPoint;
  122. int outputPosition = startPoint;
  123. int wallValue = imageCols * imageRows * imageChannels - (5 * imageCols * imageChannels);
  124. while (startPoint + blockSize * imageChannels * sizeof(uint8_t) > currentPos && currentPos < wallValue) {
  125. double outChannel1 = 0;
  126. double outChannel2 = 0;
  127. double outChannel3 = 0;
  128. for (h = 0; h < 5; h++) {
  129. for (w = 0; w < 5; w++) {
  130. int pixelPosXY = currentPos + h * imageChannels * imageCols + w * imageChannels;
  131. double channel1 = inputImage[pixelPosXY];
  132. double channel2 = inputImage[pixelPosXY + 1];
  133. double channel3 = inputImage[pixelPosXY + 2];
  134. double *matrixVal = &cudaMatrix[h+w*5];
  135. outChannel1 += *matrixVal * channel1;
  136. outChannel2 += *matrixVal * channel2;
  137. outChannel3 += *matrixVal * channel3;
  138. //cout << x << " x " << y << " y "<< h <<" h "<< w <<" w\n" ;
  139. }
  140. }
  141. outImgage[outputPosition] = outChannel1;
  142. outImgage[outputPosition + 1] = outChannel2;
  143. outImgage[outputPosition + 2] = outChannel3;
  144. outputPosition += 3;
  145. currentPos += 3;
  146. if (currentPos > imageCols * imageRows * imageChannels - (5 * imageCols * imageChannels)) {
  147. break;
  148. }
  149. }
  150. }
  151.  
  152.  
  153. void compGaussianMatrix2D(int size, double sigma) {
  154. matrix = new double*[size];
  155. for (int i = 0; i < size; ++i) {
  156. matrix[i] = new double[size];
  157. }
  158.  
  159. double result = 0.;
  160. int i, j;
  161. for (i = 0; i < size; i++) {
  162. for (j = 0; j < size; j++) {
  163. matrix[i][j] = exp(-(i*i + j * j) / (2 * sigma*sigma)) / (2 * M_PI *sigma*sigma);
  164. result += matrix[i][j];
  165. }
  166. }
  167.  
  168. for (i = 0; i < size; i++) {
  169. for (j = 0; j < size; j++) {
  170. matrix[i][j] = matrix[i][j] / result;
  171. //cout << matrix[i][j] << " ";
  172. }
  173. //cout << "\n";
  174. }
  175. };
  176.  
  177. void compGaussianMatrix1D(int size) {
  178. matrix1D = new double[size*size];
  179. int i, j;
  180. for (i = 0; i < size; i++) {
  181. for (j = 0; j < size; j++) {
  182. matrix1D[i+j*size] = matrix[i][j];
  183. }
  184. }
  185. }
  186.  
  187. //wczytuje parametry z argv
  188. int loadParams(int argc, char** argv) {
  189. imageinputPath = "2.jpg";
  190. imageOutputPath = "out.jpg";
  191.  
  192. if (argc == 1) {
  193. cout << "Nie podano sciezek do pliku wejsciowego i wyjsciowego!";
  194. return -1;
  195. }
  196. else {
  197. imageinputPath = argv[1];
  198.  
  199. }
  200.  
  201. if (argc == 2) {
  202. cout << "Nie podano sciezki wyjsciowej do pliku!";
  203. return -1;
  204. }
  205. else {
  206. imageOutputPath = argv[2];
  207. }
  208. return 0;
  209. };
  210.  
  211. //zwraca macierz obrazu
  212. Mat * loadImage() {
  213. static Mat inputImage;
  214. if (imageinputPath.length() != 0) {
  215. inputImage = imread(imageinputPath, IMREAD_COLOR);
  216. if (inputImage.empty()) {
  217. cout << "Cant load file! \n";
  218. return NULL;
  219. }
  220. }
  221. else {
  222. cout << "error! Invalid image path!\n";
  223. return NULL;
  224. }
  225. return &inputImage;
  226. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement