예제 #1
1
        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;
        }
예제 #2
0
        private void QuerySurfAlgo(string queryImagePath)
        {
            WriteQueryStatus("Start querying...");
            SaveSurfSettingValues();
            SurfSettings       surfSetting = GetSurfSetting();
            List <ImageRecord> searchImage = new List <ImageRecord>();
            bool didRepoLoadingtookplace   = false;
            long repoLoadingTimeInMs       = 0;

            if (!SurfRepository.IsRepositoryInMemoryLoaded(surfSetting.Algorithm))
            {
                didRepoLoadingtookplace = true;
                WriteQueryStatus("Loading Repository in memory...");
                _stopWatch = Stopwatch.StartNew();
                SurfRepository.LoadRespositoryFromFile(surfSetting.Algorithm);
                _stopWatch.Stop();
                repoLoadingTimeInMs = _stopWatch.ElapsedMilliseconds;
                WriteQueryStatus(string.Format("Repository loading took {0} ms", repoLoadingTimeInMs));
            }

            string msg;

            if (surfSetting.Algorithm == SurfAlgo.Linear)
            {
                SurfQuery2 surfQuery = new SurfQuery2();
                _stopWatch  = Stopwatch.StartNew();
                searchImage = surfQuery.QueryImage(queryImagePath, surfSetting);
                _stopWatch.Stop();
                if (didRepoLoadingtookplace)
                {
                    msg = string.Format("Loading tooked {0} ms, quering tooked {1} ms", repoLoadingTimeInMs, _stopWatch.ElapsedMilliseconds);
                }
                else
                {
                    msg = string.Format("Image Query Completed, it took {0} ms", _stopWatch.ElapsedMilliseconds);
                }
                WriteQueryStatus(msg);
            }
            else if (surfSetting.Algorithm == SurfAlgo.Flaan)
            {
                SurfQuery1 surfQuery = new SurfQuery1();
                _stopWatch  = Stopwatch.StartNew();
                searchImage = surfQuery.QueryImage(queryImagePath, out msg, surfSetting);
                _stopWatch.Stop();
                if (didRepoLoadingtookplace)
                {
                    msg = string.Format("Loading Repo: {0} ms, Quering Total {1} ms, Details - ", repoLoadingTimeInMs, _stopWatch.ElapsedMilliseconds) + msg;
                }
                else
                {
                    msg += string.Format(" Total {0} ms", _stopWatch.ElapsedMilliseconds);
                }
                WriteQueryStatus(msg);
            }
            this.Dispatcher.Invoke(() =>
            {
                ImageList.ItemsSource = searchImage;
                lblTotalCount.Text    = searchImage.Count.ToString();
            });
        }
예제 #3
0
        private void QueryAccordSurfAlgo(string queryImagePath)
        {
            WriteQueryStatus("Start querying...");
            SaveSurfSettingValues();
            List <ImageRecord> searchImage = new List <ImageRecord>();
            SurfSettings       surfSetting = GetSurfSetting();
            string             msg;

            if (surfSetting.Algorithm == SurfAlgo.Linear)
            {
                SurfQuery4 surfQuery = new SurfQuery4();
                _stopWatch  = Stopwatch.StartNew();
                searchImage = surfQuery.QueryImage(queryImagePath, out msg, surfSetting);
                _stopWatch.Stop();
            }
            else
            {
                SurfQuery3 surfQuery = new SurfQuery3();
                _stopWatch  = Stopwatch.StartNew();
                searchImage = surfQuery.QueryImage(queryImagePath, out msg, surfSetting);
                _stopWatch.Stop();
            }
            msg += string.Format(" Total {0} ms", _stopWatch.ElapsedMilliseconds);
            WriteQueryStatus(msg);
            this.Dispatcher.Invoke(() =>
            {
                ImageList.ItemsSource = searchImage;
                lblTotalCount.Text    = searchImage.Count.ToString();
            });
        }
예제 #4
0
        private void AccordSurfAlgoIndexing(SurfSettings surfSetting)
        {
            var imageFiles     = getFiles(IndexDirectory, "*.gif|*.jpg|*.png|*.bmp|*.jpeg", SearchOption.TopDirectoryOnly);
            int totalFileCount = imageFiles.Length;

            Dispatcher.Invoke((Action) delegate
            {
                pbIndex.Minimum = 0; pbIndex.Maximum = totalFileCount; lblIndexStatus.Text = "Indexing..";
            });

            if (surfSetting.Algorithm == SurfAlgo.Linear)
            {
                SurfIndexer4 surfIndexer = new SurfIndexer4();
                if (ExecInParallel)
                {
                    surfIndexer.IndexFilesAsync(imageFiles, IndexBgWorker, WriteIndexStatus, surfSetting);
                }
                else
                {
                    surfIndexer.IndexFiles(imageFiles, IndexBgWorker, WriteIndexStatus, surfSetting);
                }
            }
            else
            {
                SurfIndexer3 surfIndexer = new SurfIndexer3();
                if (ExecInParallel)
                {
                    surfIndexer.IndexFilesAsync(imageFiles, IndexBgWorker, WriteIndexStatus, surfSetting);
                }
                else
                {
                    surfIndexer.IndexFiles(imageFiles, IndexBgWorker, WriteIndexStatus, surfSetting);
                }
            }
        }
예제 #5
0
        private void mnuOpenSurfDetail_Click(object sender, RoutedEventArgs e)
        {
            string   selectedObserverImage = string.Empty;
            string   selectedModelImage    = string.Empty;
            MenuItem mnu            = sender as MenuItem;
            Border   selectedBorder = null;

            if (mnu != null)
            {
                selectedBorder        = ((ContextMenu)mnu.Parent).PlacementTarget as Border;
                selectedObserverImage = (string)selectedBorder.Tag;
            }
            selectedModelImage = QueryImageFullPath;
            bool isObserverImagePathFound = !string.IsNullOrWhiteSpace(selectedObserverImage);

            isObserverImagePathFound = isObserverImagePathFound && File.Exists(selectedObserverImage);
            bool isModelImagePathFound = !string.IsNullOrWhiteSpace(selectedModelImage);

            isModelImagePathFound = isObserverImagePathFound && File.Exists(selectedModelImage);


            if (isObserverImagePathFound & isModelImagePathFound)
            {
                SurfSettings surfSetting = GetSurfSetting();
                if (SelectedAlgo == emAlgo.SURF)
                {
                    DrawSurfMatches.MatchInWindow(selectedModelImage, selectedObserverImage, surfSetting);
                }
                else
                {
                    AccordSurfWindow win = new AccordSurfWindow(selectedModelImage, selectedObserverImage, surfSetting);
                    win.Show();
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Draw the model image and observed image, the matched features and homography projection.
        /// </summary>
        /// <param name="modelImage">The model image</param>
        /// <param name="observedImage">The observed image</param>
        /// <param name="matchTime">The output total time for computing the homography matrix.</param>
        /// <returns>The model image and observed image, the matched features and homography projection.</returns>
        private static Image<Bgr, Byte> Draw(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage, SurfSettings surfSettings, out long matchTime)
        {
            HomographyMatrix homography;
            VectorOfKeyPoint modelKeyPoints;
            VectorOfKeyPoint observedKeyPoints;
            Matrix<int> indices;
            Matrix<byte> mask;

            FindMatch(modelImage, observedImage, surfSettings, out matchTime, out modelKeyPoints, out observedKeyPoints, out indices, out mask, out homography);

            //Draw the matched keypoints
            Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints,
               indices, new Bgr(255, 0, 0), new Bgr(255, 255, 0), mask, Features2DToolbox.KeypointDrawType.DEFAULT);

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

            return result;
        }
예제 #7
0
 public AccordSurfWindow(string modelImagePath, string observerImagePath, SurfSettings setting)
     : this()
 {
     this.ModelImagePath = modelImagePath;
     this.ObserverImagePath = observerImagePath;
     this.SurfSetting = setting;
 }
예제 #8
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

            List <SURFRecord2> surfRecord2List = new List <SURFRecord2>();
            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))
                {
                    ImageFeature <float>[] observerFeatures = surfDectector.DetectFeatures(observerImage, null);

                    if (observerFeatures.Length > 4)
                    {
                        SURFRecord2 record = new SURFRecord2
                        {
                            Id               = i,
                            ImageName        = fi.Name,
                            ImagePath        = fi.FullName,
                            observerFeatures = observerFeatures
                        };
                        surfRecord2List.Add(record);
                    }
                    else
                    {
                        Debug.WriteLine(fi.Name + " skip from index, because it didn't have significant feature");
                    }
                }
                IndexBgWorker.ReportProgress(i);
            }
            SurfRepository.AddSURFRecord2List(surfRecord2List);
            sw1.Stop();
            logWriter(string.Format("Index Complete, it tooked {0} ms. Saving Repository...", sw1.ElapsedMilliseconds));

            sw2 = Stopwatch.StartNew();
            SurfRepository.SaveRepository(SurfAlgo.Linear);
            sw2.Stop();

            logWriter(string.Format("Index tooked {0} ms. Saving Repository tooked {1} ms", sw1.ElapsedMilliseconds, sw2.ElapsedMilliseconds));
        }
