赞
踩
博主将在 编程语言|CUDA入门中不定期更新NPP库相关知识
本文主要利用npp实现图像中的resize操作,主要步骤如下:
nppiResize_8u_C3R
函数定义NppStatus
nppiResize_8u_C3R(const Npp8u * pSrc, int nSrcStep, NppiSize oSrcSize, NppiRect oSrcRectROI,
Npp8u * pDst, int nDstStep, NppiSize oDstSize, NppiRect oDstRectROI, int eInterpolation);
nSrcStep
指的是步长,即每行数据所占字节数,一般用opencv读取的图像,步长数都是
W
∗
3
W * 3
W∗3,matSrc.step
来获取步长;NppiSize
**指感兴趣区域操作,这里赋值为图像的大小即可**eInterpolation**
e开头,显然是个枚举,这里指resize中所使用插值类型npp支持的插值类型都定义在NppiInterpolationMode
这个枚举中,可以在nppdefs.h中查看
常见的有最近邻、线程插值、三次插值等
typedef enum
{
NPPI_INTER_UNDEFINED = 0,
NPPI_INTER_NN = 1, /**< 最近邻插值 */
NPPI_INTER_LINEAR = 2, /**< 线性插值 */
NPPI_INTER_CUBIC = 4, /**< 三次插值 */
NPPI_INTER_CUBIC2P_BSPLINE, /**< Two-parameter cubic filter (B=1, C=0) */
NPPI_INTER_CUBIC2P_CATMULLROM, /**< Two-parameter cubic filter (B=0, C=1/2) */
NPPI_INTER_CUBIC2P_B05C03, /**< Two-parameter cubic filter (B=1/2, C=3/10) */
NPPI_INTER_SUPER = 8, /**< Super sampling. */
NPPI_INTER_LANCZOS = 16, /**< Lanczos filtering. */
NPPI_INTER_LANCZOS3_ADVANCED = 17, /**< Generic Lanczos filtering with order 3. */
NPPI_SMOOTH_EDGE = (1 << 31) /**< Smooth edge filtering. */
} NppiInterpolationMode;
通常调用opencv的resize函数,即可实现resize操作
如
cv::resize(matSrc, matDst, cv::Size(nRzW, nRzH));
但当出现图像内存解码在GPU上,总不能从GPU将数据拷贝到host端,再调用opencv的resize函数,再从host端拷贝到device端,再执行模型推断,那中间这个拷贝的过程显然是没有必要的。 好在NVIDIA已经提供了nppiResize
函数用来实现这个功能;
const int nRzH = 450; const int nRzW = 800; void npp_resizeData() { cv::Mat matSrc = cv::imread("./data/Fig0638(a)(lenna_RGB).jpg"); int nH = matSrc.rows; int nW = matSrc.cols; int nC = matSrc.channels(); int nStep = matSrc.step; printf("nH = %d, nW = %d, nC = %d, nStep = %d\n", nH, nW, nC, nStep); // 1. 将图像数据拷贝到设备端 Npp8u *pu8srcData_dev = NULL; cudaMalloc((void **)&pu8srcData_dev, nH * nW * nC * sizeof(Npp8u)); cudaMemcpy(pu8srcData_dev, matSrc.data, nH * nW * nC * sizeof(Npp8u), cudaMemcpyHostToDevice); // 2. 在设备端开辟空间 Npp8u *pu8dstData_dev = NULL; NppiSize npp_srcSize{nW, nH}; NppiSize npp_dstSize{nRzW, nRzH}; cudaMalloc((void **)&pu8dstData_dev, nRzH * nRzW * nC * sizeof(Npp8u)); cudaMemset(pu8dstData_dev, 0, nRzH * nRzW * nC * sizeof(Npp8u)); // 3.调用nppiresize函数 nppiResize_8u_C3R( (Npp8u*)pu8srcData_dev, nStep, npp_srcSize, NppiRect{0, 0, nW, nH}, (Npp8u*)pu8dstData_dev, nRzW * 3, npp_dstSize, NppiRect{0, 0, nRzW, nRzH}, NPPI_INTER_LINEAR ); // 将resize后的图像内存(设备端)拷贝到host端 cv::Mat newimage(nRzH, nRzW, CV_8UC3); cudaMemcpy(newimage.data, pu8dstData_dev, nRzH * nRzW * 3, cudaMemcpyDeviceToHost); if (pu8dstData_dev != NULL) { cudaFree(pu8dstData_dev); pu8dstData_dev = NULL; } if (pu8srcData_dev != NULL) { cudaFree(pu8srcData_dev); pu8srcData_dev = NULL; } // 保存图像,验证结果 cv::imwrite("./rzImage_npp.jpg", newimage); }
原图:
512
∗
512
512*512
512∗512大小
resize后
450
∗
800
450*800
450∗800大小
为河北祈福
为栖霞矿难祈福
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。