EmguCV - 匹配模板

发布于 2024-09-05 22:51:44 字数 1134 浏览 10 评论 0原文

我有一些这样的代码来查找结果图像中模板的所有实例。

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[,,] 的坐标有关,关于

我错在哪里有什么想法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

牵你手 2024-09-12 22:51:44

答案实际上是:

由于您使用的是 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 的结果,或者查看数据的直方图形式。

小心
克里斯

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

愿得七秒忆 2024-09-12 22:51:44

您在数组中放错了 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);
                }

            }

        }

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

            }

        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文