Exemplo n.º 1
0
        public CudaBFMatcher CreateMatcher()
        {
            var _cudaBruteForceMatcher = new CudaBFMatcher(
                this.model.Type
                );

            return(_cudaBruteForceMatcher);
        }
Exemplo n.º 2
0
        public void FindMatch(Image <Gray, byte> modelImage, Image <Gray, byte> observedImage, double hessianThresh, int k,
                              double uniquenessThreshold, VectorOfVectorOfDMatch matches, out VectorOfKeyPoint modelKeyPoints,
                              out VectorOfKeyPoint observedKeyPoints, out Mat mask, out Mat homography)
        {
            homography        = null;
            modelKeyPoints    = new VectorOfKeyPoint();
            observedKeyPoints = new VectorOfKeyPoint();

            CudaSURFDetector surfCuda = new CudaSURFDetector((float)hessianThresh);

            using (GpuMat gpuModelImage = new GpuMat(modelImage))
                //extract features from the object image
                using (GpuMat gpuModelKeyPoints = surfCuda.DetectKeyPointsRaw(gpuModelImage, null))
                    using (
                        GpuMat gpuModelDescriptors = surfCuda.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints))
                        using (CudaBFMatcher matcher = new CudaBFMatcher(DistanceType.L2))
                        {
                            surfCuda.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints);

                            // extract features from the observed image
                            using (GpuMat gpuObservedImage = new GpuMat(observedImage))
                                using (GpuMat gpuObservedKeyPoints = surfCuda.DetectKeyPointsRaw(gpuObservedImage, null))
                                    using (
                                        GpuMat gpuObservedDescriptors = surfCuda.ComputeDescriptorsRaw(gpuObservedImage, null,
                                                                                                       gpuObservedKeyPoints))
                                    {
                                        matcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, matches, k);

                                        surfCuda.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints);

                                        mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1);
                                        mask.SetTo(new MCvScalar(255));
                                        Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask);

                                        int nonZeroCount = CvInvoke.CountNonZero(mask);
                                        if (nonZeroCount >= 4)
                                        {
                                            nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints,
                                                                                                       matches, mask, 1.5, 20);
                                            if (nonZeroCount >= 4)
                                            {
                                                homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints,
                                                                                                                      observedKeyPoints, matches, mask, 2);
                                            }
                                        }
                                    }
                        }
        }
