示例#1
0
        private static void FindMatch(Image <Gray, Byte> modelImage, Image <Gray, byte> observedImage, SurfSettings surfSettings, out long matchTime, out VectorOfKeyPoint modelKeyPoints, out VectorOfKeyPoint observedKeyPoints, out Matrix <int> indices, out Matrix <byte> mask, out HomographyMatrix homography)
        {
            #region Surf Dectator Region
            double hessianThresh       = 500;
            double uniquenessThreshold = 0.8;

            if (surfSettings != null)
            {
                hessianThresh       = surfSettings.HessianThresh.Value;
                uniquenessThreshold = surfSettings.UniquenessThreshold.Value;
            }

            SURFDetector surfCPU = new SURFDetector(hessianThresh, false);
            #endregion



            int       k = 2;
            Stopwatch watch;
            homography = null;


            //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);
            BruteForceMatcher <float> matcher             = new BruteForceMatcher <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 = watch.ElapsedMilliseconds;
        }
        //主要是在這端對比的
        public void FindMatch(Image <Gray, Byte> modelImage, Image <Gray, byte> observedImage, out long matchTime, out VectorOfKeyPoint modelKeyPoints,
                              out VectorOfKeyPoint observedKeyPoints, out Matrix <int> indices, out Matrix <byte> mask, out HomographyMatrix homography)
        {
            int          k = 2;
            double       uniquenessThreshold = 0.8;
            SURFDetector surfCPU             = new SURFDetector(500, false); //設定處理特徵值的方式
            Stopwatch    watch;                                              //監看處理時間

            homography = null;                                               //如果相同,取得四邊形

            //extract features from the object image
            modelKeyPoints = new VectorOfKeyPoint();
            Matrix <float> modelDescriptors = surfCPU.DetectAndCompute(modelImage, null, modelKeyPoints); //modelKeyPoints : 算出 特徵點? //modelDescriptors :



            // extract features from the observed image
            observedKeyPoints = new VectorOfKeyPoint();
            Matrix <float> observedDescriptors = surfCPU.DetectAndCompute(observedImage, null, observedKeyPoints); //observedKeyPoints : 取得特徵點 //

            //ImagePrecess processor = new ImagePrecess(observedImage.ToBitmap(),320,240);
            //observedDescriptors = processor.GetImageFeature();
            //observedKeyPoints=processor.GetImageVectorOfKeyPoint();


            watch = Stopwatch.StartNew();
            //
            BruteForceMatcher <float> matcher = new BruteForceMatcher <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);//會把剛剛match完的結果抓來看是不是不明確或是不確定的,而跑完的結果放在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 = watch.ElapsedMilliseconds;
        }
示例#3
0
        public StopSignDetector(Image <Bgr, Byte> stopSignModel)
        {
            _detector = new SURFDetector(500);
            using (Image <Gray, Byte> redMask = GetRedPixelMask(stopSignModel))
            {
                _modelKeypoints   = new VectorOfKeyPoint();
                _modelDescriptors = new Mat();
                _detector.DetectAndCompute(redMask, null, _modelKeypoints, _modelDescriptors, false);
                if (_modelKeypoints.Size == 0)
                {
                    throw new Exception("No image feature has been found in the stop sign model");
                }
            }

            _modelDescriptorMatcher = new BFMatcher(DistanceType.L2);
            _modelDescriptorMatcher.Add(_modelDescriptors);

            _octagon = new VectorOfPoint(
                new Point[]
            {
                new Point(1, 0),
                new Point(2, 0),
                new Point(3, 1),
                new Point(3, 2),
                new Point(2, 3),
                new Point(1, 3),
                new Point(0, 2),
                new Point(0, 1)
            });
        }
示例#4
0
        public void TestBOWKmeansTrainer()
        {
            Image <Gray, byte> box      = EmguAssert.LoadImage <Gray, byte>("box.png");
            SURFDetector       detector = new SURFDetector(500);
            VectorOfKeyPoint   kpts     = new VectorOfKeyPoint();
            Mat descriptors             = new Mat();

            detector.DetectAndCompute(box, null, kpts, descriptors, false);

            BOWKMeansTrainer trainer = new BOWKMeansTrainer(100, new MCvTermCriteria(), 3, CvEnum.KMeansInitType.PPCenters);

            trainer.Add(descriptors);
            Mat vocabulary = new Mat();

            trainer.Cluster(vocabulary);

            BFMatcher matcher = new BFMatcher(DistanceType.L2);

            BOWImgDescriptorExtractor extractor = new BOWImgDescriptorExtractor(detector, matcher);

            extractor.SetVocabulary(vocabulary);

            Mat descriptors2 = new Mat();

            extractor.Compute(box, kpts, descriptors2);
        }
        public void ProcessImage(Image <Gray, Byte> modelImage)
        {
            _modelKeyPoints = new VectorOfKeyPoint();
            _modelImage     = modelImage;
            SURFDetector surfCPU = new SURFDetector(500, false);

            _feature = surfCPU.DetectAndCompute(modelImage, null, _modelKeyPoints);
        }
