Hi,
I applied gaussian convolution to an image filled with constant value and got obvious error in the rightmost few dozen pixels. Below is the code and attached is the result.
I am using Orin 36.3.0
Thank you
/*
g++ -I /usr/local/include/opencv4 \
-L /usr/local/lib \
-I /usr/local/cuda/targets/aarch64-linux/include \
-L /usr/local/cuda/targets/aarch64-linux/lib \
-o testNpp testNpp.cpp \
-lopencv_core -lopencv_cudaimgproc -lopencv_imgcodecs -lopencv_imgproc \
-lnppif -lnppc -lnppisu
width=500 height=500 outputFileName=out.png ./testNpp
*/
#include <npp.h>
#include <opencv2/opencv.hpp> //OpenCV only for cv::write, upload and download
int main(int argc, char ** argv)
{
const char * outputFileName = getenv("outputFileName");
if(!outputFileName)
{
printf("no outputFileName\n");
return -1;
}
int width = 512;
int height = 512;
const char * temp = getenv("width");
if(temp)
{
width = strtol(temp, NULL, 10);
}
temp = getenv("height");
if(temp)
{
height = strtol(temp, NULL, 10);
}
printf("width %d height %d\n", width, height);
int kernelSize {5};
cv::cuda::GpuMat gpuInput;
gpuInput.create(height, width, CV_8UC1);
gpuInput.setTo(cv::Scalar(0x80));
if(getenv("withCross"))
{
//Let's make a cross
cv::cuda::GpuMat rect1(gpuInput, cv::Rect (0, height/2, width, 10));
rect1.setTo(cv::Scalar(0));
cv::cuda::GpuMat rect2(gpuInput, cv::Rect (width/2, 0, 10, height));
rect2.setTo(cv::Scalar(255));
}
double sigma {3.0};
cv::cuda::GpuMat gpuKernel;
cv::Mat uf(1, kernelSize + 2, CV_32F, 0.0);//should be 2 pixel wider than the kernel.
uf.at<float>(0, 1 + kernelSize/2) = 1.0;
std::cout << uf << std::endl;
cv::Mat kf(1, kernelSize, CV_32F, 0.0);
cv::GaussianBlur(uf, kf, cv::Size(kernelSize, 1), sigma, 1);
cv::Mat kernel = kf(cv::Rect(1, 0, kernelSize, 1));//Exclude starting and ending 0
std::cout << kernel << std::endl;
cv::cuda::GpuMat gpuResult;
gpuKernel.upload(kernel);
gpuResult.create(height, width, CV_8UC1);
NppiPoint oSrcOffset {0,0};
NppiSize roi { width, height};
NppiPoint anchor { kernelSize/2, kernelSize/2 };
printf("%p %d %p %d %p\n", gpuInput.data, (int)gpuInput.step, gpuResult.data, (int)gpuResult.step, gpuKernel.data);
NppStatus nppStatus = nppiFilterGaussAdvanced_8u_C1R(
gpuInput.data, gpuInput.step,
gpuResult.data, gpuResult.step,
roi, kernelSize, (const Npp32f *)gpuKernel.data);
if(nppStatus)
{
printf("nppiFilterGaussAdvanced_8u_C1R failed: %d\n", nppStatus);
return -1;
}
cv::Mat output;
gpuResult.download(output);
if(!cv::imwrite(outputFileName, output))
{
printf("cv::imwrite %s failed\n", outputFileName);
return -1;
}
return 0;
}