Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.
6704 Discussions

Difference in the output of Nearest Neighbour resize using IPP 7.0 resize/ippiResize_16u_C1R and API and IPP 2017-ResizeNearest

sumit_j_
Beginner
797 Views

HI All,

I am trying resize my images using IPPI_INTER_NN. When I have used IPP 7.0 Resize-ippiResize_16u_C1R to resize image my output is very much different from the same generated through  IPP 2017/9.-0 -ResizeNearest.

Plz suggests what is the cause of this.

Regards,

Sumit Jha

0 Kudos
7 Replies
Jing_Xu
Employee
797 Views

Function interface had been changed from 7.0 to the latest one. E.g. there is no ippiResize_16u_C1R in recent versions. I'll ask our engineer team and get back to you with detailed information.

0 Kudos
Valentin_K_Intel
Employee
797 Views

Hi Sumit,

The main difference between ippiResize and ippiResizeNearest is the scaling approaches, which are used by these functions. The first function resizes a number of "distances" between image pixels, while the second one considers pixels as "squares" and resizes a number of such "squares". For example, if we double an image with the size 4x4, in the first case for image width = 4 we have 3 distances and applying scale=2 we'll have 6 distances and 7 pixels output while for the new approach we'll have 8 pixels. So most likely that is the reason of differences between output images produced by the functions ippiResizeNearest and ippiResize.

Thanks,
Valentin

0 Kudos
sumit_j_
Beginner
797 Views

Hi Valentin,

I am trying to resize one test image - of 6x4  by downsample factor of 2 i.e resize output will be 3x2.

My image - 32F-
[[60, 30, 70, 100, 90,120]
[10, 20, 30, 40, 50, 60] 
[100, 200, 300, 400, 500, 600]
[1, 2, 3, 4, 5, 6]]
My output using- ResizeNearest(IPP2017)- 
 [[ 60 70 90] 
[100 300 500]]

while using Resize of IPP7 - it gives -
[[20 40 60]
[2 4 6]]
Basically one start processing from (0,0) and other from (1,1).

Is there any ways by which i  can get same  old output - resize (ipp7) from using Resizenearest (IPP 2017).

 In  IPP manual, 

Ippstatus ippiResizeNearest_<mod>(const Ipp<datatype>* pSrc, Ipp32s srcStep,
Ipp<datatype>* pDst, Ipp32s dstStep, IppiPoint dstOffset, IppiSize dstSize, const
IppiResizeSpec_32f* pSpec, Ipp8u* pBuffer);

What is the use of "dstOffset" in  this api . Can  i  use this for shifting location of  start pixel from (0,0) to (1,1).

 

Regards,

Sumit Jha

 

 

 

                            

 

0 Kudos
Valentin_K_Intel
Employee
797 Views

Hi Sumit,

Sorry for the delay with the answer. Unfortunately there is no any way to get the same old result from ResizeNearest. You can use WarpAffineNearest to get the result similar to the old Resize function. I will prepare a code example and back with the answer.

Thanks,
Valentin

0 Kudos
Valentin_K_Intel
Employee
797 Views

Hi Sumit,

Please try the following code.

#include <ipp.h>

IppStatus ResizeNearestExample_16u_C1R(Ipp16u* pSrc, IppiSize srcSize, int srcStep, Ipp16u* pDst, IppiSize dstSize,
    int dstStep, double xScale, double yScale)
{
    IppiWarpSpec* pSpec = 0;
    int specSize = 0, initSize = 0, bufSize = 0; Ipp8u* pBuffer  = 0;
    const Ipp32u numChannels = 1;
    IppiPoint dstOffset = {0, 0};
    IppStatus status = ippStsNoErr;
    IppiBorderType borderType = ippBorderInMem;
    IppiWarpDirection direction = ippWarpForward;
    double coeffs[2][3] = {0};

    coeffs[0][0] = xScale;
    coeffs[1][1] = yScale;

    coeffs[0][2] = -0.5;
    coeffs[1][2] = -0.5;

    /* Spec and init buffer sizes */
    status = ippiWarpAffineGetSize(srcSize, dstSize, ipp16u, coeffs, ippNearest, direction, borderType, &specSize, &initSize);

    if (status != ippStsNoErr) return status;

    /* Memory allocation */
    pSpec = (IppiWarpSpec*)ippsMalloc_8u(specSize);

    if (pSpec == NULL)
    {
        ippsFree(pSpec);
        return ippStsNoMemErr;
    }

    /* Filter initialization */
    status = ippiWarpAffineNearestInit(srcSize, dstSize, ipp16u, coeffs, direction, numChannels, borderType, 0, 0, pSpec);

    if (status != ippStsNoErr)
    {
        ippsFree(pSpec);
        return status;
    }

    /* work buffer size */
    status = ippiWarpGetBufferSize(pSpec, dstSize, &bufSize);
    if (status != ippStsNoErr)
    {
        ippsFree(pSpec);
        return status;
    }

    pBuffer = ippsMalloc_8u(bufSize);
    if (pBuffer == NULL)
    {
        ippsFree(pSpec);
        return ippStsNoMemErr;
    }

    /* Resize processing */
    status = ippiWarpAffineNearest_16u_C1R(pSrc, srcStep, pDst, dstStep, dstOffset, dstSize, pSpec, pBuffer);

    ippsFree(pSpec);
    ippsFree(pBuffer);

    return status;
}


int main()
{
    IppiSize srcSize = {6, 4};
    IppiSize dstSize = {3, 2};
    double scaleX = 0.5, scaleY = 0.5;
    Ipp16u srcImage[4*6] =
    {
        60,   30,  70, 100,  90, 120,
        10,   20,  30,  40,  50,  60,
        100, 200, 300, 400, 500, 600,
          1,   2,   3,   4,   5,   6
    };
    Ipp16u dstImage[2*3] = {0};
    int srcStep = srcSize.width * sizeof(Ipp16u);
    int dstStep = dstSize.width * sizeof(Ipp16u);

    ResizeNearestExample_16u_C1R(srcImage, srcSize, srcStep, dstImage, dstSize, dstStep, 0.5, 0.5);

    return 0;
}

Here is the information about how to use ippiResize<Interpolation> : https://software.intel.com/en-us/ipp-dev-reference-using-intel-ipp-resize-functions-with-prior-initialization.

The dstOffset parameter is used for tiling. It specifies the image (tile) ROI offset with respect to the destination image origin.

Thanks,
Valentin

0 Kudos
sumit_j_
Beginner
797 Views

Hi Valentin,

Thank your for your effort and sharing code. Can you plz tell me that will this code will work for ant downscale factor ( factor > < 1) ?

Regards,

Sumit Jha

 

0 Kudos
Valentin_K_Intel
Employee
797 Views

Hi Sumit,

The code should work correctly for any downscale factor. Please let me know, if there are any problems with the code.

Thanks,
Valentin

0 Kudos
Reply