Problem about Median Filter

I’m trying to use median filter to perform a 3x3 filter on an image.
(Using nppiFilterMedian_8u_C3R for color image, nppiFilterMedian_8u_C1R for gray image, nppiFilterMedian_32f_C1R for depth map.)

I was able to run the code and I was successfully able to create the filtered image.

The problem is that the filter shifts the image slightly.
To be more specific, when using a 3x3 mask, the last 2 rows and the 2 two columns of the image are not masked, resulting an image that is shifted by 2 pixels upwards and 2 pixel towards left.

I’ve tried to set anchor point with negative value, and the image move upward.
So I tried to set anchor point with positive value, then it came out kernel error.

Does anybody having the same problem?

Thank you

Are you using any of the border functions?
How have you set your ROI’s?

Thanks for your reply.

I’m just set ROI using width * height.
And with no border functions.(do not have knowledge about this.)

The median filter has a border region (equal to filter radius) which it will not process.

You can handle border behavior with border functions in the npp doc. I’m not going to try to write a tutorial on it here, and the npp doc admittedly has not much info about how to use this API.

npp behaves similarly to intel ipp. If you study the intel docs for how to do an ipp median filter, you should be able to use corresponding functions in npp to do the same thing.

If you google “ipp median filter example” you’ll find various useful hits in the top 10.

If you are still having trouble and want to provide a short complete code that implements npp median filter for a simple test case, I will take a look, as time permits.

Thanks for your reply.

I found ipp have function ippiFilterMedianBorder().

http://hpc.ipp.ac.cn/wp-content/uploads/2015/12/documentation_2016/en/ipp/common/ipp_manual/GUID-F70F9576-DAF2-4C94-869F-1127E741A17F.htm

But nppi do not have the similar function nppiFilterMedianBorder().

ps. Accroding to this link(https://software.intel.com/en-us/node/503723), anchor cell is usuallay the mid of the mask(kernal). But when I set anchor point with any positive value (eg. just using (mask.x / 2 - 1, mask.y / 2 - 1)), there came a CUDA kernal error.

I’ve modified sample code from Intel’s site above.
(Change ipp8u->Npp8u, etc.)

Npp8u pSrcCpu[9 * 8] =
{
	0, 1, 2, 120, 121, 122, 50, 51, 52,
	1, 2, 3, 121, 122, 123, 52, 52, 53,
	3, 4, 5, 130, 131, 132, 63, 64, 65,
	4, 5, 6, 131, 132, 133, 64, 65, 66,
	5, 6, 7, 132, 133, 134, 65, 66, 67,
	8, 7, 6, 134, 133, 132, 67, 66, 65,
	7, 6, 5, 133, 132, 131, 66, 65, 64,
	6, 5, 4, 132, 131, 130, 65, 64, 63
};
Npp8u    *pSrc;
cudaMalloc(&pSrc, 9 * 8 * sizeof(Npp8u));
cudaMemcpy(pSrc, pSrcCpu, sizeof(Npp8u) * 9 * 8, cudaMemcpyHostToDevice);
Npp8u    *pDst;
cudaMalloc(&pDst, 8 * 7 * sizeof(Npp8u));
Npp8u   *pBuffer;
NppiSize roiSize = { 8, 7 };
int    srcStep = 9 * sizeof(Npp8u);
int    dstStep = 8 * sizeof(Npp8u);
Npp32u    bufferSize;
NppStatus status;
NppiSize  maskSize = { 3, 3 };
NppiPoint anchor = { 1, 1 };

nppiFilterMedianGetBufferSize_8u_C1R(roiSize, maskSize, &bufferSize);
std::cout << "buffer size: " << bufferSize << std::endl;
cudaMalloc(&pBuffer, bufferSize);
status = nppiFilterMedian_8u_C1R(pSrc + srcStep, srcStep, pDst, dstStep, roiSize, maskSize, anchor, pBuffer);

unsigned char *pDstCpu;
pDstCpu = (unsigned char*)malloc(8 * 7);
cudaMemcpy(pDstCpu, pDst, sizeof(Npp8u) * 8 * 7, cudaMemcpyDeviceToHost);
for (int i = 0; i < 7; i++)//row
{
	for (int j = 0; j < 8; j++)//col
	{
		std::cout << (int)(pDstCpu[i * 8 + j]) << " ";
	}
	std::cout << std::endl;
}
cudaFree(pSrc);
cudaFree(pDst);
cudaFree(pBuffer);
free(pDstCpu);

These code can run well.

Not really an answer – just an extension to your question…

How do the NPPI functions perform a median filter on 3-channel images? The documentation does not say. I would guess you would convert to HSV and sort first on V, then on S, and then on H? I wish the documentation wasn’t so sparse.

http://docs.nvidia.com/cuda/npp/group__image__filter__median.html

e.g. : here is 3-channel median filter:

http://docs.nvidia.com/cuda/npp/group__image__filter__median.html#ga028138edcd00c09012cb61950867b766