I have a source image ‘src’ with dimension ‘widthSrc x heightSrc’ and a destination image ‘dst’ with dimension ‘widthDst x heightDst’.
Now I would like to use the NPP function ‘nppiResizeSqrPixel’ to write a resized version of the whole source image into the whole destination image ‘dst’. The used interpolation method will be either nearest, bilinear or bicubic interpolation.
Now my question: It is crucially important that EVERY pixel in destination image ‘dst’ is written by the ‘nppiResizeSqrPixel’ function, it would be a disaster if a pixel would be left out by the function. How do I have to calculate the parameter values ‘xFactor’, ‘yFactor’, ‘xShift’, ‘yShift’ in order to ensure this ? Would be great if someone could provide a clear formula. My guess is that i have to set xShift and yShift to 0, and xFactor to ‘(widthDst - 1) / (widthSrc - 1)’ and yFactor in the same way - but I am not sure.
The corresponding section in the NPP documentation PDF (Cuda Toolkit 7.0) is listed below, but somehow I don’t get the right clue from this documentation.
[Excerpt from NPP docu follows]
ResizeSqrPixel attempts to choose source pixels that would approximately represent the center of the destination
pixels. It does so by using the following scaling formula to select source pixels for interpolation:
nAdjustedXFactor = 1.0 / nXFactor;
nAdjustedYFactor = 1.0 / nYFactor;
nAdjustedXShift = nXShift * nAdjustedXFactor + ((1.0 - nAdjustedXFactor) * 0.5);
nAdjustedYShift = nYShift * nAdjustedYFactor + ((1.0 - nAdjustedYFactor) * 0.5);
nSrcX = nAdjustedXFactor * nDstX - nAdjustedXShift;
nSrcY = nAdjustedYFactor * nDstY - nAdjustedYShift;
In the ResizeSqrPixel functions below source image clip checking is handled as follows:
If the source pixel fractional x and y coordinates are greater than or equal to oSizeROI.x and less than
oSizeROI.x + oSizeROI.width and greater than or equal to oSizeROI.y and less than oSizeROI.y + oSizeROI.height
then the source pixel is considered to be within the source image clip rectangle and the source
image is sampled. Otherwise the source image is not sampled and a destination pixel is not written to the
Have you found a failure with your current code? If so can you send along a failure case?
I just want to make sure that for ALL possible image size of src and dst image all Pixel are written in dst. So it’s difficult to write a test Case for that cause I would have to iterate over all possible image size combinations up to Let’s say 8k Resolution, which means 8000 ^ 4 cases.
Please define “disaster”.
It is not clear to me what you are after. There are no 100% guarantees with software, bugs are always a possibility. If you are sufficiently paranoid about some destination pixels not being written, you may want to bulk initialize the destination image to a suitable default prior to calling nppiResizeSqrPixel().
According to my limited understanding of image processing, resizing works by determining, for each destination pixel, which source pixel(s) contribute to it according to the selected resizing factor and interpolation. That implies in the case of whole-image resizing all destination pixels are written with some information, and unless there is a bug, the information written should correctly reflect the relevant source pixels.
As for brute-force testing, a rule of thumb is than one can test about 2^40 test cases a day on a modern PC, so an exhaustive test might be feasible if you are willing to let it crank for a week.
We (NVIDIA) recently found a bug in the rotation code which at some scale factors can cause the last source pixel in a row or column to not be sampled. ResizeSqrPixel contains a similar test which probably also needs fixed. It would be great if you could send us an example of a failure case. In the meantime, a possible work around would be to increase oSrcROI.width and oSrcROI.height by 1. To be safe in all cases however, this may require that you increase the memory allocated for your source image by 1 in both width and height.
Note all destination pixels are written, only the destination pixel for which their corresponding source pixel (with coordinaates nSrcX, nSrcY) is inside the source image roi (the source image roi will cover the whole source image for my case).
Such issues (not written pixels, for certain combinations of image sizes) have the potential for long and nasty debugging sessions (potentially days), that I mean with ‘disaster’. The exact kind of the effect can be very diverse and It can be difficult to track down the exact cause then, especially in a complex computer vision algorithm (like video denoising) with a huge amounts of individual steps (one step being the resize). Setting a default value is not an option because no good default value exists. Increasing the size of the source image prior to resizing means an additional step which will hurt performance.
For now, I will use the other resize function ‘nppiResize’ provided by NPP. It is deprecated, but for this function I can easily figure out the scaling factors and shift. So would great if the NPP team keeps this function alive also in newer cuda toolkit releases. Nonetheless, it would be great if one could provide me simple formulas which guarantee me that all pixels in ‘dst’ are written. And as I don’t have the source code for the respective NPP function, i can’t figure out myself.