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); }
private List <LoCaTeRanker> PerformExtendedSurfSearch(string queryImagePath, List <LoCaTeRanker> ImageList) { //If no images are found in Locate, return if (ImageList.Count == 0) { return(ImageList); } SURFDetector surfDectector = new SURFDetector(1000, false); Matrix <float> superMatrix = null; List <SURFRecord1> observerSurfImageIndexList = new List <SURFRecord1>(); #region Computing Model Descriptors Matrix <float> modelDescriptors; VectorOfKeyPoint modelKeyPoints = new VectorOfKeyPoint(); using (Image <Gray, byte> modelImage = new Image <Gray, byte>(queryImagePath)) { modelDescriptors = surfDectector.DetectAndCompute(modelImage, null, modelKeyPoints); } #endregion #region Computing Surf Descriptors int rows = 0; int numProcs = Environment.ProcessorCount; int concurrencyLevel = numProcs * 2; ConcurrentDictionary <long, Matrix <float> > obserableSurfPoints = new ConcurrentDictionary <long, Matrix <float> >(concurrencyLevel, ImageList.Count); Parallel.ForEach(ImageList, img => { string imagePath = img.ImagePath; using (Image <Gray, byte> observerImage = new Image <Gray, byte>(imagePath)) { VectorOfKeyPoint observerKeyPoints = new VectorOfKeyPoint(); Matrix <float> observerDescriptors = surfDectector.DetectAndCompute(observerImage, null, observerKeyPoints); obserableSurfPoints.TryAdd(img.Id, observerDescriptors); } }); foreach (var rec in ImageList) { Matrix <float> observerDescriptors = obserableSurfPoints[rec.Id]; if (superMatrix != null) { superMatrix = superMatrix.ConcateVertical(observerDescriptors); } else { superMatrix = observerDescriptors; } int initRow = rows; int endRows = rows + observerDescriptors.Rows - 1; observerSurfImageIndexList.Add(new SURFRecord1 { Id = rec.Id, ImageName = rec.ImageName, ImagePath = rec.ImagePath, IndexStart = rows, IndexEnd = endRows, Distance = 0 }); rows = endRows + 1; } //foreach (var rec in ImageList) //{ // string imagePath = rec.ImagePath; // using (Image<Gray, byte> observerImage = new Image<Gray, byte>(imagePath)) // { // VectorOfKeyPoint observerKeyPoints = new VectorOfKeyPoint(); // Matrix<float> observerDescriptors = surfDectector.DetectAndCompute(observerImage, null, observerKeyPoints); // if (superMatrix != null) // superMatrix = superMatrix.ConcateVertical(observerDescriptors); // else // superMatrix = observerDescriptors; // int initRow = rows; int endRows = rows + observerDescriptors.Rows - 1; // observerSurfImageIndexList.Add(new SURFRecord1 // { // Id = rec.Id, // ImageName = rec.ImageName, // ImagePath = rec.ImagePath, // IndexStart = rows, // IndexEnd = endRows, // Distance = 0 // }); // rows = endRows + 1; // } //} #endregion Emgu.CV.Flann.Index flannIndex = new Emgu.CV.Flann.Index(superMatrix, 4); var indices = new Matrix <int>(modelDescriptors.Rows, 2); // matrix that will contain indices of the 2-nearest neighbors found var dists = new Matrix <float>(modelDescriptors.Rows, 2); // matrix that will contain distances to the 2-nearest neighbors found flannIndex.KnnSearch(modelDescriptors, indices, dists, 2, 24); IntervalTreeHelper.CreateTree(observerSurfImageIndexList); for (int i = 0; i < indices.Rows; i++) { // filter out all inadequate pairs based on distance between pairs if (dists.Data[i, 0] < (0.3 * dists.Data[i, 1])) { var img = IntervalTreeHelper.GetImageforRange(indices[i, 0]); if (img != null) { img.Distance++; } } } int maxMatch = Convert.ToInt32(observerSurfImageIndexList.Select(rec => rec.Distance).Max()); observerSurfImageIndexList = observerSurfImageIndexList.OrderByDescending(rec => rec.Distance).ToList(); int totalImageCount = observerSurfImageIndexList.Count; for (int i = 0; i < totalImageCount; i++) { long id = observerSurfImageIndexList[i].Id; var img2 = ImageList.Where(img => img.Id == id).SingleOrDefault(); if (img2 != null) { double countofMatch = observerSurfImageIndexList[i].Distance; if (countofMatch > 0) { img2.SurfRank = (totalImageCount - i); } } } return(ImageList); }