public static SURFRecord1 GetImageforRange(int value) { SURFRecord1 rec = null; if (_imageTree == null) { return(rec); } var indexList = _imageTree.Get(value, StubMode.ContainsStartThenEnd); if (indexList.Count > 1 || indexList.Count == 0) { return(rec); } var imageIndex = indexList[0]; rec = ImageList[imageIndex]; return(rec); }
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)); }
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); }
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)); }