Example #1
0
        public Match(
            DatabaseFin unknownFin,
            DarwinDatabase db,
            UpdateDisplayOutlinesDelegate updateOutlines,
            List <MatchFactor> matchFactors,
            bool createDefaultFactors = false)
            : this(unknownFin, db, updateOutlines)
        {
            if (!createDefaultFactors)
            {
                MatchFactors = matchFactors;
            }
            else if (Database.CatalogScheme != null)
            {
                switch (db.CatalogScheme.FeatureSetType)
                {
                case FeatureSetType.DorsalFin:
                    SetMatchOptions(RegistrationMethodType.TrimOptimalTip, true);
                    break;

                case FeatureSetType.Bear:
                    MatchFactors = MatchFactorPresets.CreateBearMatchFactors(db);
                    break;
                }
            }

            CheckUnknownForRequiredFeatures();

            // Force rediscovery (for debugging/testing, can uncomment
            //UnknownFin.FinOutline.RediscoverFeaturePoints(Database.CatalogScheme.FeatureSetType);
        }
Example #2
0
        public static List <MatchFactor> CreateBearMatchFactorsOld(DarwinDatabase database)
        {
            var matchFactors = new List <MatchFactor>();

            var controlPoints = new List <FeaturePointType>()
            {
                FeaturePointType.Nasion,
                FeaturePointType.Tip,
                FeaturePointType.PointOfInflection
            };

            var benchmarkFeatures = new List <FeaturePointType>()
            {
                FeaturePointType.Nasion,
                FeaturePointType.Tip
                //FeaturePointType.Tip,
                //FeaturePointType.Notch
            };

            var landmarkFeatures = new List <FeaturePointType>()
            {
                //FeaturePointType.LeadingEdgeBegin,
                FeaturePointType.Tip,
                FeaturePointType.Nasion,
                FeaturePointType.Notch,
                FeaturePointType.UpperLip,
                FeaturePointType.PointOfInflection
            };

            matchFactors.Add(MatchFactor.CreateOutlineFactor(
                                 0.6f,
                                 controlPoints,
                                 //OutlineErrorFunctions.MeanSquaredErrorBetweenOutlinesWithControlPoints,
                                 OutlineErrorFunctions.MeanSquaredErrorBetweenOutlineSegments,
                                 OutlineErrorFunctions.FindErrorBetweenOutlinesWithControlPointJitter,
                                 new OutlineMatchOptions
            {
                MoveTip          = true,
                MoveEndsInAndOut = false,
                UseFullFinError  = true
            }));

            matchFactors.Add(MatchFactor.CreateFeaturePointFactor(
                                 0.4f,
                                 benchmarkFeatures,
                                 landmarkFeatures,
                                 5, // Number of desired ratios
                                 database.AllFins,
                                 //FeaturePointErrorFunctions.ComputeEigenValueWeightedCosineDistance,
                                 FeaturePointErrorFunctions.ComputeMahalanobisDistance,
                                 new FeatureSetMatchOptions
            {
                UseRemappedOutline = false
            }));

            return(matchFactors);
        }
Example #3
0
 public Match(
     DatabaseFin unknownFin,
     DarwinDatabase db,
     UpdateDisplayOutlinesDelegate updateOutlines,
     RegistrationMethodType registrationMethod,
     bool useFullFinError)
     : this(unknownFin, db, updateOutlines)
 {
     SetMatchOptions(registrationMethod, useFullFinError);
 }
Example #4
0
        public Match(
            DatabaseFin unknownFin,
            DarwinDatabase db,
            UpdateDisplayOutlinesDelegate updateOutlines)
        {
            if (unknownFin == null)
            {
                throw new ArgumentNullException(nameof(unknownFin));
            }

            if (db == null)
            {
                throw new ArgumentNullException(nameof(db));
            }

            UnknownFin      = new DatabaseFin(unknownFin);
            Database        = db;
            _updateOutlines = updateOutlines;

            CurrentFinIndex = 0;

            MatchResults = new MatchResults(unknownFin.IDCode, unknownFin?.FinFilename, db?.Filename);
        }
