CUDA小白 - NPP(11) 图像处理 Comparison Operations

news2025/5/24 19:50:49

cuda小白
原始API链接 NPP

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

常见的NppStatus,可以看这里。

Thresholding Operations

分通道,逐像素进行比较,根据指定的Operation,如果不符合则更新当前值。当前模块分为两大类,一个是直接原地址进行操作,另外一类则是指定不同的输出地址。

/*
enum NppCmpOp {
  NPP_CMP_LESS,
  NPP_CMP_LESS_EQ,
  NPP_CMP_EQ,
  NPP_CMP_GREATER_EQ,
  NPP_CMP_GREATER
}; 
*/
// 通用的,如果满足比较条件,则
NppStatus nppiThreshold_8u_C3R(const Npp8u *pSrc,
							   int nSrcStep,
							   Npp8u *pDst,
							   int nDstStep,
							   NppiSize oSizeROI,
							   const Npp8u rThresholds[3],
							   NppCmpOp eComparisonOperation);
// 大于   NPP_CMP_GREATER_EQ
NppStatus nppiThreshold_GT_8u_C3R(const Npp8u *pSrc,
								  int nSrcStep,
							      Npp8u *pDst,
							      int nDstStep,
								  NppiSize oSizeROI,
							      const Npp8u rThresholds[3]);
// 小于 NPP_CMP_LESS_EQ
NppStatus nppiThreshold_LT_8u_C3R(const Npp8u *pSrc,
							      int nSrcStep,
								  Npp8u *pDst,
								  int nDstStep,
								  NppiSize oSizeROI,
								  const Npp8u rThresholds[3]);
// 指定需要设置的值
NppStatus nppiThreshold_Val_8u_C3R(const Npp8u *pSrc,
								   int nSrcStep,
								   Npp8u *pDst,
								   int nDstStep,
								   NppiSize oSizeROI,
								   const Npp8u rThresholds[3],
								   const Npp8u rValues[3],
								   NppCmpOp eComparisonOperation);
NppStatus nppiThreshold_GTVal_8u_C3R(const Npp8u * pSrc,
									 int nSrcStep,
									 Npp8u *pDst,
									 int nDstStep,
									 NppiSize oSizeROI,
									 const Npp8u rThresholds[3],
									 const Npp8u rValues[3]);
NppStatus nppiThreshold_LTVal_8u_C3R(const Npp8u *pSrc,
									 int nSrcStep,
									 Npp8u *pDst,
									 int nDstStep,
									 NppiSize oSizeROI,
									 const Npp8u rThresholds[3],
									 const Npp8u rValues[3]);
// 设置上下界
NppStatus nppiThreshold_LTValGTVal_8u_C3R(const Npp8u *pSrc,
										  int nSrcStep,
										  Npp8u *pDst,
										  int nDstStep,
										  NppiSize oSizeROI,
										  const Npp8u rThresholdsLT[3],
										  const Npp8u rValuesLT[3],
										  const Npp8u rThresholdsGT[3],
										  const Npp8u rValuesGT[3]);

两边各选用一个接口作为示例

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 = "../";
  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));  // 三通道

  NppiSize in_size;
  in_size.width = image_width;
  in_size.height = image_height;

  uint8_t threshold[3] = {150, 150, 150};
  cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  // =============== nppiThreshold_GT_8u_C3R ===============
  NppStatus status;
  status = nppiThreshold_GT_8u_C3R(in_image, image_width * 3, out_ptr1, image_width * 3, 
                                   in_size, threshold);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiThreshold_GT_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr1, image_size * 3, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "threshold_gt.jpg", out_image);

  // =============== nppiThreshold_GTVal_8u_C3R ===============
  uint8_t value[3] = {255, 255, 255};
  status = nppiThreshold_GTVal_8u_C3R(in_image, image_width * 3, out_ptr2, image_width * 3, 
                                      in_size, threshold, value);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiThreshold_GTVal_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr2, image_size * 3, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "threshold_gt_value.jpg", out_image);

  // free
  CUDA_FREE(in_image)
  CUDA_FREE(out_ptr1)
  CUDA_FREE(out_ptr2)
}
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

请添加图片描述

Comparison Operations

本文到此就只阐述比较简单的两个接口,其他的结果按需索取

NppStatus nppiCompare_8u_C3R(const Npp8u *pSrc1,
							 int nSrc1Step,
							 const Npp8u *pSrc2,
							 int nSrc2Step,
							 Npp8u *pDst,
							 int nDstStep,
							 NppiSize oSizeROI,
							 NppCmpOp eComparisonOperation);
NppStatus nppiCompareC_8u_C3R(const Npp8u *pSrc,
							  int nSrcStep,
							  const Npp8u *pConstants,
							  Npp8u * pDst,
							  int nDstStep,
							  NppiSize oSizeROI,
							  NppCmpOp eComparisonOperation);

