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); }
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); }
public Match( DatabaseFin unknownFin, DarwinDatabase db, UpdateDisplayOutlinesDelegate updateOutlines, RegistrationMethodType registrationMethod, bool useFullFinError) : this(unknownFin, db, updateOutlines) { SetMatchOptions(registrationMethod, useFullFinError); }
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); }
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); }
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); }
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."); }
// 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); }