예제 #9
0
 public static void MatchInWindow(string modelImagePath, string observedImagePath, SurfSettings surfSettings)
 {
     long matchTime;
     using (Image<Gray, Byte> modelImage = new Image<Gray, byte>(modelImagePath))
     using (Image<Gray, Byte> observedImage = new Image<Gray, byte>(observedImagePath))
     {
         Image<Bgr, byte> result = Draw(modelImage, observedImage, surfSettings, out matchTime);
         ImageViewer.Show(result, String.Format("Matched using {0} in {1} milliseconds", GpuInvoke.HasCuda ? "GPU" : "CPU", matchTime));
     }
 }
예제 #10
0
        private SurfSettings GetSurfSetting()
        {
            SurfSettings surfSetting = new SurfSettings();

            this.Dispatcher.Invoke(() =>
            {
                surfSetting.HessianThresh       = Convert.ToDouble((cmbSurfThreshold.SelectedItem as ListBoxItem).Content);
                surfSetting.UniquenessThreshold = nudsurfUniqueThreshold.Value;
                surfSetting.GoodMatchThreshold  = nudsurfGoodMatchThreshold.Value;
                surfSetting.Algorithm           = (SurfAlgo)cmbSurfApproach.SelectedIndex;
            });

            return(surfSetting);
        }
예제 #11
0
        private void btnIndex_Click(object sender, RoutedEventArgs e)
        {
            btnIndex.IsEnabled = false;
            if (SelectedAlgo == emAlgo.SURF || SelectedAlgo == emAlgo.AccordSurf)
            {
                //Save Settings
                SaveSurfSettingValues();

                //Pass Surf Settings
                SurfSettings surfSetting = GetSurfSetting();

                IndexBgWorker.RunWorkerAsync(surfSetting);
            }
            else if (SelectedAlgo == emAlgo.Locate)
            {
                LocateSettings locateSetting = GetLocateSetting();
                SaveLocateSetting();
                IndexBgWorker.RunWorkerAsync(locateSetting);
            }
            else
            {
                IndexBgWorker.RunWorkerAsync();
            }
        }
예제 #12
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));
        }
예제 #13
0
 public void CalculateSurfDescriptor(Image img, SurfSettings surfSetting)
 {
 }
예제 #14
0
        public void IndexFiles(FileInfo[] imageFiles, System.ComponentModel.BackgroundWorker IndexBgWorker,
            Action<string> logWriter,
            SurfSettings surfSetting = null)
        {
            //For Time Profilling
            long readingTime, indexingTime, saveingTime;

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

            if (surfSetting != null)
            {
                hessianThresh = surfSetting.HessianThresh.Value;
                uniquenessThreshold = surfSetting.UniquenessThreshold.Value;
            }
            float hessianThreshold2 = (float)hessianThresh / 1000000;
            SpeededUpRobustFeaturesDetector surf = new SpeededUpRobustFeaturesDetector(hessianThreshold2);
            #endregion

            int rows = 0;

            List<SURFRecord1> observerSurfImageIndexList = new List<SURFRecord1>();
            List<SpeededUpRobustFeaturePoint> listOfAllObserverImagesSurfPoints = new List<SpeededUpRobustFeaturePoint>();
            Stopwatch sw1;

            sw1 = Stopwatch.StartNew();
            logWriter("Index started...");
            int totalFileCount = imageFiles.Length;
            for (int i = 0; i < totalFileCount; i++)
            {
                var fi = imageFiles[i];
                using (Bitmap observerImage = (Bitmap)Image.FromFile(fi.FullName))
                {
                    List<SpeededUpRobustFeaturePoint> observerImageSurfPoints = surf.ProcessImage(observerImage);

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

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

                        observerSurfImageIndexList.Add(record);

                        listOfAllObserverImagesSurfPoints.AddRange(observerImageSurfPoints);

                        rows = endRows + 1;
                    }
                    else
                    {
                        Debug.WriteLine(fi.Name + " skip from index, because it didn't have significant feature");
                    }
                }
                IndexBgWorker.ReportProgress(i);
            }
            sw1.Stop();
            readingTime = sw1.ElapsedMilliseconds;
            logWriter(string.Format("Reading Surb Complete, it tooked {0} ms. Saving Repository...", readingTime));

            //------------Initialize Tree from Data
            sw1.Reset(); sw1.Start();
            double[][] superMatrix = listOfAllObserverImagesSurfPoints.Select(c => c.Descriptor).ToArray();
            int[] outputs = new int[superMatrix.Length];
            for (int i = 0; i < outputs.Length; i++)
                outputs[i] = i;

            Accord.MachineLearning.Structures.KDTree<int> tree =
                  Accord.MachineLearning.Structures.KDTree.FromData(superMatrix,
                          outputs,
                          Accord.Math.Distance.Euclidean, inPlace: true);
            sw1.Stop();
            indexingTime = sw1.ElapsedMilliseconds;
            logWriter(string.Format("Intializing KD Tree: {0}", indexingTime));

            //--------------Saving Indexed Records
            sw1.Reset(); sw1.Start();
            SurfAccordDataSet surfAccordDataset = new SurfAccordDataSet
            {
                SurfImageIndexRecord = observerSurfImageIndexList,
                IndexedTree = tree
            };
            string repoFileStoragePath = Path.Combine(DirectoryHelper.SaveDirectoryPath, "SurfAccordDataSet.bin");
            if (File.Exists(repoFileStoragePath))
                File.Delete(repoFileStoragePath);
            using (FileStream s = File.Create(repoFileStoragePath))
            {
                //Polenter.Serialization.SharpSerializerBinarySettings bs =
                //    new Polenter.Serialization.SharpSerializerBinarySettings(Polenter.Serialization.BinarySerializationMode.SizeOptimized);
                //Polenter.Serialization.SharpSerializer formatter = new Polenter.Serialization.SharpSerializer(bs);
                //formatter.Serialize(surfAccordDataset, s);
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter
                    = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                formatter.Serialize(s, surfAccordDataset);
                s.Close();
            }
            sw1.Stop();
            saveingTime = sw1.ElapsedMilliseconds;
            logWriter(string.Format("Saving Surf Accord Dataset: {0}", saveingTime));

            //Invalidating Cache
            CacheHelper.Remove("SurfAccordDataSet");
            CacheHelper.Remove("SurfAccordIntervalTree");

            logWriter(string.Format("Reading: {0} ms, Indexing: {1} ms, Saving Indexed data {2}", readingTime, indexingTime, saveingTime));
        }
예제 #15
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;
        }
예제 #16
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);
        }
예제 #17
0
 public void CalculateSurfDescriptor(Image img, SurfSettings surfSetting)
 {
 }