Example #5
0
        public static List <MatchFactor> CreateBearMatchFactors(DarwinDatabase database)
        {
            var matchFactors = new List <MatchFactor>();

            var controlPoints = new List <FeaturePointType>()
            {
                FeaturePointType.Nasion,
                FeaturePointType.Tip,
                FeaturePointType.PointOfInflection,

                // Our alternate control point to also try a mapping on
                FeaturePointType.BottomLipProtrusion
            };

            matchFactors.Add(MatchFactor.CreateOutlineFactor(
                                 0.55f,
                                 controlPoints,
                                 //OutlineErrorFunctions.MeanSquaredErrorBetweenOutlinesWithControlPoints,
                                 OutlineErrorFunctions.MeanSquaredErrorBetweenOutlineSegments,
                                 OutlineErrorFunctions.FindErrorBetweenOutlinesWithControlPointJitter,
                                 new OutlineMatchOptions
            {
                MoveTip                = true,
                MoveEndsInAndOut       = false,
                UseFullFinError        = true,
                JumpDistancePercentage = 0.01f,
                TrimBeginLeadingEdge   = true,

                // Also need to make sure there are 4 control points passed in if this is true
                TryAlternateControlPoint3 = false
            }));

            matchFactors.Add(MatchFactor.CreateFeatureFactor(
                                 0.1f,
                                 FeatureErrorFunctions.ComputeCurvatureError,
                                 FeatureType.BrowCurvature));

            matchFactors.Add(MatchFactor.CreateFeatureFactor(
                                 0.05f,
                                 FeatureErrorFunctions.ComputeMouthDentError,
                                 FeatureType.HasMouthDent));

            var benchmarkFeatures = new List <FeaturePointType>()
            {
                //FeaturePointType.Nasion,
                //FeaturePointType.Tip
                FeaturePointType.Tip,
                FeaturePointType.Notch
            };

            var landmarkFeatures = new List <FeaturePointType>()
            {
                //FeaturePointType.LeadingEdgeBegin,
                FeaturePointType.Tip,
                FeaturePointType.Nasion,
                FeaturePointType.Notch,
                FeaturePointType.UpperLip,
                FeaturePointType.PointOfInflection
            };

            matchFactors.Add(MatchFactor.CreateFeaturePointFactor(
                                 0.35f,
                                 benchmarkFeatures,
                                 landmarkFeatures,

                                 // Pass in a specific set of ratios.  If not passed, it'll automatically
                                 // compute the ratio permutations of all the landmarks we pass in.
                                 //GetVerticalFeaturePointCombinations(),

                                 5, // Number of desired ratios
                                 database.AllFins,
                                 //FeaturePointErrorFunctions.ComputeEigenValueWeightedCosineDistance,
                                 FeaturePointErrorFunctions.ComputeMahalanobisDistance,

                                 // The option below will compare after using the lowest error mapping
                                 // from the outline error function above, assuming there's an outline error
                                 // function before this.
                                 new FeatureSetMatchOptions
            {
                UseRemappedOutline = false
            }));

            return(matchFactors);
        }
Example #6
0
        public static List <MatchFactor> CreateBearMatchFactorsOld2(DarwinDatabase database)
        {
            var matchFactors = new List <MatchFactor>();

            var controlPoints = new List <FeaturePointType>()
            {
                FeaturePointType.Nasion,
                FeaturePointType.Tip,
                FeaturePointType.PointOfInflection,

                // Our alternate control point to also try a mapping on
                FeaturePointType.BottomLipProtrusion
            };

            matchFactors.Add(MatchFactor.CreateOutlineFactor(
                                 0.55f,
                                 controlPoints,
                                 //OutlineErrorFunctions.MeanSquaredErrorBetweenOutlinesWithControlPoints,
                                 OutlineErrorFunctions.MeanSquaredErrorBetweenOutlineSegments,
                                 OutlineErrorFunctions.FindErrorBetweenOutlinesWithControlPointJitter,
                                 new OutlineMatchOptions
            {
                MoveTip                   = true,
                MoveEndsInAndOut          = false,
                UseFullFinError           = true,
                JumpDistancePercentage    = 0.01f,
                TrimBeginLeadingEdge      = true,
                TryAlternateControlPoint3 = true
            }));

            matchFactors.Add(MatchFactor.CreateFeatureFactor(
                                 0.1f,
                                 FeatureErrorFunctions.ComputeCurvatureError,
                                 FeatureType.BrowCurvature));

            matchFactors.Add(MatchFactor.CreateFeatureFactor(
                                 0.05f,
                                 FeatureErrorFunctions.ComputeMouthDentError,
                                 FeatureType.HasMouthDent));

            var benchmarkFeatures = new List <FeaturePointType>()
            {
                FeaturePointType.Nasion,
                FeaturePointType.Tip
                //FeaturePointType.Tip,
                //FeaturePointType.Notch
            };

            var landmarkFeatures = new List <FeaturePointType>()
            {
                //FeaturePointType.LeadingEdgeBegin,
                FeaturePointType.Tip,
                FeaturePointType.Nasion,
                FeaturePointType.Notch,
                FeaturePointType.UpperLip,
                FeaturePointType.PointOfInflection
            };

            matchFactors.Add(MatchFactor.CreateFeaturePointFactor(
                                 0.35f,
                                 benchmarkFeatures,
                                 landmarkFeatures,
                                 5, // Number of desired ratios
                                 database.AllFins,
                                 //FeaturePointErrorFunctions.ComputeEigenValueWeightedCosineDistance,
                                 FeaturePointErrorFunctions.ComputeMahalanobisDistance,
                                 new FeatureSetMatchOptions
            {
                UseRemappedOutline = false
            }));

            return(matchFactors);
        }
