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

Mismatch in output of ippiResizeLinear<mod> from older resize API ippiResize<mod> and also from legacy ippiresizeSqrPixel<mod>

Zion_H_
Beginner
891 Views

Hi,

Initially I was using older version of IPP resize API (ippiResize_16u_C1R)  with linear interpolation and BorderType Const. Since the IPP9.0 ResizeLinear with takes only two type of BorderType parameter (ippBorderInMem & ippBorderRepl), so I used src image with margin and border value zero and called ippiResizeLinear_16u_C1R with border type ippBorderInMem. But output of ippiResizeLinear_16u_C1R API is different from that resize API in older version.

Even the resize API from legacy(ippiresizeSqrPixel_16u_C1R) gives different output for linear interpolation. All three Resize API have different output for linear interpolation.

Given below is my code

IppiBorderType borderType = ippBorderInMem;
Ipp16u boarderValue = 0;
IppiBorderSize borderSize;
ResizeLinearInit_16u(src.getRoiSize(), dst.getRoiSize(), pSpec);
ResizeGetBufferSize_16u(pSpec, dst.getRoiSize(), 1, &workBufSize);
ResizeGetBorderSize_16u(pSpec, &borderSize);
ResizeLinear(srcWithMargin, dst, Point(0, 0), dst.getRoiSize(), borderType, &boarderValue, pSpec, workBuffer);
 

I need to keep backward compatibility, so please suggest me cause of mismatch and what can be done..?

 

Regards 
Ubhay

0 Kudos
7 Replies
BMart1
New Contributor II
891 Views

Is the result different also well inside the image, away from borders? Some functions put the pixel position at the corner of the square and others at the center.

0 Kudos
Zion_H_
Beginner
891 Views

Results are different on border as well as inside. 

0 Kudos
Tatyana_B_Intel
Employee
891 Views
Hi Ubhay,
 
The main difference between ippiResize and ippiResizeLinear 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 ippiResizeLinear and ippiResize.
The functions ippiResizeSqrPixel and ippiResizeLinear have the similar scaling approach, so we should explore your particular case to find the reason of the different output.
Also ippiResize_16u_C1R doesn't support border type Const. Could you please provide your source code example for all your 3 cases in order to check the difference?
 
Best regards,
Tatyana Bysheva
0 Kudos
Zion_H_
Beginner
891 Views
 
Hi,
 
Please find the code below  and Image in Attachment. 
 
//IPP OLD
Img<IP_16U> lena("Read Image");
Img<IP_16U> lenaRefdst(640, 640);
double xFactorL = double(lenaRefdst.getRoi().size.width) / double(lena.getRoi().size.width);
double yFactorL = double(lenaRefdst.getRoi().size.height) / double(lena.getRoi().size.height);
ippiResize_16u_C1R(lena.getImgPtr(),lena.getSize(),lena.getWStep(),lena.getRoi().ToIppiRect(),lenaRefdst.getRoiPtr(),lenaRefdst.getWStep(),lenaRefdst.getRoiSize(),xFactorL, yFactorL, IPPI_INTER_LINEAR);

//IPP Legacy
Img<IP_16U> lenaLegacydst(640, 640);
int  nBufferSize;
ippiResizeGetBufSize(lena.getRoi().ToRect(), lenaLegacydst.getRoi().ToRect(), 1, IPPI_INTER_LINEAR, &nBufferSize);
Ipp8u* pBuffer = (Ipp8u*)ippMalloc(nBufferSize);
ippiResizeSqrPixel_16u_C1R(lena.getRoiPtr(),lena.getRoiSize(),lena.getWStep(),lena.getRoi().ToIppiRect(), lenaLegacydst.getRoiPtr(), lenaLegacydst.getWStep(),lenaLegacydst.getRoi().ToIppiRect(),xFactorL, yFactorL, 0, 0,IPPI_INTER_LINEAR, pBuffer);

//IPP 2017
IppiBorderType borderType = ippBorderInMem;
Ipp16u boarderValue = 0;
Img<IP_16U> lenaWithMargin(lena.getRoiSize().width, lena.getRoiSize().height, margin);
Ipp::Copy(lena, lenaWithMargin);
lenaWithMargin.SetConstBorder((IP_16U)0, margin);
Img<IP_16U> lena2017dst(640, 640);
int specSize1, initSize1, workBufSize1;
Ipp::ResizeGetSize_16u(lenaWithMargin.getRoiSize(), lena2017dst.getRoiSize(),IPPI_INTER_LINEAR, 0, &specSize1, &initSize1);
IppiResizeSpec_32f * pSpec1 = (IppiResizeSpec_32f *)ippMalloc(specSize1);
Ipp::ResizeLinearInit_16u(lenaWithMargin.getRoiSize(), lena2017dst.getRoiSize(), pSpec1);
Ipp::ResizeGetBufferSize_16u(pSpec1, lena2017dst.getRoiSize(), 1, &workBufSize1);
Ipp8u* pBuffer1 = (Ipp8u*)ippMalloc(workBufSize1);
Ipp::ResizeLinear(lenaWithMargin, lena2017dst, Point(0, 0), lena2017dst.getRoiSize(), borderType, &boarderValue, pSpec1, pBuffer1);

Please find source image and results image in attached zip file.
SrcImage  = "lena.tif" (512x512)
IPP_OLD_Result = "lena_IPPOLD_ippiResize.tif" (640x640)
IPP_Legacy_result = "lena_Legacy_ippiResizeSqrPixel.tif" 
(640x640)
IPP2017_Result  = "lena_IPP2017_ippiResizeLinear.tif" (640x640)

Please  suggest  how can I reproduce the result of  "ippiResize_16u_C1R" from IPP2017 resize API- ResizeLinear. 
Also is it  possible to get the same result by using ippiResizeSqrPixel_16u_C1R ?  I was trying to use IppWarpAffine() to get same result for NearestNeighbours resize but it didn't work.
In term of resize image quality which one is better  between ippiResize_16u_C1R and ResizeLinear ?
 
 
 
Regards
Ubhay

 

 

0 Kudos
Valentin_K_Intel
Employee
891 Views

Hi Ubhay,

Thank you for the provided materials. We will investigate the issue and get back with an answer.

Best regards,
Valentin

0 Kudos
Zion_H_
Beginner
891 Views

Hi,

I was waiting for your response. Are you able to reproduce the error..? 
Please update me if you have any solution.

Regards 
Ubhay

0 Kudos
Tatyana_B_Intel
Employee
891 Views

Hi Ubhay,

Sorry for delay with the response. Your issue was investigated.

I see the only difference in borders processing. ippiResizeSqrPixel_16u_C1R uses Replicate border type by default. ippiResizeLinear_16u_C1R supports Replicate and InMem border types (and you used InMem border type with reconstructing border pixels with Constant border). As a result you received different output. If you would like to receive the similar output using these two functions, you have to use ippiResizeLinear_16u_C1R with Replicate border type.

As for receiving the same results using ippiResizeSqrPixel_16u_C1R, it's impossible due to different scaling approaches as it was mentioned above.

As for image quality, the scaling approach in ippiResizeLinear function seems to be more natural than the ippiResize approach. For example if we double 10x10 image using ippiResizeLinear approach we'll receive the image 20x20, while using the second approach with scaleFactor 0.5 the output size will be 19x19 image.

Best regards,

Tatyana Bysheva

0 Kudos
Reply