예제 #18
0
        public void IndexFiles(FileInfo[] imageFiles, System.ComponentModel.BackgroundWorker IndexBgWorker,
                               Action <string> logWriter,
                               SurfSettings surfSetting = null)
        {
            //For Time Profilling
            long readingTime, indexingTime = 0, saveingTime = 0;

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

            if (surfSetting != null)
            {
                hessianThresh       = surfSetting.HessianThresh.Value;
                uniquenessThreshold = surfSetting.UniquenessThreshold.Value;
            }
            float hessianThreshold2 = (float)hessianThresh / 1000000;
            SpeededUpRobustFeaturesDetector surf = new SpeededUpRobustFeaturesDetector(hessianThreshold2);
            #endregion

            int rows = 0;

            Stopwatch sw1;

            sw1 = Stopwatch.StartNew();
            logWriter("Index started...");

            string fullFileName = Path.Combine(DirectoryHelper.SaveDirectoryPath, "SurfAccordLinear.bin");
            if (File.Exists(fullFileName))
            {
                File.Delete(fullFileName);
            }
            using (FileStream fs = new FileStream(fullFileName, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf
                    = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                int totalFileCount = imageFiles.Length;
                for (int i = 0; i < totalFileCount; i++)
                {
                    var fi = imageFiles[i];

                    using (Bitmap observerImage = (Bitmap)Image.FromFile(fi.FullName))
                    {
                        List <SpeededUpRobustFeaturePoint> observerImageSurfPoints = surf.ProcessImage(observerImage);

                        if (observerImageSurfPoints.Count > 4)
                        {
                            SURFAccordRecord3 record = new SURFAccordRecord3
                            {
                                Id              = i,
                                ImageName       = fi.Name,
                                ImagePath       = fi.FullName,
                                SurfDescriptors = observerImageSurfPoints
                            };
                            bf.Serialize(fs, record);
                        }
                        else
                        {
                            Debug.WriteLine(fi.Name + " skip from index, because it didn't have significant feature");
                        }
                    }
                    IndexBgWorker.ReportProgress(i);
                }
                fs.Close();
            }

            sw1.Stop();
            readingTime = sw1.ElapsedMilliseconds;
            logWriter(string.Format("Reading Surb Complete, it tooked {0} ms. Saving Repository...", readingTime));


            logWriter(string.Format("Reading: {0} ms, Indexing: {1} ms, Saving Indexed data {2}", readingTime, indexingTime, saveingTime));
        }
예제 #19
0
        private Bitmap CompareAndDrawImage(Bitmap modelImage, Bitmap observedImage, SurfSettings setting)
        {
            Stopwatch watch1 = new Stopwatch();
            Stopwatch watch2 = new Stopwatch();

            Bitmap returnBitmap;

            watch2.Start();
            watch1.Reset(); watch1.Start();
            double hessianThreshold = setting.HessianThresh.HasValue ? setting.HessianThresh.Value : 500;
            float hessianThreshold2 = (float)hessianThreshold / 1000000;

            Debug.WriteLine("hessianThreshold2: {0}", hessianThreshold2);
            SpeededUpRobustFeaturesDetector surf = new SpeededUpRobustFeaturesDetector(hessianThreshold2);
            List<SpeededUpRobustFeaturePoint> surfPoints1 = surf.ProcessImage(modelImage);
            List<SpeededUpRobustFeaturePoint> surfPoints2 = surf.ProcessImage(observedImage);

            Debug.WriteLine("Surf points count: {0}", surfPoints1.Count);
            Debug.WriteLine("Surf points count: {0}", surfPoints2.Count);
            //long memoryFootprint = MemorySize.GetBlobSizeinKb(surfPoints2);
            //Debug.WriteLine("Surf extractor: {0} kb", memoryFootprint);

            watch1.Stop();
            Debug.WriteLine("Surf Detection tooked {0} ms", watch1.ElapsedMilliseconds);

            watch1.Reset(); watch1.Start();
            // Show the marked points in the original images
            Bitmap img1mark = new FeaturesMarker(surfPoints1, 2).Apply(modelImage);
            Bitmap img2mark = new FeaturesMarker(surfPoints2, 2).Apply(observedImage);
            // Concatenate the two images together in a single image (just to show on screen)
            Concatenate concatenate = new Concatenate(img1mark);
            returnBitmap = concatenate.Apply(img2mark);
            watch1.Stop();
            Debug.WriteLine("Surf point plotting tooked {0} ms", watch1.ElapsedMilliseconds);

            //watch1.Reset(); watch1.Start();
            //List<IntPoint>[] coretionalMatches = getMatches(surfPoints1, surfPoints2);
            //watch1.Stop();
            //Debug.WriteLine("Correctional Match tooked {0} ms", watch1.ElapsedMilliseconds);

            //// Get the two sets of points
            //IntPoint[] correlationPoints11 = coretionalMatches[0].ToArray();
            //IntPoint[] correlationPoints22 = coretionalMatches[1].ToArray();

            //Debug.WriteLine("Correclation points count: {0}", correlationPoints11.Length);
            //Debug.WriteLine("Correclation points count: {0}", correlationPoints22.Length);

            Debug.WriteLine("Threshold: {0}", setting.UniquenessThreshold.Value);
            watch1.Reset(); watch1.Start();
            // Step 2: Match feature points using a k-NN
            KNearestNeighborMatching matcher = new KNearestNeighborMatching(2);
            matcher.Threshold = setting.UniquenessThreshold.Value;
            IntPoint[][] matches = matcher.Match(surfPoints1, surfPoints2);
            watch1.Stop();
            Debug.WriteLine("Knn Match tooked {0} ms", watch1.ElapsedMilliseconds);

            // Get the two sets of points
            IntPoint[] correlationPoints1 = matches[0];
            IntPoint[] correlationPoints2 = matches[1];

            Debug.WriteLine("Knn points count: {0}", correlationPoints1.Length);
            Debug.WriteLine("Knn points count: {0}", correlationPoints2.Length);

            //watch1.Reset(); watch1.Start();
            //// Show the marked correlations in the concatenated image
            //PairsMarker pairs = new PairsMarker(
            //    correlationPoints1, // Add image1's width to the X points to show the markings correctly
            //    correlationPoints2.Apply(p => new IntPoint(p.X + modelImage.Width, p.Y)), Color.Blue);

            //returnBitmap = pairs.Apply(returnBitmap);
            //watch1.Stop();
            //Debug.WriteLine("Match pair marking tooked {0} ms", watch1.ElapsedMilliseconds);

            if (correlationPoints1.Length < 4 || correlationPoints2.Length < 4)
            {
                MessageBox.Show("Insufficient points to attempt a fit.");
                return null;
            }

            watch1.Reset(); watch1.Start();
            // Step 3: Create the homography matrix using a robust estimator
            //RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.001, 0.99);
            RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.001, 0.99);
            MatrixH homography = ransac.Estimate(correlationPoints1, correlationPoints2);
            watch1.Stop();
            Debug.WriteLine("Ransac tooked {0} ms", watch1.ElapsedMilliseconds);

            watch1.Reset(); watch1.Start();
            // Plot RANSAC results against correlation results
            IntPoint[] inliers1 = correlationPoints1.Submatrix(ransac.Inliers);
            IntPoint[] inliers2 = correlationPoints2.Submatrix(ransac.Inliers);
            watch1.Stop();
            Debug.WriteLine("Ransac SubMatrix {0} ms", watch1.ElapsedMilliseconds);

            Debug.WriteLine("Ransac points count: {0}", inliers1.Length);
            Debug.WriteLine("Ransac points count: {0}", inliers2.Length);

            watch1.Reset(); watch1.Start();
            PairsMarker inlierPairs = new PairsMarker(
               inliers1, // Add image1's width to the X points to show the markings correctly
               inliers2.Apply(p => new IntPoint(p.X + modelImage.Width, p.Y)), Color.Red);

            returnBitmap = inlierPairs.Apply(returnBitmap);
            watch1.Stop();
            Debug.WriteLine("Ransac plotting tooked {0} ms", watch1.ElapsedMilliseconds);

            watch2.Stop();
            return returnBitmap;
        }
예제 #20
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();
            Stopwatch sw1 = new Stopwatch();
            long      _loadingTime = 0, _modelImageDectionlong = 0, _queryingTime = 0, _matchingTime = 0;
            #endregion Diagnostic Region

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

            if (surfSetting != null)
            {
                hessianThresh       = surfSetting.HessianThresh.Value;
                uniquenessThreshold = surfSetting.UniquenessThreshold.Value;
                minGoodMatchPercent = surfSetting.GoodMatchThreshold.Value;
            }
            float hessianThreshold2 = (float)hessianThresh / 1000000;
            SpeededUpRobustFeaturesDetector surf = new SpeededUpRobustFeaturesDetector(hessianThreshold2);
            #endregion Surf Dectator Region

            #region Get Model Dectection and Validation
            sw.Reset(); sw.Start();
            List <SpeededUpRobustFeaturePoint> modelImageSurfPoints;
            using (Bitmap modelImage = (Bitmap)Image.FromFile(queryImagePath))
            {
                modelImageSurfPoints = surf.ProcessImage(modelImage);
            }

            if (modelImageSurfPoints == null ||
                modelImageSurfPoints.Count < 4)
            {
                throw new InvalidOperationException("Insuffucient interesting point in query image, try another query image");
            }
            sw.Stop();
            _modelImageDectionlong = sw.ElapsedMilliseconds;
            #endregion

            #region Search Images
            sw.Reset(); sw.Start();
            string fullFileName = Path.Combine(DirectoryHelper.SaveDirectoryPath, "SurfAccordLinear.bin");
            if (!File.Exists(fullFileName))
            {
                string exMsg = string.Format("Can't get the Surf Index at {0}, please index first", fullFileName);
                throw new FileNotFoundException(fullFileName);
            }
            using (FileStream fs = new FileStream(fullFileName, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf
                    = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                long fileLength = fs.Length;
                while (fs.Position < fileLength)
                {
                    SURFAccordRecord3        record  = (SURFAccordRecord3)bf.Deserialize(fs);
                    KNearestNeighborMatching matcher = new KNearestNeighborMatching(2);
                    matcher.Threshold = uniquenessThreshold;
                    sw1.Start();
                    AForge.IntPoint[][] matches = matcher.Match(modelImageSurfPoints, record.SurfDescriptors);
                    sw1.Stop();
                    var countOfMatchPoint = matches[0].Length;
                    if (countOfMatchPoint > 0)
                    {
                        double totalnumberOfModelFeature = modelImageSurfPoints.Count;
                        double matchPercentage           = ((totalnumberOfModelFeature - (double)countOfMatchPoint) / totalnumberOfModelFeature);
                        matchPercentage = (1 - matchPercentage) * 100;
                        matchPercentage = Math.Round(matchPercentage);
                        if (matchPercentage >= minGoodMatchPercent)
                        {
                            record.Distance = matchPercentage;
                            rtnImageList.Add(record.Clone());
                        }
                    }
                    record = null;
                }
                fs.Close();
            }
            sw.Stop();
            _matchingTime = sw1.ElapsedMilliseconds;
            _queryingTime = sw.ElapsedMilliseconds;
            #endregion

            string msg = String.Format("Loading: {0}, Model detection: {1}, Querying: {2}, Matching: {3}",
                                       _loadingTime, _modelImageDectionlong, _queryingTime, _matchingTime);
            messageToLog = msg;

            if (rtnImageList.Count > 0)
            {
                rtnImageList = rtnImageList.OrderByDescending(rec => rec.Distance)
                               .ToList <ImageRecord>();
            }
            return(rtnImageList);
        }
