当前位置:   article > 正文

使用cuda加速图像缩放的例子_cuda resize

cuda resize

一、前言

本文主要讲解了cuda并行加速的一个小例子,对图像缩放的最近邻插值算法做加速。

二、代码实现

由于进行缩放时,每个新像素点的计算方法均一致,故可使用并行计算,opencv中的resize也是这么做的。

  1. //main.cu
  2. #include "cuda_runtime.h"
  3. #include <windows.h>
  4. #include <iostream>
  5. #include <opencv2/core/core.hpp>
  6. #include <opencv2/highgui/highgui.hpp>
  7. #include <opencv2/imgproc/imgproc.hpp>
  8. using namespace cv;
  9. using namespace std;
  10. void resizeImage(const Mat &_src, Mat &_dst, const Size &s )
  11. {
  12. _dst = Mat::zeros(s, CV_8UC3);
  13. double fRows = s.height / (float)_src.rows;
  14. double fCols = s.width / (float)_src.cols;
  15. int pX = 0;
  16. int pY = 0;
  17. for (int i = 0; i != _dst.rows; ++i){
  18. for (int j = 0; j != _dst.cols; ++j){
  19. pX = cvRound(i/(double)fRows);
  20. pY = cvRound(j/(double)fCols);
  21. if (pX < _src.rows && pX >= 0 && pY < _src.cols && pY >= 0){
  22. _dst.at<Vec3b>(i, j)[0] = _src.at<Vec3b>(pX, pY)[0];
  23. _dst.at<Vec3b>(i, j)[1] = _src.at<Vec3b>(pX, pY)[1];
  24. _dst.at<Vec3b>(i, j)[2] = _src.at<Vec3b>(pX, pY)[2];
  25. }
  26. }
  27. }
  28. }
  29. bool initCUDA()
  30. {
  31. int count;
  32. cudaGetDeviceCount(&count);
  33. if (count == 0){
  34. fprintf(stderr, "There is no device.\n");
  35. return false;
  36. }
  37. int i;
  38. for (i = 0; i < count; i++){
  39. cudaDeviceProp prop;
  40. if (cudaGetDeviceProperties(&prop, i) == cudaSuccess){
  41. if (prop.major >= 1){
  42. break;
  43. }
  44. }
  45. }
  46. if (i == count){
  47. fprintf(stderr, "There is no device supporting CUDA 1.x.\n");
  48. return false;
  49. }
  50. cudaSetDevice(i);
  51. return true;
  52. }
  53. __global__ void kernel(uchar* _src_dev, uchar * _dst_dev, int _src_step, int _dst_step ,
  54. int _src_rows, int _src_cols, int _dst_rows, int _dst_cols)
  55. {
  56. int i = blockIdx.x;
  57. int j = blockIdx.y;
  58. double fRows = _dst_rows / (float)_src_rows;
  59. double fCols = _dst_cols / (float)_src_cols;
  60. int pX = 0;
  61. int pY = 0;
  62. pX = (int)(i / fRows);
  63. pY = (int)(j / fCols);
  64. if (pX < _src_rows && pX >= 0 && pY < _src_cols && pY >= 0){
  65. *(_dst_dev + i*_dst_step + 3 * j + 0) = *(_src_dev + pX*_src_step + 3 * pY);
  66. *(_dst_dev + i*_dst_step + 3 * j + 1) = *(_src_dev + pX*_src_step + 3 * pY + 1);
  67. *(_dst_dev + i*_dst_step + 3 * j + 2) = *(_src_dev + pX*_src_step + 3 * pY + 2);
  68. }
  69. }
  70. void resizeImageGpu(const Mat &_src, Mat &_dst, const Size &s)
  71. {
  72. _dst = Mat(s, CV_8UC3);
  73. uchar *src_data = _src.data;
  74. int width = _src.cols;
  75. int height = _src.rows;
  76. uchar *src_dev , *dst_dev;
  77. cudaMalloc((void**)&src_dev, 3 * width*height * sizeof(uchar) );
  78. cudaMalloc((void**)&dst_dev, 3 * s.width * s.height * sizeof(uchar));
  79. cudaMemcpy(src_dev, src_data, 3 * width*height * sizeof(uchar), cudaMemcpyHostToDevice);
  80. double fRows = s.height / (float)_src.rows;
  81. double fCols = s.width / (float)_src.cols;
  82. int src_step = _src.step;
  83. int dst_step = _dst.step;
  84. dim3 grid(s.height, s.width);
  85. kernel << < grid, 1 >> >(src_dev, dst_dev, src_step, dst_step, height, width, s.height, s.width);
  86. cudaMemcpy(_dst.data, dst_dev, 3 * s.width * s.height * sizeof(uchar), cudaMemcpyDeviceToHost);
  87. }
  88. int main()
  89. {
  90. Mat src = cv::imread("E:\\学习资料\\测试标准图\\lena.bmp" , 1);
  91. Mat dst_cpu;
  92. double start = GetTickCount();
  93. resizeImage(src, dst_cpu, Size(src.cols * 2, src.rows * 2));
  94. double end = GetTickCount();
  95. cout << "cpu缩放所耗费的时间:" << end - start << "\n";
  96. initCUDA();
  97. Mat dst_gpu;
  98. start = GetTickCount();
  99. resizeImageGpu(src, dst_gpu, Size(src.cols * 2, src.rows * 2));
  100. end = GetTickCount();
  101. cout << "gpu缩放所耗费的时间:" << end - start << "\n";
  102. cv::imshow("Demo", dst_cpu);
  103. waitKey(0);
  104. return 0;
  105. }
三、实验结果

本文实验环境为vs2013+cuda7.0+opencv2.4.9,可以得到结果如下,当在将512*512的lena图像放大为1024*1024时,使用gpu并行计算的方法加快了一倍多,但若要进行缩小运算时,使用gpu加速则不一定会快,因为数据上传会占用时间。


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/432413
推荐阅读
相关标签
  

闽ICP备14008679号