private static byte[] SaveDatabase(PhotoFingerPrintDatabaseWrapper database) { var builder = new FlatBufferBuilder(DefaultBufferSize); CreatePhotoFingerPrintDatabase(database, builder); return(builder.SizedByteArray()); }
/// <summary> /// Save a fingerprint database to a file /// </summary> /// <param name="database">The database to save</param> /// <param name="filePath">The file path to save it to</param> public static void Save(PhotoFingerPrintDatabaseWrapper database, string filePath) { byte[] rawDatabaseBytes = SaveDatabase(database); using (BinaryWriter writer = new BinaryWriter(File.Open(filePath, FileMode.Create))) { writer.Write(rawDatabaseBytes); } }
private static void CreatePhotoFingerPrintDatabase(PhotoFingerPrintDatabaseWrapper database, FlatBufferBuilder builder) { Offset <PhotoFingerPrint>[] photoFingerPrintArray = CreatePhotoFingerPrintArray(database, builder); VectorOffset photoFingerPrintDatabaseVectorOffset = PhotoFingerPrintDatabase.CreateFingerPrintsVector(builder, photoFingerPrintArray); Offset <PhotoFingerPrintDatabase> databaseOffset = PhotoFingerPrintDatabase.CreatePhotoFingerPrintDatabase(builder, photoFingerPrintDatabaseVectorOffset); PhotoFingerPrintDatabase.FinishPhotoFingerPrintDatabaseBuffer(builder, databaseOffset); }
private static IDictionary <string, ISet <PhotoFingerPrintWrapper> > MapPhotosToVideos( PhotoFingerPrintDatabaseWrapper photoDatabase, VideoFingerPrintDatabaseMetaTableWrapper metatable ) { IDictionary <string, ISet <PhotoFingerPrintWrapper> > resultMap = new Dictionary <string, ISet <PhotoFingerPrintWrapper> >(); IDictionary <string, VideoFingerPrintWrapper> fileNameToVideoFingerPrintMap = MetaTableUtils.EnumerateVideoFingerPrints(metatable).ToDictionary(e => e.FilePath); BKTree <FrameMetricWrapper> bktree = ModelMetricUtils.CreateBKTree(metatable); foreach (PhotoFingerPrintWrapper photo in photoDatabase.PhotoFingerPrints) { // 1. Find bucket of possible candidates IDictionary <FrameMetricWrapper, int> treeResults = bktree.Query( new PhotoMetricWrapper { Photo = photo, }, DefaultMetricThreshold ); IDictionary <string, ISet <FrameMetricWrapper> > collapsedTreeResults = ModelMetricUtils.CollapseTreeResults(treeResults); // 2. Find most likely result and add it to the bucket if (treeResults.Count > 0) { VideoFingerPrintWrapper mostLikelyVideo = FindMostLikelyVideo(photo, collapsedTreeResults, fileNameToVideoFingerPrintMap); // In the case where we didn't get any results, we just skip this photo and move alone if (mostLikelyVideo == null) { continue; } ISet <PhotoFingerPrintWrapper> bucket; string videoFileName = mostLikelyVideo.FilePath; if (resultMap.TryGetValue(videoFileName, out bucket) == false) { bucket = new HashSet <PhotoFingerPrintWrapper>(); resultMap.Add(videoFileName, bucket); } } } return(resultMap); }
private static void ExecuteSearch(string[] args) { string photoFile = GetPhotoPath(args); string databaseFile = GetDatabasePath(args); if (string.IsNullOrWhiteSpace(photoFile) || string.IsNullOrWhiteSpace(databaseFile)) { PrintHelp("Photo path or database path not provided"); return; } if (File.Exists(photoFile) == false) { PrintHelp("Photo file does not exist"); return; } if (File.Exists(databaseFile) == false) { PrintHelp("Database does not exist"); return; } using (Image frame = Image.FromFile(photoFile)) { PhotoFingerPrintDatabaseWrapper database = PhotoFingerPrintDatabaseLoader.Load(databaseFile); ulong imageHash = FrameIndexer.CalculateFramePerceptionHashOnly(frame); var results = from fingerPrint in database.PhotoFingerPrints.AsParallel() let distance = DistanceCalculator.CalculateHammingDistance(imageHash, fingerPrint.PHash) where distance < 5 orderby distance select new { Distance = distance, FilePath = fingerPrint.FilePath }; foreach (var result in results) { Console.WriteLine(string.Format("{0} - {1}", result.Distance, result.FilePath)); } } }
private static void ExecuteIndex(string[] args) { IEnumerable <string> photoFiles = GetPhotoPaths(args).Distinct(); string databaseFile = GetDatabasePath(args); if (photoFiles.Any() == false || string.IsNullOrWhiteSpace(databaseFile)) { PrintHelp("Photo file or database path not provided"); return; } PhotoFingerPrintDatabaseWrapper database = File.Exists(databaseFile) ? PhotoFingerPrintDatabaseLoader.Load(databaseFile) : new PhotoFingerPrintDatabaseWrapper(); IEnumerable <PhotoFingerPrintWrapper> fingerPrintBag = IndexPhotosImpl(photoFiles, database); database.PhotoFingerPrints = fingerPrintBag.ToArray(); PhotoFingerPrintDatabaseSaver.Save(database, databaseFile); }
private static Offset <PhotoFingerPrint>[] CreatePhotoFingerPrintArray(PhotoFingerPrintDatabaseWrapper database, FlatBufferBuilder builder) { int photoFingerPrintCounter = 0; var photoFingerPrintArray = new Offset <PhotoFingerPrint> [database.PhotoFingerPrints.Length]; foreach (PhotoFingerPrintWrapper fingerPrint in database.PhotoFingerPrints) { StringOffset filePathOffset = builder.CreateString(fingerPrint.FilePath); VectorOffset grayScaleImageOffset = PhotoFingerPrint.CreateEdgeGrayScaleThumbVector(builder, fingerPrint.EdgeGrayScaleThumb); PhotoFingerPrint.StartPhotoFingerPrint(builder); PhotoFingerPrint.AddFilePath(builder, filePathOffset); PhotoFingerPrint.AddPhash(builder, fingerPrint.PHash); PhotoFingerPrint.AddEdgeGrayScaleThumb(builder, grayScaleImageOffset); photoFingerPrintArray[photoFingerPrintCounter] = PhotoFingerPrint.EndPhotoFingerPrint(builder); photoFingerPrintCounter++; } return(photoFingerPrintArray); }
public void TestPhotoIndexerSerialization() { var photoFingerPrint = new PhotoFingerPrintWrapper { FilePath = "test.png", PHash = 0x0A, EdgeGrayScaleThumb = new byte[] { 0, 1, 1 }, }; var database = new PhotoFingerPrintDatabaseWrapper { PhotoFingerPrints = new[] { photoFingerPrint }, }; using (var memoryStream = new MemoryStream()) { PhotoFingerPrintDatabaseSaver.Save(database, memoryStream); byte[] savedDatabase = memoryStream.ToArray(); PhotoFingerPrintDatabaseWrapper reloadedDatabase = PhotoFingerPrintDatabaseLoader.Load(savedDatabase); Assert.AreEqual(database, reloadedDatabase); } }
/// <summary> /// Save a fingerprint database to a stream /// </summary> /// <param name="database">The database to save</param> /// <param name="outStream">The stream to write to</param> public static void Save(PhotoFingerPrintDatabaseWrapper database, Stream outStream) { byte[] buffer = SaveDatabase(database); outStream.Write(buffer, 0, buffer.Length); }
private static IEnumerable <PhotoFingerPrintWrapper> IndexPhotosImpl(IEnumerable <string> photoFiles, PhotoFingerPrintDatabaseWrapper database) { PhotoFileReaderExecutor photoReader = new PhotoFileReaderExecutor(photoFiles, 3); PhotoFileIndexerExecutor photoIndexer = new PhotoFileIndexerExecutor(photoReader, 4); Task photoReaderTask = photoReader.LoadPhotos(); Task photoIndexerTask = photoIndexer.Start(); Task.WaitAll(photoReaderTask, photoIndexerTask); return(photoIndexer.GetFingerPrints()); }