Example #7
0
        public static void SaveDatasetImages(string datasetDirectory, DarwinDatabase database)
        {
            if (datasetDirectory == null)
            {
                throw new ArgumentNullException(nameof(datasetDirectory));
            }

            if (database == null)
            {
                throw new ArgumentNullException(nameof(database));
            }

            if (!Directory.Exists(datasetDirectory))
            {
                throw new ArgumentOutOfRangeException(nameof(datasetDirectory));
            }

            Trace.WriteLine("Starting dataset export...");

            string fullImagesDirectory = Path.Combine(datasetDirectory, ImagesDirectoryName);

            Directory.CreateDirectory(fullImagesDirectory);

            var csvRecords = new List <MLCsvRecord>();

            int individualNum = 1;

            foreach (var dbFin in database.AllFins)
            {
                var fin = CatalogSupport.FullyLoadFin(dbFin);

                if (!string.IsNullOrEmpty(fin?.IDCode))
                {
                    Trace.WriteLine("Exporting " + fin.IDCode);
                }

                if (fin.FinOutline.FeatureSet.CoordinateFeaturePoints == null ||
                    fin.FinOutline.FeatureSet.CoordinateFeaturePoints.Count < 1 ||
                    !fin.FinOutline.FeatureSet.CoordinateFeaturePoints.ContainsKey(Features.FeaturePointType.Eye))
                {
                    // If we don't have the features we need, skip to the next one
                    continue;
                }

                var mlImage = ConvertDatabaseFinToMLImage(fin.FinImage, fin.FinOutline.ChainPoints, fin.Scale);

                string imageFilename = individualNum.ToString().PadLeft(6, '0') + ".jpg";

                mlImage.Image.Save(Path.Combine(fullImagesDirectory, imageFilename), ImageFormat.Jpeg);

                csvRecords.Add(new MLCsvRecord
                {
                    image       = imageFilename,
                    eye_x       = mlImage.XRatio * (float)(fin.FinOutline.FeatureSet.CoordinateFeaturePoints[Features.FeaturePointType.Eye].Coordinate.X / fin.Scale - mlImage.XMin),
                    eye_y       = mlImage.YRatio * (float)(fin.FinOutline.FeatureSet.CoordinateFeaturePoints[Features.FeaturePointType.Eye].Coordinate.Y / fin.Scale - mlImage.YMin),
                    nasalfold_x = mlImage.XRatio * (float)(fin.FinOutline.FeatureSet.CoordinateFeaturePoints[Features.FeaturePointType.NasalLateralCommissure].Coordinate.X / fin.Scale - mlImage.XMin),
                    nasalfold_y = mlImage.YRatio * (float)(fin.FinOutline.FeatureSet.CoordinateFeaturePoints[Features.FeaturePointType.NasalLateralCommissure].Coordinate.Y / fin.Scale - mlImage.YMin)
                });

                individualNum += 1;
            }

            using (var writer = new StreamWriter(Path.Combine(datasetDirectory, CsvFilename), false))
                using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
                {
                    csv.WriteRecords(csvRecords);
                }

            Trace.WriteLine("done.");
        }
