public void TemplateMatchTest(double threshold, uint maxCount, TemplateMatchType type) { var imageFolder = Path.GetFullPath(@".\_TestResources\CvMatchTest"); var sourceImage = Path.Combine(imageFolder, "source.png"); var testImage1 = Path.Combine(imageFolder, "test1.png"); //Îļþ²âÊÔ var matchResult = CvMatch.TemplateMatch(sourceImage, testImage1, type, new TemplateMatchArgument() { MaxCount = maxCount, Threshold = threshold, ExtensionConfig = new Dictionary <string, object>() { { MatchArgument.ConsoleOutput, true }, { MatchArgument.PreviewMatchResult, true } } }); Assert.IsTrue(matchResult.Success && matchResult.MatchItems.Any()); //Bitmap²âÊÔ using var sourceBitmap = new Bitmap(sourceImage); using var testBitmap1 = new Bitmap(testImage1); matchResult = CvMatch.TemplateMatch(sourceBitmap, testBitmap1, type, new TemplateMatchArgument() { MaxCount = maxCount, Threshold = threshold, ExtensionConfig = new Dictionary <string, object>() { { MatchArgument.ConsoleOutput, true }, { MatchArgument.PreviewMatchResult, true } } }); Assert.IsTrue(matchResult.Success && matchResult.MatchItems.Any()); }
/// <summary> /// 进行模版匹配 /// </summary> /// <param name="sourceMat">对应的查询(原始)图像</param> /// <param name="searchMat">对应的训练(模板)图像</param> /// <param name="type">匹配算法</param> /// <param name="argument">匹配参数(可选)</param> /// <returns></returns> internal static TemplateMatchResult Match(Mat sourceMat, Mat searchMat, TemplateMatchType type = TemplateMatchType.CCOEFF_NORMED, TemplateMatchArgument argument = null) { var matchModes = ConvertToMatchModes(type); using var resultMat = new Mat(); resultMat.Create(sourceMat.Rows - searchMat.Rows + 1, sourceMat.Cols - searchMat.Cols + 1, MatType.CV_32FC1); //进行模版匹配 Cv2.MatchTemplate(sourceMat, searchMat, resultMat, matchModes); //对结果进行归一化 Cv2.Normalize(resultMat, resultMat, 1, 0, NormTypes.MinMax, -1); //如果没有传入匹配参数,则使用默认参数 argument ??= new TemplateMatchArgument(); var matchResult = GetMatchResult(searchMat, resultMat, matchModes, argument); argument.OutputDebugMessage($"[TemplateMatch] [{type}] The result of the match is ({matchResult.Success}) ({matchResult.MatchItems.Count})."); if (matchResult.Success) { var bestMatch = matchResult.MatchItems[0]; argument.OutputDebugMessage($"[TemplateMatch] [{type}] The center point of the best match is ({bestMatch.Point}), and the rect is {bestMatch.Rectangle}."); } argument.PreviewDebugTemplateMatchResult(matchResult, sourceMat); return(matchResult); }
internal static TemplateMatchModes ConvertToMatchModes(TemplateMatchType type) { var i = (int)type; if (Enum.IsDefined(typeof(TemplateMatchModes), i)) { return((TemplateMatchModes)Enum.ToObject(typeof(TemplateMatchModes), i)); } return(TemplateMatchModes.CCoeffNormed); }
/// <summary> /// 进行模版匹配 /// </summary> /// <param name="sourceImage">对应的查询(原始)图像</param> /// <param name="searchImage">对应的训练(模板)图像(宽高不得超过被查询图像)</param> /// <param name="type">匹配算法</param> /// <param name="argument">匹配参数(可选)</param> /// <returns></returns> public static TemplateMatchResult TemplateMatch(Mat sourceImage, Mat searchImage, TemplateMatchType type = TemplateMatchType.CCOEFF_NORMED, TemplateMatchArgument argument = null) { if (searchImage.Empty()) { throw new ArgumentOutOfRangeException(nameof(searchImage), "不允许使用空的查询(原始)图像进行识别"); } if (sourceImage.Empty()) { throw new ArgumentOutOfRangeException(nameof(searchImage), "不允许使用空的查询(原始)图像进行识别"); } if (sourceImage.Type() == searchImage.Type()) { return(Match.TemplateMatch.Match(sourceImage, searchImage, type, argument)); } using var sourceMat = new Mat(sourceImage.Rows, sourceImage.Cols, MatType.CV_8UC1); using var searchMat = new Mat(searchImage.Rows, searchImage.Cols, MatType.CV_8UC1); Cv2.CvtColor(sourceImage, sourceMat, ColorConversionCodes.BGR2GRAY); Cv2.CvtColor(searchImage, searchMat, ColorConversionCodes.BGR2GRAY); return(Match.TemplateMatch.Match(sourceMat, searchImage, type, argument)); }
/// <summary> /// 进行模版匹配 /// </summary> /// <param name="sourceImage">对应的查询(原始)图像</param> /// <param name="searchImage">对应的训练(模板)图像(宽高不得超过被查询图像)</param> /// <param name="type">匹配算法</param> /// <param name="argument">匹配参数(可选)</param> /// <returns></returns> public static TemplateMatchResult TemplateMatch(Bitmap sourceImage, Bitmap searchImage, TemplateMatchType type = TemplateMatchType.CCOEFF_NORMED, TemplateMatchArgument argument = null) { if (sourceImage == null) { throw new ArgumentNullException(nameof(sourceImage)); } if (searchImage == null) { throw new ArgumentNullException(nameof(searchImage)); } using var sourceMat = OpenCvSharp.Extensions.BitmapConverter.ToMat(sourceImage); using var searchMat = OpenCvSharp.Extensions.BitmapConverter.ToMat(searchImage); if (sourceMat.Width < searchMat.Width || sourceMat.Height < searchMat.Height) { throw new ArgumentException("对应的训练(模板)图像sourceImage,宽高不得超过searchImage。"); } return(TemplateMatch(sourceMat, searchMat, type, argument)); }
/// <summary> /// 进行模版匹配 /// </summary> /// <param name="sourceImage">对应的查询(原始)图像</param> /// <param name="searchImage">对应的训练(模板)图像(宽高不得超过被查询图像)</param> /// <param name="type">匹配算法</param> /// <param name="argument">匹配参数(可选)</param> /// <returns></returns> public static TemplateMatchResult TemplateMatch(string sourceImage, string searchImage, TemplateMatchType type = TemplateMatchType.CCOEFF_NORMED, TemplateMatchArgument argument = null) { if (!File.Exists(sourceImage)) { throw new FileNotFoundException(sourceImage); } if (!File.Exists(searchImage)) { throw new FileNotFoundException(searchImage); } using var sourceMat = new Mat(sourceImage); using var searchMat = new Mat(searchImage); if (sourceMat.Width < searchMat.Width || sourceMat.Height < searchMat.Height) { throw new ArgumentException("对应的训练(模板)图像sourceImage,宽高不得超过searchImage。"); } return(TemplateMatch(sourceMat, searchMat, type, argument)); }