CUDA小白 - NPP(2) - Arithmetic and Logical Operations(2)

news2024/12/26 21:16:42

cuda小白
原始API链接 NPP

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

常见的NppStatus,可以看这里。

如有问题,请指出,谢谢

Logical Operations

逻辑操作主要就是与、或、异或、右移、左移,非等逻辑操作,同样还是分为两个大类,一个是基于单张图像和常数的,另外一个是基于多张图像的。

AndC

第一大类以AndC为例子,主要是就是比较图像与提供的constant(每个通道一个值)进行与操作之后的结果。

// 有无I的区别在于是否直接对图像进行操作
NppStatus nppiAndC_8u_C3R(const Npp8u *pSrc1,
						  int nSrc1Step,
					      const Npp8u aConstants[3],
					      Npp8u *pDst,
						  int nDstStep,
						  NppiSize oSizeROI);
NppStatus nppiAndC_8u_C3IR(const Npp8u aConstants[3],
						   Npp8u *pSrcDst,
						   int nSrcDstStep,
						   NppiSize oSizeROI);
code
#include <iostream>
#include <cuda_runtime.h>
#include <npp.h>
#include <opencv2/opencv.hpp>

#define PRINT_VALUE(value) {  \
  std::cout << "[GPU] " << #value << " = " << value << std::endl; }

#define CUDA_FREE(ptr) { if (ptr != nullptr) { cudaFree(ptr); ptr = nullptr; } }

int main() {
  std::string directory = "../";
  // =============== load image ===============
  cv::Mat image = cv::Mat(500, 500, CV_8UC3, cv::Scalar(255, 255, 255));
  cv::Rect rc1 = cv::Rect(150, 150, 200, 200);
  cv::Rect rc2 = cv::Rect(200, 200, 200, 200);
  cv::Rect rc3 = cv::Rect(300, 0, 100, 200);
  cv::Rect rc4 = cv::Rect(0, 0, 200, 100);
  cv::Mat(200, 200, CV_8UC3, cv::Scalar(75, 75, 75)).copyTo(image(rc1));
  cv::Mat(200, 200, CV_8UC3, cv::Scalar(100, 100, 100)).copyTo(image(rc2));
  cv::Mat(200, 100, CV_8UC3, cv::Scalar(125, 125, 125)).copyTo(image(rc3));
  cv::Mat(100, 200, CV_8UC3, cv::Scalar(150, 150, 150)).copyTo(image(rc4));
  cv::imwrite(directory + "orin.jpg", image);

  int image_width = image.cols;
  int image_height = image.rows;
  int image_size = image_width * image_height * 3;
  std::cout << "Image info : image_width = " << image_width
            << ", image_height = " << image_height << std::endl;

  // =============== malloc && cpy ===============
  uint8_t *in_ptr;
  cudaMalloc((void**)&in_ptr, image_size * sizeof(uint8_t));
  cudaMemcpy(in_ptr, image.data, image_size, cudaMemcpyHostToDevice);

  uint8_t *out_ptr, *out_ptr1;
  cudaMalloc((void**)&out_ptr, image_size * sizeof(uint8_t));
  cudaMalloc((void**)&out_ptr1, image_size * sizeof(uint8_t));
  
  NppiSize roi1, roi2;
  roi1.width = image_width;
  roi1.height = image_height;
  roi2.width = image_width / 2;
  roi2.height = image_height / 2;

  uint8_t constant[3] = { (uint8_t)100, (uint8_t)100, (uint8_t)100 };

  // nppiAdd_8u_C3RSfs
  cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  cv::Mat out_image1 = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  NppStatus status;
  status = nppiAndC_8u_C3R(in_ptr, image_width * 3, constant, out_ptr, 
                           image_width * 3, roi1);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAndC_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "and.jpg", out_image);

  status = nppiAndC_8u_C3R(in_ptr, image_width * 3, constant, out_ptr1, 
                           image_width * 3, roi2);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAndC_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image1.data, out_ptr1, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "and_roi.jpg", out_image1);

  // free
  CUDA_FREE(in_ptr)
  CUDA_FREE(out_ptr)
  CUDA_FREE(out_ptr1)
}
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. 该函数是将图像的三个通道分别于Constant的值进行按位与的操作,测试的例子中分别使用了255,75, 100, 125, 150三种像素,与100与之后分别为100,4,4,100,100,4。
  2. 由于roi的存在,可以仅保存roi区域内的结果,也就是说输出的地址其可以仅申请roi的区域的大小。
