CUDA小白 - NPP(2) -图像处理-算数和逻辑操作(2)

news2025/1/16 5:50:43

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/944495.html

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

相关文章

Vue项目直接报错

最近自己在做一个vue2项目&#xff0c;vue并不熟悉&#xff0c;所以求解&#xff01;&#xff01;&#xff01; 通过命令&#xff1a;vue create app 创建项目&#xff0c;但打开后&#xff0c;浏览器直接报错&#xff0c;意思为&#xff1a;不能在模块外使用import语句(at ho…

c++ opencv将彩色图像按连通域区分

要将彩色图像按连通域区分&#xff0c;您可以使用 OpenCV 中的 cv::connectedComponents 函数。 下面是一个简单的示例代码&#xff0c;说明如何使用 cv::connectedComponents 函数来检测并标记图像中的连通域&#xff1a; #include <opencv2/opencv.hpp> #include <…

智能制造产业链数字化转型、数字化互联工厂建设方案PPT

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除&#xff0c;更多浏览公众号&#xff1a;智慧方案文库 篇幅有限&#xff0c;无法完全展示&#xff0c;喜欢资料可转发评论&#xff0c;私信了解更多信息。

初次跑yolo5遇到的一些问题

1. ImportError: cannot import name COMMON_SAFE_ASCII_CHARACTERS‘ from charset-normalizerconstant‘ 这个报错可能是由于charset_normalizer模块的版本问题引起的。尝试更新charset_normalizer模块到最新版本&#xff0c;或者使用较旧的版本&#xff0c;看看是否可以解…

Java 中数据结构HashSet的用法

Java HashSet HashSet 基于 HashMap 来实现的&#xff0c;是一个不允许有重复元素的集合。 HashSet 允许有 null 值。 HashSet 是无序的&#xff0c;即不会记录插入的顺序。 HashSet 不是线程安全的&#xff0c; 如果多个线程尝试同时修改 HashSet&#xff0c;则最终结果是…

Android屏幕显示 android:screenOrientation configChanges

显示相关 屏幕朝向 https://developer.android.com/reference/android/content/res/Configuration.html#orientation 具体区别如下&#xff1a; activity.getResources().getConfiguration().orientation获取的是当前设备的实际屏幕方向值&#xff0c;可以动态地根据设备的旋…

恒运资本:市盈率怎么算?

市盈率&#xff08;P/E ratio&#xff09;是判别一家公司股票价格合理性的一个重要目标&#xff0c;也是投资者评估公司股票投资价值的重要参阅目标。市盈率越高&#xff0c;表明相对于公司的收益来说&#xff0c;该公司的股票定价越高。市盈率越低&#xff0c;则表明该股票被低…

虚拟列表的实现

一、什么是虚拟列表 在传统的列表渲染中&#xff0c;如果列表数据过多&#xff0c;一次性渲染所有数据将耗费大量的时间和内存。当我们上下滚动时&#xff0c;性能低的浏览器或电脑都会感觉到非常的卡&#xff0c;这对用户的体验时是致命的。 于是我们会想到懒加载&#xff0…

如何使用c3p0连接池???

1.首先下载架包。。。&#xff08;下载链接&#xff1a;https://note.youdao.com/ynoteshare/index.html?id61e2cc939390acc9c7e5017907e98044&typenote&_time1693296531722&#xff09; 2.将架包加入项目文件。 创建一个lib目录&#xff0c;将架包复制进去 右键点击l…

ManageEngine ServiceDesk Plus之CVE漏洞

什么是CVE&#xff1f; CVE的英文全称是“Common Vulnerabilities & Exposures”即通用漏洞披露&#xff0c;CVE像是一个字典表&#xff0c;为广泛认同的信息安全漏洞给出一个公共的名称。 使用一个公共名称&#xff0c;可以帮助用户在各自独立的各种漏洞数据库中共享数据…

价格管控的有效措施

