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

cuda小白

原始API链接 NPP

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

常见的NppStatus,可以看这里

如有问题,请指出,谢谢

Convert Bit Depth

主要分为两个大类,一个是数据类型的扩大(8u/s ->16u/s/f -> 32u/s/f),一个是缩小(32u/s -> 16u/s -> 8u/s)。

cpp 复制代码
// Alpha 表示4维图像在变换的过程中是否影响Aplha通道
// Increase Bit Depth
// _Ctx for nppStreamCtx
// R 和 Rs的区别应该是 s涉及到有符号转换为无符号的时候需要添加,conversion with saturarion(饱和度)
// 例如:
//     nppiCOnvert_8u16u_C1R 就是将uint8_t的单通道图像转换为uint16_t的单通道图像
//     nppiCOnvert_32s32u_C1Rs 就是将int32_t的单通道图像转换为uint32_t的单通道图像
NppStatus nppiConvert_[TYPE1][TYPE2]_[Alpha]C[CHANNEL]R(const TYPE1 *pSrc, 
									                    int nSrcStep,
									                    TYPE2 *pDst,
									                    int nDstStep,
									                    NppiSize oSizeROI,
									                    ...);
// Decreased Bit Depth
// 大致用法与上面的一致
// 可以指定四舍五入的模式以及尺度,如果需要指定一般R的后面会跟上Sfs
// 例如:
//    nppiConvert_32u8u_C1RSfs(..., NppRoundMode , int nScaleFactor);
NppStatus nppiConvert_[TYPE1][TYPE2]_[Alpha]C[CHANNEL]R(const TYPE1 *pSrc, 
									                    int nSrcStep,
									                    TYPE2 *pDst,
									                    int nDstStep,
									                    NppiSize oSizeROI,
									                    ...);

需要注意的是,所有16f数据类型的数据 在至少是16字节对齐的时候可以达到最优的性能

Scale Bit Depth

对于每个像素值进行scale的操作,同样也分为升和降两种。

cpp 复制代码
// dstPixelValue = dstMinRangeValue + scaleFactor * (srcPixelValue - srcMinRangeValue)

// _Ctx for nppStreamCtx
// Alpha 表示4维图像在变换的过程中是否影响Aplha通道
// ============== Scale To Higher Bit Depth =================
//    1. 8u -> 16u/s || 32 s
NppStatus nppiScale_[TYPE1][TYPE2]_[Alpha]C[CHANNEL]R(const TYPE1 *pSrc, 
									                  int nSrcStep,
									                   TYPE2 *pDst,
									                   int nDstStep,
									                   NppiSize oSizeROI,
									                   ...);

//    2. 8u -> 32f  限定最小值和最大值
NppStatus nppiScale_8u32f_[Alpha]C[CHANNEL]R(const Npp8u *pSrc, 
						                     int nSrcStep,
						                     Npp32f *pDst,
						                     int nDstStep,
						                     NppiSize oSizeROI,
						                     Npp32f nMin,
						                     Npp32f nMax,
						                     ...);
// ============== Scale To Lower Bit Depth =================

//   1. 16u/s -> 8u || 32s -> 8u
NppStatus nppiScale_[TYPE1][TYPE2]_[Alpha]C[CHANNEL]R(const TYPE1 *pSrc, 
									                  int nSrcStep,
									                  TYPE2 *pDst,
									                  int nDstStep,
									                  NppiSize oSizeROI,
									                  NppHintAlgorithm hint,
									                  ...);
//    2. 32f -> 8u  限定最小值和最大值
NppStatus nppiScale_8u32f_[Alpha]C[CHANNEL]R(const Npp8u *pSrc, 
						                     int nSrcStep,
						                     Npp32f *pDst,
						                     int nDstStep,
						                     NppiSize oSizeROI,
						                     Npp32f nMin,
						                     Npp32f nMax,
						                     ...);

Duplicate Channel

主要是将单个通道的图像重复维多通道图像。

cpp 复制代码
// 以uint8_t的单通道变为三通道
NppStatus nppiDup_8u_C1C3R(const Npp8u *pSrc,
						   int nSrcStep,
						   Npp8u *pDst,
						   int nDstStep,
						   NppiSize oDstSizeROI);

以一个图像转为灰度图,然后调用接口变为三个通道的图像结果,代码比较简单,这里就不贴了,直接上结果。

Transpose

transpose的功能与matrix的transpose比较类型,沿着图像主对角线完成的图像镜像。

cpp 复制代码
NppStatus nppiTranspose_8u_C3R(const Npp8u *pSrc,
							   int nSrcStep,
							   Npp8u *pDst,
							   int nDstStep,
							   NppiSize oSrcROI);	

由于代码也比较简单,这里就直接贴出最终的test结果了。

注意:

  1. 如果图像的宽高不等,则transpose之后的结果对应的step以及存图的时候需要注意一下正确的尺寸值。![请添加图片描述](https://img-blog.csdnimg.cn/04c27760bd3843bcb418bcc107cac01d.png

Swap Channels

当前模块的比较常用的就是RGB和BGR的变换

cpp 复制代码
// 以为uint8_t为例,主要的接口有两个,第一个是输入与输出地址不同,第二个是同一个地址
NppStatus nppiSwapChannels_8u_C3R(const Npp8u *pSrc,
								  int nSrcStep,
								  Npp8u *pDst,
								  int nDstStep,
								  NppiSize oSizeROI,
								  const int aDstOrder[3]);
NppStatus nppiSwapChannels_8u_C3IR(Npp8u *pDst,
								   int nDstStep,
								   NppiSize oSizeROI,
								   const int aDstOrder[3]);

例子也比较简答,使用起来也很方便,这里直接贴结果

相关推荐
獨枭2 分钟前
C++ 项目中使用 .dll 和 .def 文件的操作指南
c++
霁月风4 分钟前
设计模式——观察者模式
c++·观察者模式·设计模式
橘色的喵5 分钟前
C++编程:避免因编译优化引发的多线程死锁问题
c++·多线程·memory·死锁·内存屏障·内存栅栏·memory barrier
何曾参静谧41 分钟前
「C/C++」C/C++ 之 变量作用域详解
c语言·开发语言·c++
AI街潜水的八角1 小时前
基于C++的决策树C4.5机器学习算法(不调包)
c++·算法·决策树·机器学习
JSU_曾是此间年少1 小时前
数据结构——线性表与链表
数据结构·c++·算法
此生只爱蛋2 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
何曾参静谧3 小时前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
lulu_gh_yu3 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
ULTRA??4 小时前
C加加中的结构化绑定(解包,折叠展开)
开发语言·c++