And

针对两张图的操作,包含与、或、非、异或。

NppStatus nppiAnd_8u_C3R(const Npp8u *pSrc1,
						 int nSrc1Step,
					 	 const Npp8u *pSrc2,
					  	 int nSrc2Step,
					 	 Npp8u *pDst,
						 int nDstStep,
						 NppiSize oSizeROI);
	
NppStatus nppiAnd_8u_C3IR(const Npp8u *pSrc,
						  int nSrcStep,
						  Npp8u *pSrcDst,
						  int nSrcDstStep,
						  NppiSize oSizeROI);
code
#include <iostream>
#include <cuda_runtime.h>
#include <npp.h>
#include <opencv2/opencv.hpp>

#define PRINT_VALUE(value) {  \
  std::cout << "[GPU] " << #value << " = " << value << std::endl; }

#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 * 3;

  cv::Mat image = cv::Mat(image_height, image_width, CV_8UC3, cv::Scalar(100, 125, 150));
  
  std::cout << "Image info : image_width = " << image_width
            << ", image_height = " << image_height << std::endl;

  // =============== malloc && cpy ===============
  uint8_t *in_ptr, *mask;
  cudaMalloc((void**)&in_ptr, image_size * sizeof(uint8_t));
  cudaMalloc((void**)&mask, image_size * sizeof(uint8_t));
  cudaMemcpy(in_ptr, image_dog.data, image_size, cudaMemcpyHostToDevice);
  cudaMemcpy(mask, image.data, image_size, cudaMemcpyHostToDevice);

  uint8_t *out_ptr, *out_ptr1;
  cudaMalloc((void**)&out_ptr, image_size * sizeof(uint8_t));
  cudaMalloc((void**)&out_ptr1, image_size * sizeof(uint8_t));
  
  NppiSize roi1, roi2;
  roi1.width = image_width;
  roi1.height = image_height;
  roi2.width = image_width / 2;
  roi2.height = image_height / 2;

  // nppiAdd_8u_C3RSfs
  cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  cv::Mat out_image1 = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  NppStatus status;
  status = nppiAnd_8u_C3R(in_ptr, image_width * 3, mask, image_width * 3, out_ptr, 
                          image_width * 3, roi1);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAnd_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "and.jpg", out_image);

  status = nppiAnd_8u_C3R(in_ptr, image_width * 3, mask, image_width * 3, out_ptr1, 
                          image_width * 3, roi2);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAnd_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image1.data, out_ptr1, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "and_roi.jpg", out_image1);

  // free
  CUDA_FREE(in_ptr)
  CUDA_FREE(out_ptr)
  CUDA_FREE(out_ptr1)
}
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![请添加图片描述](https://img-blog.csdnimg.cn/ce7447a784744aa88e9818c5b8c7a5e6.png)

                      ${OpenCV_LIBS}
                      ${CUDA_LIBS}
)
result

请添加图片描述

Alpha Composition

主要功能是图像的合成(AlphaComp)以及图像的不透明度调整(AlphaPremulC)。

AlphaCompC

该接口主要完成的两张图像(单通道,三通道,四通道)的合成,主要是操作是根据NppiAlphaOp来完成一定的操作。

NppStatus nppiAlphaCompC_8u_C3R(const Npp8u *pSrc1,
								int nSrc1Step,
								Npp8u nAlpha1,
								const Npp8u *pSrc2,
								int nSrc2Step,
								Npp8u nAlpha2,
								Npp8u *pDst,
								int nDstStep,
								NppiSize oSizeROI,
								NppiAlphaOp eAlphaOp);

AlphaComp

该接口主要完成的两张单通道或者四通道的图像的合成。主要是操作是根据NppiAlphaOp来完成一定的操作。

