EmguCV - MatchTemplate - PullRequest
       11

EmguCV - MatchTemplate

3 голосов
/ 15 июня 2010

У меня есть такой код, чтобы найти все экземпляры шаблона в результирующем изображении.

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

и затем циклически проверять свойство imgMatch.Data [,,], если оценка превышает порог(скажем,> 0,75) и поместите маркеры на изображение о совпадении.Но совпадения не имеют никакого смысла, я подозреваю, что я неправильно понимаю координаты.

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

            }

        }

Если я использую MinMax, как показано ниже:

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

и установите маркер (прямоугольник), чтобы выделить совпадение, я получаю очень хороший результат.Так что я уверен, что это связано с определением координат для imgMatch.Data [,,]

Есть идеи, где я ошибаюсь?

Ответы [ 2 ]

4 голосов
/ 14 октября 2011

вы потеряли координаты X и Y в массиве.Попробуйте это:

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

            }

        }
4 голосов
/ 14 сентября 2011

Ну, ответ на самом деле:

Поскольку вы используете Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCOEFF_NORMED, результаты зависят от размера шаблона. Любой результат, который вы получите, то есть точка совпадения, фактически является ссылкой на верхний левый угол шаблона, поэтому для нахождения центра вашего соответствия просто вычтите половину ширины шаблона из X и половину высоты шаблона из 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);
}

В дополнение к этому, вы используете только порог 0,75, более высокий порог 0,9 или выше даст более желательные результаты. Чтобы точно оценить, какой порог значений вам нужен, посмотрите на imgMatch напрямую или альтернативно посмотрите на формирование гистограммы данных.

Береги себя Chris

...