品牌为了发展&#xff0c;会不断拓展销售渠道&#xff0c;随之也会有更多的经销商加入&#xff0c;经销商变多了&#xff0c;渠道问题也会逐渐突显&#xff0c;比如低价、窜货、假货&#xff0c;窜货和假货问题其实就是低价问题&#xff0c;所以治理好价格&#xff0c;就是解决…

数据倾斜优化

数据倾斜发生的原因有哪些&#xff1f; map输出数据按key Hash的分配到reduce中&#xff0c;由于key分布不均匀、业务数据本身的特性、建表时考虑不周等原因造成的reduce 上的数据量差异过大。 数据倾斜解决方式有哪些 group by 导致的数据倾斜 1.开启Map-Side聚合后&#x…

MSLearn 开学季:AI 进阶系列|PromptFlow - 做一个教育行业的 Copilot 应用

点击蓝字 关注我们 编辑&#xff1a;Alan Wang 排版&#xff1a;Rani Sun 微软 Reactor 为帮助广开发者&#xff0c;技术爱好者&#xff0c;更好的学习 .NET Core, C#, Python&#xff0c;数据科学&#xff0c;机器学习&#xff0c;AI&#xff0c;区块链, IoT 等技术&#xff0…

美创科技一体化智能化公共数据平台数据安全建设实践

公共数据是当今政府数字化转型的关键要素和未来价值释放的核心锚点&#xff0c;也是“网络强国”、“数字中国”的战略性资源。 作为数字化改革先行省份&#xff0c;近年来&#xff0c;浙江省以一体化智能化公共数据平台作为数字化改革的支撑总平台&#xff0c;实现了全省公共数…

华为云云服务器评测|华为云云耀云服务器L实例评测使用

文章目录 华为云云耀云服务器L实例简介华为云云耀云服务器L实例参数华为云云耀云服务器L实例部署网站的步骤华为云云耀云服务器L实例的核心卖点华为云云耀云服务器L实例适用于多种核心应用场景华为云云耀云服务器L实例总体感受 华为云云耀云服务器L实例简介 华为云云耀云服务器…

解决方案 | 法大大电子签:智慧银行建设背后的“助推器”

随着互联网技术的不断发展&#xff0c;银行业正在经历一场前所未有的数字化革命&#xff0c;平台搭建、场景化金融、在线金融逐渐成为商业银行转型智慧银行的发力点。而电子合同在银行业的广泛应用&#xff0c;为银行业务流程的无纸化、高效能提供了强有力的支持。 聚焦效率及…

高频电流探头的钳口使用和如何调零消磁

高频电流探头采用霍尔效应传感器技术来测量交流和直流信号&#xff0c;标配通用的 BNC 接口&#xff0c;可直接用示波器或记录仪等观察测量波形及数值&#xff0c;具有强大的通用性能。 电流探头钳口使用&#xff1a; 为电流指示方向。测量时&#xff0c;被测导体电流方向与指…

SSM - Springboot - MyBatis-Plus 全栈体系(一)

第一章 Maven 高效构建Java应用&#xff1a;Maven入门和进阶 一、Maven 简介和快速入门 1. Maven 介绍 Maven 是一款为 Java 项目构建管理、依赖管理的工具&#xff08;软件&#xff09;&#xff0c;使用 Maven 可以自动化构建、测试、打包和发布项目&#xff0c;大大提高了…

java自动登录 selenium 自动登录并获取cookie

选择操作网页 我用的edge&#xff0c;谷歌我的版本太高没有对应的驱动… 下载Edge的驱动程序&#xff0c;直接解压就好里面只有一个.exe文件 https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ 复制即用&#xff0c;看注释 import com.alibaba.fastjs…

【TI毫米波雷达笔记】毫米波雷达芯片out_of_box开箱demo代码解读(以IWR6843AOP为例)

【TI毫米波雷达笔记】毫米波雷达芯片out_of_box开箱demo代码解读 结构框架&#xff1a; blog.csdn.net/weixin_53403301/article/details/132522364功能 IWR6843AOP的开箱工程是根据IWR6843AOPEVM开发板来的 该工程可以将IWR6843AOP的两个串口利用起来 实现的功能主要是两个…