Exemple #1
0
        /// <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));
        }
Exemple #2
0
        /// <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));
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
        /// <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));
        }
Exemple #5
0
        /// <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);
        }