Exemplo n.º 3
0
        public void TestBruteForceHammingDistance()
        {
            if (CudaInvoke.HasCuda)
            {
                Image <Gray, byte>       box   = new Image <Gray, byte>("box.png");
                FastDetector             fast  = new FastDetector(100, true);
                BriefDescriptorExtractor brief = new BriefDescriptorExtractor(32);

                #region extract features from the object image
                Stopwatch        stopwatch      = Stopwatch.StartNew();
                VectorOfKeyPoint modelKeypoints = new VectorOfKeyPoint();
                fast.DetectRaw(box, modelKeypoints);
                Mat modelDescriptors = new Mat();
                brief.Compute(box, modelKeypoints, modelDescriptors);
                stopwatch.Stop();
                Trace.WriteLine(String.Format("Time to extract feature from model: {0} milli-sec", stopwatch.ElapsedMilliseconds));
                #endregion

                Image <Gray, Byte> observedImage = new Image <Gray, byte>("box_in_scene.png");

                #region extract features from the observed image
                stopwatch.Reset(); stopwatch.Start();
                VectorOfKeyPoint observedKeypoints = new VectorOfKeyPoint();
                fast.DetectRaw(observedImage, observedKeypoints);
                Mat observedDescriptors = new Mat();
                brief.Compute(observedImage, observedKeypoints, observedDescriptors);
                stopwatch.Stop();
                Trace.WriteLine(String.Format("Time to extract feature from image: {0} milli-sec", stopwatch.ElapsedMilliseconds));
                #endregion

                Mat homography = null;
                using (GpuMat <Byte> gpuModelDescriptors = new GpuMat <byte>(modelDescriptors)) //initialization of GPU code might took longer time.
                {
                    stopwatch.Reset(); stopwatch.Start();
                    CudaBFMatcher hammingMatcher = new CudaBFMatcher(DistanceType.Hamming);

                    //BFMatcher hammingMatcher = new BFMatcher(BFMatcher.DistanceType.Hamming, modelDescriptors);
                    int            k        = 2;
                    Matrix <int>   trainIdx = new Matrix <int>(observedKeypoints.Size, k);
                    Matrix <float> distance = new Matrix <float>(trainIdx.Size);

                    using (GpuMat <Byte> gpuObservedDescriptors = new GpuMat <byte>(observedDescriptors))
                        //using (GpuMat<int> gpuTrainIdx = new GpuMat<int>(trainIdx.Rows, trainIdx.Cols, 1, true))
                        //using (GpuMat<float> gpuDistance = new GpuMat<float>(distance.Rows, distance.Cols, 1, true))
                        using (VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch())
                        {
                            Stopwatch w2 = Stopwatch.StartNew();
                            //hammingMatcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, matches, k);
                            hammingMatcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, matches, k, null, true);
                            w2.Stop();
                            Trace.WriteLine(String.Format("Time for feature matching (excluding data transfer): {0} milli-sec",
                                                          w2.ElapsedMilliseconds));
                            //gpuTrainIdx.Download(trainIdx);
                            //gpuDistance.Download(distance);


                            Mat mask = new Mat(distance.Rows, 1, DepthType.Cv8U, 1);
                            mask.SetTo(new MCvScalar(255));
                            Features2DToolbox.VoteForUniqueness(matches, 0.8, mask);

                            int nonZeroCount = CvInvoke.CountNonZero(mask);
                            if (nonZeroCount >= 4)
                            {
                                nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeypoints, observedKeypoints,
                                                                                           matches, mask, 1.5, 20);
                                if (nonZeroCount >= 4)
                                {
                                    homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeypoints,
                                                                                                          observedKeypoints, matches, mask, 2);
                                }
                                nonZeroCount = CvInvoke.CountNonZero(mask);
                            }

                            stopwatch.Stop();
                            Trace.WriteLine(String.Format("Time for feature matching (including data transfer): {0} milli-sec",
                                                          stopwatch.ElapsedMilliseconds));
                        }
                }

                if (homography != null)
                {
                    Rectangle rect = box.ROI;
                    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)
                    };

                    PointF[] points = CvInvoke.PerspectiveTransform(pts, homography);
                    //homography.ProjectPoints(points);

                    //Merge the object image and the observed image into one big image for display
                    Image <Gray, Byte> res = box.ConcateVertical(observedImage);

                    for (int i = 0; i < points.Length; i++)
                    {
                        points[i].Y += box.Height;
                    }
                    res.DrawPolyline(Array.ConvertAll <PointF, Point>(points, Point.Round), true, new Gray(255.0), 5);
                    //ImageViewer.Show(res);
                }
            }
        }