예제 #21
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 _loadingTime, _modelImageDectionlong, _queryingTime, _treeQuery, _loopTime = 0;
            #endregion Diagnostic Region

            #region Get KD-Tree Index
            sw.Reset(); sw.Start();
            //--------------Getting Indexed Records
            SurfAccordDataSet surfAccordDataset;
            bool isExist= CacheHelper.Get<SurfAccordDataSet>("SurfAccordDataSet", out surfAccordDataset);
            if (!isExist)
            {
                string repoFileStoragePath = Path.Combine(DirectoryHelper.SaveDirectoryPath, "SurfAccordDataSet.bin");
                if (!File.Exists(repoFileStoragePath))
                {
                    string exMsg = string.Format("Can't get the Surf Index at {0}, please index first", repoFileStoragePath);
                    throw new FileNotFoundException(exMsg);
                }
                using (FileStream s = File.OpenRead(repoFileStoragePath))
                {
                    //Polenter.Serialization.SharpSerializerBinarySettings bs =
                    //    new Polenter.Serialization.SharpSerializerBinarySettings(Polenter.Serialization.BinarySerializationMode.SizeOptimized);
                    //Polenter.Serialization.SharpSerializer formatter = new Polenter.Serialization.SharpSerializer(bs);
                    //formatter.Serialize(surfAccordDataset, s);
                    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter
                        = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                    surfAccordDataset = (SurfAccordDataSet)formatter.Deserialize(s);
                    s.Close();
                }
                CacheHelper.Add<SurfAccordDataSet>(surfAccordDataset, "SurfAccordDataSet");
            }
            if (surfAccordDataset == null)
                throw new InvalidOperationException("Can't get the Surf Index, please index first");
            sw.Stop();
            _loadingTime = sw.ElapsedMilliseconds;
            #endregion

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

            if (surfSetting != null)
            {
                hessianThresh = surfSetting.HessianThresh.Value;
                uniquenessThreshold = surfSetting.UniquenessThreshold.Value;
                goodMatchDistThreshold = surfSetting.GoodMatchThreshold.Value;
            }
            float hessianThreshold2 = (float)hessianThresh / 1000000;
            SpeededUpRobustFeaturesDetector surf = new SpeededUpRobustFeaturesDetector(hessianThreshold2);
            #endregion Surf Dectator Region

            #region Get Model Dectection and Validation
            sw.Reset(); sw.Start();
            List<SpeededUpRobustFeaturePoint> modelImageSurfPoints;
            using (Bitmap modelImage = (Bitmap)Image.FromFile(queryImagePath))
            {
                modelImageSurfPoints = surf.ProcessImage(modelImage);
            }

            if (modelImageSurfPoints == null
                || modelImageSurfPoints.Count < 4)
            {
                throw new InvalidOperationException("Insuffucient interesting point in query image, try another query image");
            }
            sw.Stop();
            _modelImageDectionlong = sw.ElapsedMilliseconds;
            #endregion

            #region Search Images
            sw.Reset(); sw.Start();
            //------------Search Images
            Accord.MachineLearning.Structures.KDTree<int> tree = surfAccordDataset.IndexedTree;
            double[][] listofQueryDescriptors = modelImageSurfPoints.Select(ft => ft.Descriptor).ToArray();
            double[] myscores = new double[listofQueryDescriptors.Length];
            int[] labels = Enumerable.Repeat(-1, listofQueryDescriptors.Length).ToArray();
            for (int i = 0; i < listofQueryDescriptors.Length; i++)
            {
                KDTreeNodeCollection<int> neighbors = tree.ApproximateNearest(listofQueryDescriptors[i],2, 90d);
                //KDTreeNodeCollection<int> neighbors = tree.Nearest(listofQueryDescriptors[i], uniquenessThreshold, 2);
                Dictionary<int, double> keyValueStore = new Dictionary<int, double>();
                double similarityDist = 0;
                foreach (KDTreeNodeDistance<int> point in neighbors)
                {
                    int label = point.Node.Value;
                    double d = point.Distance;

                    // Convert to similarity measure
                    if (keyValueStore.ContainsKey(label))
                    {
                        similarityDist = keyValueStore[label];
                        similarityDist += 1.0 / (1.0 + d);
                        keyValueStore[label] = similarityDist;
                    }
                    else
                    {
                        similarityDist = 1.0 / (1.0 + d);
                        keyValueStore.Add(label, similarityDist);
                    }
                }
                if (keyValueStore.Count > 0)
                {
                    int maxIndex = keyValueStore.Aggregate((l, r) => l.Value > r.Value ? l : r).Key;
                    labels[i] = maxIndex;
                    double sumOfAllValues = keyValueStore.Values.Sum();
                    myscores[i] = keyValueStore[maxIndex] / sumOfAllValues;
                }
            }
            sw.Stop();
            _queryingTime = sw.ElapsedMilliseconds;

            sw.Reset(); sw.Start();
            List<SURFRecord1> listOfSurfImages = surfAccordDataset.SurfImageIndexRecord;
            //----------Create Interval Tree from ImageMetaData
            IntervalTreeLib.IntervalTree<SURFRecord1, int> intervalTree;
            bool isTreeExist = CacheHelper.Get<IntervalTreeLib.IntervalTree<SURFRecord1, int>>("SurfAccordIntervalTree", out intervalTree);
            if (!isTreeExist)
            {
                intervalTree = new IntervalTreeLib.IntervalTree<SURFRecord1, int>();
                foreach (var record in listOfSurfImages)
                {
                    intervalTree.AddInterval(record.IndexStart, record.IndexEnd, record);
                }
                CacheHelper.Add<IntervalTreeLib.IntervalTree<SURFRecord1, int>>(intervalTree, "SurfAccordIntervalTree");
            }

            //--------------Matching Target image similarity
            for (int i = 0; i < listofQueryDescriptors.Length; i++)
            {
                int rowNum = labels[i];
                if (rowNum == -1) continue;
                double dist = myscores[i];
                SURFRecord1 rec = intervalTree.Get(rowNum, IntervalTreeLib.StubMode.ContainsStartThenEnd).FirstOrDefault();
                rec.Distance++;
            }
            sw.Stop();
            _loopTime = sw.ElapsedMilliseconds;
            #endregion

            string msg = String.Format("Loading: {0}, Model detection: {1}, Querying: {2}, Looping: {3}",
                                                _loadingTime, _modelImageDectionlong, _queryingTime, _loopTime);
            messageToLog = msg;
            rtnImageList = listOfSurfImages.Where(rec => rec.Distance > goodMatchDistThreshold)
                                    .OrderByDescending(rec => rec.Distance)
                                    .ToList<ImageRecord>();

            return rtnImageList;
        }