目的就是比较两张图或者将一张图与一个constant进行比较,并且生成一个二进制的结果图像。二进制的结果图像类型是8UC1,如果是不同的话,则设置为0,反之表示uint8_t的最大值。

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 = "../";
  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_image1, *in_image2;
  cudaMalloc((void**)&in_image1, image_size * 3 * sizeof(uint8_t));
  cudaMalloc((void**)&in_image2, image_size * 3 * sizeof(uint8_t));
  cudaMemcpy(in_image1, image_dog.data, image_size * 3 * sizeof(uint8_t), cudaMemcpyHostToDevice);
  
  cv::Mat mask = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  int step = 4;
  int step_width = image_width / step;
  cv::Mat ones = cv::Mat::ones(image_height, step_width, CV_8UC3);
  for (int i = 1; i < step; ++i) {
    cv::Rect rc1 = cv::Rect(i * step_width, 0, step_width, image_height);
    mask(rc1) = ones.clone() * 50 * i;
  }
  
  cudaMemcpy(in_image2, mask.data, image_size * 3 * sizeof(uint8_t), cudaMemcpyHostToDevice);

  // output
  uint8_t *out_ptr1, *out_ptr2;
  cudaMalloc((void**)&out_ptr1, image_size * sizeof(uint8_t));  // 三通道
  cudaMalloc((void**)&out_ptr2, image_size * sizeof(uint8_t));  // 三通道

  NppiSize in_size;
  in_size.width = image_width;
  in_size.height = image_height;

  cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC1);
  NppStatus status;
  // =============== nppiCompare_8u_C3R ===============
  status = nppiCompare_8u_C3R(in_image1, image_width * 3, in_image2, image_width * 3, 
                              out_ptr1, image_width, in_size, NPP_CMP_GREATER);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiCompare_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr1, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "compare.jpg", out_image);

  // =============== nppiCompareC_8u_C3R ===============
  uint8_t constant[3] = {100, 100, 100};
  status = nppiCompareC_8u_C3R(in_image1, image_width * 3, constant, out_ptr2, image_width, 
                               in_size, NPP_CMP_GREATER);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiCompareC_8u_C3R failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr2, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "comparec.jpg", out_image);

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

                      ${CUDA_LIBS}
)
result

请添加图片描述

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

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

相关文章

显示器有白点闪烁、间歇黑屏解决办法

问题描述 以上三张图片是不到一秒内通过手机视频拍摄显示器画面&#xff0c;可以看到第一张图大桥下和第二张图片右下角岛屿初均有红点闪烁。当触发黑屏时&#xff0c;显示器整体白点闪烁。并且时常黑屏&#xff0c;几秒后恢复。 解决办法 检查HDMI连接线是否脱落&#xff0c…

初识canvas

对于一个前端人员来说&#xff0c;canvas是必须掌握的技能之一。如果你想像画画一样在浏览器上作画&#xff0c;那么canvas就可以做你的画布。 接下啦我们就以画画的标准来初步认识下canvas 1.画布 画画的第一步你得有一张画纸或者画布&#xff0c;canvas标签就是我们的画布…

查看mysql 容量

SQL SELECT table_schema "database", sum( data_length index_length) / 1024 / 1024 /1024 "size in GB" FROM information_schema.TABLES GROUP BY table_schema;结果

CSS 之 grid 网格布局

一、简介 ​ display: grid;用于设置元素内部的布局类型为网格布局&#xff0c;其外显类型为块级元素。该类型的元素将内部分为行和列&#xff0c;划分成一个个单元格&#xff0c;并通过一系列相关属性控制单元格及其内容的布局和大小。 ​ 该属性值的主要应用场景为&#xf…

1297. 子串的最大出现次数

1297. 子串的最大出现次数 // 返回子串的最大出现次数&#xff1a;用hash表 // 子串中 不同字母的次数 < maxLetters && 子串长度> minSize && 子串长度 < maxSizeint maxFreq(char * s, int maxLetters, int minSize, int maxSize){}

【算法】矩阵快速幂优化动态规划

文章目录 知识讲解题目列表[矩阵快速幂] 题目列表&#x1f4d5;70. 爬楼梯解法1——线性DP解法2——矩阵快速幂 509. 斐波那契数1137. 第 N 个泰波那契数1220. 统计元音字母序列的数目解法1——线性DP解法2——矩阵快速幂优化DP 552. 学生出勤记录 II&#xff08;&#x1f6b9;…

Kafka 常见问题

文章目录 kafka 如何确保消息的可靠性传输Kafka 高性能的体现利用Partition实现并行处理利用PageCache 如何提高 Kafka 性能调整内核参数来优化IO性能减少网络开销批处理数据压缩降低网络负载高效的序列化方式 kafka 如何确保消息的可靠性传输 消费端弄丢了数据 唯一可能导致…

第N个数字

给你一个整数 n &#xff0c;请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …] 中找出并返回第 n 位上的数字。 我觉得这题是哪以理解的 看这个题解 func findNthDigit(n int) int {digit : 1start : 1count : 9for n > count {n - countdigitstart start …

这个发表在 Nature Genetics的水稻全基因组关联数据库 RHRD,很赞!!!

