• CUDA小白 - NPP(6) 图像处理 Geometry Transforms (2)


    cuda小白
    原始API链接 NPP

    GPU架构近些年也有不少的变化,具体的可以参考别的博主的介绍,都比较详细。还有一些cuda中的专有名词的含义,可以参考《详解CUDA的Context、Stream、Warp、SM、SP、Kernel、Block、Grid》

    常见的NppStatus,可以看这里

    Affine Transform

    仿射变换
    在这里插入图片描述

    // 仿射变换
    NppStatus nppiWarpAffine_8u_C3R(const Npp8u *pSrc,
    								NppiSize oSrcSize,
    								int nSrcStep,
    								NppiRect oSrcROI,
    								Npp8u *pDst,
    								int nDstStep,
    								NppiRect oDstROI,
    								const double aCoeffs[2][3],
    								int eInterpolation);
    // 同样的2x3的矩阵的逆仿射变换
    NppStatus nppiWarpAffineBack_8u_C3R(const Npp8u *pSrc,
    									NppiSize oSrcSize,
    									int nSrcStep,
    									NppiRect oSrcROI,
    									Npp8u *pDst,
    									int nDstStep,
    									NppiRect oDstROI,
    									const double aCoeffs[2][3],
    									int eInterpolation);
    // 源图像的四边形 仿射变换到 目标的四边形,平时使用较少,后续不进行测试
    NppStatus nppiWarpAffineQuad_8u_C3R(const Npp8u *pSrc,
    									NppiSize oSrcSize,
    									int nSrcStep,
    									NppiRect oSrcROI,
    									const double aSrcQuad[4][2],
    									Npp8u *pDst,
    									int nDstStep,
    									NppiRect oDstROI,
    									const double aDstQuad[4][2],
    									int eInterpolation);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    code
    #include 
    #include 
    #include 
    #include 
    
    #define CUDA_FREE(ptr) { if (ptr != nullptr) { cudaFree(ptr); ptr = nullptr; } }
    
    int main() {
      std::string directory = "../";
      cv::Mat image_dog = cv::imread(directory + "dog.png");
      int image_width = image_dog.cols;
      int image_height = image_dog.rows;
      int image_size = image_width * image_height;
    
      // =============== device memory ===============
      // input
      uint8_t *in_image;
      cudaMalloc((void**)&in_image, image_size * 3 * sizeof(uint8_t));
      cudaMemcpy(in_image, image_dog.data, image_size * 3 * sizeof(uint8_t), cudaMemcpyHostToDevice);
    
      // output
      uint8_t *out_ptr1, *out_ptr2;
      cudaMalloc((void**)&out_ptr1, image_size * 3 * sizeof(uint8_t));  // 三通道
      cudaMalloc((void**)&out_ptr2, image_size * 3 * sizeof(uint8_t));  // 三通道
    
      double angle = 30.0;
      double scale = 0.6;
      cv::Point center = cv::Point(image_width / 2, image_height / 2);
      cv::Mat rot_mat = cv::getRotationMatrix2D(center, angle, scale);
      double coeffs[2][3] = { rot_mat.at<double>(0, 0),
                              rot_mat.at<double>(0, 1),
                              rot_mat.at<double>(0, 2),
                              rot_mat.at<double>(1, 0),
                              rot_mat.at<double>(1, 1),
                              rot_mat.at<double>(1, 2)};
    
      NppiSize in_size;
      in_size.width = image_width;
      in_size.height = image_height;
      NppiRect rc;
      rc.x = 0;
      rc.y = 0;
      rc.width = image_width;
      rc.height = image_height;
    
      cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC3);
      NppStatus status;
      // =============== nppiWarpAffine_8u_C3R ===============
      status = nppiWarpAffine_8u_C3R(in_image, in_size, image_width * 3, rc, out_ptr1, image_width * 3, 
                                     rc, coeffs, NPPI_INTER_LINEAR);
      if (status != NPP_SUCCESS) {
        std::cout << "[GPU] ERROR nppiWarpAffine_8u_C3R failed, status = " << status << std::endl;
        return false;
      }
      cudaMemcpy(out_image.data, out_ptr1, image_size * 3, cudaMemcpyDeviceToHost);
      cv::imwrite(directory + "affine.jpg", out_image);
    
       // =============== nppiWarpAffineBack_8u_C3R ===============
      status = nppiWarpAffineBack_8u_C3R(out_ptr1, in_size, image_width * 3, rc, out_ptr2, image_width * 3, 
                                         rc, coeffs, NPPI_INTER_LINEAR);
      if (status != NPP_SUCCESS) {
        std::cout << "[GPU] ERROR nppiWarpAffineBack_8u_C3R failed, status = " << status << std::endl;
        return false;
      }
      cudaMemcpy(out_image.data, out_ptr2, image_size * 3, cudaMemcpyDeviceToHost);
      cv::imwrite(directory + "affine_back.jpg", out_image);
    
      // free
      CUDA_FREE(in_image)
      CUDA_FREE(out_ptr1)
      CUDA_FREE(out_ptr2)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    make
    cmake_minimum_required(VERSION 3.20)
    project(test)
    
    find_package(OpenCV REQUIRED)
    include_directories(${OpenCV_INCLUDE_DIRS})
    
    find_package(CUDA REQUIRED)
    include_directories(${CUDA_INCLUDE_DIRS})
    file(GLOB CUDA_LIBS "/usr/local/cuda/lib64/*.so")
    
    add_executable(test test.cpp)
    target_link_libraries(test
                          ${OpenCV_LIBS}
                          ${CUDA_LIBS}
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    result

    请添加图片描述

    Perspective Transform

    透视变换

    NppStatus nppiWarpPerspective_8u_C3R(const Npp8u *pSrc,
    									 NppiSize oSrcSize,
    									 int nSrcStep,
    									 NppiRect oSrcROI,
    									 Npp8u *pDst,
    									 int nDstStep,
    									 NppiRect oDstROI,
    									 const double aCoeffs[3][3],
    									 int eInterpolation);
    
    NppStatus nppiWarpPerspectiveBack_8u_C3R(const Npp8u *pSrc,
    									     NppiSize oSrcSize,
    								         int nSrcStep,
    										 NppiRect oSrcROI,
    										 Npp8u *pDst,
    										 int nDstStep,
    										 NppiRect oDstROI,
    										 const double aCoeffs[3][3],
    										 int eInterpolation);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    code
    #include 
    #include 
    #include 
    #include 
    
    #define CUDA_FREE(ptr) { if (ptr != nullptr) { cudaFree(ptr); ptr = nullptr; } }
    
    int main() {
      std::string directory = "../";
      cv::Mat image_dog = cv::imread(directory + "dog.png");
      int image_width = image_dog.cols;
      int image_height = image_dog.rows;
      int image_size = image_width * image_height;
    
      // =============== device memory ===============
      // input
      uint8_t *in_image;
      cudaMalloc((void**)&in_image, image_size * 3 * sizeof(uint8_t));
      cudaMemcpy(in_image, image_dog.data, image_size * 3 * sizeof(uint8_t), cudaMemcpyHostToDevice);
    
      // output
      uint8_t *out_ptr1, *out_ptr2;
      cudaMalloc((void**)&out_ptr1, image_size * 3 * sizeof(uint8_t));  // 三通道
      cudaMalloc((void**)&out_ptr2, image_size * 3 * sizeof(uint8_t));  // 三通道
    
      cv::Point2f src_pts[4], dst_pts[4];
      src_pts[0].x = 0.0;
      src_pts[0].y = 0.0;
      src_pts[1].x = image_width - 1.0;
      src_pts[1].y = 0.0;
      src_pts[2].x = 0.0;
      src_pts[2].y = image_height - 1.0;
      src_pts[3].x = image_width - 1.0;
      src_pts[3].y = image_height - 1.0;
    
      dst_pts[0].x = image_width * 0.05;
      dst_pts[0].y = image_height * 0.05;
      dst_pts[1].x = image_width * 0.9;
      dst_pts[1].y = image_height * 0.1;
      dst_pts[2].x = image_width * 0.2;
      dst_pts[2].y = image_height * 0.8;
      dst_pts[3].x = image_width * 0.85;
      dst_pts[3].y = image_height * 0.85;
    
      cv::Mat warp_mat = cv::getPerspectiveTransform(src_pts, dst_pts);
      double coeffs[3][3] = { warp_mat.at<double>(0, 0),
                              warp_mat.at<double>(0, 1),
                              warp_mat.at<double>(0, 2),
                              warp_mat.at<double>(1, 0),
                              warp_mat.at<double>(1, 1),
                              warp_mat.at<double>(1, 2),
                              warp_mat.at<double>(2, 0),
                              warp_mat.at<double>(2, 1),
                              warp_mat.at<double>(2, 2) };
      
      NppiSize in_size;
      in_size.width = image_width;
      in_size.height = image_height;
      NppiRect rc;
      rc.x = 0;
      rc.y = 0;
      rc.width = image_width;
      rc.height = image_height;
    
      cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC3);
      NppStatus status;
      // =============== nppiWarpPerspective_8u_C3R ===============
      status = nppiWarpPerspective_8u_C3R(in_image, in_size, image_width * 3, rc, out_ptr1, image_width * 3, 
                                          rc, coeffs, NPPI_INTER_LINEAR);
      if (status != NPP_SUCCESS) {
        std::cout << "[GPU] ERROR nppiWarpPerspective_8u_C3R failed, status = " << status << std::endl;
        return false;
      }
      cudaMemcpy(out_image.data, out_ptr1, image_size * 3, cudaMemcpyDeviceToHost);
      cv::imwrite(directory + "perspective.jpg", out_image);
    
      // =============== nppiWarpPerspectiveBack_8u_C3R ===============
      status = nppiWarpPerspectiveBack_8u_C3R(out_ptr1, in_size, image_width * 3, rc, out_ptr2, image_width * 3, 
                                              rc, coeffs, NPPI_INTER_LINEAR);
      if (status != NPP_SUCCESS) {
        std::cout << "[GPU] ERROR nppiWarpPerspectiveBack_8u_C3R failed, status = " << status << std::endl;
        return false;
      }
      cudaMemcpy(out_image.data, out_ptr2, image_size * 3, cudaMemcpyDeviceToHost);
      cv::imwrite(directory + "perspective_back.jpg", out_image);
    
      // free
      CUDA_FREE(in_image)
      CUDA_FREE(out_ptr1)
      CUDA_FREE(out_ptr2)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    make
    cmake_minimum_required(VERSION 3.20)
    project(test)
    
    find_package(OpenCV REQUIRED)
    include_directories(${OpenCV_INCLUDE_DIRS})
    
    find_package(CUDA REQUIRED)
    include_directories(${CUDA_INCLUDE_DIRS})
    file(GLOB CUDA_LIBS "/usr/local/cuda/lib64/*.so")
    
    add_executable(test test.cpp)
    target_link_libraries(test
                          ${OpenCV_LIBS}
                          ${CUDA_LIBS}
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    result

    请添加图片描述

  • 相关阅读:
    基于JavaWeb的学生成绩管理系统
    Mini-Gemini: Mining the Potential of Multi-modality Vision Language Models论文解读
    基于单片机GP2D12测距-proteus仿真-源程序
    hive 知识总结
    使用vim对比两个文件
    DevOps(九)Selenium 介绍和Jenkins集成
    线性代数学习笔记8-1:复数矩阵与Hermite矩阵、酉矩阵、傅里叶矩阵和快速傅里叶变换FFT
    简易实现Spring Framework底层机制
    Docker 链接sqlserver时出现en-us is an invalid culture错误解决方案
    如何自动注册推特推广号,推特注册的具体步骤
  • 原文地址:https://blog.csdn.net/u011732139/article/details/132802633