public override bool run() { Point minLoc, maxLoc; double minVal, maxVal; Angle = 0; templ = (Mat)getValue("templ"); mode = (TemplateMatchModes)getValue("mode"); Mat t = src.MatchTemplate(templ, mode); t.MinMaxLoc(out minLoc, out maxLoc); t.MinMaxLoc(out minVal, out maxVal); switch (mode) { case TemplateMatchModes.CCoeff: case TemplateMatchModes.CCoeffNormed: case TemplateMatchModes.CCorr: case TemplateMatchModes.CCorrNormed: Loc = maxLoc; Val = maxVal; break; case TemplateMatchModes.SqDiff: case TemplateMatchModes.SqDiffNormed: Val = minVal; Loc = minLoc; break; default: break; } return(true); }
/// <summary> /// Creates implementation for cuda::TemplateMatching . /// </summary> /// <param name="srcType">Input source type. CV_32F and CV_8U depth images (1..4 channels) are supported /// for now.</param> /// <param name="method">Specifies the way to compare the template with the image. /// The following methods are supported for the CV_8U depth images for now: /// - CV_TM_SQDIFF /// - CV_TM_SQDIFF_NORMED /// - CV_TM_CCORR /// - CV_TM_CCORR_NORMED /// - CV_TM_CCOEFF /// - CV_TM_CCOEFF_NORMED /// The following methods are supported for the CV_32F images for now: /// - CV_TM_SQDIFF /// - CV_TM_CCORR</param> /// <param name="user_block_size">You can use field user_block_size to set specific block size. If you /// leave its default value Size(0,0) then automatic estimation of block size will be used(which is /// optimized for speed). By varying user_block_size you can reduce memory requirements at the cost /// of speed.</param> /// <returns></returns> public static TemplateMatching create(int srcType, TemplateMatchModes method, Size?user_block_size = null) { IntPtr ptr = NativeMethods.cuda_imgproc_createTemplateMatching( srcType, (int)method, user_block_size.GetValueOrDefault(new Size(0, 0))); return(new TemplateMatching(ptr)); }
public bool runRotate(double start, double end, double inteval) { Point minLoc, maxLoc; double minVal, maxVal; templ = (Mat)getValue("templ"); mode = (TemplateMatchModes)getValue("mode"); bool bFirst = true; for (double angle = start; angle < end; angle += inteval) { Mat result = new Mat(); // rotate the template and mask Mat Mat r = Cv2.GetRotationMatrix2D(new Point2f(templ.Width / 2, templ.Height / 2), angle, 1.0); Mat t = templ.WarpAffine(r, templ.Size()); Mat mask = new Mat(templ.Size(), MatType.CV_8UC1, new Scalar(255)).WarpAffine(r, templ.Size(), InterpolationFlags.Linear, BorderTypes.Constant); //Cv2.ImShow("match", src);Cv2.WaitKey(); //Cv2.ImShow("match", t); Cv2.WaitKey(); //Cv2.ImShow("match", mask); Cv2.WaitKey(); Cv2.MatchTemplate(src, t, result, mode, null); result.MinMaxLoc(out minLoc, out maxLoc); result.MinMaxLoc(out minVal, out maxVal); switch (mode) { case TemplateMatchModes.CCoeff: case TemplateMatchModes.CCoeffNormed: case TemplateMatchModes.CCorr: case TemplateMatchModes.CCorrNormed: if (bFirst || Val < maxVal) { Loc = maxLoc; Val = maxVal; Angle = angle; bFirst = false; } break; case TemplateMatchModes.SqDiff: case TemplateMatchModes.SqDiffNormed: if (bFirst || Val > minVal) { Val = minVal; Loc = minLoc; Angle = angle; bFirst = false; } break; default: break; } } return(true); }
/// <summary> /// Computes the proximity map for the raster template and the image where the template is searched for /// </summary> /// <param name="image">Image where the search is running; should be 8-bit or 32-bit floating-point</param> /// <param name="templ">Searched template; must be not greater than the source image and have the same data type</param> /// <param name="result">A map of comparison results; will be single-channel 32-bit floating-point. /// If image is WxH and templ is wxh then result will be (W-w+1) x (H-h+1).</param> /// <param name="method">Specifies the comparison method</param> /// <param name="mask">Mask of searched template. It must have the same datatype and size with templ. It is not set by default.</param> public static void MatchTemplate( InputArray image, InputArray templ, OutputArray result, TemplateMatchModes method, InputArray mask = null) { if (image == null) throw new ArgumentNullException(nameof(image)); if (templ == null) throw new ArgumentNullException(nameof(templ)); if (result == null) throw new ArgumentNullException(nameof(result)); image.ThrowIfDisposed(); templ.ThrowIfDisposed(); result.ThrowIfNotReady(); if (mask != null) mask.ThrowIfDisposed(); NativeMethods.imgproc_matchTemplate(image.CvPtr, templ.CvPtr, result.CvPtr, (int)method, ToPtr(mask)); GC.KeepAlive(image); GC.KeepAlive(templ); result.Fix(); GC.KeepAlive(mask); }
/// <summary> /// 获取匹配结果 /// </summary> /// <param name="searchMat">对应的训练(模板)图像</param> /// <param name="resultMat">匹配结果</param> /// <param name="matchModes">匹配算法</param> /// <param name="argument">匹配参数</param> /// <returns></returns> private static TemplateMatchResult GetMatchResult(Mat searchMat, Mat resultMat, TemplateMatchModes matchModes, TemplateMatchArgument argument) { var threshold = argument.Threshold; var maxCount = argument.MaxCount; var matchResult = new TemplateMatchResult(); while (matchResult.MatchItems.Count < maxCount) { double value; Point topLeft; Cv2.MinMaxLoc(resultMat, out var minValue, out var maxValue, out var minLocation, out var maxLocation); if (matchModes == TemplateMatchModes.SqDiff || matchModes == TemplateMatchModes.SqDiffNormed) { value = minValue; topLeft = minLocation; } else { value = maxValue; topLeft = maxLocation; } if (maxValue < threshold) { break; } argument.OutputDebugMessage($"[TemplateMatch] The info of the match is ([{matchModes}][{threshold:F}][{matchResult.MatchItems.Count}]) = {value:F}."); var matchItem = new TemplateMatchResultItem() { Value = value }; var centerX = topLeft.X + (double)searchMat.Width / 2; var centerY = topLeft.Y + (double)searchMat.Height / 2; matchItem.Point = new System.Drawing.Point((int)centerX, (int)centerY); matchItem.Rectangle = new System.Drawing.Rectangle(topLeft.X, topLeft.Y, searchMat.Width, searchMat.Height); matchResult.MatchItems.Add(matchItem); //屏蔽已筛选区域 if (matchModes == TemplateMatchModes.SqDiff || matchModes == TemplateMatchModes.SqDiffNormed) { Cv2.FloodFill(resultMat, topLeft, double.MaxValue); } else { Cv2.FloodFill(resultMat, topLeft, double.MinValue); } } matchResult.Success = matchResult.MatchItems.Any(); return(matchResult); }
/// <summary> /// Computes the proximity map for the raster template and the image where the template is searched for /// The input is Image where the search is running; should be 8-bit or 32-bit floating-point. /// </summary> /// <param name="templ">Searched template; must be not greater than the source image and have the same data type</param> /// <param name="method">Specifies the comparison method</param> /// <returns>A map of comparison results; will be single-channel 32-bit floating-point. /// If image is WxH and templ is wxh then result will be (W-w+1) x (H-h+1).</returns> public Mat MatchTemplate(InputArray templ, TemplateMatchModes method) { var dst = new Mat(); Cv2.MatchTemplate(this, templ, dst, method); return dst; }
/// <summary> /// CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。 /// CV_TM_CCORR 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。 /// CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。 /// CV_TM_SQDIFF_NORMED 归一化平方差匹配法 /// CV_TM_CCORR_NORMED 归一化相关匹配法 /// CV_TM_CCOEFF_NORMED 归一化相关系数匹配法 /// 通过模板匹配,用来寻找在一个大图里小图的匹配,受算法影响(templateMatchMode)来看minx越小越好或者max越大越好 /// </summary> /// <param name="sourceImahe"></param> /// <param name="targetImage"></param> /// <param name="templateMatchMode"></param> /// <param name="minx"></param> /// <param name="max"></param> public static void CompareImageByMatchTemplate(string sourceImage, string targetImage, TemplateMatchModes templateMatchMode, out double minx, out double max) { Mat mat1 = new Mat(sourceImage, ImreadModes.AnyColor); Mat mat2 = new Mat(targetImage, ImreadModes.AnyColor); Mat mat3 = new Mat(); mat3.Create(mat1.Rows - mat2.Rows + 1, mat1.Cols - mat2.Cols + 1, MatType.CV_32FC1); Cv2.MatchTemplate(mat1, mat2, mat3, templateMatchMode); Cv2.Normalize(mat3, mat3, 1, 0, NormTypes.MinMax, -1); Point minLocation, maxLocation; Cv2.MinMaxLoc(mat3, out minx, out max, out minLocation, out maxLocation); }