示例#6
0
        public static Image <Bgr, Byte> DrawFeatures(Image <Gray, Byte> modelImage)
        {
            SURFDetector      surfCPU          = new SURFDetector(500, false);
            VectorOfKeyPoint  modelKeyPoints   = new VectorOfKeyPoint();
            Matrix <float>    modelDescriptors = surfCPU.DetectAndCompute(modelImage, null, modelKeyPoints);
            Image <Bgr, Byte> result           = Features2DToolbox.DrawKeypoints(modelImage, modelKeyPoints, new Bgr(0, 0, 255), Features2DToolbox.KeypointDrawType.DEFAULT);

            return(result);
        }
示例#7
0
        public void TestSURFBlankImage()
        {
            SURFDetector       detector = new SURFDetector(500);
            Image <Gray, Byte> img      = new Image <Gray, byte>(1024, 900);
            VectorOfKeyPoint   vp       = new VectorOfKeyPoint();
            Mat descriptors             = new Mat();

            detector.DetectAndCompute(img, null, vp, descriptors, false);
        }
示例#8
0
        private void SURFfeature(Image <Gray, Byte> modelImage, Image <Gray, byte> observedImage, out VectorOfKeyPoint modelKeyPoints, out VectorOfKeyPoint observedKeyPoints, out Matrix <int> indices, out Matrix <byte> mask, out HomographyMatrix homography)
        {
            int          k = 2;
            double       uniquenessThreshold = 0.8;
            SURFDetector surfCPU             = new SURFDetector(300, false);

            homography = null;

            //extract features from the object image
            modelKeyPoints = new VectorOfKeyPoint();
            Matrix <float> modelDescriptors = surfCPU.DetectAndCompute(modelImage, null, modelKeyPoints);

            // extract features from the observed image
            observedKeyPoints = new VectorOfKeyPoint();
            Matrix <float>            observedDescriptors = surfCPU.DetectAndCompute(observedImage, null, observedKeyPoints);
            BruteForceMatcher <float> matcher             = new BruteForceMatcher <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);
                }
            }
        }
示例#9
0
        public static void FindMatch(Image <Gray, Byte> modelImage, Image <Gray, byte> observedImage, out long matchTime, out VectorOfKeyPoint modelKeyPoints, out VectorOfKeyPoint observedKeyPoints, out Matrix <int> indices, out Matrix <byte> mask, out HomographyMatrix homography)
        {
            int          k = 2;
            double       uniquenessThreshold = 0.8;
            SURFDetector surfCPU             = new SURFDetector(500, false);
            Stopwatch    watch;

            homography = null;

            if (GpuInvoke.HasCuda)
            {
                GpuSURFDetector surfGPU = new GpuSURFDetector(surfCPU.SURFParams, 0.01f);
                using (GpuImage <Gray, Byte> gpuModelImage = new GpuImage <Gray, byte>(modelImage))
                    //extract features from the object image
                    using (GpuMat <float> gpuModelKeyPoints = surfGPU.DetectKeyPointsRaw(gpuModelImage, null))
                        using (GpuMat <float> gpuModelDescriptors = surfGPU.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints))
                            using (GpuBruteForceMatcher <float> matcher = new GpuBruteForceMatcher <float>(DistanceType.L2))
                            {
                                modelKeyPoints = new VectorOfKeyPoint();
                                surfGPU.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints);
                                watch = Stopwatch.StartNew();

                                // extract features from the observed image
                                using (GpuImage <Gray, Byte> gpuObservedImage = new GpuImage <Gray, byte>(observedImage))
                                    using (GpuMat <float> gpuObservedKeyPoints = surfGPU.DetectKeyPointsRaw(gpuObservedImage, null))
                                        using (GpuMat <float> 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 (Stream stream = new Stream())
                                                        {
                                                            matcher.KnnMatchSingle(gpuObservedDescriptors, gpuModelDescriptors, gpuMatchIndices, gpuMatchDist, k, null, stream);
                                                            indices = new Matrix <int>(gpuMatchIndices.Size);
                                                            mask    = new Matrix <byte>(gpuMask.Size);

                                                            //gpu implementation of voteForUniquess
                                                            using (GpuMat <float> col0 = gpuMatchDist.Col(0))
                                                                using (GpuMat <float> col1 = gpuMatchDist.Col(1))
                                                                {
                                                                    GpuInvoke.Multiply(col1, new MCvScalar(uniquenessThreshold), col1, stream);
                                                                    GpuInvoke.Compare(col0, col1, gpuMask, CMP_TYPE.CV_CMP_LE, stream);
                                                                }

                                                            observedKeyPoints = new VectorOfKeyPoint();
                                                            surfGPU.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints);

                                                            //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();

                                                            gpuMask.Download(mask);
                                                            gpuMatchIndices.Download(indices);

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

                                                            watch.Stop();
                                                        }
                            }
            }
            else
            {
                //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);
                BruteForceMatcher <float> matcher             = new BruteForceMatcher <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 = watch.ElapsedMilliseconds;
        }