Example #8
0
        //  1.1 - the following functions used in MatchQueue context

        public static MatchResults Load(string fileName, out DarwinDatabase db, out DatabaseFin databaseFin)
        {
            MatchResults result = new MatchResults();

            db          = null;
            databaseFin = null;

            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException(nameof(fileName));
            }

            if (!File.Exists(fileName))
            {
                throw new ArgumentOutOfRangeException(nameof(fileName));
            }

            var lines = File.ReadAllLines(fileName);

            if (lines.Length < 6 || !lines[0].StartsWith("Results for ID:"))
            {
                return(result);
            }

            result._finID = lines[0].Substring(lines[0].LastIndexOf(":") + 1).Trim();

            result.TracedFinFile = lines[1].Substring(lines[1].IndexOf(":") + 1).Trim();
            result.DatabaseFile  = lines[2].Substring(lines[2].IndexOf(":") + 1).Trim();

            db = CatalogSupport.OpenDatabase(result.DatabaseFile, Options.CurrentUserOptions.DefaultCatalogScheme, false);

            //***2.2 - if we can, determine if database path has just changed drive letter
            // or some part of path that is a prefix to the SurveyArea.  If the database
            // is in the same SurveyArea and has the same database name, then we can
            // proceed with the building of the MatchResults
            //int p = mDatabaseFile.find("surveyAreas");
            //string rqdAreaAndDB = mDatabaseFile.substr(p);  // survey area and database name
            //string rqdPreamble = mDatabaseFile.substr(0, p);    // strip it to get preamble

            //string currentDBFile = db->getFilename();
            //p = currentDBFile.find("surveyAreas");
            //string currentAreaAndDB = currentDBFile.substr(p); // survey area and catalog name
            //string currentPreamble = currentDBFile.substr(0, p); // strip it to get preamble

            //if (db.Filename.ToLower() != DatabaseFile.ToLower())
            //{
            //    //cout << mDatabaseFile << endl;
            //    //cout << rqdPreamble << "   " << rqdAreaAndDB << endl;
            //    //cout << currentDBFile << endl;
            //    //cout << currentPreamble << "   " << currentAreaAndDB << endl;

            //    if (currentAreaAndDB == rqdAreaAndDB)
            //    {
            //        string msg = "The Survey Area and Catalog for the match results appear corrrect,\n";
            //        msg += "but the path to DARWIN's home folder seems to have changed.\n";
            //        msg += "Is it OK to open the indicated catalog in the current location\n";
            //        msg += "as shown below?\n\n";
            //        msg += (currentPreamble + rqdAreaAndDB);

            //        Trace.WriteLine(msg);
            //        //ErrorDialog *err = new ErrorDialog(msg);
            //        //err->show();

            //        //***2.2 - path possibly has to be fixed to FIN file as well
            //        if ((currentDBFile != mDatabaseFile) && (currentAreaAndDB == rqdAreaAndDB))
            //        {
            //            //add preamble of current DARWINHOME to FINs relative location
            //            p = mTracedFinFile.find("surveyAreas");
            //            string currentFinAreaPlus = mTracedFinFile.substr(p);
            //            mTracedFinFile = currentPreamble + currentFinAreaPlus;
            //            cout << mTracedFinFile << endl;
            //        }
            //    }
            //    else
            //    {
            //        string msg = "The WRONG database is currently loaded for viewing these results ...\n\n";
            //        msg += "LOADED DB:\n    " + db->getFilename() + "\n\n";
            //        msg += "REQUIRED DB:\n    " + mDatabaseFile + "\n\n";
            //        msg += "Please load the required database from the main window\n";
            //        msg += "and then reload the desired results file.";

            //        //ErrorDialog *err = new ErrorDialog(msg);
            //        //err->show();
            //        //***2.22 - replacing own ErrorDialog with GtkMessageDialogs
            //        GtkWidget* errd = gtk_message_dialog_new(NULL,
            //                                GTK_DIALOG_DESTROY_WITH_PARENT,
            //                                GTK_MESSAGE_ERROR,
            //                                GTK_BUTTONS_CLOSE,
            //                                msg.c_str());
            //        gtk_dialog_run(GTK_DIALOG(errd));
            //        gtk_widget_destroy(errd);
            //        return NULL;
            //    }
            //}

            DatabaseFin unkFin = CatalogSupport.OpenFinz(result.TracedFinFile);

            // get match info on each matched database fin
            // After skipping some of the headers
            for (int i = 6; i < lines.Length; i++)
            {
                string line = lines[i];

                int pos = line.IndexOf("\t");
                //string rank = line.Substring(0, pos);
                line = line.Substring(pos + 1);

                pos = line.IndexOf("\t");
                string error = line.Substring(0, pos);
                line = line.Substring(pos + 1);

                pos = line.IndexOf("\t");
                string dbFinID = line.Substring(0, pos);
                line = line.Substring(pos + 1);

                //cout << "dbFinID[" << dbFinID << "]"; //*** 2.2 - show for now

                string numStr;
                int
                    dbFinPosition,
                    uBegin, uTip, uEnd,
                    dbBegin, dbTip, dbEnd;

                pos           = line.IndexOf("\t");
                numStr        = line.Substring(0, pos);
                line          = line.Substring(pos + 1);
                dbFinPosition = int.Parse(numStr);
                //cout << "[" << dbFinPosition << "]" << endl; //*** 2.2 - show for now

                pos    = line.IndexOf("\t");
                numStr = line.Substring(0, pos);
                uBegin = int.Parse(numStr);
                line   = line.Substring(pos + 1);
                //cout << "[" << uBegin << "]";

                pos    = line.IndexOf("\t");
                numStr = line.Substring(0, pos);
                uTip   = int.Parse(numStr);
                line   = line.Substring(pos + 1);
                //cout << "[" << uTip << "]";

                pos    = line.IndexOf("\t");
                numStr = line.Substring(0, pos);
                uEnd   = int.Parse(numStr);
                line   = line.Substring(pos + 1);
                //cout << "[" << uEnd << "]";

                pos     = line.IndexOf("\t");
                numStr  = line.Substring(0, pos);
                dbBegin = int.Parse(numStr);
                line    = line.Substring(pos + 1);
                //cout << "[" << dbBegin << "]";

                pos    = line.IndexOf("\t");
                numStr = line.Substring(0, pos);
                dbTip  = int.Parse(numStr);
                line   = line.Substring(pos + 1);
                //cout << "[" << dbTip << "]";

                pos    = line.IndexOf("\t");
                numStr = line.Substring(0, pos);
                dbEnd  = int.Parse(numStr);
                line   = line.Substring(pos + 1);
                //cout << "[" << dbEnd << "]";

                //string damage = line;
                //cout << "[" << damage << "]" << endl;

                // The position is written starting at 1, but our index is 0 based
                DatabaseFin thisDBFin = db.AllFins[dbFinPosition - 1];

                // TODO: Should this throw an exception instead?
                if (thisDBFin.IDCode != dbFinID)
                {
                    Trace.WriteLine("Disaster " + thisDBFin.IDCode + " " + dbFinID);
                }

                FloatContour mappedUnknownContour = unkFin.FinOutline.ChainPoints.MapContour(
                    unkFin.FinOutline.ChainPoints[uTip],
                    unkFin.FinOutline.ChainPoints[uBegin],
                    unkFin.FinOutline.ChainPoints[uEnd],
                    thisDBFin.FinOutline.ChainPoints[dbTip],
                    thisDBFin.FinOutline.ChainPoints[dbBegin],
                    thisDBFin.FinOutline.ChainPoints[dbEnd]);

                Result r = new Result(
                    mappedUnknownContour,                 //***1.3 - Mem Leak - constructor make copy now
                    thisDBFin.FinOutline.ChainPoints,     //***1.3 - Mem Leak - constructor make copy now
                    thisDBFin.ID,
                    // TODO - This image filename stuff is a little ugly.
                    (string.IsNullOrEmpty(thisDBFin.OriginalImageFilename)) ? thisDBFin.ImageFilename : thisDBFin.OriginalImageFilename,
                    thisDBFin.ThumbnailFilenameUri,
                    dbFinPosition - 1,     // position of fin in database
                    double.Parse(error),
                    thisDBFin.IDCode,
                    thisDBFin.Name,
                    thisDBFin.DamageCategory,
                    thisDBFin.DateOfSighting,
                    thisDBFin.LocationCode);

                r.SetMappingControlPoints(
                    uBegin, uTip, uEnd,      // beginning, tip & end of unknown fin
                    dbBegin, dbTip, dbEnd);  // beginning, tip & end of database fin

                result.Results.Add(r);
            }

            databaseFin = unkFin;
            result.SetRankings();
            return(result);
        }