CUDA小白 - NPP(4) 图像处理 Data Exchange and Initialization(1)

cuda小白
原始API链接 NPP

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

常见的NppStatus,可以看这里。

如有问题,请指出,谢谢

Image Set Operations

当前模块主要功能是set图像中的像素值,主要分为三个大类:将ROI区域内的所有像素设置为一个特殊的值(Set),mask赋值(Masked Set),以及单通道赋值(Channel Set)。
三个大类分别以一个三通道的uint8_t为例子简单介绍一下。

// ROI区域内的三通道设置为aValue
NppStatus nppiSet_8u_C3R(const Npp8u aValue[3],Npp8u *pDst,int nDstStep,NppiSize oSizeROI);
// 通过mask控制ROI区域内的那些像素会被set
NppStatus nppiSet_8u_C3MR(const Npp8u aValue[3],Npp8u *pDst,int nDstStep,NppiSize oSizeROI,const Npp8u *pMask,int nMaskStep);	
// 通过pointer的起始位置区别,选择某通道设置为固定值
NppStatus nppiSet_8u_C3CR(Npp8u nValue,Npp8u *pDst,int nDstStep,NppiSize oSizeROI);
code
#include <iostream>
#include <cuda_runtime.h>
#include <npp.h>
#include <opencv2/opencv.hpp>#define CUDA_FREE(ptr) { if (ptr != nullptr) { cudaFree(ptr); ptr = nullptr; } }int main() {std::string directory = "../";// =============== load image ===============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 ===============uint8_t *out_ptr1, *out_ptr2, *out_ptr3;cudaMalloc((void**)&out_ptr1, image_size * 3 * sizeof(uint8_t));cudaMalloc((void**)&out_ptr2, image_size * 3 * sizeof(uint8_t));cudaMalloc((void**)&out_ptr3, image_size * 3 * sizeof(uint8_t));cudaMemcpy(out_ptr1, image_dog.data, image_size * 3 * sizeof(uint8_t), cudaMemcpyHostToDevice);cudaMemcpy(out_ptr2, image_dog.data, image_size * 3 * sizeof(uint8_t), cudaMemcpyHostToDevice);cudaMemcpy(out_ptr3, image_dog.data, image_size * 3 * sizeof(uint8_t), cudaMemcpyHostToDevice);cv::Mat mask = cv::Mat::zeros(image_height, image_width, CV_8UC1);cv::Mat mask1 = cv::Mat::ones(image_height * 3 / 4, image_width * 3 / 4, CV_8UC1);cv::Rect rc1 = cv::Rect(image_width / 4, image_height / 4, image_width * 3 / 4, image_height * 3 / 4);mask1.copyTo(mask(rc1));uint8_t *gpu_mask;cudaMalloc((void**)&gpu_mask, image_size * sizeof(uint8_t));cudaMemcpy(gpu_mask, mask.data, image_size * sizeof(uint8_t), cudaMemcpyHostToDevice);NppiSize roi1, roi2;roi1.width = image_width;roi1.height = image_height;roi2.width = image_width / 2;roi2.height = image_height / 2;cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC3);NppStatus status;// =============== nppiSet_8u_C3R ===============uint8_t value[3] = { 255, 0, 0 };status = nppiSet_8u_C3R(value, out_ptr1, image_width * 3, roi1);if (status != NPP_SUCCESS) {std::cout << "[GPU] ERROR nppiSet_8u_C3R failed, status = " << status << std::endl;return false;}cudaMemcpy(out_image.data, out_ptr1, image_size * 3, cudaMemcpyDeviceToHost);cv::imwrite(directory + "set.jpg", out_image);// =============== nppiSet_8u_C3R ===============uint8_t value2[3] = { 0, 0, 255 };status = nppiSet_8u_C3MR(value2, out_ptr2, image_width * 3, roi1, gpu_mask, image_width);if (status != NPP_SUCCESS) {std::cout << "[GPU] ERROR nppiSet_8u_C3MR failed, status = " << status << std::endl;return false;}cudaMemcpy(out_image.data, out_ptr2, image_size * 3, cudaMemcpyD![请添加图片描述](https://img-blog.csdnimg.cn/9da721ce7d4649839ef40228bb3937e1.png)
eviceToHost);cv::imwrite(directory + "set_mask.jpg", out_image);// greenstatus = nppiSet_8u_C3CR(255, out_ptr3 + image_width * 3 * 200 + 1, image_width * 3, roi1);if (status != NPP_SUCCESS) {std::cout << "[GPU] ERROR nppiSet_8u_C3CR failed, status = " << status << std::endl;return false;}cudaMemcpy(out_image.data, out_ptr3, image_size * 3, cudaMemcpyDeviceToHost);cv::imwrite(directory + "set_channel.jpg", out_image);// freeCUDA_FREE(out_ptr1)CUDA_FREE(out_ptr2)CUDA_FREE(out_ptr3)
}
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}
)
result