示例#10
0
        private List <LoCaTeRanker> PerformExtendedSurfSearch(string queryImagePath, List <LoCaTeRanker> ImageList)
        {
            //If no images are found in Locate, return
            if (ImageList.Count == 0)
            {
                return(ImageList);
            }

            SURFDetector       surfDectector = new SURFDetector(1000, false);
            Matrix <float>     superMatrix   = null;
            List <SURFRecord1> observerSurfImageIndexList = new List <SURFRecord1>();

            #region Computing Model Descriptors
            Matrix <float>   modelDescriptors;
            VectorOfKeyPoint modelKeyPoints = new VectorOfKeyPoint();
            using (Image <Gray, byte> modelImage = new Image <Gray, byte>(queryImagePath))
            {
                modelDescriptors = surfDectector.DetectAndCompute(modelImage, null, modelKeyPoints);
            }
            #endregion

            #region Computing Surf Descriptors
            int rows = 0;

            int numProcs         = Environment.ProcessorCount;
            int concurrencyLevel = numProcs * 2;
            ConcurrentDictionary <long, Matrix <float> > obserableSurfPoints = new ConcurrentDictionary <long, Matrix <float> >(concurrencyLevel, ImageList.Count);

            Parallel.ForEach(ImageList, img =>
            {
                string imagePath = img.ImagePath;
                using (Image <Gray, byte> observerImage = new Image <Gray, byte>(imagePath))
                {
                    VectorOfKeyPoint observerKeyPoints = new VectorOfKeyPoint();
                    Matrix <float> observerDescriptors = surfDectector.DetectAndCompute(observerImage, null, observerKeyPoints);
                    obserableSurfPoints.TryAdd(img.Id, observerDescriptors);
                }
            });

            foreach (var rec in ImageList)
            {
                Matrix <float> observerDescriptors = obserableSurfPoints[rec.Id];
                if (superMatrix != null)
                {
                    superMatrix = superMatrix.ConcateVertical(observerDescriptors);
                }
                else
                {
                    superMatrix = observerDescriptors;
                }

                int initRow = rows; int endRows = rows + observerDescriptors.Rows - 1;
                observerSurfImageIndexList.Add(new SURFRecord1
                {
                    Id         = rec.Id,
                    ImageName  = rec.ImageName,
                    ImagePath  = rec.ImagePath,
                    IndexStart = rows,
                    IndexEnd   = endRows,
                    Distance   = 0
                });
                rows = endRows + 1;
            }

            //foreach (var rec in ImageList)
            //{
            //    string imagePath = rec.ImagePath;
            //    using (Image<Gray, byte> observerImage = new Image<Gray, byte>(imagePath))
            //    {
            //        VectorOfKeyPoint observerKeyPoints = new VectorOfKeyPoint();

            //        Matrix<float> observerDescriptors = surfDectector.DetectAndCompute(observerImage, null, observerKeyPoints);
            //        if (superMatrix != null)
            //            superMatrix = superMatrix.ConcateVertical(observerDescriptors);
            //        else
            //            superMatrix = observerDescriptors;

            //        int initRow = rows; int endRows = rows + observerDescriptors.Rows - 1;
            //        observerSurfImageIndexList.Add(new SURFRecord1
            //        {
            //            Id = rec.Id,
            //            ImageName = rec.ImageName,
            //            ImagePath = rec.ImagePath,
            //            IndexStart = rows,
            //            IndexEnd = endRows,
            //            Distance = 0
            //        });
            //        rows = endRows + 1;
            //    }
            //}
            #endregion

            Emgu.CV.Flann.Index flannIndex = new Emgu.CV.Flann.Index(superMatrix, 4);
            var indices = new Matrix <int>(modelDescriptors.Rows, 2);   // matrix that will contain indices of the 2-nearest neighbors found
            var dists   = new Matrix <float>(modelDescriptors.Rows, 2); // matrix that will contain distances to the 2-nearest neighbors found
            flannIndex.KnnSearch(modelDescriptors, indices, dists, 2, 24);

            IntervalTreeHelper.CreateTree(observerSurfImageIndexList);
            for (int i = 0; i < indices.Rows; i++)
            {
                // filter out all inadequate pairs based on distance between pairs
                if (dists.Data[i, 0] < (0.3 * dists.Data[i, 1]))
                {
                    var img = IntervalTreeHelper.GetImageforRange(indices[i, 0]);
                    if (img != null)
                    {
                        img.Distance++;
                    }
                }
            }
            int maxMatch = Convert.ToInt32(observerSurfImageIndexList.Select(rec => rec.Distance).Max());
            observerSurfImageIndexList = observerSurfImageIndexList.OrderByDescending(rec => rec.Distance).ToList();
            int totalImageCount = observerSurfImageIndexList.Count;
            for (int i = 0; i < totalImageCount; i++)
            {
                long id   = observerSurfImageIndexList[i].Id;
                var  img2 = ImageList.Where(img => img.Id == id).SingleOrDefault();
                if (img2 != null)
                {
                    double countofMatch = observerSurfImageIndexList[i].Distance;
                    if (countofMatch > 0)
                    {
                        img2.SurfRank = (totalImageCount - i);
                    }
                }
            }

            return(ImageList);
        }
