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.rhkb.cn/news/127695.html

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

相关文章

【MySQL】表的约束

目录 MySQL表的约束 空属性 默认值 列描述 zerofill 主键 自增长 唯一键 外键 综合案例 MySQL表的约束 真正约束字段的是数据类型&#xff0c;如果插入的数据超出了对应数据类型的取值范围&#xff0c;那么数据将会插入失败。但是数据类型的约束很单一&#xff0c;为…

webpack(四)plugin

定义 和loader的区别 loader:文件加载器&#xff0c;能够加载资源&#xff0c;并对这些文件进行一些处理&#xff0c;诸如编译、压缩等&#xff0c;最终一起打包到指定的文件中。plugin:赋予了webpack各种灵活的功能&#xff0c;例如打包优化、资源管理、环境变量注入等&…

C++初阶:C++入门

目录 一.iostream文件 二.命名空间 2.1.命名空间的定义 2.2.命名空间的使用 三.C的输入输出 四.缺省参数 4.1.缺省参数概念 4.2.缺省参数分类 4.3.缺省参数注意事项 4.4.缺省参数用途 五.函数重载 5.1.重载函数概念 5.2.C支持函数重载的原理--名字修饰(name Mangl…

第 2 章 线性表(学生健康登记表实现)

1. 示例代码 1) status.h /* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H #define STATUS_H/* 函数结果状态码 */ #define TRUE 1 /* 返回值为真 */ #define FALSE 0 /* 返回值为假 */ #define RET_OK 0 /* 返回值正确 */ #define INFEASI…

【自学开发之旅】Flask-回顾--对象拆分-蓝图(二)

url-统一资源定位符-不同的url对应不同的资源 作为服务端&#xff0c;url和视图函数的映射关系就是路由。 定义传递参数的方式&#xff1a; 1.创建动态url app.route("/login2/<username>/<passwd>") def login2(username, passwd):if username "…

数据分析和可视化平台:Splunk Enterprise for mac v9.1.1激活版 兼容m1

Splunk Enterprise 是一个数据分析和可视化平台&#xff0c;可帮助企业理解其数据。虽然没有适用于 Mac OS 的 Splunk Enterprise 官方版本&#xff0c;但他们确实为 Mac OS 提供了一个名为“Splunk Light”的应用程序&#xff0c;它提供了基本的数据索引、搜索和仪表板。或者&…

基于Yolov8的中国交通标志(CCTSDB)识别检测系统

目录 1.Yolov8介绍 2.纸箱破损数据集介绍 2.1数据集划分 2.2 通过voc_label.py得到适合yolov8训练需要的 2.3生成内容如下 3.训练结果分析 1.Yolov8介绍 Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的&…

【数据分析】Python:处理缺失值的常见方法

在数据分析和机器学习中&#xff0c;缺失值是一种常见的现象。在实际数据集中&#xff0c;某些变量的某些条目可能没有可用的值。处理缺失值是一个重要的数据预处理步骤。在本文中&#xff0c;我们将介绍如何在 Pandas 中处理缺失值。 我们将探讨以下内容&#xff1a; 什么是缺…

Redis-带你深入学习数据类型list

目录 1、list列表 2、list相关命令 2.1、添加相关命令&#xff1a;rpush、lpush、linsert 2.2、查找相关命令&#xff1a;lrange、lindex、llen 2.3、删除相关命令&#xff1a;lpop、rpop、lrem、ltrim 2.4、修改相关命令&#xff1a;lset 2.5、阻塞相关命令&#xff1a…

appium环境搭建

一.appium环境搭建 1.python3 python3的下载安装这里就不多做介绍了&#xff0c;当然你也可以选择自己喜欢的语音&#xff0c;比如java… 2.jdk 1&#xff09;下载地址 官网(需登录账号)&#xff1a; https://www.oracle.com/java/technologies/downloads/ 百度网盘&…

Qt应用开发(基础篇)——向导对话框 QWizard

一、前言 QWizard类继承于QDialog&#xff0c;为有向导界面需求的应用环境提供了一个框架。 对话框窗口 QDialog QWizard向导对话框是一个拥有队列界面的特殊对话框&#xff0c;向导的目的是引导用户一步一步的完成预设的流程。向导常用于软件安装界面向导、硬件线路安装向导、…

界面控件DevExpress WPF(v23.2)下半年发展路线图

本文主要概述了DevExpress官方在下半年&#xff08;v23.2&#xff09;中一些与DevExpress WPF相关的开发计划。 通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 DevExpress …

一起学数据结构(5)——栈和队列

1. 栈的相关定义及特点&#xff1a; 1. 栈的相关定义&#xff1a; 在正式介绍栈的定义之前&#xff0c;首先来回顾一下关于线性表的定义&#xff1a; 线性表是具有相同数据类型的个数据元素的有限序列&#xff0c;其中为表长。当时&#xff0c;可以把线性表看作一个空表&…

SwiftUI 内功加持:“曳光弹“实现自定义样式进度条(ProgressView)

概览 虽然 SwiftUI 已为我们内置了很多常用视图&#xff0c;不过有时我们还是需要根据实际来进一步美化显示或增加功能。 如上图所示&#xff0c;在本篇博文中我们将结合敏捷哲学中一个超级实用的开发技巧&#xff1a;曳光弹&#xff0c;来一步一个脚印循序渐进的实现 Progres…

redisson分布式锁

RLock官网解释 基于Redis的Java分布式可重入锁对象&#xff0c;实现了锁接口。 如果获得锁的Redisson实例崩溃&#xff0c;那么这种锁可能永远挂起在获得状态。为了避免这种情况&#xff0c;Redisson维护了锁看门狗&#xff0c;它在锁持有者Redisson实例活着的时候延长锁过期时…

逻辑回归(Logistic Regression)

1.分类问题 在分类问题中&#xff0c;你要预测的变量 y是离散的值&#xff0c;我们将学习一种叫做逻辑回归 (Logistic Regression) 的算法&#xff0c;这是目前最流行使用最广泛的一种学习算法。 在分类问题中&#xff0c;我们尝试预测的是结果是否属于某一个类&#xff08;例…

MultipartFile是什么

Multipart是一种file的类型 在我们进行文件上传时所发出的请求&#xff0c;我们页面对请求格式有明确的要求: 1.post提交表单方式 2.编码格式enctype必须是muitipart/form-data&#xff0c;这种格式适合传输数据量大的二进制数据文件 3.类型必须是file类 流程举例&#xf…

软件测试报告有什么用?

报告类型 不同的报告类型有不同的报告用途&#xff0c;以下分类别进行分析 1、登记测试报告 可以用于软件产品的增值税即征即退、软件企业的双软评估以及计算机系统集成资质的材料 2、鉴定\确认测试报告 可以用用于政府项目申报、高新认证、项目结题、创新产品认定、各类政…

Excel怎么批量生成文件夹

Excel怎么批量生成文件夹的链接: https://jingyan.baidu.com/article/ea24bc398d9dcb9b63b3312f.html

C 风格文件输入/输出---直接输入/输出---(std::fread)---(std::fwrite)

C 标准库的 C I/O 子集实现 C 风格流输入/输出操作。 <cstdio> 头文件提供通用文件支持并提供有窄和多字节字符输入/输出能力的函数&#xff0c;而 <cwchar>头文件提供有宽字符输入/输出能力的函数。 从直接输入/输出 文件读取 std::fread 从给定输入流 stream …