OpenCv:查找多个匹配项
我有以下内容,但我无法弄清楚如何在源图像中找到所有匹配项。
static void Main() { using (var template = Cv.LoadImage(@"imageslogo.png", LoadMode.GrayScale)) using (var source = Cv.LoadImage(@"imagesmanyLogos.png", LoadMode.GrayScale)) using (var sourceColour = Cv.LoadImage(@"imagesmanyLogos.png", LoadMode.Color)) { var width = source.Width - template.Width + 1; var height = source.Height - template.Height + 1; using (var result = Cv.CreateImage(Cv.Size(width, height), BitDepth.F32, 1)) { Cv.MatchTemplate(source, template, result, MatchTemplateMethod.SqDiff); var THRESHOLD = 0.08D; double minVal, maxVal; CvPoint minLoc, maxLoc; Cv.MinMaxLoc(result, out minVal, out maxVal, out minLoc, out maxLoc); var outlineColor = (minVal > THRESHOLD) ? CvColor.Green : CvColor.Red; Cv.Rectangle(sourceColour, Cv.Point(minLoc.X, minLoc.Y), Cv.Point(minLoc.X + template.Width, minLoc.Y + template.Height), outlineColor, 1, 0, 0); } using (var window = new CvWindow("Test")) { while (CvWindow.WaitKey(10) < 0) { window.Image = sourceColour; } } } }
我可以概述最佳匹配,而不是所有比赛。 我需要以某种方式获得所有比赛。
使用matchTemplate方法,输出图像将为您提供像素值,表示模板在此特定位置的匹配程度。 在您的情况下,由于您使用了MatchTemplateMethod.SqDiff,因此值越低,匹配越好。
问题是,当你使用minMaxLoc函数时,你会得到你要求的东西,这是最好的匹配,在这种情况下,min)。
所有匹配都是其值低于您设置的阈值的像素。 既然我不习惯csharp,这就是它在C ++中的用法,你可以进行翻译:
// after your call to MatchTemplate float threshold = 0.08; cv::Mat thresholdedImage; cv::threshold(result, thresholdedImage, threshold, 255, CV_THRESH_BINARY); // the above will set pixels to 0 in thresholdedImage if their value in result is lower than the threshold, to 255 if it is larger. // in C++ it could also be written cv::Mat thresholdedImage = result < threshold; // Now loop over pixels of thresholdedImage, and draw your matches for (int r = 0; r < thresholdedImage.rows; ++r) { for (int c = 0; c < thresholdedImage.cols; ++c) { if (!thresholdedImage.at(r, c)) // = thresholdedImage(r,c) == 0 cv::circle(sourceColor, cv::Point(c, r), template.cols/2, CV_RGB(0,255,0), 1); } }
从C ++翻译并使用OpenCvSharp包装器,上面的代码替换了minMaxLoc行,对我有用:
double threshold=0.9 var thresholdImage=Cv.CreateImage(newImageSize, BitDepth.F32,1); Cv.Threshold(result, thresholdImage, threshold, 255, ThresholdType.Binary); for (int r = 0; r < thresholdImage.GetSize().Height; r++) { for (int c = 0; c < thresholdImage.GetSize().Width; c++) { if (thresholdImage.GetRow(r)[c].Val0 > 0) { Cv.Rectangle(soruceColour, Cv.Point(c, r), Cv.Point(c + template.Width, r + template.Height), CvColor.Red, 1, 0, 0); } } }
这是使用Min_Max和Match_Template方法的解决方案。 希望它会有所帮助。
public void multipleTemplateMatch(string SourceImages, string tempImage) { Image image_source = new Image(SourceImages); Image image_partial1 = new Image(tempImage); double threshold = 0.9; ImageFinder imageFinder = new ImageFinder(image_source, image_partial1, threshold); imageFinder.FindThenShow(); }
这是一个有用的课程。
class ImageFinder { private List rectangles; public Image BaseImage { get; set; } public Image SubImage { get; set; } public Image ResultImage { get; set; } public double Threashold { get; set; } public List Rectangles { get { return rectangles; } } public ImageFinder(Image baseImage, Image subImage, double threashold) { rectangles = new List (); BaseImage = baseImage; SubImage = subImage; Threashold = threashold; } public void FindThenShow() { FindImage(); DrawRectanglesOnImage(); ShowImage(); } public void DrawRectanglesOnImage() { ResultImage = BaseImage.Copy(); foreach (var rectangle in this.rectangles) { ResultImage.Draw(rectangle, new Bgr(Color.Blue), 1); } } public void FindImage() { rectangles = new List (); using (Image imgSrc = BaseImage.Copy()) { while (true) { using (Image result = imgSrc.MatchTemplate(SubImage, TemplateMatchingType.CcoeffNormed)) { double[] minValues, maxValues; Point[] minLocations, maxLocations; result.MinMax(out minValues, out maxValues, out minLocations, out maxLocations); if (maxValues[0] > Threashold) { Rectangle match = new Rectangle(maxLocations[0], SubImage.Size); imgSrc.Draw(match, new Bgr(Color.Blue), -1); rectangles.Add(match); } else { break; } } } } } public void ShowImage() { Random rNo = new Random(); string outFilename = "matched Templates" + rNo.Next(); CvInvoke.Imshow(outFilename, ResultImage); } }
如果您觉得这很有用,请投票同样有用。 谢谢
上述就是C#学习教程:OpenCv:查找多个匹配项分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/992154.html