请添加图片描述
注意:

  1. mask使用的是单通道的,仅表示那些像素需要进行set,那些不需要
  2. 通道的set,通过指针来表示是针对那个通道进行转换。输入指针表示开始set的起始位置,对于三通道的图像而言,则是隔两个set一次。

Image Copy Operations

除了比较常见的copy操作(copy,masked copy,channel copy)之外,还有一些planar和packed之间的来回拷贝,拷贝的同时伴随着border,以及Copy Sub-pixel(没接触过)

// 单纯的拷贝
NppStatus nppiCopy_8u_C3R(const Npp8u *pSrc,int nSrcStep,Npp8u *pDst,int nDstStep,NppiSize oSizeROI);	
// 依据mask有选择性的进行拷贝
NppStatus nppiCopy_8u_C3MR(const Npp8u *pSrc,int nSrcStep,Npp8u *pDst,int nDstStep,NppiSize oSizeROI,const Npp8u *pMask,int nMaskStep);	
// Channel Copy, 将一个多通道的某个通道拷贝到另外一个多通道图像的某一个channel
NppStatus nppiCopy_8u_C3CR(const Npp8u *pSrc,int nSrcStep,Npp8u *pDst,int nDstStep,NppiSize oSizeROI);	
// Extract Channel Copy, 将一个多通道的某个通道拷贝到另外一个单通道的图像
NppStatus nppiCopy_8u_C3C1R(const Npp8u * pSrc,int nSrcStep,Npp8u *pDst,int nDstStep,NppiSize oSizeROI);	
// Insert Channel Copy, 一个单通道的图像拷贝到多通道中的某一个通道
NppStatus nppiCopy_8u_C1C3R(const Npp8u * pSrc,int nSrcStep,Npp8u * pDst,int nDstStep,NppiSize oSizeROI);
// 剩下的接口平时接触较少,所以暂时不做详细介绍
code
#include <iostream>
#include <cuda_runtime.h>
#include <npp.h>
#include <opencv2/opencv.hpp>#define CUDA_FREE(ptr) { if (ptr != nullptr) { cudaFree(ptr); ptr = nullptr; } }int main() {std::string directory = "../";// =============== load image ===============cv::Mat image_dog = cv::imread(directory + "dog.png");cv::Mat image_dog_gray;cv::cvtColor(image_dog, image_dog_gray, CV_RGB2GRAY);int image_width = image_dog.cols;int image_height = image_dog.rows;int image_size = image_width * image_height;// =============== device memory ===============uint8_t *in_image, *in_img_gray;cudaMalloc((void**)&in_image, image_size * 3 * sizeof(uint8_t));cudaMalloc((void**)&in_img_gray, image_size * sizeof(uint8_t));cudaMemcpy(in_image, image_dog.data, image_size * 3 * sizeof(uint8_t), cudaMemcpyHostToDevice);cudaMemcpy(in_img_gray, image_dog_gray.data, image_size * sizeof(uint8_t), cudaMemcpyHostToDevice);uint8_t *out_ptr1, *out_ptr2, *out_ptr3, *out_ptr4, *out_ptr5;cudaMalloc((void**)&out_ptr1, image_size * 3 * sizeof(uint8_t));  // 三通道cudaMalloc((void**)&out_ptr2, image_size * 3 * sizeof(uint8_t));  // 三通道cudaMalloc((void**)&out_ptr3, image_size * 3 * sizeof(uint8_t));  // 三通道cudaMalloc((void**)&out_ptr4, image_size * sizeof(uint8_t));  // 单通道cudaMalloc((void**)&out_ptr5, image_size * 3 * sizeof(uint8_t));  // 三通道// maskcv::Mat mask = cv::Mat::zeros(image_height, image_width, CV_8UC1);cv::Mat mask1 = cv::Mat::ones(image_height * 3 / 4, image_width * 3 / 4, CV_8UC1);cv::Rect rc1 = cv::Rect(image_width / 4, image_height / 4, image_width * 3 / 4, image_height * 3 / 4);mask1.copyTo(mask(rc1));uint8_t *gpu_mask;cudaMalloc((void**)&gpu_mask, image_size * sizeof(uint8_t));cudaMemcpy(gpu_mask, mask.data, image_size * sizeof(uint8_t), cudaMemcpyHostToDevice);NppiSize roi1, roi2;roi1.width = image_width;roi1.height = image_height;roi2.width = image_width / 2;roi2.height = image_height / 2;cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC3);cv::Mat out_single = cv::Mat::zeros(image_height, image_width, CV_8UC1);NppStatus status;// =============== nppiCopy_8u_C3R ===============status = nppiCopy_8u_C3R(in_image, image_width * 3, out_ptr1, image_width * 3, roi1);if (status != NPP_SUCCESS) {std::cout << "[GPU] ERROR nppiCopy_8u_C3R failed, status = " << status << std::endl;return false;}cudaMemcpy(out_image.data, out_ptr1, image_size * 3, cudaMemcpyDeviceToHost);cv::imwrite(directory + "copy.jpg", out_image);// =============== nppiCopy_8u_C3MR ===============status = nppiCopy_8u_C3MR(in_image, image_width * 3, out_ptr2, image_width * 3, roi1, gpu_mask, image_width);if (status != NPP_SUCCESS) {std::cout << "[GPU] ERROR nppiCopy_8u_C3MR failed, status = " << status << std::endl;return false;}cudaMemcpy(out_image.data, out_ptr2, image_size * 3, cudaMemcpyDeviceToHost);cv::imwrite(directory + "copy_mask.jpg", out_image);// =============== nppiCopy_8u_C3CR ===============status = nppiCopy_8u_C3CR(in_image, image_width * 3, out_ptr3, image_width * 3, roi1);if (status != NPP_SUCCESS) {std::cout << "[GPU] ERROR nppiCopy_8u_C3CR failed, status = " << status << std::endl;return false;}cudaMemcpy(out_image.data, out_ptr3, image_size * 3, cudaMemcpyDeviceToHost);cv::imwrite(directory + "copy_channel.jpg", out_image);// =============== nppiCopy_8u_C3C1R ===============status = nppiCopy_8u_C3C1R(in_image, image_width * 3, out_ptr4, image_width, roi1);if (status != NPP_SUCCESS) {std::cout << "[GPU] ERROR nppiCopy_8u_C3C1R failed, status = " << status << std::endl;return false;}cudaMemcpy(out_single.data, out_ptr4, image_size, cudaMemcpyDeviceToHost);cv::imwrite(directory + "copy_channel_extract.jpg", out_single);// =============== nppiCopy_8u_C1C3R ===============status = nppiCopy_8u_C1C3R(in_img_gray, image_width, out_ptr5, image_width * 3, roi1);if (status != NPP_SUCCESS) {std::cout << "[GPU] ERROR nppiCopy_8u_C1C3R failed, status = " << status << std::endl;return false;}cudaMemcpy(out_image.data, out_ptr5, image_size * 3, cudaMemcpyDeviceToHost);cv::imwrite(directory + "copy_channel_insert.jpg", out_image);// freeCUDA_FREE(in_image)CUDA_FREE(in_img_gray)CUDA_FREE(out_ptr1)CUDA_FREE(out_ptr2)CUDA_FREE(out_ptr3)CUDA_FREE(out_ptr4)CUDA_FREE(out_ptr5)
}
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}
)
result

