Issue with Nearest Cross Correlation (Intel IPP 7.0)

Issue with Nearest Cross Correlation (Intel IPP 7.0)

So I'm trying to do a simple template match test with NCC based on code from the documentation. But I'm having trouble trying to come up with something I can use to determine a match. Image data is 8 bpp grayscale. Any advice?

IppiSize tmp1Size = { tmp1->width, tmp1->height };
IppiSize tmp2Size = { tmp2->width, tmp2->height };
IppiSize resSize = {tmp1->width+tmp2->width-1, tmp1->height+tmp2->height-1 };
Ipp32f min, max;
IppStatus status;
Ipp32f *out, *r;
Ipp32f normC;

out = malloc(sizeof(Ipp32f) * resSize.width * resSize.height);
r = malloc(sizeof(Ipp32f) * resSize.width * resSize.height);
status = ippiCrossCorrFull_Norm_8u32f_C1R(tmp2->data, tmp2->width, tmp2Size, tmp1->data, tmp1->width, tmp1Size, out, resSize.width);
status = ippiMinMax_32f_C1R( out, tmp1->width+tmp2->width, resSize, &min, &max );
normC = 1.0f/max;
status = ippiMulC_32f_C1R(out, resSize.width, normC, r, resSize.width, resSize);


8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Best Reply

Hi Theo,

Short notice (no relation to your example, let's NCC specialists answer):

IppStatus ippiCrossCorrFull_Norm_<mod>(const Ipp<srcDatatype>* pSrc, int srcStep, IppiSize srcRoiSize, const Ipp<srcDatatype>* pTpl, int tplStep,
IppiSize tplRoiSize, Ipp32f* pDst, int dstStep);

Almost all IPP functions after image addresses have "step" parameters, which are distance in bytes between the beginnings of consequtive image rows. So, in your example the function call should look like
       status = ippiCrossCorrFull_Norm_8u32f_C1R(tmp2->data, tmp2->width*sizeof(Ipp32f), tmp2Size, tmp1->data, tmp1->width*sizeof(Ipp32f), tmp1Size, out, resSize.width*sizeof(Ipp32f)); 

There is a difference. ROIs (IppiSize) are specified in pixels, steps - in bytes.

Good luck in your debugging,

P.S. Oops, I have been pointed that this is 8u->32f function, so the first step must be tmp2->width*sizeof(Ipp8u), i.e. simply "tmp2->width".


Hi Sergey,

Thank you for your reply. That did the trick! After making this change and also upgrading to 8.0 it's working much, much better. The only thing I'm still unsure of is how to determine the best location for a template and any weaknesses I should be aware of. By the way, is there anyone with intel(or other) that's more experienced with this that I can consult with?

Hi Theo,

of course the best location for a template is at "max" position returned by CrossCorr. It's better to use ippiCrossCorrFull_NormLevel_8u32f_C1R function as it returns normalized "matching" coefficients in the range -1.0...1.0 - so the closer to 1.0 result you have - the higher is probability that your template exactly match to this region of an image.

regards, Igor

Hi Igor,

What I meant by best location was say for instance I'm comparing two images to determine how similar they are, and I wanted to maximize accuracy and speed of the compare. So I'm using a smaller portion of the image for the compare. What area would I determine makes the most sense to compare?

Also, what weaknesses should I be aware of? Like for example I know some algorithms don't handle 1 bpp or thresholded images very well, etc.

If you need to compare 2 images - I think it's better to use one of 2 functions mentioned below. If you prefer CrossCorr for this purpose - for better speed you should use function with "valid" suffix - its output is less than for "full": image.width-template.width+1. Regarding area for comparison - difficult to say - I guess it should be area with highest concentration of features - but to determine this area you need to apply some feature detector like Canny, Harris, etc. - and all this stuff also requires time... You can apply Pyramids and compare the smallest images from pyramide top - and if some criterion is passed - switch to higher (initial) resolution - so it depends...

/* /////////////////////////////////////////////////////////////////////////////
//  Names:
//      ippiQualityIndex_8u_C1R,     ippiQualityIndex_32f_C1R,
//      ippiQualityIndex_8u_C3R,     ippiQualityIndex_32f_C3R,
//      ippiQualityIndex_8u_AC4R,    ippiQualityIndex_32f_AC4R.
//  Purpose: ippiQualityIndex() function calculates the Universal Image Quality
//           Index. Instead of traditional error summation methods, the
//           proposed index is designed by modeling any image distortion as a
//           combination of three factors: loss of correlation, luminance
//           distortion, and contrast distortion. The dynamic range of the index
//           is [-1.0, 1.0].


//  Purpose:    Evaluates per-pixel SSIM equation on filtered images.
//              Intended to be uses as part of a wSSIM evaluation pipeline according to the following reference:
//              Z. Wang, A. C. Bovik, H. R. Sheikh and E. P. Simoncelli, "Image quality assessment: From error
//              visibility to structural similarity," IEEE TIP, vol. 13, no. 4, pp. 600-612, Apr. 2004.
//              Link: h__p://
//    pDst[i] = (2*F(I1)[i]*F(I2)[i]+C1)/(F(I1)[i]^2+F(I2)[i]^2+C1)*
//              *(2*F(I1*I2)-2*F(I1)[i]*F(I2)[i]+C2)/(F(I1^2)+F(I1^2)-F(I1)[i]^2-F(I2)[i]^2+C2)
//  Parameters:
//    pSrc1                    Filtered first source image F(I1)
//    src1Step                 Step through the first source image
//    pSrc2                    Filtered second source image F(I2)
//    src2Step                 Step through the second source image
//    pSrc3                    Filtered squared first source image F(I1^2)
//    src3Step                 Step through the squared first source image
//    pSrc4                    Filtered squared second source image F(I2^2)
//    src4Step                 Step through the squared second source image
//    pSrc5                    Filtered product of the first and second source images F(I1*I2)
//    src5Step                 Step through the product of the first and second source images
//    pDst                     Pointer to the unweighted per-pixel SSIM indexes array
//    dstStep                  Step through the unweighted per-pixel SSIM indexes array
//    roiSize                  Size of the ROI
//    C1                       First predefined algorithm constant
//    C2                       Second predefined algorithm constant
//  Returns:
//    ippStsNoErr              OK
//    ippStsNullPtrErr         One of the pointers is NULL
//    ippStsSizeErr            roiSize has a field with zero or negative value
//    ippStsStepErr            At least one step value is less than or equal to zero
//    ippStsBadArgErr          Incorrect hint value

IPP_DEPRECATED("is deprecated. This function is obsolete and will be removed in one of the future IPP releases. Use the following link for details:")\
IPPAPI( IppStatus, ippiSSIM_32f_C1R,( const Ipp32f* pSrc1, int src1Step, const Ipp32f* pSrc2, int src2Step,
       const Ipp32f* pSrc3, int src3Step, const Ipp32f* pSrc4, int src4Step, const Ipp32f* pSrc5, int src5Step,
       Ipp32f* pDst, int dstStep, IppiSize roiSize, Ipp32f C1, Ipp32f C2, IppHintAlgorithm hint))

regards, Igor

Hi Igor,

First off, thanks for all your help. I really appreciate it. Basically I'm implementing a kind of cash sorter. So I'm looking at 5-7 denominations x 4 orientations. Speed is not critical, but it should be reasonable. So far NCC has worked pretty well so unless there's something better out there that's more robust I think it should be fine. I'll take a look at the functions you mentioned and get back to you.

Leave a Comment

Please sign in to add a comment. Not a member? Join today