You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

nppi三通道Resize_8u_C3R等尺寸缩放输出乱码问题

问题根因

核心错误是显存分配、主机与设备间内存拷贝的字节数计算错误。
你之前用单通道NPP缩放函数没遇到问题,是因为单通道8位图像每个像素占1字节,mat.total()返回的像素总数刚好等于需要的字节数;但3通道8位格式CV_8UC3每个像素占3字节,你代码里只分配了实际所需1/3的显存空间,NPP运行时写入越界,未被申请的显存区域数据是随机值,最终拷贝回主机端就表现为大面积乱码。
你观察到输出图只有顶部1/3区域能正常缩放、其余区域全是乱码,和这个错误的表现完全吻合:只有前1/3的像素数据落在了你合法申请的显存地址范围内,剩余2/3的像素读写都落在未申请的非法地址上。

修复方案

把所有涉及显存字节数计算的位置,从直接使用mat.total()替换为mat.total() * mat.elemSize(),一共需要修改4处代码:

  • 源图像显存分配
// 错误写法
cudaMalloc(&gpuBuffer1, mat.total());
// 修正后
cudaMalloc(&gpuBuffer1, mat.total() * mat.elemSize());
  • 目标图像显存分配
// 错误写法
cudaMalloc(&gpuBuffer2, mat.total());
// 修正后
cudaMalloc(&gpuBuffer2, mat.total() * mat.elemSize());
  • 主机到设备的内存拷贝
// 错误写法
cudaMemcpy(gpuBuffer1, mat.data, mat.total(), cudaMemcpyHostToDevice);
// 修正后
cudaMemcpy(gpuBuffer1, mat.data, mat.total() * mat.elemSize(), cudaMemcpyHostToDevice);
  • 设备到主机的内存拷贝
// 错误写法
cudaMemcpy(mat2.data, gpuBuffer2, mat.total(), cudaMemcpyDeviceToHost);
// 修正后
cudaMemcpy(mat2.data, gpuBuffer2, mat.total() * mat.elemSize(), cudaMemcpyDeviceToHost);
优化建议
  • 你代码里传入NPP的行步长参数mat.cols * 3在当前场景下是正确的,但更稳妥的写法是直接传入OpenCV Mat自带的mat.step属性作为步长,后续如果遇到带行对齐填充的Mat数据,不会出现步长计算错误。
  • 建议给所有CUDA API、NPP API调用加统一的错误检查,遇到越界访问这类问题时,用cuda-memcheck工具运行程序可以直接抛出非法内存访问的报错信息,大幅缩短问题定位时间。

内容的提问来源于stack exchange,提问作者Brian Yeh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 18:51:49