Exemplo n.º 4
0
        public static void FindMatch(Mat modelImage, Mat observedImage, out long matchTime, out VectorOfKeyPoint modelKeyPoints, out VectorOfKeyPoint observedKeyPoints, VectorOfVectorOfDMatch matches, out Mat mask, out Mat homography)
        {
            int    k = 2;
            double uniquenessThreshold = 0.8;
            double hessianThresh       = 300;

            Stopwatch watch;

            homography = null;

            modelKeyPoints    = new VectorOfKeyPoint();
            observedKeyPoints = new VectorOfKeyPoint();

            if (CudaInvoke.HasCuda)
            {
                CudaSURF surfCuda = new CudaSURF((float)hessianThresh);
                using (GpuMat gpuModelImage = new GpuMat(modelImage))
                    //extract features from the object image
                    using (GpuMat gpuModelKeyPoints = surfCuda.DetectKeyPointsRaw(gpuModelImage, null))
                        using (GpuMat gpuModelDescriptors = surfCuda.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints))
                            using (CudaBFMatcher matcher = new CudaBFMatcher(DistanceType.L2)) {
                                surfCuda.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints);
                                watch = Stopwatch.StartNew();

                                // extract features from the observed image
                                using (GpuMat gpuObservedImage = new GpuMat(observedImage))
                                    using (GpuMat gpuObservedKeyPoints = surfCuda.DetectKeyPointsRaw(gpuObservedImage, null))
                                        using (GpuMat gpuObservedDescriptors = surfCuda.ComputeDescriptorsRaw(gpuObservedImage, null, gpuObservedKeyPoints))
                                        //using (GpuMat tmp = new GpuMat())
                                        //using (Stream stream = new Stream())
                                        {
                                            matcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, matches, k);

                                            surfCuda.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints);

                                            mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1);
                                            mask.SetTo(new MCvScalar(255));
                                            Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask);

                                            int nonZeroCount = CvInvoke.CountNonZero(mask);
                                            if (nonZeroCount >= 4)
                                            {
                                                nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints,
                                                                                                           matches, mask, 1.5, 20);
                                                if (nonZeroCount >= 4)
                                                {
                                                    homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints,
                                                                                                                          observedKeyPoints, matches, mask, 2);
                                                }
                                            }
                                        }
                                watch.Stop();
                            }
            }
            else
            {
                using (UMat uModelImage = modelImage.GetUMat(AccessType.Read))
                    using (UMat uObservedImage = observedImage.GetUMat(AccessType.Read)) {
                        SURF surfCPU = new SURF(hessianThresh);
                        //extract features from the object image
                        UMat modelDescriptors = new UMat();
                        surfCPU.DetectAndCompute(uModelImage, null, modelKeyPoints, modelDescriptors, false);

                        watch = Stopwatch.StartNew();

                        // extract features from the observed image
                        UMat observedDescriptors = new UMat();
                        surfCPU.DetectAndCompute(uObservedImage, null, observedKeyPoints, observedDescriptors, false);
                        BFMatcher matcher = new BFMatcher(DistanceType.L2);
                        matcher.Add(modelDescriptors);

                        matcher.KnnMatch(observedDescriptors, matches, k, null);
                        mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1);
                        mask.SetTo(new MCvScalar(255));
                        Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask);


                        watch.Stop();
                    }
            }
            matchTime = watch.ElapsedMilliseconds;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Finds matching points in the faces using SURF
        /// </summary>
        /// <param name="modelImage">
        /// The model image.
        /// </param>
        /// <param name="observedImage">
        /// The observed image.
        /// </param>
        /// <param name="matchTime">
        /// The match time.
        /// </param>
        /// <param name="modelKeyPoints">
        /// The model key points.
        /// </param>
        /// <param name="observedKeyPoints">
        /// The observed key points.
        /// </param>
        /// <param name="matches">
        /// The matches.
        /// </param>
        /// <param name="mask">
        /// The mask.
        /// </param>
        /// <param name="homography">
        /// The homography.
        /// </param>
        /// <param name="score">
        /// The score.
        /// </param>
        private void FindMatch(
            Mat modelImage,
            Mat observedImage,
            out long matchTime,
            out VectorOfKeyPoint modelKeyPoints,
            out VectorOfKeyPoint observedKeyPoints,
            VectorOfVectorOfDMatch matches,
            out Mat mask,
            out Mat homography,
            out long score)
        {
            int       k = 2;
            double    uniquenessThreshold = 5;
            Stopwatch watch;

            homography = null;
            mask       = null;
            score      = 0;



            modelKeyPoints    = new VectorOfKeyPoint();
            observedKeyPoints = new VectorOfKeyPoint();



            if (Controller.Instance.Cuda)
            {
                CudaSURF surfGPU = new CudaSURF(700f, 4, 2, false);
                using (CudaImage <Gray, byte> gpuModelImage = new CudaImage <Gray, byte>(modelImage))
                    //extract features from the object image
                    using (GpuMat gpuModelKeyPoints = surfGPU.DetectKeyPointsRaw(gpuModelImage, null))
                        using (GpuMat gpuModelDescriptors =
                                   surfGPU.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints))
                            using (CudaBFMatcher matcher = new CudaBFMatcher(DistanceType.L2))
                            {
                                surfGPU.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints);
                                watch = Stopwatch.StartNew();

                                // extract features from the observed image
                                using (CudaImage <Gray, Byte> gpuObservedImage = new CudaImage <Gray, byte>(observedImage))
                                    using (GpuMat gpuObservedKeyPoints = surfGPU.DetectKeyPointsRaw(gpuObservedImage, null))
                                        using (GpuMat gpuObservedDescriptors = surfGPU.ComputeDescriptorsRaw(
                                                   gpuObservedImage,
                                                   null,
                                                   gpuObservedKeyPoints))
                                            using (GpuMat <int> gpuMatchIndices = new GpuMat <int>(
                                                       gpuObservedDescriptors.Size.Height,
                                                       k,
                                                       1,
                                                       true))
                                                using (GpuMat <float> gpuMatchDist = new GpuMat <float>(
                                                           gpuObservedDescriptors.Size.Height,
                                                           k,
                                                           1,
                                                           true))
                                                    //using (GpuMat<Byte> gpuMask = new GpuMat<byte>(gpuMatchIndices.Size.Height, 1, 1))
                                                    using (Emgu.CV.Cuda.Stream stream = new Emgu.CV.Cuda.Stream())
                                                    {
                                                        matcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, matches, k, null);
                                                        //indices = new Matrix<int>(gpuMatchIndices.Size);
                                                        //mask = new Matrix<byte>(gpuMask.Size);

                                                        mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1);
                                                        mask.SetTo(new MCvScalar(255));


                                                        surfGPU.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints);

                                                        /*//gpu implementation of voteForUniquess
                                                         * using (GpuMat col0 = gpuMatchDist.Col(0))
                                                         * using (GpuMat col1 = gpuMatchDist.Col(1))
                                                         * {
                                                         *  CudaInvoke.Multiply(col1, new GpuMat(), col1, 1, DepthType.Default, stream);
                                                         *  CudaInvoke.Compare(col0, col1, mask, CmpType.LessEqual, stream);
                                                         * }*/

                                                        Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask);

                                                        //wait for the stream to complete its tasks
                                                        //We can perform some other CPU intesive stuffs here while we are waiting for the stream to complete.
                                                        stream.WaitForCompletion();
                                                        //gpuMatchIndices.Download(indices);
                                                        if (CudaInvoke.CountNonZero(mask) >= 4)
                                                        {
                                                            int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(
                                                                modelKeyPoints,
                                                                observedKeyPoints,
                                                                matches,
                                                                mask,
                                                                1.5,
                                                                20);
                                                            if (nonZeroCount >= 4)
                                                            {
                                                                homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(
                                                                    modelKeyPoints,
                                                                    observedKeyPoints,
                                                                    matches,
                                                                    mask,
                                                                    2);
                                                            }
                                                        }

                                                        watch.Stop();
                                                    }

                                for (int i = 0; i < matches.Size; i++)
                                {
                                    score++;
                                }
                            }
            }

            //else
            //{
            //    SURF surfCPU = new SURF(500, 4, 2, false);
            //    //extract features from the object image
            //    modelKeyPoints = new VectorOfKeyPoint();
            //    Matrix<float> modelDescriptors = surfCPU.DetectAndCompute(modelImage, null, modelKeyPoints);

            //    watch = Stopwatch.StartNew();

            //    // extract features from the observed image
            //    observedKeyPoints = new VectorOfKeyPoint();
            //    Matrix<float> observedDescriptors = surfCPU.DetectAndCompute(observedImage, null, observedKeyPoints);
            //    BFMatcher matcher = new BFMatcher<float>(DistanceType.L2);
            //    matcher.Add(modelDescriptors);

            //    indices = new Matrix<int>(observedDescriptors.Rows, k);
            //    using (Matrix<float> dist = new Matrix<float>(observedDescriptors.Rows, k))
            //    {
            //        matcher.KnnMatch(observedDescriptors, indices, dist, k, null);
            //        mask = new Matrix<byte>(dist.Rows, 1);
            //        mask.SetValue(255);
            //        Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask);
            //    }

            //    int nonZeroCount = CvInvoke.cvCountNonZero(mask);
            //    if (nonZeroCount >= 4)
            //    {
            //        nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20);
            //        if (nonZeroCount >= 4)
            //            homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2);
            //    }

            //    watch.Stop();
            //}
            matchTime = 0;
        }
