Question

I have some code like this to find all instances of the template in the result image.

Image<Gray, Byte> templateImage = new Image<Gray, Byte>(bmpSnip);
Image<Gray, float> imgMatch = sourceImage.MatchTemplate(templateImage, Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCOEFF_NORMED);

and then looping through the imgMatch.Data[,,] Property check if the score exceeds a threshold (say > 0.75) and place markers on the image about a match. But the matches make no sense whatsoever, I suspect I am getting the co-ordinates wrong.

        float[,,] matches = imgMatch.Data;
        for (int x = 0; x < matches.GetLength(0); x++)
        {
            for (int y = 0; y < matches.GetLength(1); y++)
            {
                double matchScore = matches[x, y, 0];
                if (matchScore > 0.75)
                {
                    Rectangle rect = new Rectangle(new Point(x,y), new Size(1, 1));
                    imgSource.Draw(rect, new Bgr(Color.Blue), 1);
                }

            }

        }

If I use the MinMax as below:

double[] min, max;
Point[] pointMin, pointMax;
imgMatch.MinMax(out min, out max, out pointMin, out pointMax);

and set a marker (rectangle) to highlight a match I get a very good result. So I am pretty sure it has to do with identifying co-ordinates for imgMatch.Data[,,]

Any ideas on where I am wrong?

Was it helpful?

Solution

Well the answer actually is:

Since you are using Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCOEFF_NORMED the results are dependant on the template size. Any result that the you get i.e. a match point is actually a reference to the top left corner of the template so to find the centre of your match simply subtract half the template width from X and half the template height from Y.

if (matchScore > 0.75)
{
    Rectangle rect = new Rectangle(new Point(x - templateImage.Width ,y - templateImage-Height), new Size(1, 1));
    imgSource.Draw(rect, new Bgr(Color.Blue), 1);
}

In addition to this you are only using a threshold of 0.75 a higher threshold of 0.9 or above will produce more desirable results. To accurately evaluate what threshold of values you require look at you result in imgMatch directly or alternatively look at the histogram formation of the data.

Take Care Chris

OTHER TIPS

you have misplaced the X and Y coordinate in array. Try this:

        float[, ,] matches = imgMatch.Data;
        for (int y = 0; y < matches.GetLength(0); y++)
        {
            for (int x = 0; x < matches.GetLength(1); x++)
            {
                double matchScore = matches[y, x, 0];
                if (matchScore > 0.75)
                {
                   Rectangle rect = new Rectangle(new Point(x,y), new Size(1, 1));
                   imgSource.Draw(rect, new Bgr(Color.Blue), 1);
                }

            }

        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top