static void Main()
        {
            var photos   = PhotoMetadataCsv.FromCSV(GALLERY_CSV).ToList();
            var sketches = PhotoMetadataCsv.FromCSV(SKETCHS_CSV).ToList();

            var extractor = TestUtils.GetPhotoSketchFeatureExtractor(Params.GetReferenceShape());
            // extract or load from dumped db
            //var db = ExtractFeaturesDB(extractor, true);
            var db   = FaceFeaturesDB.CreateFromDump(DUMPED_DB);
            var cbir = new PhotoSketchCBIR(extractor)
            {
                Database = db
            };

            TestSingleComponents(cbir, sketches);
            TestDifferentFusion(cbir, sketches);
            TestBestCBR(cbir, sketches);
        }
        // Compute the average image
        private static void GlobalAvgImage()
        {
            var photos   = PhotoMetadataCsv.FromCSV(GALLERY_CSV).ToList();
            var sketches = PhotoMetadataCsv.FromCSV(SKETCHS_CSV).ToList();

            var boundingParams   = Params.GetComponentBoundingBoxParams();
            var alignerExtractor = ComponentAlignerFactory.FromReferenceShape(boundingParams, Params.GetReferenceShape());

            // compute average images
            //var images = new List<Image<Gray, byte>>();
            var photosComponents = new List <FaceComponentContainer>();

            foreach (var photo in sketches)
            {
                try
                {
                    var img = Normalization.Preprocessing.PreprocessImage(photo.AbsolutePath);
                    //images.Add(img);
                    var container = alignerExtractor.ExtractComponentsFromImage(img);
                    photosComponents.Add(container);
                }
                catch (IndexOutOfRangeException e) { }
                catch (ArgumentException e) { }
            }

            var hair     = photosComponents.Select(c => c.Hair).ToArray();
            var eyes     = photosComponents.Select(c => c.Eyes).ToArray();
            var eyebrows = photosComponents.Select(c => c.Eyebrows).ToArray();
            var nose     = photosComponents.Select(c => c.Nose).ToArray();
            var mouth    = photosComponents.Select(c => c.Mouth).ToArray();

            ImageViewer.Show(ImageUtils.CreateAvgImage(160, 80, hair));
            ImageViewer.Show(ImageUtils.CreateAvgImage(144, 29, eyebrows));
            ImageViewer.Show(ImageUtils.CreateAvgImage(144, 29, eyes));
            ImageViewer.Show(ImageUtils.CreateAvgImage(96, 96, nose));
            ImageViewer.Show(ImageUtils.CreateAvgImage(160, 80, mouth));
            //ImageViewer.Show(ImageUtils.CreateAvgImage(200, 250, images));
        }
        public TaskExtractGalleryFeatures(PhotoSketchFeatureExtractor extractor, string galleryPath)
        {
            WorkerReportsProgress = true;
            DoWork += (s, e) =>
            {
                var db              = new FaceFeaturesDB();
                var photos          = PhotoMetadataCsv.FromCSV(galleryPath).ToList();
                var totalPhotos     = photos.Count;
                var currentProgress = 0;

                Parallel.ForEach(photos, photo =>
                {
                    try {
                        var feature = extractor.ExtractFaceFeatures(photo.AbsolutePath);
                        db.AddPhotoFeatures(photo, feature);
                    } catch (ArgumentException) { }

                    Interlocked.Increment(ref currentProgress);
                    ReportProgress((int)(currentProgress / (float)totalPhotos * 100));
                });

                e.Result = db;
            };
        }