历经半个世纪的发展&#xff0c;杂交水稻育种取得了巨大的成就&#xff0c;培育出了大量的高产、优质、适应环境变化的品系。本数据库是一个综合性的杂交水稻数据库&#xff08;http://ricehybridresource.cemps.ac.cn/#/&#xff09;&#xff0c;涵盖了从1976年至2017年间发布…

【Unity】简单的深度虚化shader

【Unity】简单的深度虚化shader 实现效果 可以用于对地图场景边界的白模处理 实现方法 1.关键方法 UnityObjectToClipPos&#xff1a;将物体坐标转换为屏幕坐标 LinearEyeDepth&#xff1a;将屏幕坐标中的z值转换为实际的深度值 saturate&#xff1a;将值规范到0~1之间&am…

Java 消息策略的实现 - Kafak 是怎么设计的

这个也是开放讨论题&#xff0c;主要讨论下 Kafka 在消息中是如何进行实现的。 1_cCyPNzf95ygMFUgsrleHtw976506 21.4 KB 总结 这个题目的开发性太强了。 Kafka 可以用的地方非常多&#xff0c;我经历过的项目有 Kafka 用在消息处理策略上的。这个主要是 IoT 项目&#xff0c…

three.js中的3D模型分层显示(分类型显示);使用dat.gui控制three.js中的3D模型分层显示;dat.gui调用一次但是渲染了多个

效果如上&#xff0c;就是可以通过dat.gui控制3D模型中仅仅显示管线或者是仅仅显示除了管线之外的模型。 1.在模型导入的时候就按照类型&#xff08;分层的类别标识&#xff09; 区别开&#xff08;我这里是按照是否是管线&#xff09; 这里是new THREE.Object3D();必须的否则…

Python基础学习笔记3

深度学习实践 深度学习离不开编程 深度学习离不开数学分析&#xff08;高等数学&#xff09;、线性代数、概率论等知识&#xff0c;更离不开以编程为核心的动手实践。 Python编程语言 无论是在机器学习还是深度学习中&#xff0c;Python已经成为主导性的编程语言。而且&…

OJ练习第178题——收集树中金币

收集树中金币 力扣链接&#xff1a;2603. 收集树中金币 题目描述 给你一个 n 个节点的无向无根树&#xff0c;节点编号从 0 到 n - 1 。给你整数 n 和一个长度为 n - 1 的二维整数数组 edges &#xff0c;其中 edges[i] [ai, bi] 表示树中节点 ai 和 bi 之间有一条边。再给…

计算机视觉与深度学习-全连接神经网络-训练过程-欠拟合、过拟合和Dropout- [北邮鲁鹏]

目录标题 机器学习的根本问题过拟合overfitting泛化能力差。应对过拟合最优方案次优方案调节模型大小约束模型权重&#xff0c;即权重正则化(常用的有L1、L2正则化)L1 正则化L2 正则化对异常值的敏感性随机失活(Dropout)随机失活的问题 欠拟合 机器学习的根本问题 机器学习的根…

【企业级SpringBoot单体项目模板】 —— 全局配置

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;SpringBoot、模版、企业级☀️每日 一言&#xff1a;你坚持下来了&#xff0c;而别人坚持不下来&#xff0c;这就是你的资本。 文章目录 一、全局异常配置1.1 全局异常处理1.2 处理业务异常类1.3…

如何用ate自动测试设备对DC-DC电源模块负载调整率进行测试?

电源模块负载调整率测试是功能测试之一&#xff0c;是电源模块非常重要的一项指标&#xff0c;它的大小直接影响着电源模块的整体质量。因此使用ate自动测试设备对DC-DC电源模块负载调整率进行测试是制造生产过程中至关重要的一环。 电源模块负载调整率计算公式&#xff1a; 负…

1.测试 —— 答疑篇

什么是软件测试&#xff1a; 软件测试是不是就是找 bug &#xff1f; 软件测试就是证明软件不存在错误的过程 软件测试就是为了证明程序能够正确运行 刚新买来一部手机&#xff0c;我们要干什么&#xff1f; 一场考试 , 做完一遍题目之后 , 进行一遍检查 , 就是在 "…

10个强大的 JavaScript 动画库、直接抄作业

动画&#xff0c;是吸引你客户注意的好方法之一。 在项目开发中&#xff0c;我们可以通过创造有趣的动画来为我们的项目增加视觉感与用户体验&#xff0c;同时&#xff0c;也为我们的网站增添了独特的美感&#xff0c;而且还提高了用户参与度并创造了令人难忘的第一印象。 因…

十几款IDEA开发必备的插件,新手必用

IDEA有很多优秀的插件&#xff0c;使用它们不仅大大增加了开发效率&#xff0c;也能给大家带来更好的coding体验。“工欲善其事必先利其器”&#xff0c;以下插件基本都可以通过 IDEA 自带的插件管理中心安装。 1、CodeGlance 拖动浏览代码更加方便&#xff0c;还有放大镜功能。…