예제 #22
0
        public List <ImageRecord> QueryImage(string queryImagePath, SurfSettings surfSetting = null)
        {
            List <ImageRecord> rtnImageList = new List <ImageRecord>();

            var observerFeatureSets = SurfRepository.GetSurfRecordList();

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

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

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

            using (Image <Gray, byte> modelImage = new Image <Gray, byte>(queryImagePath))
            {
                ImageFeature <float>[] modelFeatures = surfDectector.DetectFeatures(modelImage, null);

                if (modelFeatures.Length < 4)
                {
                    throw new InvalidOperationException("Model image didn't have any significant features to detect");
                }

                Features2DTracker <float> tracker = new Features2DTracker <float>(modelFeatures);
                foreach (var surfRecord in observerFeatureSets)
                {
                    string queryImageName = System.IO.Path.GetFileName(queryImagePath);
                    string modelImageName = surfRecord.ImageName;

                    Features2DTracker <float> .MatchedImageFeature[] matchedFeatures = tracker.MatchFeature(surfRecord.observerFeatures, 2);

                    Features2DTracker <float> .MatchedImageFeature[] uniqueFeatures = Features2DTracker <float> .VoteForUniqueness(matchedFeatures, uniquenessThreshold);

                    Features2DTracker <float> .MatchedImageFeature[] uniqueRotOriFeatures = Features2DTracker <float> .VoteForSizeAndOrientation(uniqueFeatures, 1.5, 20);

                    int goodMatchCount = 0;
                    goodMatchCount = uniqueRotOriFeatures.Length;
                    bool isMatch = false;

                    double totalnumberOfModelFeature = modelFeatures.Length;
                    double matchPercentage           = ((totalnumberOfModelFeature - (double)goodMatchCount) / totalnumberOfModelFeature);
                    matchPercentage = (1 - matchPercentage) * 100;
                    matchPercentage = Math.Round(matchPercentage);
                    if (matchPercentage >= minGoodMatchPercent)
                    {
                        HomographyMatrix homography =
                            Features2DTracker <float> .GetHomographyMatrixFromMatchedFeatures(uniqueRotOriFeatures);

                        if (homography != null)
                        {
                            isMatch = homography.IsValid(5);
                            if (isMatch)
                            {
                                surfRecord.Distance = matchPercentage;
                                rtnImageList.Add((ImageRecord)surfRecord);
                            }
                        }
                    }

                    //bool isMatch = false;
                    //if (uniqueFeatures.Length > 4)
                    //{
                    //    HomographyMatrix homography =
                    //        Features2DTracker<float>.GetHomographyMatrixFromMatchedFeatures(uniqueRotOriFeatures);
                    //    if (homography != null)
                    //    {
                    //        isMatch = homography.IsValid(5);
                    //    }
                    //}

                    //if (isMatch)
                    //{
                    //    surfRecord.Distance = goodMatchCount;
                    //    rtnImageList.Add((ImageRecord)surfRecord);
                    //}

                    //int goodMatchCount = 0;
                    //foreach (Features2DTracker<float>.MatchedImageFeature ms in matchedFeatures)
                    //{
                    //    if (ms.SimilarFeatures[0].Distance < uniquenessThreshold)
                    //        goodMatchCount++;
                    //}



                    //double totalnumberOfModelFeature = modelFeatures.Length;
                    //double matchPercentage = ((totalnumberOfModelFeature - (double)goodMatchCount) / totalnumberOfModelFeature);
                    //matchPercentage = (1 - matchPercentage) * 100;
                    //matchPercentage = Math.Round(matchPercentage);
                    //if (matchPercentage >= minGoodMatchPercent)
                    //{
                    //    surfRecord.Distance = matchPercentage;
                    //    rtnImageList.Add((ImageRecord)surfRecord);
                    //}
                }
            }
            rtnImageList = rtnImageList.OrderByDescending(x => x.Distance).ToList();
            return(rtnImageList);
        }
예제 #23
0
        public List<ImageRecord> QueryImage(string queryImagePath,  SurfSettings surfSetting = null)
        {
            List<ImageRecord> rtnImageList = new List<ImageRecord>();

            var observerFeatureSets = SurfRepository.GetSurfRecordList();

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

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

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

            using (Image<Gray, byte> modelImage = new Image<Gray, byte>(queryImagePath))
            {
                ImageFeature<float>[] modelFeatures = surfDectector.DetectFeatures(modelImage, null);

                if (modelFeatures.Length < 4) throw new InvalidOperationException("Model image didn't have any significant features to detect");

                Features2DTracker<float> tracker = new Features2DTracker<float>(modelFeatures);
                foreach (var surfRecord in observerFeatureSets)
                {
                    string queryImageName = System.IO.Path.GetFileName(queryImagePath);
                    string modelImageName = surfRecord.ImageName;

                    Features2DTracker<float>.MatchedImageFeature[] matchedFeatures = tracker.MatchFeature(surfRecord.observerFeatures, 2);

                    Features2DTracker<float>.MatchedImageFeature[] uniqueFeatures = Features2DTracker<float>.VoteForUniqueness(matchedFeatures, uniquenessThreshold);

                    Features2DTracker<float>.MatchedImageFeature[] uniqueRotOriFeatures = Features2DTracker<float>.VoteForSizeAndOrientation(uniqueFeatures, 1.5, 20);

                    int goodMatchCount = 0;
                    goodMatchCount = uniqueRotOriFeatures.Length;
                    bool isMatch = false;

                    double totalnumberOfModelFeature = modelFeatures.Length;
                    double matchPercentage = ((totalnumberOfModelFeature - (double)goodMatchCount) / totalnumberOfModelFeature);
                    matchPercentage = (1 - matchPercentage) * 100;
                    matchPercentage = Math.Round(matchPercentage);
                    if (matchPercentage >= minGoodMatchPercent)
                    {

                        HomographyMatrix homography =
                            Features2DTracker<float>.GetHomographyMatrixFromMatchedFeatures(uniqueRotOriFeatures);
                        if (homography != null)
                        {
                            isMatch = homography.IsValid(5);
                            if (isMatch)
                            {
                                surfRecord.Distance = matchPercentage;
                                rtnImageList.Add((ImageRecord)surfRecord);
                            }
                        }
                    }

                    //bool isMatch = false;
                    //if (uniqueFeatures.Length > 4)
                    //{
                    //    HomographyMatrix homography =
                    //        Features2DTracker<float>.GetHomographyMatrixFromMatchedFeatures(uniqueRotOriFeatures);
                    //    if (homography != null)
                    //    {
                    //        isMatch = homography.IsValid(5);
                    //    }
                    //}

                    //if (isMatch)
                    //{
                    //    surfRecord.Distance = goodMatchCount;
                    //    rtnImageList.Add((ImageRecord)surfRecord);
                    //}

                    //int goodMatchCount = 0;
                    //foreach (Features2DTracker<float>.MatchedImageFeature ms in matchedFeatures)
                    //{
                    //    if (ms.SimilarFeatures[0].Distance < uniquenessThreshold)
                    //        goodMatchCount++;
                    //}

                    //double totalnumberOfModelFeature = modelFeatures.Length;
                    //double matchPercentage = ((totalnumberOfModelFeature - (double)goodMatchCount) / totalnumberOfModelFeature);
                    //matchPercentage = (1 - matchPercentage) * 100;
                    //matchPercentage = Math.Round(matchPercentage);
                    //if (matchPercentage >= minGoodMatchPercent)
                    //{
                    //    surfRecord.Distance = matchPercentage;
                    //    rtnImageList.Add((ImageRecord)surfRecord);
                    //}
                }
            }
            rtnImageList = rtnImageList.OrderByDescending(x => x.Distance).ToList();
            return rtnImageList;
        }
예제 #24
0
        private void AccordSurfAlgoIndexing(SurfSettings surfSetting)
        {
            var imageFiles = getFiles(IndexDirectory, "*.gif|*.jpg|*.png|*.bmp|*.jpeg", SearchOption.TopDirectoryOnly);
            int totalFileCount = imageFiles.Length;

            Dispatcher.Invoke((Action)delegate
            {
                pbIndex.Minimum = 0; pbIndex.Maximum = totalFileCount; lblIndexStatus.Text = "Indexing..";
            });

            if (surfSetting.Algorithm == SurfAlgo.Linear)
            {
                SurfIndexer4 surfIndexer = new SurfIndexer4();
                if (ExecInParallel)
                    surfIndexer.IndexFilesAsync(imageFiles, IndexBgWorker, WriteIndexStatus, surfSetting);
                else
                    surfIndexer.IndexFiles(imageFiles, IndexBgWorker, WriteIndexStatus, surfSetting);
            }
            else
            {
                SurfIndexer3 surfIndexer = new SurfIndexer3();
                if (ExecInParallel)
                    surfIndexer.IndexFilesAsync(imageFiles, IndexBgWorker, WriteIndexStatus, surfSetting);
                else
                    surfIndexer.IndexFiles(imageFiles, IndexBgWorker, WriteIndexStatus, surfSetting);
            }
        }
예제 #25
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));
        }
