代码之家  ›  专栏  ›  技术社区  ›  Mikos

emgucv-匹配模板

  •  3
  • Mikos  · 技术社区  · 14 年前

    我有一些这样的代码可以在结果图像中找到模板的所有实例。

    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 回复  |  直到 13 年前
        1
  •  4
  •   Chris    13 年前

    其实答案是:

    由于您使用的是emgu.cv.cvenum.tm_type.cv_tm_cceff,因此结果取决于模板大小。您得到的任何结果,即匹配点实际上是对模板左上角的引用,因此要找到匹配的中心,只需从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结果,或者查看数据的直方图形式。

    当心 克里斯

        2
  •  3
  •   Alfonso Muriel    13 年前

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