我有一些像这样的代码来查找结果图像中的所有模板实例. ImageGray, Byte templateImage = new ImageGray, Byte(bmpSnip);ImageGray, float imgMatch = sourceImage.MatchTemplate(templateImage, Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCOE
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 [,,]的坐标有关.
关于我错在哪里的任何想法?
答案实际上是:由于您使用的是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,或者查看数据的直方图形成.
照顾自己克里斯