请添加图片描述
注意:

  1. 由于提取三个通道进行copy,存图的时候只有单个通道,因此呈现出来的结果是灰色的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/108074.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言数组和指针笔试题(一)(一定要看)

目录 一维数组例题1例题2例题3例题4例题5例题6例题7例题8例题9例题10例题输出结果 字符数组一例题1例题2例题3例题4例题5例题6例题7 一维数组 int a[] {1,2,3,4}; 1:printf("%d\n",sizeof(a)); 2:printf("%d\n",sizeof(a0)); 3:printf("%d\n",…

【算法系列 | 8】深入解析查找算法之—二分查找

序言 心若有阳光&#xff0c;你便会看见这个世界有那么多美好值得期待和向往。 决定开一个算法专栏&#xff0c;希望能帮助大家很好的了解算法。主要深入解析每个算法&#xff0c;从概念到示例。 我们一起努力&#xff0c;成为更好的自己&#xff01; 今天第8讲&#xff0c;讲一…

Linux中执行bash脚本报错/bin/bash^M: bad interpreter: No such file or directory

文章目录 参考博客&#xff1a; Linux中执行bash脚本报错/bin/bash^M: bad interpreter: No such file or directory 首先在此对这位博主表示感谢。 运行bash脚本会出现两个文件&#xff0c;1037.err和1037.out。 1037.err的文件内容如下&#xff1a; /data/home/user12/.lsbat…

C++ std::future

std::future是用来接收一个线程的执行结果的&#xff0c;并且是一次性的。 共享状态shared state future可以关联一个共享状态&#xff0c;共享状态是用来储存要执行结果的。这个结果是async、promise、packaged_task设置的&#xff0c;且这个结果只能设置一次。 创建future …

NLP机器翻译全景:从基本原理到技术实战全解析

目录 一、机器翻译简介1. 什么是机器翻译 (MT)?2. 源语言和目标语言3. 翻译模型4. 上下文的重要性 二、基于规则的机器翻译 (RBMT)1. 规则的制定2. 词典和词汇选择3. 限制与挑战4. PyTorch实现 三、基于统计的机器翻译 (SMT)1. 数据驱动2. 短语对齐3. 评分和选择4. PyTorch实现…

【Linux-day11-线程的创建与同步】

Linux 线程的创建与同步 线程的概念 线程是进程内部的一条执行序列或执行路径&#xff0c;一个进程可以包含多条线程。 进程与线程的区别 进程是资源分配的最小单位&#xff0c;线程是 CPU 调度的最小单位进程有自己的独立地址空间&#xff0c;线程共享进程中的地址空间进…

数据结构基础7:二叉树【链式结构】实现和递归思想。

二叉树的链式结构实现 一.二叉树链式结构的实现&#xff1a;1.前置说明&#xff1a;1.创建二叉树&#xff1a;2.二叉树的结构&#xff1a; 2.二叉树的遍历&#xff1a;1.二叉树的前中后序遍历&#xff1a;2.内容拓展&#xff1a; 二.二叉树链式(题目)题目一&#xff1a;计算节点…

yolov7简化网络yaml配置文件

yolov7代码结构简单&#xff0c;效果还好&#xff0c;但是动辄超过70几个模块的配置文件对于想要对网络进行魔改的朋友还是不怎么友好的&#xff0c;使用最小的tiny也有77个模块 代码的整体结构简单&#xff0c;直接将ELAN结构化写成一个类就能像yolov5一样仅仅只有20几个模块&…

【操作系统】进程控制

进程控制&#xff1a;创建新进程&#xff0c;撤销已有进程&#xff0c;实现进程状态转换等。 原语&#xff1a;进程控制用的程序段。执行期间不允许中断&#xff0c;用&#xff02;关中断&#xff02;和&#xff02;开中断&#xff02;指令&#xff08;特权指令&#xff09;实…

Android性能优化之应用瘦身(APK瘦身)

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览2.1 apk组成 三、优化方向3.1 源代码3.1.1 代码混…

Dedecms最新版--0day分享分析(二)

前言 接上一篇的Tricks&#xff0c;既然利用远程文件下载方式成为了实现RCE的最好方法&#xff0c;毕竟在执行的时候没有恶意shell文件&#xff0c;恶意木马被存放于远端服务器&#xff0c;那么下文的day就是对远程恶意文件的利用。 环境 下载最新版本&#xff1a; https://…

Kotlin Files Paths write ByteArray writeString写多行BufferedWriter

Kotlin Files Paths write ByteArray writeString写多行BufferedWriter import java.nio.file.Files import java.nio.file.Paths import java.nio.file.StandardOpenOptionfun main(args: Array<String>) {val filePath "./myfile.txt"val path Paths.get(…