Exemplo n.º 6
0
        private string[] FindFeatureMatches(string sourceFile, string[] targetFiles, ObservableCollection <string> output)
        {
            //Emgu.CV.CvInvoke
            // Currently we are only interested in jpg files.
            targetFiles = targetFiles
                          .Where(targetFile =>
            {
                var extension = Path.GetExtension(targetFile).ToLower();
                return(extension == ".jpg" || extension == ".jpeg");
            })
                          .ToArray();

            var matchingFiles = new List <string>();

            using var sourceImage = CvInvoke.Imread(sourceFile, ImreadModes.Grayscale);
            using var sourceMat   = new GpuMat();

            //CudaInvoke.CvtColor(sourceImage, sourceMat, ColorConversion.Bgr2Bgra);

            sourceMat.Upload(sourceImage);
            using var sourceDescriptors = new GpuMat();

            using var detector = new CudaORBDetector();
            var sourceKeyPoints = detector.Detect(sourceMat, null);

            detector.Compute(sourceMat, new VectorOfKeyPoint(sourceKeyPoints), sourceDescriptors);
            //detector.DetectAndCompute(sourceImage, null, sourceKeyPoints, sourceDescriptors, false);


            Parallel.ForEach(targetFiles, new ParallelOptions {
                MaxDegreeOfParallelism = 40
            }, targetFile =>
            {
                try
                {
                    if (targetFile == sourceFile)
                    {
                        return;                               // No need to match the original file.
                    }
                    if (new FileInfo(targetFile).Length == 0) // We cannot compare empty images.
                    {
                        return;
                    }

                    using var targetImage = CvInvoke.Imread(targetFile, ImreadModes.Grayscale);
                    using var targetMat   = new GpuMat();
                    targetMat.Upload(targetImage);

                    //                using var difference = new Mat();
                    //                Cv2.Subtract(sourceImage, targetImage, difference);
                    //
                    //                Cv2.Split(difference, out var split);
                    //                var r = split[0];
                    //                var g = split[1];
                    //                var b = split[2];
                    //                var completeMatch = Cv2.CountNonZero(r) == 0 && Cv2.CountNonZero(g) == 0 && Cv2.CountNonZero(b) == 0;
                    using var targetDescriptors = new GpuMat();
                    //var targetKeyPoints = new VectorOfKeyPoint();

                    using var detector2 = new CudaORBDetector();
                    var targetKeyPoints = detector2.Detect(targetMat, null);
                    detector2.Compute(targetMat, new VectorOfKeyPoint(targetKeyPoints), targetDescriptors);
                    //detector.DetectAndCompute(targetImage, null, targetKeyPoints, targetDescriptors, false);

                    // Needed to compensate for some crashes.
                    // See: https://stackoverflow.com/questions/25089393/opencv-flannbasedmatcher
                    if (sourceKeyPoints.Length >= 2 && targetKeyPoints.Length >= 2)
                    {
                        using var matches = new VectorOfVectorOfDMatch();
                        using var matcher = new CudaBFMatcher(DistanceType.Hamming);
                        matcher.KnnMatch(sourceDescriptors, targetDescriptors, matches, KnnMatchValue);
                        var goodPoints = matches.ToArrayOfArray().Where(match => match.Length > 1)
                                         .Where(match => match[0].Distance < match[1].Distance * MatchDistance)
                                         //.Select(match => match[0])
                                         .ToArray();

                        var matchCount = sourceKeyPoints.Length >= targetKeyPoints.Length
                            ? sourceKeyPoints.Length
                            : targetKeyPoints.Length;

                        var matchQuality = (float)goodPoints.Length / matchCount;

                        if (matchQuality >= MinimumMatchQuality)
                        {
                            using var outputImage       = new Mat();
                            using var scaledOutputImage = new Mat();
                            Features2DToolbox.DrawMatches(
                                sourceImage, new VectorOfKeyPoint(sourceKeyPoints),
                                targetImage, new VectorOfKeyPoint(targetKeyPoints),
                                new VectorOfVectorOfDMatch(goodPoints), outputImage,
                                new Bgr(System.Drawing.Color.Yellow).MCvScalar,
                                new Bgr(System.Drawing.Color.Red).MCvScalar);
                            CvInvoke.Resize(outputImage, scaledOutputImage, System.Drawing.Size.Empty, 0.1f, 0.1f);
                            Application.Current?.Dispatcher?.Invoke(() => CvInvoke.Imshow("Match preview", scaledOutputImage));
                            //Cv2.ImWrite(targetFile + ".comparison.jpg", scaledOutputImage);

                            var sb = new StringBuilder();
                            sb.AppendLine($"{DateTime.Now} Matching:");
                            sb.AppendLine($"Source: {sourceFile}");
                            sb.AppendLine($"Target: {targetFile}");
                            sb.Append($"Match found with quality: {matchQuality}");
                            output.Add(sb.ToString());
                        }
                    }
                }
                catch (Exception e)
                {
                    var sb        = new StringBuilder();
                    var exception = e.ToString().Replace(Environment.NewLine, " ");
                    sb.Append($"{DateTime.Now} Unable to match file: {targetFile}: {exception}");
                    output.Add(sb.ToString());
                }
            });

            return(matchingFiles.ToArray());
        }