예제 #26
0
        private SurfSettings GetSurfSetting()
        {
            SurfSettings surfSetting = new SurfSettings();

            this.Dispatcher.Invoke(() =>
            {
                surfSetting.HessianThresh = Convert.ToDouble((cmbSurfThreshold.SelectedItem as ListBoxItem).Content);
                surfSetting.UniquenessThreshold = nudsurfUniqueThreshold.Value;
                surfSetting.GoodMatchThreshold = nudsurfGoodMatchThreshold.Value;
                surfSetting.Algorithm = (SurfAlgo)cmbSurfApproach.SelectedIndex;
            });

            return surfSetting;
        }
예제 #27
0
        /// <summary>
        /// Draw the model image and observed image, the matched features and homography projection.
        /// </summary>
        /// <param name="modelImage">The model image</param>
        /// <param name="observedImage">The observed image</param>
        /// <param name="matchTime">The output total time for computing the homography matrix.</param>
        /// <returns>The model image and observed image, the matched features and homography projection.</returns>
        private static Image <Bgr, Byte> Draw(Image <Gray, Byte> modelImage, Image <Gray, byte> observedImage, SurfSettings surfSettings, out long matchTime)
        {
            HomographyMatrix homography;
            VectorOfKeyPoint modelKeyPoints;
            VectorOfKeyPoint observedKeyPoints;
            Matrix <int>     indices;
            Matrix <byte>    mask;

            FindMatch(modelImage, observedImage, surfSettings, out matchTime, out modelKeyPoints, out observedKeyPoints, out indices, out mask, out homography);

            //Draw the matched keypoints
            Image <Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints,
                                                                     indices, new Bgr(255, 0, 0), new Bgr(255, 255, 0), mask, Features2DToolbox.KeypointDrawType.DEFAULT);

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

            return(result);
        }
예제 #28
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      _loadingTime, _modelImageDectionlong, _queryingTime, _treeQuery, _loopTime = 0;
            #endregion Diagnostic Region

            #region Get KD-Tree Index
            sw.Reset(); sw.Start();
            //--------------Getting Indexed Records
            SurfAccordDataSet surfAccordDataset;
            bool isExist = CacheHelper.Get <SurfAccordDataSet>("SurfAccordDataSet", out surfAccordDataset);
            if (!isExist)
            {
                string repoFileStoragePath = Path.Combine(DirectoryHelper.SaveDirectoryPath, "SurfAccordDataSet.bin");
                if (!File.Exists(repoFileStoragePath))
                {
                    string exMsg = string.Format("Can't get the Surf Index at {0}, please index first", repoFileStoragePath);
                    throw new FileNotFoundException(exMsg);
                }
                using (FileStream s = File.OpenRead(repoFileStoragePath))
                {
                    //Polenter.Serialization.SharpSerializerBinarySettings bs =
                    //    new Polenter.Serialization.SharpSerializerBinarySettings(Polenter.Serialization.BinarySerializationMode.SizeOptimized);
                    //Polenter.Serialization.SharpSerializer formatter = new Polenter.Serialization.SharpSerializer(bs);
                    //formatter.Serialize(surfAccordDataset, s);
                    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter
                        = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                    surfAccordDataset = (SurfAccordDataSet)formatter.Deserialize(s);
                    s.Close();
                }
                CacheHelper.Add <SurfAccordDataSet>(surfAccordDataset, "SurfAccordDataSet");
            }
            if (surfAccordDataset == null)
            {
                throw new InvalidOperationException("Can't get the Surf Index, please index first");
            }
            sw.Stop();
            _loadingTime = sw.ElapsedMilliseconds;
            #endregion

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

            if (surfSetting != null)
            {
                hessianThresh          = surfSetting.HessianThresh.Value;
                uniquenessThreshold    = surfSetting.UniquenessThreshold.Value;
                goodMatchDistThreshold = surfSetting.GoodMatchThreshold.Value;
            }
            float hessianThreshold2 = (float)hessianThresh / 1000000;
            SpeededUpRobustFeaturesDetector surf = new SpeededUpRobustFeaturesDetector(hessianThreshold2);
            #endregion Surf Dectator Region

            #region Get Model Dectection and Validation
            sw.Reset(); sw.Start();
            List <SpeededUpRobustFeaturePoint> modelImageSurfPoints;
            using (Bitmap modelImage = (Bitmap)Image.FromFile(queryImagePath))
            {
                modelImageSurfPoints = surf.ProcessImage(modelImage);
            }

            if (modelImageSurfPoints == null ||
                modelImageSurfPoints.Count < 4)
            {
                throw new InvalidOperationException("Insuffucient interesting point in query image, try another query image");
            }
            sw.Stop();
            _modelImageDectionlong = sw.ElapsedMilliseconds;
            #endregion

            #region Search Images
            sw.Reset(); sw.Start();
            //------------Search Images
            Accord.MachineLearning.Structures.KDTree <int> tree = surfAccordDataset.IndexedTree;
            double[][] listofQueryDescriptors = modelImageSurfPoints.Select(ft => ft.Descriptor).ToArray();
            double[]   myscores = new double[listofQueryDescriptors.Length];
            int[]      labels   = Enumerable.Repeat(-1, listofQueryDescriptors.Length).ToArray();
            for (int i = 0; i < listofQueryDescriptors.Length; i++)
            {
                KDTreeNodeCollection <int> neighbors = tree.ApproximateNearest(listofQueryDescriptors[i], 2, 90d);
                //KDTreeNodeCollection<int> neighbors = tree.Nearest(listofQueryDescriptors[i], uniquenessThreshold, 2);
                Dictionary <int, double> keyValueStore = new Dictionary <int, double>();
                double similarityDist = 0;
                foreach (KDTreeNodeDistance <int> point in neighbors)
                {
                    int    label = point.Node.Value;
                    double d     = point.Distance;

                    // Convert to similarity measure
                    if (keyValueStore.ContainsKey(label))
                    {
                        similarityDist       = keyValueStore[label];
                        similarityDist      += 1.0 / (1.0 + d);
                        keyValueStore[label] = similarityDist;
                    }
                    else
                    {
                        similarityDist = 1.0 / (1.0 + d);
                        keyValueStore.Add(label, similarityDist);
                    }
                }
                if (keyValueStore.Count > 0)
                {
                    int maxIndex = keyValueStore.Aggregate((l, r) => l.Value > r.Value ? l : r).Key;
                    labels[i] = maxIndex;
                    double sumOfAllValues = keyValueStore.Values.Sum();
                    myscores[i] = keyValueStore[maxIndex] / sumOfAllValues;
                }
            }
            sw.Stop();
            _queryingTime = sw.ElapsedMilliseconds;

            sw.Reset(); sw.Start();
            List <SURFRecord1> listOfSurfImages = surfAccordDataset.SurfImageIndexRecord;
            //----------Create Interval Tree from ImageMetaData
            IntervalTreeLib.IntervalTree <SURFRecord1, int> intervalTree;
            bool isTreeExist = CacheHelper.Get <IntervalTreeLib.IntervalTree <SURFRecord1, int> >("SurfAccordIntervalTree", out intervalTree);
            if (!isTreeExist)
            {
                intervalTree = new IntervalTreeLib.IntervalTree <SURFRecord1, int>();
                foreach (var record in listOfSurfImages)
                {
                    intervalTree.AddInterval(record.IndexStart, record.IndexEnd, record);
                }
                CacheHelper.Add <IntervalTreeLib.IntervalTree <SURFRecord1, int> >(intervalTree, "SurfAccordIntervalTree");
            }

            //--------------Matching Target image similarity
            for (int i = 0; i < listofQueryDescriptors.Length; i++)
            {
                int rowNum = labels[i];
                if (rowNum == -1)
                {
                    continue;
                }
                double      dist = myscores[i];
                SURFRecord1 rec  = intervalTree.Get(rowNum, IntervalTreeLib.StubMode.ContainsStartThenEnd).FirstOrDefault();
                rec.Distance++;
            }
            sw.Stop();
            _loopTime = sw.ElapsedMilliseconds;
            #endregion

            string msg = String.Format("Loading: {0}, Model detection: {1}, Querying: {2}, Looping: {3}",
                                       _loadingTime, _modelImageDectionlong, _queryingTime, _loopTime);
            messageToLog = msg;
            rtnImageList = listOfSurfImages.Where(rec => rec.Distance > goodMatchDistThreshold)
                           .OrderByDescending(rec => rec.Distance)
                           .ToList <ImageRecord>();

            return(rtnImageList);
        }
        private Bitmap CompareAndDrawImage(Bitmap modelImage, Bitmap observedImage, SurfSettings setting)
        {
            Stopwatch watch1 = new Stopwatch();
            Stopwatch watch2 = new Stopwatch();

            Bitmap returnBitmap;

            watch2.Start();
            watch1.Reset(); watch1.Start();
            double hessianThreshold  = setting.HessianThresh.HasValue ? setting.HessianThresh.Value : 500;
            float  hessianThreshold2 = (float)hessianThreshold / 1000000;

            Debug.WriteLine("hessianThreshold2: {0}", hessianThreshold2);
            SpeededUpRobustFeaturesDetector    surf        = new SpeededUpRobustFeaturesDetector(hessianThreshold2);
            List <SpeededUpRobustFeaturePoint> surfPoints1 = surf.ProcessImage(modelImage);
            List <SpeededUpRobustFeaturePoint> surfPoints2 = surf.ProcessImage(observedImage);


            Debug.WriteLine("Surf points count: {0}", surfPoints1.Count);
            Debug.WriteLine("Surf points count: {0}", surfPoints2.Count);
            //long memoryFootprint = MemorySize.GetBlobSizeinKb(surfPoints2);
            //Debug.WriteLine("Surf extractor: {0} kb", memoryFootprint);

            watch1.Stop();
            Debug.WriteLine("Surf Detection tooked {0} ms", watch1.ElapsedMilliseconds);

            watch1.Reset(); watch1.Start();
            // Show the marked points in the original images
            Bitmap img1mark = new FeaturesMarker(surfPoints1, 2).Apply(modelImage);
            Bitmap img2mark = new FeaturesMarker(surfPoints2, 2).Apply(observedImage);
            // Concatenate the two images together in a single image (just to show on screen)
            Concatenate concatenate = new Concatenate(img1mark);

            returnBitmap = concatenate.Apply(img2mark);
            watch1.Stop();
            Debug.WriteLine("Surf point plotting tooked {0} ms", watch1.ElapsedMilliseconds);


            //watch1.Reset(); watch1.Start();
            //List<IntPoint>[] coretionalMatches = getMatches(surfPoints1, surfPoints2);
            //watch1.Stop();
            //Debug.WriteLine("Correctional Match tooked {0} ms", watch1.ElapsedMilliseconds);

            //// Get the two sets of points
            //IntPoint[] correlationPoints11 = coretionalMatches[0].ToArray();
            //IntPoint[] correlationPoints22 = coretionalMatches[1].ToArray();

            //Debug.WriteLine("Correclation points count: {0}", correlationPoints11.Length);
            //Debug.WriteLine("Correclation points count: {0}", correlationPoints22.Length);

            Debug.WriteLine("Threshold: {0}", setting.UniquenessThreshold.Value);
            watch1.Reset(); watch1.Start();
            // Step 2: Match feature points using a k-NN
            KNearestNeighborMatching matcher = new KNearestNeighborMatching(2);

            matcher.Threshold = setting.UniquenessThreshold.Value;
            IntPoint[][] matches = matcher.Match(surfPoints1, surfPoints2);
            watch1.Stop();
            Debug.WriteLine("Knn Match tooked {0} ms", watch1.ElapsedMilliseconds);

            // Get the two sets of points
            IntPoint[] correlationPoints1 = matches[0];
            IntPoint[] correlationPoints2 = matches[1];

            Debug.WriteLine("Knn points count: {0}", correlationPoints1.Length);
            Debug.WriteLine("Knn points count: {0}", correlationPoints2.Length);

            //watch1.Reset(); watch1.Start();
            //// Show the marked correlations in the concatenated image
            //PairsMarker pairs = new PairsMarker(
            //    correlationPoints1, // Add image1's width to the X points to show the markings correctly
            //    correlationPoints2.Apply(p => new IntPoint(p.X + modelImage.Width, p.Y)), Color.Blue);

            //returnBitmap = pairs.Apply(returnBitmap);
            //watch1.Stop();
            //Debug.WriteLine("Match pair marking tooked {0} ms", watch1.ElapsedMilliseconds);

            if (correlationPoints1.Length < 4 || correlationPoints2.Length < 4)
            {
                MessageBox.Show("Insufficient points to attempt a fit.");
                return(null);
            }

            watch1.Reset(); watch1.Start();
            // Step 3: Create the homography matrix using a robust estimator
            //RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.001, 0.99);
            RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.001, 0.99);
            MatrixH homography = ransac.Estimate(correlationPoints1, correlationPoints2);

            watch1.Stop();
            Debug.WriteLine("Ransac tooked {0} ms", watch1.ElapsedMilliseconds);

            watch1.Reset(); watch1.Start();
            // Plot RANSAC results against correlation results
            IntPoint[] inliers1 = correlationPoints1.Submatrix(ransac.Inliers);
            IntPoint[] inliers2 = correlationPoints2.Submatrix(ransac.Inliers);
            watch1.Stop();
            Debug.WriteLine("Ransac SubMatrix {0} ms", watch1.ElapsedMilliseconds);

            Debug.WriteLine("Ransac points count: {0}", inliers1.Length);
            Debug.WriteLine("Ransac points count: {0}", inliers2.Length);

            watch1.Reset(); watch1.Start();
            PairsMarker inlierPairs = new PairsMarker(
                inliers1, // Add image1's width to the X points to show the markings correctly
                inliers2.Apply(p => new IntPoint(p.X + modelImage.Width, p.Y)), Color.Red);

            returnBitmap = inlierPairs.Apply(returnBitmap);
            watch1.Stop();
            Debug.WriteLine("Ransac plotting tooked {0} ms", watch1.ElapsedMilliseconds);

            watch2.Stop();
            return(returnBitmap);
        }