示例#11
0
        public Image <Bgr, float> alignment(Image <Bgr, float> fImage, Image <Bgr, float> lImage)
        {
            HomographyMatrix homography = null;
            SURFDetector     surfCPU    = new SURFDetector(500, false);
            VectorOfKeyPoint modelKeyPoints;
            VectorOfKeyPoint observedKeyPoints;
            Matrix <int>     indices;

            Matrix <byte> mask;

            int    k = 2;
            double uniquenessThreshold = 0.8;


            Image <Gray, Byte> fImageG = fImage.Convert <Gray, Byte>();
            Image <Gray, Byte> lImageG = lImage.Convert <Gray, Byte>();

            //extract features from the object image
            modelKeyPoints = new VectorOfKeyPoint();
            Matrix <float> modelDescriptors = surfCPU.DetectAndCompute(fImageG, null, modelKeyPoints);


            // extract features from the observed image
            observedKeyPoints = new VectorOfKeyPoint();
            Matrix <float>            observedDescriptors = surfCPU.DetectAndCompute(lImageG, null, observedKeyPoints);
            BruteForceMatcher <float> matcher             = new BruteForceMatcher <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);
                }
            }
            Image <Bgr, Byte> result = Features2DToolbox.DrawMatches(fImageG, modelKeyPoints, lImageG, observedKeyPoints,
                                                                     indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT);

            if (homography != null)
            {
                //draw a rectangle along the projected model
                Rectangle rect = fImageG.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)
                };
                homography.ProjectPoints(pts);

                result.DrawPolyline(Array.ConvertAll <PointF, Point>(pts, Point.Round), true, new Bgr(Color.Red), 5);

                Image <Bgr, byte>  mosaic     = new Image <Bgr, byte>(fImageG.Width + fImageG.Width, fImageG.Height);
                Image <Bgr, byte>  warp_image = mosaic.Clone();
                Image <Bgr, float> result2    = new Image <Bgr, float>(fImage.Size);
                Image <Gray, Byte> result3    = new Image <Gray, Byte>(fImage.Size);
                CvInvoke.cvWarpPerspective(fImage.Ptr, result2, homography.Ptr, (int)INTER.CV_INTER_CUBIC + (int)WARP.CV_WARP_FILL_OUTLIERS, new MCvScalar(0));
                return(result2);
            }
            return(null);
        }