Exemplo n.º 7
0
        /// <summary>
        /// Detect image using SURF
        /// </summary>
        /// <param name="modelImage"></param>
        /// <param name="observedImage"></param>
        /// <param name="modelKeyPoints"></param>
        /// <param name="observedKeyPoints"></param>
        /// <param name="matches"></param>
        /// <param name="mask"></param>
        /// <param name="homography"></param>
        public static void FindMatch(Mat modelImage, Mat observedImage, out VectorOfKeyPoint modelKeyPoints, out VectorOfKeyPoint observedKeyPoints, VectorOfVectorOfDMatch matches, out Mat mask, out Mat homography, out int score)
        {
            int    k = 2;
            double uniquenessThreshold = 0.8;
            double hessianThresh       = 300;

            homography = null;

            modelKeyPoints    = new VectorOfKeyPoint();
            observedKeyPoints = new VectorOfKeyPoint();

            if (CudaInvoke.HasCuda)
            {
                CudaSURF surfCuda = new CudaSURF((float)hessianThresh);
                using (GpuMat gpuModelImage = new GpuMat(modelImage))
                    //extract features from the object image
                    using (GpuMat gpuModelKeyPoints = surfCuda.DetectKeyPointsRaw(gpuModelImage, null))
                        using (GpuMat gpuModelDescriptors = surfCuda.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints))
                            using (CudaBFMatcher matcher = new CudaBFMatcher(DistanceType.L2))
                            {
                                surfCuda.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints);

                                // extract features from the observed image
                                using (GpuMat gpuObservedImage = new GpuMat(observedImage))
                                    using (GpuMat gpuObservedKeyPoints = surfCuda.DetectKeyPointsRaw(gpuObservedImage, null))
                                        using (GpuMat gpuObservedDescriptors = surfCuda.ComputeDescriptorsRaw(gpuObservedImage, null, gpuObservedKeyPoints))
                                        //using (GpuMat tmp = new GpuMat())
                                        //using (Stream stream = new Stream())
                                        {
                                            matcher.KnnMatch(gpuObservedDescriptors, gpuModelDescriptors, matches, k);

                                            surfCuda.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints);

                                            mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1);
                                            mask.SetTo(new MCvScalar(255));
                                            Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask);

                                            score = 0;
                                            for (int i = 0; i < matches.Size; i++)
                                            {
                                                if ((byte)mask.GetData().GetValue(i, 0) == 0)
                                                {
                                                    continue;
                                                }
                                                foreach (var e in matches[i].ToArray())
                                                {
                                                    ++score;
                                                }
                                            }

                                            int nonZeroCount = CvInvoke.CountNonZero(mask);
                                            if (nonZeroCount >= 4)
                                            {
                                                nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints,
                                                                                                           matches, mask, 1.5, 20);
                                                if (nonZeroCount >= 4)
                                                {
                                                    homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints,
                                                                                                                          observedKeyPoints, matches, mask, 2);
                                                }
                                            }
                                        }
                            }
            }
            else
            {
                using (UMat uModelImage = modelImage.GetUMat(AccessType.Read))
                    using (UMat uObservedImage = observedImage.GetUMat(AccessType.Read))
                    {
                        SURF surfCPU = new SURF(hessianThresh);
                        //extract features from the object image
                        UMat modelDescriptors = new UMat();
                        surfCPU.DetectAndCompute(uModelImage, null, modelKeyPoints, modelDescriptors, false);

                        // extract features from the observed image
                        UMat observedDescriptors = new UMat();
                        surfCPU.DetectAndCompute(uObservedImage, null, observedKeyPoints, observedDescriptors, false);
                        BFMatcher matcher = new BFMatcher(DistanceType.L2);
                        matcher.Add(modelDescriptors);

                        matcher.KnnMatch(observedDescriptors, matches, k, null);
                        mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1);
                        mask.SetTo(new MCvScalar(255));
                        Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask);

                        score = 0;
                        for (int i = 0; i < matches.Size; i++)
                        {
                            //if (mask.GetData(true)[0] == 0) continue;
                            foreach (var e in matches[i].ToArray())
                            {
                                ++score;
                            }
                        }

                        int nonZeroCount = CvInvoke.CountNonZero(mask);
                        if (nonZeroCount >= 4)
                        {
                            nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints,
                                                                                       matches, mask, 1.5, 20);
                            if (nonZeroCount >= 4)
                            {
                                homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints,
                                                                                                      observedKeyPoints, matches, mask, 2);
                            }
                        }
                    }
            }
        }
