- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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);

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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,

Sergey

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".

Link Copied

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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,

Sergey

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".

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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?

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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].

//

or

/*

// 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://www.ece.uwaterloo.ca/~z70wang/publications/ssim.html

//

// pDst* = (2*F(I1) *F(I2)+C1)/(F(I1)^2+F(I2)^2+C1)**

// *(2*F(I1*I2)-2*F(I1)*F(I2)+C2)/(F(I1^2)+F(I1^2)-F(I1)^2-F(I2)^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: http://software.intel.com/en-us/articles/intel-ipp-71-deprecated-features/")\

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page