#c# #opencv #emgucv
#c# #opencv #emgucv
Вопрос:
Я использую EmguCV
, чтобы найти шаблон на изображении со следующим кодом:
CvInvoke.MatchTemplate(image, template, result, Emgu.CV.CvEnum.TemplateMatchingType.CcoeffNormed); double minVal = Double.MaxValue; double maxVal = Double.MinValue; var minLoc = new Point(); var maxLoc = new Point(); CvInvoke.MinMaxLoc(result, ref minVal, ref maxVal, ref minLoc, ref maxLoc); if (maxVal gt; threshold) { // Do something }
Это отлично работает, чтобы получить лучшее совпадение.
Но в некоторых случаях я знаю, что существует несколько совпадений, и я хотел бы увидеть все совпадения, чтобы позже сгруппировать их groupRectangles
.
Как я могу изменить свой код, чтобы повторить все совпадения?
******* ОБНОВЛЕНИЕ
Я решил эту проблему с помощью следующего кода, не очень хорошо понимая, что происходит, собранного из других небольших фрагментов, которые я нашел. Но это кажется очень неуклюжим, кроме того, кажется, что он получает много ложных срабатываний, чего, похоже, не происходило при использовании кода с одним совпадением. т. Е., если шаблона нет на изображении, код с одним совпадением не нашел его, но этот код находит множество возможных совпадений, которые совершенно неверны. Он находит правильные совпадения, когда они появляются на экране, но с большим количеством других неправильных вещей.
CvInvoke.MatchTemplate(image, template, result, Emgu.CV.CvEnum.TemplateMatchingType.CcoeffNormed); // Normalize the result image into a matrix of floats (thresholds?) Mat thresholds = new Mat(); CvInvoke.Normalize(result, thresholds, 0, 1, Emgu.CV.CvEnum.NormType.MinMax); var rectangles = new Listlt;Rectanglegt;(); var size = new Size(template.Width, template.Height); // Convert it to a multidimensional array to be able to iterate through it // (is it really necessary, isn't something native in EmguCV for this?) var thresholdData = thresholds.GetData(); for (int y = 0; y lt; thresholdData.GetLength(0); y ) { for (int x = 0; x lt; thresholdData.GetLength(1); x ) { var value = (float)thresholdData.GetValue(y, x); if (value gt; threshold) { rectangles.Add(new Rectangle(x, y, size.Width, size.Height)); } } } var groupedRectangles = new VectorOfRect(rectangles.ToArray()); CvInvoke.GroupRectangles(groupedRectangles, 1); var groupedRectanglesArray = groupedRectangles.ToArray(); foreach (var rect in groupedRectanglesArray) { response.Add(new TemplateMatch { Position = new Point(rect.Left, rect.Top), Score = -1, // For multiple matches, I cannot find the score anymore, because they were grouped Size = size, Valid = true, }); }