Exemplo n.º 8
0
        public static void FindMatch(Mat modelImage, Mat observedImage, out long matchTime, out VectorOfKeyPoint modelKeyPoints,
                                     out VectorOfKeyPoint observedKeyPoints, VectorOfVectorOfDMatch matches, out Mat mask, out Mat homography, double hessianThresh)
        {
            int    k = 2;
            double uniquenessThreshold = 0.8;
            //double hessianThresh = 300;设置阈值,这个值越大,最终的特征点越少

            Stopwatch sw;

            homography = null;

            modelKeyPoints    = new VectorOfKeyPoint();
            observedKeyPoints = new VectorOfKeyPoint();

#if !__IOS__
            //判断是否存在NVIDIA显卡,如果存在就是使用GPU进行计算
            if (CudaInvoke.HasCuda)
            {
                //SURF算法
                //创建一个CudaSurf 侦测器
                CudaSURF surfCuda = new CudaSURF((float)hessianThresh);
                //在Gpu中 使用GpuMat 来替代cv::Mat
                using (GpuMat gpuModelImage = new GpuMat(modelImage))

                    //从图像中提取特征点
                    using (GpuMat gpuModelKeyPoints = surfCuda.DetectKeyPointsRaw(gpuModelImage, null))
                        //创建特征点描述器
                        using (GpuMat gupModelDescriptors = surfCuda.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints))
                            //创建匹配器
                            using (CudaBFMatcher matcher = new CudaBFMatcher(DistanceType.L2))
                            {
                                surfCuda.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints);
                                sw = Stopwatch.StartNew();

                                using (GpuMat gpuObservedImage = new GpuMat(observedImage))
                                    using (GpuMat gpuObservedKeyPoints = surfCuda.DetectKeyPointsRaw(gpuObservedImage, null))
                                        using (GpuMat gpuObservedDescriptors = surfCuda.ComputeDescriptorsRaw(gpuObservedImage, null, gpuObservedKeyPoints))

                                        //using (GpuMat tmp = new GpuMat())
                                        //using (Stream stream = new Stream())
                                        {
                                            matcher.KnnMatch(gpuObservedDescriptors, gpuObservedDescriptors, matches, k);

                                            surfCuda.DownloadKeypoints(gpuModelKeyPoints, observedKeyPoints);
                                            mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1);
                                            mask.SetTo(new MCvScalar(255));

                                            //过滤匹配特征,,如果匹配点是比较罕见,那么就剔除
                                            Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask);
                                            //返回数组中的非零元素
                                            int nonZeroCount = CvInvoke.CountNonZero(mask);
                                            if (nonZeroCount >= 4)
                                            {
                                                //剔除
                                                nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, matches, mask, 1.5, 20);
                                                if (nonZeroCount >= 4)
                                                {
                                                    homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, matches, mask, 2);
                                                }
                                            }
                                        }
                                sw.Stop();
                            }
            }
            else