NppStatus nppiAlphaComp_8u_AC1R(const Npp8u *pSrc1,
								int nSrc1Step,
								const Npp8u *pSrc2,
								int nSrc2Step,
								Npp8u *pDst,
								int nDstStep,
								NppiSize oSizeROI,
								NppiAlphaOp eAlphaOp);

与AlphaCompC的区别在于,AlphaCompC可以指定每个输入图像的比例来完成对应的Operation,而AlphaComp则是没有。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【100天精通python】Day50:python web编程_Django框架从安装到使用

目录 1 安装Django Web框架 2 创建一个Django 项目 3 数据模型 3.1 在应用程序的 models.py 文件中定义数据模 3.2 创建模型的迁移文件并应用 3.2.1 查询模型对象&#xff1a; 3.2.2 创建新模型对象&#xff1a; 3.2.3 更新模型对象&#xff1a; 3.2.4 删除模型对象&a…

JUC并发编程---Lock锁

文章目录 什么是Locksynchronized加锁和Lock加锁代码示例synchronized使用Lock加锁 公平锁和非公平锁公平锁&#xff1a;非公平锁&#xff1a;Lock和Synchronized的区别 synchronized 版的生产者和消费者Lock 版的生产者和消费者生产者和消费者出现的问题Condition精准通知和唤…

机器视觉工程师,人学习最大的能力是理解与善于运用,而不是记住能力

谁记得以前记住的元素周期表&#xff0c;谁能记得住乘法口诀。 如果我们去看一眼&#xff0c;就会迅速记起来。再加上我们小学机械般的练习题。再到我们在现实生活中经常用到。 其实我们机器视觉工程师&#xff0c;一定要去看&#xff0c;还要去练习​。实操软件&#xff0c;多…

深度学习-4-二维目标检测-YOLOv5源码测试与训练

本文采用的YOLOv5源码是ultralytics发行版3.1 YOLOv5源码测试与训练 1.Anaconda环境配置 1.1安装Anaconda Anaconda 是一个用于科学计算的 Python 发行版&#xff0c;支持 Linux, Mac, Windows, 包含了众多流行的科学计算、数据分析的 Python 包。 官方网址下载安装包&…

【SQL应知应会】索引 • Oracle版:B-树索引;位图索引;函数索引;单列与复合索引;分区索引

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文免费学习&#xff0c;自发文起3天后&#xff0c;会收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习&#xff0c;有基础也有进阶&#xff0c;有MySQL也有Oracle …

面试被打脸,数据结构底层都不知道么--回去等通知吧

数据结构之常见的8种数据结构&#xff1a; -数组Array -链表 Linked List -堆 heap -栈 stack -队列 Queue -树 Tree -散列表 Hash -图 Graph 数据结构-链表篇 Linklist定义&#xff1a; -是一种线性表&#xff0c;并不会按线性的顺序存储数据&#xff0c;即逻辑上相邻…

解码自我注意的魔力:深入了解其直觉和机制

一、说明 自我注意机制是现代机器学习模型中的关键组成部分&#xff0c;尤其是在处理顺序数据时。这篇博文旨在提供这种机制的详细概述&#xff0c;解释它是如何工作的&#xff0c;它的优点&#xff0c;以及它背后的数学原理。我们还将讨论它在变压器模型中的实现和多头注意力的…

设计模式-10--多例模式(Multition pattern)

一、什么是多例模式&#xff08;Multition pattern&#xff09; 多例模式&#xff08;Multition pattern&#xff09;是单例模式的一种扩展&#xff0c;它属于对象创建类型的设计模式。在多例模式中&#xff0c;一个类可以有多个实例&#xff0c;并且这些实例都是该类本身。因…

实现不同局域网间的文件共享和端口映射,使用Python自带的HTTP服务

文章目录 1. 前言2. 本地文件服务器搭建2.1 python的安装和设置2.2 cpolar的安装和注册 3. 本地文件服务器的发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 数据共享作为和连接作为互联网的基础应用&#xff0c;不仅在商业和办公场景有广泛的应用…

设计模式-5--适配器模式(Adapter Pattern)

一、什么是适配器模式&#xff08;Adapter Pattern&#xff09; 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许将一个类的接口转换成客户端所期望的另一个接口。适配器模式主要用于解决不兼容接口之间的问题&#xff0c;使得原本…

