如何解决无法理解NPP nppiFilterMedian参数ROI,掩码,偏移量等
2020/08/30编辑
我在NVIDIA论坛上https://forums.developer.nvidia.com/t/nppifiltermedian-memory-out-of-bounds-with-y-axis-mask/149420
对我的问题进行了更全面的演示。原始问题
我很难确定nppiFilterMedian函数系列的适当参数-特别是nppiFilterMedian_32f_C1R。我使用了推力和NPP的混合物。
我的最初目标是将MATLAB代码转录为C ++。这是一个使用“ movmedian”在水平和垂直方向上应用中值滤波器(一维滤波器大小)的基本MATLAB示例:
>> input = [(-10.0:-7);(-6:-3)]
input =
-10 -9 -8 -7
-6 -5 -4 -3
>> output = movmedian(input,3,1)
output =
-8 -7 -6 -5
-8 -7 -6 -5
>> output = movmedian(input,2)
output =
-9.5000 -9.0000 -8.0000 -7.5000
-5.5000 -5.0000 -4.0000 -3.5000
在那之后,我花了一些时间尝试使其通过Thrust和NPP与CUDA一起使用:
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include "npp.h"
#include "nppi.h"
#include "filter.h"
int main(int argc,char **argv) {
int width = 2;
int height = 4;
int nstep = width*sizeof(Npp32f);
int filter_len = 3;
thrust::device_vector<float> input(width*height,0.0F);
thrust::device_vector<float> output(width*height,0.0F);
NppiSize roi = NppiSize{width,height};
NppiSize mask_horizontal = NppiSize{1,filter_len};
NppiPoint anchor_horizontal = NppiPoint{0,1}; // start in center of filter
NppiSize mask_vertical = NppiSize{filter_len,1};
NppiPoint anchor_vertical = NppiPoint{1,0}; // start in center of filter
Npp8u* buffer_horizontal;
Npp32u buffer_size_horizontal;
Npp8u* buffer_vertical;
Npp32u buffer_size_vertical;
NppStatus npp_status = nppiFilterMedianGetBufferSize_32f_C1R(
roi,mask_horizontal,&buffer_size_horizontal);
if (npp_status != NPP_NO_ERROR) {
std::cerr << "NPP error " << npp_status << std::endl;
std::exit(1);
}
cudaError cuda_status
= cudaMalloc(( void** )&buffer_horizontal,buffer_size_horizontal);
if (cuda_status != cudaSuccess) {
std::cerr << cudaGetErrorString(cuda_status);
std::exit(1);
}
float start = -10.0f;
for (std::size_t i = 0; i < width; ++i) {
for (std::size_t j = 0; j < height; ++j) {
input[i*height + j] = start;
start += 1.0F;
}
}
std::cout << "input" << std::endl;
for (int i = 0; i < width; ++i) {
std::cout << "row " << i << std::endl;
for (std::size_t j = 0; j < height; ++j) {
std::cout << input[i*height + j] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << std::endl;
// apply horizontal 1D median filter
nppiFilterMedian_32f_C1R(thrust::raw_pointer_cast(input.data()),nstep,thrust::raw_pointer_cast(output.data()),roi,anchor_horizontal,buffer_horizontal);
std::cout << "output horizontal" << std::endl;
for (int i = 0; i < width; ++i) {
std::cout << "row " << i << std::endl;
for (std::size_t j = 0; j < height; ++j) {
std::cout << output[i*height + j] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << std::endl;
// apply vertical 1D median filter
nppiFilterMedian_32f_C1R(thrust::raw_pointer_cast(input.data()),mask_vertical,anchor_vertical,buffer_vertical);
std::cout << "output vertical" << std::endl;
for (int i = 0; i < width; ++i) {
std::cout << "row " << i << std::endl;
for (std::size_t j = 0; j < height; ++j) {
std::cout << output[i*height + j] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << std::endl;
cudaFree(buffer_horizontal);
cudaFree(buffer_vertical);
}
打印的输出如下:
input
row 0
-10 -9 -8 -7
row 1
-6 -5 -4 -3
output horizontal
row 0
-8 -7 -8 -7
row 1
-6 -5 -4 -3
output vertical
row 0
-9 -9 -8 -7
row 1
-6 -5 -4 -3
垂直看起来可能是正确的(浮点精度较低-也许是GPGPU吗?),但水平不是。
通常,我对ROI,锚点,步距的概念非常困惑,尤其是ROI src指针偏移量:https://docs.nvidia.com/cuda/npp/nppi_conventions_lb.html#roi_specification
我不确定我是否应该从偏移量1开始,然后将roi减小1(以确保滤镜的左侧不小于0或大于width-1)。
任何帮助将不胜感激。
FWIW,我能够使用一个更简单的中值滤波器库mf2d-它不能提供与MATLAB完全相同的输出,但是总体来说,它在整体算法中似乎可以正常工作。
在简单的库中,参数少得多(没有roi,mask,anchor等)。我的函数调用很简单:
// apply 1D median filter in horizontal direction
median_filter_2d<float>(height,width,filter_len,input.data(),output.data());
// apply 1D median filter in vertical direction
median_filter_2d<float>(height,output.data());
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。