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