#endif
            {
                using (UMat uModelImage = modelImage.ToUMat(AccessType.Read))
                    using (UMat uObservedImage = observedImage.ToUMat(AccessType.Read)) {
                        //创建surf算法器
                        SURF surfCPU = new SURF(hessianThresh);

                        //从源的图像提取描述符
                        UMat modelDescriptors = new UMat();
                        surfCPU.DetectAndCompute(uModelImage, null, modelKeyPoints, modelDescriptors, false);
                        sw = Stopwatch.StartNew();

                        //从观察图像中提取描述器
                        UMat observedDescriptors = new UMat();
                        surfCPU.DetectAndCompute(uObservedImage, null, observedKeyPoints, observedDescriptors, false);

                        //Brute Force匹配
                        BFMatcher matcher = new BFMatcher(DistanceType.L2);
                        matcher.Add(modelDescriptors);
                        //matches:VectorOfVectorOfDMatch
                        //observedDescriptors:VectorOfKeyPoint
                        matcher.KnnMatch(observedDescriptors, matches, k, null);

                        mask = new Mat(matches.Size, 1, DepthType.Cv8U, 1);
                        mask.SetTo(new MCvScalar(255));
                        //过滤匹配特征,,如果匹配点是比较罕见,那么就剔除
                        Features2DToolbox.VoteForUniqueness(matches, uniquenessThreshold, mask);
                        //返回数组中的非零元素
                        int nonZeroCount = CvInvoke.CountNonZero(mask);
                        if (nonZeroCount >= 4)
                        {
                            //剔除那些旋转和缩放不与大多数匹配和旋转统一的特征点
                            nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, matches, mask, 1.5, 20);
                            if (nonZeroCount >= 4)
                            {
                                //使用RANDSAC算法获取单应性矩阵,如果矩阵不能恢复,返回null
                                homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, matches, mask, 2);
                            }
                        }
                        sw.Stop();
                    }
            }
            matchTime = sw.ElapsedMilliseconds;
        }