예제 #30
0
 public void IndexFilesAsync(FileInfo[] imageFiles, System.ComponentModel.BackgroundWorker IndexBgWorker,
                             Action <string> logWriter,
                             SurfSettings surfSetting = null)
 {
     throw new NotImplementedException();
 }
예제 #31
0
        public void IndexFiles(FileInfo[] imageFiles, System.ComponentModel.BackgroundWorker IndexBgWorker,
            Action<string> logWriter,
            SurfSettings surfSetting = null)
        {
            //For Time Profilling
            long readingTime, indexingTime = 0 , saveingTime = 0;

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

            if (surfSetting != null)
            {
                hessianThresh = surfSetting.HessianThresh.Value;
                uniquenessThreshold = surfSetting.UniquenessThreshold.Value;
            }
            float hessianThreshold2 = (float)hessianThresh / 1000000;
            SpeededUpRobustFeaturesDetector surf = new SpeededUpRobustFeaturesDetector(hessianThreshold2);
            #endregion

            int rows = 0;

            Stopwatch sw1;

            sw1 = Stopwatch.StartNew();
            logWriter("Index started...");

            string fullFileName = Path.Combine(DirectoryHelper.SaveDirectoryPath, "SurfAccordLinear.bin");
            if (File.Exists(fullFileName))
                File.Delete(fullFileName);
            using (FileStream fs = new FileStream(fullFileName, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf
                    = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                int totalFileCount = imageFiles.Length;
                for (int i = 0; i < totalFileCount; i++)
                {
                    var fi = imageFiles[i];

                    using (Bitmap observerImage = (Bitmap)Image.FromFile(fi.FullName))
                    {
                        List<SpeededUpRobustFeaturePoint> observerImageSurfPoints = surf.ProcessImage(observerImage);

                        if (observerImageSurfPoints.Count > 4)
                        {
                            SURFAccordRecord3 record = new SURFAccordRecord3
                            {
                                Id = i,
                                ImageName = fi.Name,
                                ImagePath = fi.FullName,
                                SurfDescriptors = observerImageSurfPoints
                            };
                            bf.Serialize(fs, record);
                        }
                        else
                        {
                            Debug.WriteLine(fi.Name + " skip from index, because it didn't have significant feature");
                        }
                    }
                    IndexBgWorker.ReportProgress(i);
                }
                fs.Close();
            }

            sw1.Stop();
            readingTime = sw1.ElapsedMilliseconds;
            logWriter(string.Format("Reading Surb Complete, it tooked {0} ms. Saving Repository...", readingTime));

            logWriter(string.Format("Reading: {0} ms, Indexing: {1} ms, Saving Indexed data {2}", readingTime, indexingTime, saveingTime));
        }
예제 #32
0
        public void IndexFiles(FileInfo[] imageFiles, System.ComponentModel.BackgroundWorker IndexBgWorker,
                               Action <string> logWriter,
                               SurfSettings surfSetting = null)
        {
            //For Time Profilling
            long readingTime, indexingTime, saveingTime;

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

            if (surfSetting != null)
            {
                hessianThresh       = surfSetting.HessianThresh.Value;
                uniquenessThreshold = surfSetting.UniquenessThreshold.Value;
            }
            float hessianThreshold2 = (float)hessianThresh / 1000000;
            SpeededUpRobustFeaturesDetector surf = new SpeededUpRobustFeaturesDetector(hessianThreshold2);
            #endregion

            int rows = 0;

            List <SURFRecord1> observerSurfImageIndexList = new List <SURFRecord1>();
            List <SpeededUpRobustFeaturePoint> listOfAllObserverImagesSurfPoints = new List <SpeededUpRobustFeaturePoint>();
            Stopwatch sw1;

            sw1 = Stopwatch.StartNew();
            logWriter("Index started...");
            int totalFileCount = imageFiles.Length;
            for (int i = 0; i < totalFileCount; i++)
            {
                var fi = imageFiles[i];
                using (Bitmap observerImage = (Bitmap)Image.FromFile(fi.FullName))
                {
                    List <SpeededUpRobustFeaturePoint> observerImageSurfPoints = surf.ProcessImage(observerImage);

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

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

                        observerSurfImageIndexList.Add(record);

                        listOfAllObserverImagesSurfPoints.AddRange(observerImageSurfPoints);

                        rows = endRows + 1;
                    }
                    else
                    {
                        Debug.WriteLine(fi.Name + " skip from index, because it didn't have significant feature");
                    }
                }
                IndexBgWorker.ReportProgress(i);
            }
            sw1.Stop();
            readingTime = sw1.ElapsedMilliseconds;
            logWriter(string.Format("Reading Surb Complete, it tooked {0} ms. Saving Repository...", readingTime));

            //------------Initialize Tree from Data
            sw1.Reset(); sw1.Start();
            double[][] superMatrix = listOfAllObserverImagesSurfPoints.Select(c => c.Descriptor).ToArray();
            int[]      outputs     = new int[superMatrix.Length];
            for (int i = 0; i < outputs.Length; i++)
            {
                outputs[i] = i;
            }

            Accord.MachineLearning.Structures.KDTree <int> tree =
                Accord.MachineLearning.Structures.KDTree.FromData(superMatrix,
                                                                  outputs,
                                                                  Accord.Math.Distance.Euclidean, inPlace: true);
            sw1.Stop();
            indexingTime = sw1.ElapsedMilliseconds;
            logWriter(string.Format("Intializing KD Tree: {0}", indexingTime));


            //--------------Saving Indexed Records
            sw1.Reset(); sw1.Start();
            SurfAccordDataSet surfAccordDataset = new SurfAccordDataSet
            {
                SurfImageIndexRecord = observerSurfImageIndexList,
                IndexedTree          = tree
            };
            string repoFileStoragePath = Path.Combine(DirectoryHelper.SaveDirectoryPath, "SurfAccordDataSet.bin");
            if (File.Exists(repoFileStoragePath))
            {
                File.Delete(repoFileStoragePath);
            }
            using (FileStream s = File.Create(repoFileStoragePath))
            {
                //Polenter.Serialization.SharpSerializerBinarySettings bs =
                //    new Polenter.Serialization.SharpSerializerBinarySettings(Polenter.Serialization.BinarySerializationMode.SizeOptimized);
                //Polenter.Serialization.SharpSerializer formatter = new Polenter.Serialization.SharpSerializer(bs);
                //formatter.Serialize(surfAccordDataset, s);
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter
                    = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                formatter.Serialize(s, surfAccordDataset);
                s.Close();
            }
            sw1.Stop();
            saveingTime = sw1.ElapsedMilliseconds;
            logWriter(string.Format("Saving Surf Accord Dataset: {0}", saveingTime));


            //Invalidating Cache
            CacheHelper.Remove("SurfAccordDataSet");
            CacheHelper.Remove("SurfAccordIntervalTree");

            logWriter(string.Format("Reading: {0} ms, Indexing: {1} ms, Saving Indexed data {2}", readingTime, indexingTime, saveingTime));
        }
