Esempio n. 1
0
        /// <summary>
        ///     进行特征点匹配
        /// </summary>
        /// <param name="sourceImage">对应的查询(原始)图像</param>
        /// <param name="searchImage">对应的训练(模板)图像(宽高不得超过被查询图像)</param>
        /// <param name="featureMatchType">特征点匹配算法</param>
        /// <param name="argument">匹配参数(可选)</param>
        /// <returns></returns>
        public static FeatureMatchResult FeatureMatch(Mat sourceImage, Mat searchImage,
                                                      FeatureMatchType featureMatchType = FeatureMatchType.Sift, FeatureMatchArgument argument = null)
        {
            if (searchImage.Empty())
            {
                throw new ArgumentOutOfRangeException(nameof(searchImage), "不允许使用空的查询(原始)图像进行识别");
            }

            if (sourceImage.Empty())
            {
                throw new ArgumentOutOfRangeException(nameof(searchImage), "不允许使用空的查询(原始)图像进行识别");
            }

            if (sourceImage.Type() == searchImage.Type())
            {
                return(argument == null
                    ? Match.FeatureMatch.Match(sourceImage, searchImage, featureMatchType)
                    : Match.FeatureMatch.Match(sourceImage, searchImage, featureMatchType, 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(argument == null
                ? Match.FeatureMatch.Match(sourceMat, sourceMat, featureMatchType)
                : Match.FeatureMatch.Match(sourceMat, sourceMat, featureMatchType, argument));
        }
Esempio n. 2
0
        public void CreateFeatureProviderTest(FeatureMatchType featureType)
        {
            var provider = FeatureMatchFactory.CreateFeatureProvider(featureType);

            Assert.IsNotNull(provider);
            Assert.AreEqual(featureType, provider.MatchFeatureType);
        }
Esempio n. 3
0
        public void FeatureMatchTest(double ratio, int threshold, FeatureMatchType type)
        {
            var imageFolder = Path.GetFullPath(@".\_TestResources\CvMatchTest");
            var sourceImage = Path.Combine(imageFolder, "source.png");
            var testImage1  = Path.Combine(imageFolder, "test1.png");

            //Îļþ²âÊÔ
            var matchResult = CvMatch.FeatureMatch(sourceImage, testImage1, type, new FeatureMatchArgument()
            {
                Ratio           = ratio,
                RansacThreshold = (uint)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.FeatureMatch(sourceImage, testImage1, type, new FeatureMatchArgument()
            {
                Ratio           = ratio,
                RansacThreshold = (uint)threshold,
                ExtensionConfig = new Dictionary <string, object>()
                {
                    { MatchArgument.ConsoleOutput, true },
                    { MatchArgument.PreviewMatchResult, true }
                }
            });
            Assert.IsTrue(matchResult.Success && matchResult.MatchItems.Any());
        }
Esempio n. 4
0
        /// <summary>
        ///     进行特征点匹配
        /// </summary>
        /// <param name="sourceMat">对应的查询(原始)图像</param>
        /// <param name="searchMat">对应的训练(模板)图像</param>
        /// <param name="featureMatchType">特征点匹配算法</param>
        /// <returns></returns>
        internal static FeatureMatchResult Match(Mat sourceMat, Mat searchMat, FeatureMatchType featureMatchType)
        {
            var featureProvider = FeatureMatchFactory.CreateFeatureProvider(featureMatchType);

            if (featureProvider == null)
            {
                return(new FeatureMatchResult()
                {
                    Success = false
                });
            }

            return(featureProvider.Match(sourceMat, searchMat));
        }
Esempio n. 5
0
        /// <summary>
        ///     根据<see cref="FeatureMatchType"/>创建<see cref="IFeatureProvider"/>的实例
        /// </summary>
        /// <param name="featureType"></param>
        /// <returns></returns>
        public static IFeatureProvider CreateFeatureProvider(FeatureMatchType featureType)
        {
            //通过反射获取所有的 IFeatureProvider
            var types = Assembly.GetExecutingAssembly().GetTypes()
                        .Where(x => x.GetInterfaces().Contains(typeof(IFeatureProvider)) && !x.IsAbstract && x.IsClass).ToList();

            if (!types.Any())
            {
                return(null);
            }

            var type = types.FirstOrDefault(x => GetMatchFeatureTypeFromAttribute(x) == featureType);

            if (type == null)
            {
                return(null);
            }

            return(Activator.CreateInstance(type) as IFeatureProvider);
        }
        public AlgorithmResult DetectFeatureMatch(
            string modelName,
            string observedeName,
            FeatureDetectType detectType,
            FeatureMatchType matchType,
            int k,
            double uniquenessThreshold)
        {
            AlgorithmResult   result        = new AlgorithmResult();
            Image <Bgr, byte> modelImage    = ImageHelper.GetImage(modelName);
            Image <Bgr, byte> observedImage = ImageHelper.GetImage(observedeName);
            Mat resultImage = new Mat();

            // Get features from modelImage
            var modelKeyPoints   = new VectorOfKeyPoint();
            var modelDescriptors = new UMat();

            GetDetector(detectType).DetectAndCompute(
                modelImage.Convert <Gray, byte>(),
                null,
                modelKeyPoints,
                modelDescriptors,
                false);

            // Get features from observedImage
            var observedKeyPoints   = new VectorOfKeyPoint();
            var observedDescriptors = new UMat();

            GetDetector(detectType).DetectAndCompute(
                observedImage.Convert <Gray, byte>(),
                null,
                observedKeyPoints,
                observedDescriptors,
                false);

            // Perform match with selected matcher
            var matches = new VectorOfVectorOfDMatch();

            if (matchType == FeatureMatchType.Flann)
            {
                // TODO: Add parameters for GetIndexParams
                var flannMatcher = new FlannBasedMatcher(new AutotunedIndexParams(), new SearchParams());
                flannMatcher.Add(modelDescriptors);
                flannMatcher.KnnMatch(
                    observedDescriptors,
                    matches,
                    k,
                    null);
            }
            else
            {
                // TODO: Add parameters for DistanceType
                var bfMatcher = new BFMatcher(DistanceType.L2);
                bfMatcher.Add(modelDescriptors);
                bfMatcher.KnnMatch(
                    observedDescriptors,
                    matches,
                    k,
                    null);
            }

            // Find homography
            Mat homography = null;
            var mask       = new Mat(matches.Size, 1, DepthType.Cv8U, 1);

            mask.SetTo(new MCvScalar(255));

            VoteForUniqueness(matches, uniquenessThreshold, mask);

            // If 4 or more patches continue
            int nonZeroCount = CvInvoke.CountNonZero(mask);

            if (nonZeroCount >= 4)
            {
                // Filter for majority scale and rotation
                nonZeroCount = VoteForSizeAndOrientation(
                    modelKeyPoints, observedKeyPoints, matches, mask, 1.5, 20);

                // If 4 or more patches continue
                if (nonZeroCount >= 4)
                {
                    homography = GetHomographyMatrixFromMatchedFeatures(modelKeyPoints,
                                                                        observedKeyPoints, matches, mask, 2);
                }
            }

            // Draw the matched keypoints
            DrawMatches(
                modelImage, modelKeyPoints, observedImage, observedKeyPoints,
                matches, resultImage, new MCvScalar(255, 255, 255), new MCvScalar(255, 255, 255), mask);

            // Draw the projected region on the image
            if (homography != null)
            {
                // Draw a rectangle along the projected model
                Rectangle rect = new Rectangle(Point.Empty, modelImage.Size);
                PointF[]  pts  = new PointF[]
                {
                    new PointF(rect.Left, rect.Bottom),
                    new PointF(rect.Right, rect.Bottom),
                    new PointF(rect.Right, rect.Top),
                    new PointF(rect.Left, rect.Top)
                };

                // Transform the perspective of the points array based on the homography
                // And get a rotated rectangle for the homography
                pts = CvInvoke.PerspectiveTransform(pts, homography);

                Point[] points = Array.ConvertAll(pts, Point.Round);
                using (VectorOfPoint vp = new VectorOfPoint(points))
                {
                    CvInvoke.Polylines(resultImage, vp, true, new MCvScalar(255, 0, 0, 255), 5);
                }
            }

            result.ImageArray = ImageHelper.SetImage(resultImage.ToImage <Bgr, byte>());

            return(result);
        }
Esempio n. 7
0
        /// <summary>
        ///     进行特征点匹配
        /// </summary>
        /// <param name="sourceImage">对应的查询(原始)图像</param>
        /// <param name="searchImage">对应的训练(模板)图像(宽高不得超过被查询图像)</param>
        /// <param name="featureMatchType">特征点匹配算法</param>
        /// <param name="argument">匹配参数(可选)</param>
        /// <returns></returns>
        public static FeatureMatchResult FeatureMatch(Bitmap sourceImage, Bitmap searchImage, FeatureMatchType featureMatchType = FeatureMatchType.Sift, FeatureMatchArgument 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(FeatureMatch(sourceMat, searchMat, featureMatchType, argument));
        }
Esempio n. 8
0
        /// <summary>
        ///     进行特征点匹配
        /// </summary>
        /// <param name="sourceImage">对应的查询(原始)图像</param>
        /// <param name="searchImage">对应的训练(模板)图像(宽高不得超过被查询图像)</param>
        /// <param name="featureMatchType">特征点匹配算法</param>
        /// <param name="argument">匹配参数(可选)</param>
        /// <returns></returns>
        public static FeatureMatchResult FeatureMatch(string sourceImage, string searchImage, FeatureMatchType featureMatchType = FeatureMatchType.Sift, FeatureMatchArgument 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(FeatureMatch(sourceMat, searchMat, featureMatchType, argument));
        }
Esempio n. 9
0
 public FeatureProviderTypeAttribute(FeatureMatchType type)
 {
     FeatureMatchType = type;
 }