示例#12
0
        public static void FindMatch(Image <Gray, Byte> modelImage, Image <Gray, byte> observedImage, out long matchTime, out VectorOfKeyPoint modelKeyPoints, out VectorOfKeyPoint observedKeyPoints, VectorOfVectorOfDMatch matches, out Matrix <byte> mask, out HomographyMatrix homography)
        {
            int    k = 2;
            double uniquenessThreshold = 0.8;
            double hessianThresh       = 300;

            Stopwatch watch;

            homography = null;

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

         #if !IOS
            if (CudaInvoke.HasCuda)
            {
                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 (CudaBruteForceMatcher matcher = new CudaBruteForceMatcher(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 Matrix <byte>(matches.Size, 1);
                                            mask.SetValue(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
         #endif
            {
                using (UMat uModelImage = modelImage.Mat.ToUMat(AccessType.Read))
                    using (UMat uObservedImage = observedImage.Mat.ToUMat(AccessType.Read))
                    {
                        SURFDetector surfCPU = new SURFDetector(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);
                        BruteForceMatcher matcher = new BruteForceMatcher(DistanceType.L2);
                        matcher.Add(modelDescriptors);

                        matcher.KnnMatch(observedDescriptors, matches, k, null);
                        mask = new Matrix <byte>(matches.Size, 1);
                        mask.SetValue(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();
                    }
            }
            matchTime = watch.ElapsedMilliseconds;
        }
示例#13
0
        private void FindStopSign(Image <Bgr, byte> img, List <Image <Gray, Byte> > stopSignList, List <Rectangle> boxList, VectorOfVectorOfPoint contours, int[,] hierachy, int idx)
        {
            for (; idx >= 0; idx = hierachy[idx, 0])
            {
                using (VectorOfPoint c = contours[idx])
                    using (VectorOfPoint approx = new VectorOfPoint())
                    {
                        CvInvoke.ApproxPolyDP(c, approx, CvInvoke.ArcLength(c, true) * 0.02, true);
                        double area = CvInvoke.ContourArea(approx);
                        if (area > 200)
                        {
                            double ratio = CvInvoke.MatchShapes(_octagon, approx, Emgu.CV.CvEnum.ContoursMatchType.I3);

                            if (ratio > 0.1) //not a good match of contour shape
                            {
                                //check children
                                if (hierachy[idx, 2] >= 0)
                                {
                                    FindStopSign(img, stopSignList, boxList, contours, hierachy, hierachy[idx, 2]);
                                }
                                continue;
                            }

                            Rectangle box = CvInvoke.BoundingRectangle(c);

                            Image <Gray, Byte> candidate;
                            using (Image <Bgr, Byte> tmp = img.Copy(box))
                                candidate = tmp.Convert <Gray, byte>();
                            //Emgu.CV.UI.ImageViewer.Show(candidate);
                            //set the value of pixels not in the contour region to zero
                            using (Image <Gray, Byte> mask = new Image <Gray, byte>(box.Size))
                            {
                                mask.Draw(contours, idx, new Gray(255), -1, LineType.EightConnected, null, int.MaxValue, new Point(-box.X, -box.Y));

                                double mean = CvInvoke.Mean(candidate, mask).V0;
                                candidate._ThresholdBinary(new Gray(mean), new Gray(255.0));
                                candidate._Not();
                                mask._Not();
                                candidate.SetValue(0, mask);
                            }

                            int              minMatchCount         = 8;
                            double           uniquenessThreshold   = 0.8;
                            VectorOfKeyPoint _observeredKeypoint   = new VectorOfKeyPoint();
                            Mat              _observeredDescriptor = new Mat();
                            _detector.DetectAndCompute(candidate, null, _observeredKeypoint, _observeredDescriptor, false);

                            if (_observeredKeypoint.Size >= minMatchCount)
                            {
                                int k = 2;
                                //Matrix<int> indices = new Matrix<int>(_observeredDescriptor.Size.Height, k);
                                Mat mask;
                                //using (Matrix<float> dist = new Matrix<float>(_observeredDescriptor.Size.Height, k))
                                using (VectorOfVectorOfDMatch matches = new VectorOfVectorOfDMatch())
                                {
                                    _modelDescriptorMatcher.KnnMatch(_observeredDescriptor, 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 >= minMatchCount)
                                {
                                    boxList.Add(box);
                                    stopSignList.Add(candidate);
                                }
                            }
                        }
                    }
            }
        }
示例#14
0
        private Image <Bgr, byte> Match(Image <Bgr, byte> image1, Image <Bgr, byte> image2, int flag)
        {
            HomographyMatrix homography      = null;
            SURFDetector     surfDetectorCPU = new SURFDetector(500, false);

            int    k = 2;           //number of matches that we want ot find between image1 and image2
            double uniquenessThreshold = 0.8;

            Matrix <int>  indices;
            Matrix <byte> mask;

            VectorOfKeyPoint KeyPointsImage1;
            VectorOfKeyPoint KeyPointsImage2;

            Image <Gray, Byte> Image1G = image1.Convert <Gray, Byte>();
            Image <Gray, Byte> Image2G = image2.Convert <Gray, Byte>();

            if (GpuInvoke.HasCuda)      //Using CUDA, the GPUs can be used for general purpose processing (i.e., not exclusively graphics), speed up performance
            {
                Console.WriteLine("Here");
                GpuSURFDetector surfDetectorGPU = new GpuSURFDetector(surfDetectorCPU.SURFParams, 0.01f);

                // extract features from Image1
                using (GpuImage <Gray, Byte> gpuImage1 = new GpuImage <Gray, byte>(Image1G))                                                     //convert CPU input image to GPUImage(greyscale)
                    using (GpuMat <float> gpuKeyPointsImage1 = surfDetectorGPU.DetectKeyPointsRaw(gpuImage1, null))                              //find key points for image
                        using (GpuMat <float> gpuDescriptorsImage1 = surfDetectorGPU.ComputeDescriptorsRaw(gpuImage1, null, gpuKeyPointsImage1)) //calculate descriptor for each key point
                            using (GpuBruteForceMatcher <float> matcher = new GpuBruteForceMatcher <float>(DistanceType.L2))                     //create a new matcher object
                            {
                                KeyPointsImage1 = new VectorOfKeyPoint();
                                surfDetectorGPU.DownloadKeypoints(gpuKeyPointsImage1, KeyPointsImage1);                                 //copy the Matrix from GPU to CPU

                                // extract features from Image2
                                using (GpuImage <Gray, Byte> gpuImage2 = new GpuImage <Gray, byte>(Image2G))
                                    using (GpuMat <float> gpuKeyPointsImage2 = surfDetectorGPU.DetectKeyPointsRaw(gpuImage2, null))
                                        using (GpuMat <float> gpuDescriptorsImage2 = surfDetectorGPU.ComputeDescriptorsRaw(gpuImage2, null, gpuKeyPointsImage2))

                                            //for each descriptor of each image2 , we find k best matching points and their distances from image1 descriptors

                                            using (GpuMat <int> gpuMatchIndices = new GpuMat <int>(gpuDescriptorsImage2.Size.Height, k, 1, true))      //stores indices of k best mathces
                                                using (GpuMat <float> gpuMatchDist = new GpuMat <float>(gpuDescriptorsImage2.Size.Height, k, 1, true)) //stores distance of k best matches

                                                    using (GpuMat <Byte> gpuMask = new GpuMat <byte>(gpuMatchIndices.Size.Height, 1, 1))               //stores result of comparison
                                                        using (Stream stream = new Stream())
                                                        {
                                                            matcher.KnnMatchSingle(gpuDescriptorsImage2, gpuDescriptorsImage1, gpuMatchIndices, gpuMatchDist, k, null, stream); //matching descriptors of image2 to image1 and storing the k best indices and corresponding distances

                                                            indices = new Matrix <int>(gpuMatchIndices.Size);
                                                            mask    = new Matrix <byte>(gpuMask.Size);

                                                            //gpu implementation of voteForUniquess
                                                            using (GpuMat <float> col0 = gpuMatchDist.Col(0))
                                                                using (GpuMat <float> col1 = gpuMatchDist.Col(1))
                                                                {
                                                                    GpuInvoke.Multiply(col1, new MCvScalar(uniquenessThreshold), col1, stream); //by setting stream, we perform an Async Task
                                                                    GpuInvoke.Compare(col0, col1, gpuMask, CMP_TYPE.CV_CMP_LE, stream);         //col0 >= 0.8col1 , only then is it considered a good match
                                                                }

                                                            KeyPointsImage2 = new VectorOfKeyPoint();
                                                            surfDetectorGPU.DownloadKeypoints(gpuKeyPointsImage2, KeyPointsImage2);

                                                            //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();

                                                            gpuMask.Download(mask);
                                                            gpuMatchIndices.Download(indices);

                                                            if (GpuInvoke.CountNonZero(gpuMask) >= 4)
                                                            {
                                                                int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(KeyPointsImage1, KeyPointsImage2, indices, mask, 1.5, 20); //count the number of nonzero points in the mask(this stored the comparison result of col0 >= 0.8col1)
                                                                //we can create a homography matrix only if we have atleast 4 matching points
                                                                if (nonZeroCount >= 4)
                                                                {
                                                                    homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(KeyPointsImage1, KeyPointsImage2, indices, mask, 2);
                                                                }
                                                            }
                                                        }
                            }
            }
            else
            {
                Console.WriteLine("No CUDA");
                //extract features from image2
                KeyPointsImage1 = new VectorOfKeyPoint();
                Matrix <float> DescriptorsImage1 = surfDetectorCPU.DetectAndCompute(Image1G, null, KeyPointsImage1);

                //extract features from image1
                KeyPointsImage2 = new VectorOfKeyPoint();
                Matrix <float>            DescriptorsImage2 = surfDetectorCPU.DetectAndCompute(Image2G, null, KeyPointsImage2);
                BruteForceMatcher <float> matcher           = new BruteForceMatcher <float>(DistanceType.L2);
                matcher.Add(DescriptorsImage1);

                indices = new Matrix <int>(DescriptorsImage2.Rows, k);
                using (Matrix <float> dist = new Matrix <float>(DescriptorsImage2.Rows, k))
                {
                    matcher.KnnMatch(DescriptorsImage2, 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(KeyPointsImage1, KeyPointsImage2, indices, mask, 1.5, 20);
                    if (nonZeroCount >= 4)
                    {
                        homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(KeyPointsImage1, KeyPointsImage2, indices, mask, 2);
                    }
                }
            }
            Image <Bgr, Byte> mImage = image1.Convert <Bgr, Byte>();
            Image <Bgr, Byte> oImage = image2.Convert <Bgr, Byte>();
            Image <Bgr, Byte> result = new Image <Bgr, byte>(mImage.Width + oImage.Width, mImage.Height);

            //Image<Bgr, Byte> temp = Features2DToolbox.DrawMatches(image1, KeyPointsImage1, image2, KeyPointsImage2, indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT);

            if (homography != null)
            {  //draw a rectangle along the projected model
                Rectangle rect = image1.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)
                };

                homography.ProjectPoints(pts);

                HomographyMatrix origin = new HomographyMatrix();                //I perform a copy of the left image with a not real shift operation on the origin
                origin.SetIdentity();
                origin.Data[0, 2] = 0;
                origin.Data[1, 2] = 0;
                Image <Bgr, Byte> mosaic = new Image <Bgr, byte>(mImage.Width + oImage.Width, mImage.Height * 2);

                Image <Bgr, byte> warp_image = mosaic.Clone();
                mosaic = mImage.WarpPerspective(origin, mosaic.Width, mosaic.Height, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR, Emgu.CV.CvEnum.WARP.CV_WARP_DEFAULT, new Bgr(0, 0, 0));

                warp_image = oImage.WarpPerspective(homography, warp_image.Width, warp_image.Height, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR, Emgu.CV.CvEnum.WARP.CV_WARP_INVERSE_MAP, new Bgr(200, 0, 0));
                Image <Gray, byte> warp_image_mask = oImage.Convert <Gray, byte>();
                warp_image_mask.SetValue(new Gray(255));
                Image <Gray, byte> warp_mosaic_mask = mosaic.Convert <Gray, byte>();
                warp_mosaic_mask.SetZero();
                warp_mosaic_mask = warp_image_mask.WarpPerspective(homography, warp_mosaic_mask.Width, warp_mosaic_mask.Height, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR, Emgu.CV.CvEnum.WARP.CV_WARP_INVERSE_MAP, new Gray(0));

                warp_image.Copy(mosaic, warp_mosaic_mask);
                if (flag == 1)
                {
                    Console.WriteLine("Using Image Blending");
                    return(blend(mosaic, warp_image, warp_mosaic_mask, 2));
                }
                else
                {
                    Console.WriteLine("No Image Blending");
                    return(mosaic);
                }
            }
            return(null);
        }
示例#15
0
        public List <ImageRecord> QueryImage(string queryImagePath, out string messageToLog, SurfSettings surfSetting = null)
        {
            List <ImageRecord> rtnImageList = new List <ImageRecord>();

            #region Diagnostic Region
            Stopwatch sw = new Stopwatch();
            long      IndexingTime = 0; long QueryingTime = 0; long LoopTime = 0;
            #endregion Diagnostic Region

            SurfDataSet observerDataset = SurfRepository.GetSurfDataSet();
            if (observerDataset == null)
            {
                throw new InvalidOperationException("Can't get the Surf Index, please index first");
            }

            #region Surf Dectator Region
            double hessianThresh       = 500;
            double uniquenessThreshold = 0.8;

            if (surfSetting != null)
            {
                hessianThresh       = surfSetting.HessianThresh.Value;
                uniquenessThreshold = surfSetting.UniquenessThreshold.Value;
            }

            SURFDetector surfDectector = new SURFDetector(hessianThresh, false);
            #endregion Surf Dectator Region



            Matrix <float> modelDescriptors;


            using (Image <Gray, byte> modelImage = new Image <Gray, byte>(queryImagePath))
            {
                VectorOfKeyPoint modelKeyPoints = new VectorOfKeyPoint();
                modelDescriptors = surfDectector.DetectAndCompute(modelImage, null, modelKeyPoints);
                if (modelDescriptors.Rows < 4)
                {
                    throw new InvalidOperationException("Model image didn't have any significant features to detect");
                }
                Matrix <float> superMatrix = observerDataset.SuperMatrix;

                sw.Start();
                Emgu.CV.Flann.Index flannIndex;
                if (!SurfRepository.Exists("flannIndex"))
                {
                    flannIndex = new Emgu.CV.Flann.Index(superMatrix, 4);
                    SurfRepository.AddFlannIndex(flannIndex, "flannIndex");
                }
                else
                {
                    flannIndex = SurfRepository.GetFlannIndex("flannIndex");
                }

                sw.Stop(); IndexingTime = sw.ElapsedMilliseconds; sw.Reset();

                var indices = new Matrix <int>(modelDescriptors.Rows, 2);   // matrix that will contain indices of the 2-nearest neighbors found
                var dists   = new Matrix <float>(modelDescriptors.Rows, 2); // matrix that will contain distances to the 2-nearest neighbors found

                sw.Start();
                flannIndex.KnnSearch(modelDescriptors, indices, dists, 2, 24);
                sw.Stop(); QueryingTime = sw.ElapsedMilliseconds; sw.Reset();

                List <SURFRecord1> imageList = observerDataset.SurfImageIndexRecord;
                imageList.ForEach(x => x.Distance = 0);

                //Create Interval Tree for Images
                IntervalTreeHelper.CreateTree(imageList);


                sw.Start();
                for (int i = 0; i < indices.Rows; i++)
                {
                    // filter out all inadequate pairs based on distance between pairs
                    if (dists.Data[i, 0] < (uniquenessThreshold * dists.Data[i, 1]))
                    {
                        var img = IntervalTreeHelper.GetImageforRange(indices[i, 0]);
                        if (img != null)
                        {
                            img.Distance++;
                        }
                    }
                }
                sw.Stop(); LoopTime = sw.ElapsedMilliseconds;

                string msg = String.Format("Indexing: {0}, Querying: {1}, Looping: {2}", IndexingTime, QueryingTime, LoopTime);
                messageToLog = msg;

                rtnImageList = imageList.Where(x => x.Distance > surfSetting.GoodMatchThreshold).OrderByDescending(x => x.Distance).Select(x => (ImageRecord)x).ToList();
            }



            return(rtnImageList);
        }
示例#16
0
        public void IndexFiles(FileInfo[] imageFiles, System.ComponentModel.BackgroundWorker IndexBgWorker,
                               Action <string> logWriter,
                               SurfSettings surfSetting = null)
        {
            #region Surf Dectator Region
            double hessianThresh       = 500;
            double uniquenessThreshold = 0.8;

            if (surfSetting != null)
            {
                hessianThresh       = surfSetting.HessianThresh.Value;
                uniquenessThreshold = surfSetting.UniquenessThreshold.Value;
            }

            SURFDetector surfDectector = new SURFDetector(hessianThresh, false);
            #endregion

            int rows = 0;

            Matrix <float>     superMatrix = null;
            List <SURFRecord1> observerSurfImageIndexList = new List <SURFRecord1>();

            Stopwatch sw1, sw2;

            sw1 = Stopwatch.StartNew();
            logWriter("Index started...");
            int totalFileCount = imageFiles.Length;
            for (int i = 0; i < totalFileCount; i++)
            {
                var fi = imageFiles[i];
                using (Image <Gray, byte> observerImage = new Image <Gray, byte>(fi.FullName))
                {
                    VectorOfKeyPoint observerKeyPoints  = new VectorOfKeyPoint();
                    Matrix <float>   observerDescriptor = surfDectector.DetectAndCompute(observerImage, null, observerKeyPoints);

                    if (observerDescriptor.Rows > 4)
                    {
                        int initRow = rows; int endRows = rows + observerDescriptor.Rows - 1;

                        SURFRecord1 record = new SURFRecord1
                        {
                            Id         = i,
                            ImageName  = fi.Name,
                            ImagePath  = fi.FullName,
                            IndexStart = rows,
                            IndexEnd   = endRows
                        };

                        observerSurfImageIndexList.Add(record);

                        if (superMatrix == null)
                        {
                            superMatrix = observerDescriptor;
                        }
                        else
                        {
                            superMatrix = superMatrix.ConcateVertical(observerDescriptor);
                        }

                        rows = endRows + 1;
                    }
                    else
                    {
                        Debug.WriteLine(fi.Name + " skip from index, because it didn't have significant feature");
                    }
                }
                IndexBgWorker.ReportProgress(i);
            }
            sw1.Stop();
            logWriter(string.Format("Index Complete, it tooked {0} ms. Saving Repository...", sw1.ElapsedMilliseconds));
            SurfDataSet surfDataset = new SurfDataSet
            {
                SurfImageIndexRecord = observerSurfImageIndexList,
                SuperMatrix          = superMatrix
            };
            sw2 = Stopwatch.StartNew();
            SurfRepository.AddSuperMatrixList(surfDataset);
            SurfRepository.SaveRepository(SurfAlgo.Flaan);
            sw2.Stop();

            logWriter(string.Format("Index tooked {0} ms. Saving Repository tooked {1} ms", sw1.ElapsedMilliseconds, sw2.ElapsedMilliseconds));
        }
示例#17
0
        public void TestSURFDetector2()
        {
            //Trace.WriteLine("Size of MCvSURFParams: " + Marshal.SizeOf(typeof(MCvSURFParams)));
            Image <Gray, byte> box      = EmguAssert.LoadImage <Gray, byte>("box.png");
            SURFDetector       detector = new SURFDetector(400);

            Stopwatch        watch = Stopwatch.StartNew();
            VectorOfKeyPoint vp1   = new VectorOfKeyPoint();
            Mat descriptors1       = new Mat();

            detector.DetectAndCompute(box, null, vp1, descriptors1, false);
            watch.Stop();
            EmguAssert.WriteLine(String.Format("Time used: {0} milliseconds.", watch.ElapsedMilliseconds));

            watch.Reset();
            watch.Start();
            MKeyPoint[] keypoints = detector.Detect(box, null);
            //ImageFeature<float>[] features2 = detector.Compute(box, keypoints);
            watch.Stop();
            EmguAssert.WriteLine(String.Format("Time used: {0} milliseconds.", watch.ElapsedMilliseconds));

            watch.Reset();
            watch.Start();
            //MCvSURFParams p = detector.SURFParams;

            //SURFFeature[] features3 = box.ExtractSURF(ref p);
            //watch.Stop();
            //EmguAssert.WriteLine(String.Format("Time used: {0} milliseconds.", watch.ElapsedMilliseconds));

            // EmguAssert.IsTrue(features1.Length == features2.Length);
            //EmguAssert.IsTrue(features2.Length == features3.Length);

            PointF[] pts =
#if NETFX_CORE
                Extensions.
#else
                Array.
#endif
                ConvertAll <MKeyPoint, PointF>(keypoints, delegate(MKeyPoint mkp)
            {
                return(mkp.Point);
            });
            //SURFFeature[] features = box.ExtractSURF(pts, null, ref detector);
            //int count = features.Length;

            /*
             * for (int i = 0; i < features1.Length; i++)
             * {
             * Assert.AreEqual(features1[i].KeyPoint.Point, features2[i].KeyPoint.Point);
             * float[] d1 = features1[i].Descriptor;
             * float[] d2 = features2[i].Descriptor;
             *
             * for (int j = 0; j < d1.Length; j++)
             *    Assert.AreEqual(d1[j], d2[j]);
             * }*/

            foreach (MKeyPoint kp in keypoints)
            {
                box.Draw(new CircleF(kp.Point, kp.Size), new Gray(255), 1);
            }
        }