예제 #33
0
 public void IndexFilesAsync(FileInfo[] imageFiles, System.ComponentModel.BackgroundWorker IndexBgWorker,
     Action<string> logWriter,
     SurfSettings surfSetting = null)
 {
     throw new NotImplementedException();
 }
 public AccordSurfWindow(string modelImagePath, string observerImagePath, SurfSettings setting) : this()
 {
     this.ModelImagePath    = modelImagePath;
     this.ObserverImagePath = observerImagePath;
     this.SurfSetting       = setting;
 }
예제 #35
0
        public static void MatchInWindow(string modelImagePath, string observedImagePath, SurfSettings surfSettings)
        {
            long matchTime;

            using (Image <Gray, Byte> modelImage = new Image <Gray, byte>(modelImagePath))
                using (Image <Gray, Byte> observedImage = new Image <Gray, byte>(observedImagePath))
                {
                    Image <Bgr, byte> result = Draw(modelImage, observedImage, surfSettings, out matchTime);
                    ImageViewer.Show(result, String.Format("Matched using {0} in {1} milliseconds", GpuInvoke.HasCuda ? "GPU" : "CPU", matchTime));
                }
        }
예제 #36
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();
            Stopwatch sw1 = new Stopwatch();
            long _loadingTime = 0, _modelImageDectionlong = 0, _queryingTime = 0, _matchingTime = 0;
            #endregion Diagnostic Region

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

            if (surfSetting != null)
            {
                hessianThresh = surfSetting.HessianThresh.Value;
                uniquenessThreshold = surfSetting.UniquenessThreshold.Value;
                minGoodMatchPercent = surfSetting.GoodMatchThreshold.Value;
            }
            float hessianThreshold2 = (float)hessianThresh / 1000000;
            SpeededUpRobustFeaturesDetector surf = new SpeededUpRobustFeaturesDetector(hessianThreshold2);
            #endregion Surf Dectator Region

            #region Get Model Dectection and Validation
            sw.Reset(); sw.Start();
            List<SpeededUpRobustFeaturePoint> modelImageSurfPoints;
            using (Bitmap modelImage = (Bitmap)Image.FromFile(queryImagePath))
            {
                modelImageSurfPoints = surf.ProcessImage(modelImage);
            }

            if (modelImageSurfPoints == null
                || modelImageSurfPoints.Count < 4)
            {
                throw new InvalidOperationException("Insuffucient interesting point in query image, try another query image");
            }
            sw.Stop();
            _modelImageDectionlong = sw.ElapsedMilliseconds;
            #endregion

            #region Search Images
            sw.Reset(); sw.Start();
            string fullFileName = Path.Combine(DirectoryHelper.SaveDirectoryPath, "SurfAccordLinear.bin");
            if (!File.Exists(fullFileName))
            {
                string exMsg = string.Format("Can't get the Surf Index at {0}, please index first", fullFileName);
                throw new FileNotFoundException(fullFileName);
            }
            using (FileStream fs = new FileStream(fullFileName, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf
                   = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                long fileLength = fs.Length;
                while (fs.Position < fileLength)
                {
                    SURFAccordRecord3 record = (SURFAccordRecord3)bf.Deserialize(fs);
                    KNearestNeighborMatching matcher = new KNearestNeighborMatching(2);
                    matcher.Threshold = uniquenessThreshold;
                    sw1.Start();
                    AForge.IntPoint[][] matches = matcher.Match(modelImageSurfPoints, record.SurfDescriptors);
                    sw1.Stop();
                    var countOfMatchPoint = matches[0].Length;
                    if (countOfMatchPoint > 0)
                    {
                        double totalnumberOfModelFeature = modelImageSurfPoints.Count;
                        double matchPercentage = ((totalnumberOfModelFeature - (double)countOfMatchPoint) / totalnumberOfModelFeature);
                        matchPercentage = (1 - matchPercentage) * 100;
                        matchPercentage = Math.Round(matchPercentage);
                        if (matchPercentage >= minGoodMatchPercent)
                        {
                            record.Distance = matchPercentage;
                            rtnImageList.Add(record.Clone());
                        }
                    }
                    record = null;
                }
                fs.Close();
            }
            sw.Stop();
            _matchingTime = sw1.ElapsedMilliseconds;
            _queryingTime = sw.ElapsedMilliseconds;
            #endregion

            string msg = String.Format("Loading: {0}, Model detection: {1}, Querying: {2}, Matching: {3}",
                                                _loadingTime, _modelImageDectionlong, _queryingTime, _matchingTime);
            messageToLog = msg;

            if (rtnImageList.Count > 0)
            {
                rtnImageList = rtnImageList.OrderByDescending(rec => rec.Distance)
                                       .ToList<ImageRecord>();
            }
            return rtnImageList;
        }
예제 #37
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;
        }