2D cross-correlation between an image and a template

2D cross-correlation between an image and a template

I may have missed something but i would like to use the ipp library to preform a 2D crosscorrelation.

So first question is does this function CrossCorrFull_Norm in the image library do that? 

I am assuming no.

If not what is the shortest route to get the 2D cross-correlation of a region of two images using ipp?

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

>>...So first question is does this function CrossCorrFull_Norm in the image library do that?

Please read it:

// Purpose: ippiCrossCorr_Norm() function allows you to compute the
// cross-correlation of an image and a template (another image).
// The cross-correlation values are image similarity measures: the
// higher cross-correlation at a particular pixel, the more
// similarity between the template and the image in the neighborhood
// of the pixel. If IppiSize's of image and template are Wa * Ha and
// Wb * Hb correspondingly, then the IppiSize of the resulting
// matrice with normalized cross-correlation coefficients will be
// a) in case of 'Full' suffix:
// ( Wa + Wb - 1 )*( Ha + Hb - 1 ).
// b) in case of 'Same' suffix:
// ( Wa )*( Ha ).
// c) in case of 'Valid' suffix:
// ( Wa - Wb + 1 )*( Ha - Hb + 1 ).
// Notice:
// suffix 'R' (ROI) means only scanline alingment (srcStep), in
// 'Same' and 'Full' cases no any requirements for data outstand
// the ROI - it's assumes that template and src are zerro padded.

Note: There are many ippiCrossCorr_xxx() functions in IPP and some issues were detected with some functions in the past ( here are records from my test-cases ):
// Sub-Test 03 - Rounding issue with 'ippiCrossCorrFull_NormLevel_32f_C1R' function
// Sub-Test 11 - Problem with 'ippiCrossCorrValid_NormLevel_8u32f_C1R' function
Unfortunately, I'm not sure if these problems could be reproduced in the latest edition of IPP library ( I don't have time to re-test it ).

>>// Purpose: ippiCrossCorr_Norm() function allows...

I just realized that it is a little bit confusing. So, in your case you need to look at:

>>// a) in case of 'Full' suffix:


So like i said No on the 2D part.
This function looks like it is primarily designed to be used to produce a metric (not sure which part of the cross correlation produces the metric) for scanning an image for pattern recognition. Makes sense.
Which moves me to part 2:

2D Cross Correlation can be preformed in two ways by convolution or 2D FFT multiplication. In most cases for computational efficiency it is the later.
For Referance:
Fast Normalized Cross-Correlation

i thought i would also include this which is in the documentation and very close to what i need:
Using ippiMulPack Function in Image Filtering

Status mulpack( void ) {

   Ipp32f tsrc[64], tflt[64], tdst[64];

   Ipp32f fsrc[64], fflt[64], fdst[64];

   IppiFFTSpec_R_32f *spec;

   const IppiSize roiSize8x8 = { 8, 8 }, roiSize3x3 = { 3, 3 };

   const Ipp32f filter[3*3] = {-1,-1,-1, 0,0,0, 1,1,1};

   ippiSet_32f_C1R( 0, tsrc, 8*sizeof(Ipp32f), roiSize8x8 );

   ippiAddC_32f_C1IR( 1, tsrc+8+1, 8*sizeof(Ipp32f), roiSize3x3 );

   ippiSet_32f_C1R( 0, tflt, 8*sizeof(Ipp32f), roiSize8x8 );

   ippiCopy_32f_C1R( filter, 3*sizeof(Ipp32f), tflt, 8*sizeof(Ipp32f), roiSize3x3 );

   ippiFFTInitAlloc_R_32f( &spec, 3, 3, IPP_FFT_DIV_INV_BY_N, ippAlgHintAccurate );

   ippiFFTFwd_RToPack_32f_C1R( tsrc, 8*sizeof(Ipp32f), fsrc, 8*sizeof(Ipp32f), spec, 0 );

   ippiFFTFwd_RToPack_32f_C1R( tflt, 8*sizeof(Ipp32f), fflt, 8*sizeof(Ipp32f), spec, 0 );

   ippiMulPack_32f_C1R( fsrc, 8*sizeof(Ipp32f), fflt, 8*sizeof(Ipp32f), fdst, 8*4, roiSize8x8);

   ippiFFTInv_PackToR_32f_C1R( fdst, 8*sizeof(Ipp32f), tdst, 8*sizeof(Ipp32f), spec, 0 );

   ippiFFTFree_R_32f( spec );

   return 0;

So I guess that's where i need to go! Ill post some code once i get it working. But any advice in the mean time is always helpful.

ok so i got it working here is a the 2D cross correlation in IPP FFT Version
I am also going to work on on the convolution version as well but later. If anybody sees something i missed let me know.
the data is from an image that is 16 bit so the conversion is necessary and FFT quadrants need to be swapped for easy of viewing. This is not normalized.

_inline void IPPSwapQuadrents4(Ipp32f* ptr,IppiSize size)



	//1 2

	//4 3

	int stridef = size.width*sizeof(float);

	Ipp32f* temp= (Ipp32f*)ippMalloc(size.width*size.height*sizeof(float));

	IppiSize halfs = {size.width/2,size.height/2};

	//copy quad 1 to 3


	//copy quad 3 to 1


	//copy 2 to 4

	ippiCopy_32f_C1R(ptr+halfs.width,stridef,temp + halfs.height*size.width,stridef,halfs);

	//copy 4 to 2

	ippiCopy_32f_C1R(ptr + halfs.height*size.width,stridef,temp+halfs.width,stridef,halfs);

	//copy the whole thing back



IppStatus status;

int stridef = img_size.width*sizeof(float);

Ipp32f* image_data = (Ipp32f*)ippMalloc(stridef*img_size.height);

Ipp32f* image_data2 = (Ipp32f*)ippMalloc(stridef*img_size.height);

ipp_result = (Ipp32f*)ippMalloc(img_size.width*img_size.height*sizeof(float));

status = ippiConvert_16u32f_C1R(ipp_ptr_org,stridei,image_data,stridef,img_size);

IppiRect irect = {0,0,img_size.width,img_size.height};

status = ippiRotateCenter_16u_C1R(ipp_ptr_org2,img_size,stridei,irect,ipp_ptr_org,stridei,irect,180,img_size.width/2,img_size.height/2,IPPI_INTER_LINEAR);

status = ippiConvert_16u32f_C1R(ipp_ptr_org,stridei,image_data2,stridef,img_size);

IppiFFTSpec_R_32f *spec;

status = ippiFFTInitAlloc_R_32f(&spec, 9, 9, IPP_FFT_DIV_INV_BY_N , ippAlgHintAccurate);

status = ippiFFTFwd_RToPack_32f_C1IR(image_data,stridef,spec,0);

status = ippiFFTFwd_RToPack_32f_C1IR(image_data2,stridef,spec,0);

status = ippiMulPackConj_32f_C1IR(image_data,stridef,image_data2,stridef,img_size);

status = ippiFFTInv_PackToR_32f_C1R(image_data2,stridef,ipp_result,stridef,spec,0);


status = ippiFFTFree_R_32f( spec );

Leave a Comment

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