Windows安装jdk

Windows安装jdk 小白教程&#xff0c;一看就会&#xff0c;一做就成。 1.准备安装包&#xff08;需要的滴滴我&#xff09; 2.安装 我是在d盘创建jdk目录&#xff0c;把jdk包解压到jdk里 计算机右键---属性---高级系统设置—环境变量 &#xff08;系统变量里&#xff09;--新…

小兔鲜儿 - 地址模块

目录 小兔鲜儿 - 地址模块 准备工作​ 静态结构​ 地址管理页​ 地址表单页​ 动态设置标题​ 新建地址页​ 接口封装​ 参考代码​ 地址管理页​ 接口调用​ 参考代码​ 修改地址页​ 数据回显​ 更新地址​ 表单校验​ 操作步骤​ 删除地址​ 侧滑组件用法…

Leetcode 剑指 Offer II 042. 最近的请求次数

题目难度: 简单 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 写一个 RecentCounter 类来计算特定时间范围内最近的请求。 请实…

4.2 实现基于栈的表达式求值计算器(难度4/10)

本作业主要考察&#xff1a;解释器模式的实现思想/栈结构在表达式求值方面的绝对优势 C数据结构与算法夯实基础作业列表 通过栈的应用&#xff0c;理解特定领域设计的关键作用&#xff0c;给大家眼前一亮的感觉。深刻理解计算机语言和人类语言完美结合的杰作。是作业中的上等…

钉钉机器人消息推送composer拓展 laravel-dingbot

钉钉机器人消息发送 介绍 企业内部有较多系统支撑着公司的核心业务流程&#xff0c;譬如CRM系统、交易系统、监控报警系统等等。通过钉钉的自定义机器人&#xff0c;可以将这些系统事件同步到钉钉的聊天群。 laravel-dingbot 是一款钉钉机器人消息推送的Laravel扩展&#xff…

vscode c语言代码自动格式化

1、在vscode扩展商店里面搜索Clang-format&#xff0c;安装第1个插件 2、快捷键Ctrl逗号&#xff0c;输入format&#xff0c;选择Clang-Format configuration进行配置&#xff08;其实默认就可以&#xff09; 3、vscode打开文件夹的源码&#xff0c;在该文件夹里面新建一个文件…

[前端必看,后端福利❤]如何创建美观的邮件模板并通过qq邮箱的SMTP服务向用户发送

最近在写注册功能的自动发送邮箱告知验证码的功能&#xff0c;无奈根本没有学过前端&#xff0c;只有写Qt的qss基础&#xff0c;只好借助网页设计自己想要的邮箱格式&#xff0c;最终效果如下: 也推销一下自己的项目ShaderLab&#xff0c;可运行ShaderToy上的大部分着色器代码&…

js只保留数组对象的某个属性,合并公共类型的数据,选择树形结构的数据,并保留每个节点的name

嗨&#xff0c;今天周二了哎&#xff01; 期待周五 文章目录 一、js只保留数组对象的某个属性二、合并公共类型的数据二、选择树形结构的数据&#xff0c;并保留每个节点的name 一、js只保留数组对象的某个属性 let data [{ id: 1, name: 哈哈 }, { id: 2, name: 嘻嘻 }]let n…

ModaHub魔搭社区——大模型能力落地和核心就是应用场景

从今年3月百度率先发布语言大模型生成式AI产品“文心一言”后,各大科技互联网巨头纷纷入局,国内大模型瞬间遍地开花。包括阿里、华为、商汤科技、科大讯飞、360、腾讯等,纷纷推出各类大模型。 人工智能正在进入大规模落地应用关键期。 在IDC近日发布的《中国人工智能公有云…

本地虚机Jumpserver使用域名访问报错 使用IP+端口没有错误

背景&#xff1a; 我在本地Windows VMware 15的环境中部署了CentOS7.5&#xff0c;下载jumpserver-offline-installer-v2.28.1-amd64-138.tar.gz并安装部署。 需求&#xff1a; 1、能使用http:ip访问堡垒机。达成&#xff1b; 2、能使用http:域名访问堡垒机。达成&#xff…