diff --git a/.vscode/launch.json b/.vscode/launch.json index 72ffcea..b6c138e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,14 +15,17 @@ "program": "${workspaceFolder}/Instance/bin/Debug/net6.0/win-x64/Instance.dll", "programN": "${workspaceFolder}/Not-Copy-Copy/bin/Debug/net6.0/win-x64/Not-Copy-Copy.dll", "programP": "${workspaceFolder}/PrepareForOld/bin/Debug/net6.0/win-x64/PrepareForOld.dll", - "args": [], + "args": [ + "s" + ], "env": { "ASPNETCORE_ENVIRONMENT": "Development", }, "cwd": "${workspaceFolder}", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console "console": "externalTerminal", - "stopAtEntry": false + "stopAtEntry": false, + "requireExactSource": false } ] } \ No newline at end of file diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index f92ff32..7559321 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -123,6 +123,17 @@ public class DlibDotNet return result; } + private long LogDeltaInSeconds(long ticks, string methodName) + { + long result; + if (_Log is null) + throw new NullReferenceException(nameof(_Log)); + double delta = new TimeSpan(DateTime.Now.Ticks - ticks).Seconds; + _Log.Debug($"{methodName} took {Math.Floor(delta)} seconds(s)"); + result = DateTime.Now.Ticks; + return result; + } + private long LogDeltaInMinutes(long ticks, string methodName) { long result; @@ -606,8 +617,8 @@ public class DlibDotNet } _Log.Information(". . ."); } - if (isSilent && container.SourceDirectory.EndsWith("Bohdi Ray 2016")) // 7#.1 - break; + // if (isSilent && container.SourceDirectory.EndsWith("Bohdi Ray 2016")) // 7#.1 + // break; // if (isSilent && container.SourceDirectory.EndsWith("Halloween 2013")) // 12#.1 // break; // if (isSilent && container.SourceDirectory.EndsWith("zzz =2014.4 Winter Tracy Pictures")) // 30#.2 @@ -654,17 +665,6 @@ public class DlibDotNet foreach (string outputResolution in _Configuration.OutputResolutions) { (aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory, zResultsFullGroupDirectory) = GetResultsFullGroupDirectories(configuration, model, predictorModel, outputResolution); - _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, "{}")); - _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(bResultsFullGroupDirectory, "{}")); - _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, "{}")); - if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution)) - _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(dResultsFullGroupDirectory, "[]")); - if (_Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)) - _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]")); - if (_Configuration.LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions.Contains(outputResolution)) - _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]")); - if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution)) - _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(d2ResultsFullGroupDirectory, "[]")); if (_ArgZeroIsConfigurationRootDirectory && _Exceptions.Count == 0 && outputResolution == _Configuration.OutputResolutions[0] && (propertyLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs.Any() || propertyLogic.NamedDeterministicHashCodeKeyValuePairs.Any())) { if (!string.IsNullOrEmpty(propertyLogic.DeterministicHashCodeRootDirectory) && !propertyLogic.IncorrectDeterministicHashCodeKeyValuePairs.Any()) @@ -688,11 +688,11 @@ public class DlibDotNet eDistanceCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, $"[{ticks}]"); List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection; collection = E_Distance.ParallelWork(_AppSettings.MaxDegreeOfParallelism, argZero, propertyLogic, containers); - _ = LogDeltaInMinutes(ticks, nameof(E_Distance.ParallelWork)); + _ = LogDeltaInSeconds(ticks, nameof(E_Distance.ParallelWork)); E_Distance.SavePropertyHolders(argZero, containers, zPropertyHolderSingletonDirectory); - _ = LogDeltaInMinutes(ticks, nameof(E_Distance.SavePropertyHolders)); + _ = LogDeltaInSeconds(ticks, nameof(E_Distance.SavePropertyHolders)); E_Distance.SaveThreeSigmaFaceEncodings(collection, peopleCollection, eDistanceCollectionDirectory); - _ = LogDeltaInMinutes(ticks, nameof(E_Distance.SaveThreeSigmaFaceEncodings)); + _ = LogDeltaInSeconds(ticks, nameof(E_Distance.SaveThreeSigmaFaceEncodings)); E_Distance.SaveClosest(argZero, containers, peopleCollection, eDistanceContentDirectory, dFacesContentDirectory); _ = LogDeltaInMinutes(ticks, nameof(E_Distance.SaveClosest)); } @@ -708,7 +708,18 @@ public class DlibDotNet identify.WriteAllText(configuration, _Configuration.OutputResolutions[0], identifiedCollection); if (_Configuration.LoadOrCreateThenSaveIndex && _FilePropertiesKeyValuePairs.Any()) _Index.SetIndex(configuration, model, predictorModel, _Configuration.OutputResolutions[0], _FilePropertiesKeyValuePairs); - } + } + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, "{}")); + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(bResultsFullGroupDirectory, "{}")); + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, "{}")); + if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution)) + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(dResultsFullGroupDirectory, "[]")); + if (_Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)) + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]")); + if (_Configuration.LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions.Contains(outputResolution)) + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]")); + if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution)) + _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(d2ResultsFullGroupDirectory, "[]")); } } diff --git a/Instance/Models/_D2_FaceLandmark.cs b/Instance/Models/_D2_FaceLandmark.cs index c89c653..cafc3f3 100644 --- a/Instance/Models/_D2_FaceLandmark.cs +++ b/Instance/Models/_D2_FaceLandmark.cs @@ -3,6 +3,7 @@ using System.Text.Json; using View_by_Distance.Metadata.Models; using View_by_Distance.Property.Models; using View_by_Distance.Resize.Models; +using View_by_Distance.Shared.Models.Properties; using View_by_Distance.Shared.Models.Stateless; namespace View_by_Distance.Instance.Models; @@ -44,9 +45,9 @@ internal class D2_FaceLandmarks { int x; int y; - D_Face face; int width; int height; + D_Face face; string imageFileFullName; Bitmap rotated; string rotatedImageFileFullName; @@ -104,7 +105,7 @@ internal class D2_FaceLandmarks #pragma warning restore CA1416 - internal void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, string sourceDirectory, List> subFileTuples, List parseExceptions, Item item, List faceCollections) + internal void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, string sourceDirectory, List> subFileTuples, List parseExceptions, Item item, List faceCollection) { if (_Configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration)); @@ -118,6 +119,7 @@ internal class D2_FaceLandmarks const int pointSize = 2; FileInfo rotatedFileInfo; DateTime? dateTime = null; + double deterministicHashCodeKey; long ticks = DateTime.Now.Ticks; List imageFiles = new(); bool updateDateWhenMatches = false; @@ -135,14 +137,15 @@ internal class D2_FaceLandmarks List dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); if (!Directory.Exists(facesDirectory)) _ = Directory.CreateDirectory(facesDirectory); - for (int i = 0; i < faceCollections.Count; i++) + foreach (IFace face in faceCollection) { - if (!faceCollections[i].Populated) + if (!face.Populated || face.Location?.NormalizedPixelPercentage is null) { imageFiles.Add(Array.Empty()); continue; } - fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {item.ImageFileHolder.NameWithoutExtension}.png")); + deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face); + fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png")); if (!fileInfo.Exists) { if (fileInfo.Directory?.Parent is null) @@ -153,7 +156,7 @@ internal class D2_FaceLandmarks } if (string.IsNullOrEmpty(fileInfo.DirectoryName)) continue; - rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, string.Concat(Path.GetFileNameWithoutExtension(fileInfo.FullName), " - ", i, " - R", Path.GetExtension(fileInfo.FullName)))); + rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKey} - R{item.ImageFileHolder.ExtensionLowered}")); imageFiles.Add(new string[] { fileInfo.FullName, rotatedFileInfo.FullName }); if (check) continue; @@ -172,7 +175,7 @@ internal class D2_FaceLandmarks } } if (check) - SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, item.ResizedFileHolder); + SaveFaceLandmarkImages(faceCollection, imageFiles, pointSize, item.ResizedFileHolder); } } \ No newline at end of file diff --git a/Instance/Models/_D_Face.cs b/Instance/Models/_D_Face.cs index 6cd0944..a196421 100644 --- a/Instance/Models/_D_Face.cs +++ b/Instance/Models/_D_Face.cs @@ -8,7 +8,7 @@ using View_by_Distance.Metadata.Models; using View_by_Distance.Property.Models; using View_by_Distance.Resize.Models; using View_by_Distance.Shared.Models; -using View_by_Distance.Shared.Models.Methods; +using View_by_Distance.Shared.Models.Properties; using View_by_Distance.Shared.Models.Stateless; using WindowsShortcutFactory; @@ -17,7 +17,7 @@ namespace View_by_Distance.Instance.Models; /// // List /// -public class D_Face : Shared.Models.Properties.IFace, IFace +public class D_Face : IFace, Shared.Models.Methods.IFace { internal List AngleBracketCollection { get; } @@ -116,7 +116,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace _RelativePath = relativePath; } - private D_Face(int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, Shared.Models.Properties.IFace face) + private D_Face(int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, IFace face) { _Α = face.α; _DateTime = face.DateTime; @@ -290,6 +290,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace D_Face? face = null; Rectangle rectangle; double[] rawEncoding; + double deterministicHashCodeKey; Shared.Models.FaceEncoding faceEncoding; FaceRecognitionDotNet.Image? knownImage; FaceRecognitionDotNet.Image? rotatedImage; @@ -368,7 +369,8 @@ public class D_Face : Shared.Models.Properties.IFace, IFace faceEncoding = new(rawEncoding, faceEncodings[0].Size); face.Update(α, faceEncoding, populated: true); } - faceFile = Path.Combine(facesDirectory, $"{i} - {item.ImageFileHolder.NameWithoutExtension}.png"); + deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face); + faceFile = Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"); preRotated.Save(faceFile, System.Drawing.Imaging.ImageFormat.Png); results.Add(face); } @@ -508,6 +510,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace FileInfo fileInfo; bool check = false; string parentCheck; + double deterministicHashCodeKey; List imageFiles = new(); string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) }; string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension); @@ -515,14 +518,15 @@ public class D_Face : Shared.Models.Properties.IFace, IFace bool facesDirectoryExisted = Directory.Exists(facesDirectory); if (!facesDirectoryExisted) _ = Directory.CreateDirectory(facesDirectory); - for (int i = 0; i < faceCollection.Count; i++) + foreach (IFace face in faceCollection) { - if (!faceCollection[i].Populated || faceCollection[i]?.Location is null) + if (!face.Populated || face.Location?.NormalizedPixelPercentage is null) { imageFiles.Add(string.Empty); continue; } - fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {item.ImageFileHolder.NameWithoutExtension}.png")); + deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face); + fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png")); if (!fileInfo.Exists) { if (fileInfo.Directory?.Parent is null) @@ -552,12 +556,12 @@ public class D_Face : Shared.Models.Properties.IFace, IFace WindowsShortcut windowsShortcut; const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]"; string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, $"({ticks})"); - List<(Item, (string, Shared.Models.Properties.IFace?, (string, string, string, string))[])> collections = Item.GetCollection(propertyLogic, items, dFacesContentDirectory); - foreach ((Item item, (string personKey, Shared.Models.Properties.IFace? _, (string, string, string, string))[] collection) in collections) + List<(Item, (string, IFace?, (string, string, string, string))[])> collections = Item.GetCollection(propertyLogic, items, dFacesContentDirectory); + foreach ((Item item, (string personKey, IFace? _, (string, string, string, string))[] collection) in collections) { if (collection.Length != 1) continue; - foreach ((string personKey, Shared.Models.Properties.IFace? _, (string directory, string copyDirectory, string copyFileName, string shortcutFileName)) in collection) + foreach ((string personKey, IFace? _, (string directory, string copyDirectory, string copyFileName, string shortcutFileName)) in collection) { if (string.IsNullOrEmpty(personKey)) continue; diff --git a/Instance/Models/_E_Distance.cs b/Instance/Models/_E_Distance.cs index 09a9718..c02127c 100644 --- a/Instance/Models/_E_Distance.cs +++ b/Instance/Models/_E_Distance.cs @@ -91,7 +91,7 @@ internal class E_Distance for (int i = 0; i < distanceHolders.Count; i++) { distanceHolder = distanceHolders[i]; - if (distanceHolder.Face.Location.NormalizedPixelPercentage is null) + if (distanceHolder.Face.Location?.NormalizedPixelPercentage is null) continue; check = Path.Combine(distanceHolder.JSONDirectory, $"{zero} - {distanceHolder.FileHolder.NameWithoutExtension}.json"); jsonFile = Path.Combine(distanceHolder.JSONDirectory, $"{distanceHolder.Id}.{zero}{distanceHolder.FileHolder.ExtensionLowered}.json"); @@ -149,7 +149,7 @@ internal class E_Distance locationIndex = 0; else locationIndex = distanceHolder.Face.LocationIndex.Value; - if (!distanceHolder.Face.Populated || distanceHolder.Face.Location.NormalizedPixelPercentage is null) + if (!distanceHolder.Face.Populated || distanceHolder.Face.Location?.NormalizedPixelPercentage is null) normalizedPixelPercentage = 0; else normalizedPixelPercentage = distanceHolder.Face.Location.NormalizedPixelPercentage.Value; @@ -266,8 +266,6 @@ internal class E_Distance check = true; else if (hasPopulatedFace && !directoryInfo.Exists) check = true; - else if (hasPopulatedFace && !tvsDirectoryInfo.Exists) - check = true; else if (dateTimes.Any() && dateTimes.Max() > directoryInfo.LastWriteTime) check = true; if (check && !updateDateWhenMatches) @@ -541,7 +539,7 @@ internal class E_Distance else { List faceDistances = FaceRecognition.FaceDistances(tuple.FaceEncodings, faceEncoding); - result = new(face.LocationIndex, tuple.MinimumDateTime, tuple.IsWrongYear, tuple.PersonBirthday, faceDistances); + result = new(face.Location?.NormalizedPixelPercentage, tuple.MinimumDateTime, tuple.IsWrongYear, tuple.PersonBirthday, faceDistances); if (result.Minimum > Closest.MaximumMinimum) result = null; } @@ -563,7 +561,7 @@ internal class E_Distance if (itemIsWrongYear.HasValue && !itemIsWrongYear.Value && itemMinimumDateTime < personBirthday.Value) continue; faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncoding); - closest = new(face.LocationIndex, minimumDateTime, isWrongYear, personBirthday, faceDistances); + closest = new(face.Location?.NormalizedPixelPercentage, minimumDateTime, isWrongYear, personBirthday, faceDistances); if (closest.Minimum > Closest.MaximumMinimum) continue; closestCollection.Add(closest); @@ -596,7 +594,7 @@ internal class E_Distance bool? itemIsWrongYear; Closest[] closestCollection; DateTime? itemMinimumDateTime; - float deterministicHashCodeKey; + double deterministicHashCodeKey; Dictionary results = new(); foreach (Container container in containers) { @@ -618,7 +616,7 @@ internal class E_Distance for (int i = 0; i < item.Faces.Count; i++) { face = item.Faces[i]; - closest = new(face.LocationIndex, itemMinimumDateTime.Value, itemIsWrongYear); + closest = new(face.Location?.NormalizedPixelPercentage, itemMinimumDateTime.Value, itemIsWrongYear); item.Closest.Add(closest); if (!face.Populated) continue; @@ -728,7 +726,7 @@ internal class E_Distance string facesDirectory; string personDirectory; Shared.Models.Person person; - float deterministicHashCodeKey; + double deterministicHashCodeKey; const string facePopulatedKey = "Closest"; const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]"; foreach (Container container in containers) @@ -758,17 +756,17 @@ internal class E_Distance { person = peopleCollection[personKey][0]; personName = Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name); - personDirectory = Path.Combine(directory, Regex.Replace(personName, pattern, string.Empty)); + personDirectory = Path.Combine(directory, Regex.Replace(personName, pattern, string.Empty), "lnk"); results.Add(new(null, personDirectory, null, string.Empty, string.Empty)); } facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension)); - faceFileInfo = new(Path.Combine(facesDirectory, $"{closest.NormalizedPixelPercentage.Value} - {item.ImageFileHolder.NameWithoutExtension}.png")); deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, closest); checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}"); + faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png")); if (string.IsNullOrEmpty(personDirectory)) shortcutFile = string.Empty; else - shortcutFile = Path.Combine(personDirectory, $"{item.ImageFileHolder.ExtensionLowered}.lnk"); + shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk"); results.Add(new(item.ResizedFileHolder, directory, faceFileInfo, checkFile, shortcutFile)); } } @@ -799,11 +797,11 @@ internal class E_Distance else File.Copy(resizedFileHolder.FullName, checkFile); } - foreach ((FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile) in collection) + foreach ((FileHolder? resizedFileHolder, string directory, FileInfo? _, string checkFile, string shortcutFile) in collection) { - if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null || faceFileInfo is null) + if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null) continue; - if (string.IsNullOrEmpty(shortcutFile)) + if (string.IsNullOrEmpty(shortcutFile) || !resizedFileHolder.Exists) continue; try { diff --git a/Instance/appsettings.Development.json b/Instance/appsettings.Development.json index e0d950d..5bd1fe0 100644 --- a/Instance/appsettings.Development.json +++ b/Instance/appsettings.Development.json @@ -50,11 +50,12 @@ "WorkingDirectoryName": "PharesApps", "Windows": { "Configuration": { - "CheckJsonForDistanceResults": true, + "CheckJsonForDistanceResults": false, "CrossDirectoryMaxItemsInDistanceCollection": 7, "DateGroup": "2022-08-14", "DistanceFactor": 8, "FileNameDirectorySeparator": ".Z.", + "ForceFaceLastWriteTimeToCreationTime": false, "ForceMetadataLastWriteTimeToCreationTime": false, "ForcePropertyLastWriteTimeToCreationTime": false, "ForceResizeLastWriteTimeToCreationTime": false, diff --git a/Instance/appsettings.Staging.json b/Instance/appsettings.Staging.json index 01d3c92..4e85c23 100644 --- a/Instance/appsettings.Staging.json +++ b/Instance/appsettings.Staging.json @@ -50,7 +50,7 @@ "WorkingDirectoryName": "PharesApps", "Windows": { "Configuration": { - "CheckJsonForDistanceResults": true, + "CheckJsonForDistanceResults": false, "CrossDirectoryMaxItemsInDistanceCollection": 7, "DateGroup": "2022-08-14", "DistanceFactor": 8, diff --git a/Instance/appsettings.json b/Instance/appsettings.json index 4ff8359..9f27b74 100644 --- a/Instance/appsettings.json +++ b/Instance/appsettings.json @@ -50,7 +50,7 @@ "WorkingDirectoryName": "PharesApps", "Windows": { "Configuration": { - "CheckJsonForDistanceResults": true, + "CheckJsonForDistanceResults": false, "CrossDirectoryMaxItemsInDistanceCollection": 7, "DateGroup": "2022-08-14", "DistanceFactor": 8, diff --git a/Property/Models/Item.cs b/Property/Models/Item.cs index aae579b..6892bcd 100644 --- a/Property/Models/Item.cs +++ b/Property/Models/Item.cs @@ -96,7 +96,7 @@ public class Item bool? isWrongYear; DateTime minimumDateTime; PersonBirthday? personBirthday; - float deterministicHashCodeKey; + double deterministicHashCodeKey; List personKeys = new(); foreach (Item item in items) { @@ -300,7 +300,7 @@ public class Item continue; if (named.PersonBirthday is null) continue; - if (named.NormalizedPixelPercentage.HasValue && named.NormalizedPixelPercentage.Value != face.Location.NormalizedPixelPercentage) + if (named.NormalizedPixelPercentage.HasValue && named.NormalizedPixelPercentage.Value != face.Location?.NormalizedPixelPercentage) continue; key = GetKey(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday); if (!results.ContainsKey(key)) diff --git a/Property/Models/Named.cs b/Property/Models/Named.cs index 27ea279..9701310 100644 --- a/Property/Models/Named.cs +++ b/Property/Models/Named.cs @@ -29,57 +29,114 @@ public class Named this(isWrongYear, minimumDateTime, null, personBirthday) { } - private static float GetDeterministicHashCodeFileName(int id, int normalizedPixelPercentage) - => float.Parse($"{id}.{normalizedPixelPercentage}"); + private static double GetDeterministicHashCodeFileName(int id, int normalizedPixelPercentage) + => double.Parse($"{id}.{normalizedPixelPercentage}"); - public static float GetDeterministicHashCodeKey(Item item, Closest closest) + public static double GetDeterministicHashCodeKey(Item item, Closest closest) { - float result; + double result; if (item.Property?.Id is null || item.ImageFileHolder is null || closest.NormalizedPixelPercentage is null) throw new NullReferenceException(); result = GetDeterministicHashCodeFileName(item.Property.Id.Value, closest.NormalizedPixelPercentage.Value); return result; } - public static float GetDeterministicHashCodeKey(Item item, IFace face) + public static double GetDeterministicHashCodeKey(Item item, IFace face) { - float result; + double result; if (item.Property?.Id is null || item.ImageFileHolder is null || face.Location?.NormalizedPixelPercentage is null) throw new NullReferenceException(); result = GetDeterministicHashCodeFileName(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value); return result; } - public static float? GetReversedDeterministicHashCode(Dictionary> keyValuePairs, string fileName) + public static double? GetReversedDeterministicHashCode(string fileName) { - float? result; - string[] segments = fileName.Split('.'); - if (segments.Length < 2) - throw new Exception(); - string id = segments[0]; - string normalizedPixelPercentage; - if (!id.Contains('-')) - normalizedPixelPercentage = segments[1]; - else - { - segments = fileName.Split(' '); - if (segments.Length < 3) - throw new Exception(); - id = segments[2]; - string locationIdex = segments[0]; - if (int.TryParse(id, out int idValue) && int.TryParse(locationIdex, out int locationIndexValue) && keyValuePairs.ContainsKey(idValue) && keyValuePairs[idValue].Count > locationIndexValue) - normalizedPixelPercentage = string.Concat(keyValuePairs[idValue][locationIndexValue].Location.NormalizedPixelPercentage); - else - { - id = string.Empty; - normalizedPixelPercentage = string.Empty; - } - } - if (!float.TryParse(string.Concat(id, '.', normalizedPixelPercentage), out float resultValue)) + double? result; + if (fileName.Length < 2 || fileName[1..].Contains('-')) result = null; else - result = resultValue; + { + string[] segments = fileName.Split('.'); + if (segments.Length < 2) + throw new Exception(); + string id = segments[0]; + string normalizedPixelPercentage = segments[1]; + if (!double.TryParse(string.Concat(id, '.', normalizedPixelPercentage), out double resultValue)) + result = null; + else + result = resultValue; + } return result; } + public static (string?, double?) GetReversedDeterministicHashCode(Dictionary> keyValuePairs, string file) + { + double? result; + string? check; + string fileName = Path.GetFileName(file); + if (!fileName.Contains('-')) + { + check = null; + result = null; + } + else + { + string id; + int? normalizedPixelPercentage; + if (!keyValuePairs.Any()) + { + check = null; + id = string.Empty; + normalizedPixelPercentage = null; + } + else + { + string[] segments = fileName.Split(' '); + if (segments.Length < 3) + throw new Exception(); + id = segments[2].Split('.')[0]; + string locationIdex = segments[0]; + if (!int.TryParse(id, out int idValue) || !int.TryParse(locationIdex, out int locationIndexValue) || !keyValuePairs.ContainsKey(idValue)) + { + check = null; + id = string.Empty; + normalizedPixelPercentage = null; + } + else + { + List faces = keyValuePairs[idValue]; + if (faces.Count <= locationIndexValue) + { + check = null; + id = string.Empty; + normalizedPixelPercentage = null; + } + else + { + IFace face = faces[locationIndexValue]; + if (face.Location?.NormalizedPixelPercentage is null) + { + check = null; + id = string.Empty; + normalizedPixelPercentage = null; + } + else + { + string extensionLowered = Path.GetExtension(file).ToLower(); + normalizedPixelPercentage = face.Location.NormalizedPixelPercentage.Value; + double deterministicHashCodeKey = GetDeterministicHashCodeFileName(idValue, normalizedPixelPercentage.Value); + check = Path.Combine(string.Concat(Path.GetDirectoryName(file)), $"{deterministicHashCodeKey}{extensionLowered}"); + } + } + } + } + if (normalizedPixelPercentage is null || !double.TryParse(string.Concat(id, '.', normalizedPixelPercentage.Value), out double resultValue)) + result = null; + else + result = resultValue; + } + return new(check, result); + } + } \ No newline at end of file diff --git a/Property/Models/PropertyLogic.cs b/Property/Models/PropertyLogic.cs index 633c119..0c85166 100644 --- a/Property/Models/PropertyLogic.cs +++ b/Property/Models/PropertyLogic.cs @@ -22,8 +22,8 @@ public class PropertyLogic protected readonly string _DeterministicHashCodeRootDirectory; protected readonly Dictionary _SixCharacterNamedFaceInfo; protected readonly Dictionary _NamedFaceInfoDeterministicHashCodeKeyValuePairs; - protected readonly Dictionary _NamedDeterministicHashCodeKeyValuePairs; - protected readonly Dictionary _IncorrectDeterministicHashCodeKeyValuePairs; + protected readonly Dictionary _NamedDeterministicHashCodeKeyValuePairs; + protected readonly Dictionary _IncorrectDeterministicHashCodeKeyValuePairs; public bool Reverse { get; } public List AngleBracketCollection { get; } @@ -31,8 +31,8 @@ public class PropertyLogic public Dictionary IndicesFromNew => _IndicesFromNew; public List ExceptionsDirectories => _ExceptionsDirectories; public string DeterministicHashCodeRootDirectory => _DeterministicHashCodeRootDirectory; - public Dictionary NamedDeterministicHashCodeKeyValuePairs => _NamedDeterministicHashCodeKeyValuePairs; - public Dictionary IncorrectDeterministicHashCodeKeyValuePairs => _IncorrectDeterministicHashCodeKeyValuePairs; + public Dictionary NamedDeterministicHashCodeKeyValuePairs => _NamedDeterministicHashCodeKeyValuePairs; + public Dictionary IncorrectDeterministicHashCodeKeyValuePairs => _IncorrectDeterministicHashCodeKeyValuePairs; public Dictionary NamedFaceInfoDeterministicHashCodeKeyValuePairs => _NamedFaceInfoDeterministicHashCodeKeyValuePairs; private readonly Model? _Model; @@ -69,8 +69,8 @@ public class PropertyLogic List>? collection; Dictionary indicesFromNew = new(); Dictionary? sixCharacterNamedFaceInfo; - Dictionary namedDeterministicHashCode = new(); - Dictionary incorrectDeterministicHashCode = new(); + Dictionary namedDeterministicHashCode = new(); + Dictionary incorrectDeterministicHashCode = new(); string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory); if (string.IsNullOrEmpty(rootDirectoryParent)) throw new NullReferenceException(nameof(rootDirectoryParent)); @@ -84,9 +84,19 @@ public class PropertyLogic if (namedFaceInfoDeterministicHashCode is null) throw new NullReferenceException(nameof(namedFaceInfoDeterministicHashCode)); } - if (namedFaceInfoDeterministicHashCode.Any()) - { + string[] directories = Directory.GetDirectories(rootDirectoryParent, "*DeterministicHashCode*", SearchOption.TopDirectoryOnly); + if (!directories.Any()) deterministicHashCodeRootDirectory = string.Empty; + else + { + Dictionary> faces = new(); + deterministicHashCodeRootDirectory = directories[0]; + SetKeyValuePairs(deterministicHashCodeRootDirectory, namedDeterministicHashCode, incorrectDeterministicHashCode, faces); + } + if (!namedFaceInfoDeterministicHashCode.Any()) + sixCharacterNamedFaceInfo = new(); + else + { files = Directory.GetFiles(rootDirectoryParent, "*SixCharacter*.json", SearchOption.TopDirectoryOnly); if (files.Length != 1) sixCharacterNamedFaceInfo = new(); @@ -98,19 +108,6 @@ public class PropertyLogic throw new NullReferenceException(nameof(sixCharacterNamedFaceInfo)); } } - else - { - sixCharacterNamedFaceInfo = new(); - string[] directories = Directory.GetDirectories(rootDirectoryParent, "*DeterministicHashCode*", SearchOption.TopDirectoryOnly); - if (!directories.Any()) - deterministicHashCodeRootDirectory = string.Empty; - else - { - Dictionary> faces = new(); - deterministicHashCodeRootDirectory = directories[0]; - SetKeyValuePairs(deterministicHashCodeRootDirectory, namedDeterministicHashCode, incorrectDeterministicHashCode, faces); - } - } files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly); if (files.Length != 1) keyValuePairs = new(); @@ -148,15 +145,16 @@ public class PropertyLogic _NamedFaceInfoDeterministicHashCodeKeyValuePairs = namedFaceInfoDeterministicHashCode; } - private static void SetKeyValuePairs(string deterministicHashCodeRootDirectory, List<(string, float)> named, List<(string, float)> incorrect, Dictionary> keyValuePairs) + private static void SetKeyValuePairs(string deterministicHashCodeRootDirectory, List<(string, double)> named, List<(string, double)> incorrect, Dictionary> keyValuePairs) { string[] files; string fileName; string personKey; + string? checkFile; string[] yearDirectories; string[] personKeyDirectories; string[] personNameDirectories; - float? idAndNormalizedPixelPercentage; + double? idAndNormalizedPixelPercentage; string[] ticksDirectories = Directory.GetDirectories(deterministicHashCodeRootDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string ticksDirectory in ticksDirectories) { @@ -176,9 +174,15 @@ public class PropertyLogic if (file.EndsWith(".lnk")) continue; fileName = Path.GetFileName(file); - idAndNormalizedPixelPercentage = Named.GetReversedDeterministicHashCode(keyValuePairs, fileName); + idAndNormalizedPixelPercentage = Named.GetReversedDeterministicHashCode(fileName); if (idAndNormalizedPixelPercentage is null) - break; + { + (checkFile, idAndNormalizedPixelPercentage) = Named.GetReversedDeterministicHashCode(keyValuePairs, file); + if (idAndNormalizedPixelPercentage is null) + break; + if (!string.IsNullOrEmpty(checkFile)) + File.Move(file, checkFile); + } incorrect.Add(new(personKey, idAndNormalizedPixelPercentage.Value)); } foreach (string personNameDirectory in personNameDirectories) @@ -188,10 +192,16 @@ public class PropertyLogic { if (file.EndsWith(".lnk")) continue; - fileName = Path.GetFileNameWithoutExtension(file); - idAndNormalizedPixelPercentage = Named.GetReversedDeterministicHashCode(keyValuePairs, fileName); + fileName = Path.GetFileName(file); + idAndNormalizedPixelPercentage = Named.GetReversedDeterministicHashCode(fileName); if (idAndNormalizedPixelPercentage is null) - break; + { + (checkFile, idAndNormalizedPixelPercentage) = Named.GetReversedDeterministicHashCode(keyValuePairs, file); + if (idAndNormalizedPixelPercentage is null) + break; + if (!string.IsNullOrEmpty(checkFile)) + File.Move(file, checkFile); + } named.Add(new(personKey, idAndNormalizedPixelPercentage.Value)); } } @@ -200,51 +210,57 @@ public class PropertyLogic } } - private static void SetKeyValuePairs(string deterministicHashCodeRootDirectory, Dictionary namedDeterministicHashCode, Dictionary incorrectDeterministicHashCode, Dictionary> keyValuePairs) + private static void SetKeyValuePairs(string deterministicHashCodeRootDirectory, Dictionary namedDeterministicHashCode, Dictionary incorrectDeterministicHashCode, Dictionary> keyValuePairs) { - Dictionary> namedKeyValuePairs = new(); - Dictionary> incorrectKeyValuePairs = new(); - List<(string PersonKey, float IdAndNormalizedPixelPercentage)> named = new(); - List<(string PersonKey, float IdAndNormalizedPixelPercentage)> incorrect = new(); + Dictionary> namedKeyValuePairs = new(); + Dictionary> incorrectKeyValuePairs = new(); + List<(string PersonKey, double IdAndNormalizedPixelPercentage)> named = new(); + List<(string PersonKey, double IdAndNormalizedPixelPercentage)> incorrect = new(); SetKeyValuePairs(deterministicHashCodeRootDirectory, named, incorrect, keyValuePairs); named = (from l in named orderby l.IdAndNormalizedPixelPercentage select l).ToList(); incorrect = (from l in incorrect orderby l.IdAndNormalizedPixelPercentage select l).ToList(); - foreach ((string personKey, float idAndNormalizedPixelPercentage) in named) + foreach ((string personKey, double idAndNormalizedPixelPercentage) in named) { if (!namedKeyValuePairs.ContainsKey(idAndNormalizedPixelPercentage)) namedKeyValuePairs.Add(idAndNormalizedPixelPercentage, new()); namedKeyValuePairs[idAndNormalizedPixelPercentage].Add(personKey); } - foreach ((string personKey, float idAndNormalizedPixelPercentage) in incorrect) + foreach ((string personKey, double idAndNormalizedPixelPercentage) in incorrect) { if (!incorrectKeyValuePairs.ContainsKey(idAndNormalizedPixelPercentage)) incorrectKeyValuePairs.Add(idAndNormalizedPixelPercentage, new()); incorrectKeyValuePairs[idAndNormalizedPixelPercentage].Add(personKey); } - foreach (KeyValuePair> keyValuePair in namedKeyValuePairs) + foreach (KeyValuePair> keyValuePair in namedKeyValuePairs) namedDeterministicHashCode.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray()); - foreach (KeyValuePair> keyValuePair in incorrectKeyValuePairs) + foreach (KeyValuePair> keyValuePair in incorrectKeyValuePairs) incorrectDeterministicHashCode.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray()); } public void UpdateKeyValuePairs(List containers) { Dictionary> keyValuePairs = new(); - Dictionary namedDeterministicHashCode = new(); - Dictionary incorrectDeterministicHashCode = new(); + Dictionary namedDeterministicHashCode = new(); + Dictionary incorrectDeterministicHashCode = new(); foreach (Container container in containers) { foreach (Item item in container.Items) { if (item.ImageFileHolder is null || item.Property?.Id is null || !item.Faces.Any()) continue; + if (keyValuePairs.ContainsKey(item.Property.Id.Value)) + { + if (keyValuePairs[item.Property.Id.Value].Count != item.Faces.Count) + throw new Exception(); + continue; + } keyValuePairs.Add(item.Property.Id.Value, item.Faces); } } SetKeyValuePairs(_DeterministicHashCodeRootDirectory, namedDeterministicHashCode, incorrectDeterministicHashCode, keyValuePairs); - foreach (KeyValuePair keyValuePair in namedDeterministicHashCode) + foreach (KeyValuePair keyValuePair in namedDeterministicHashCode) _NamedDeterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value); - foreach (KeyValuePair keyValuePair in incorrectDeterministicHashCode) + foreach (KeyValuePair keyValuePair in incorrectDeterministicHashCode) _IncorrectDeterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value); } diff --git a/Shared/Models/Location.cs b/Shared/Models/Location.cs index 5ea0b78..1ea9b37 100644 --- a/Shared/Models/Location.cs +++ b/Shared/Models/Location.cs @@ -23,6 +23,8 @@ public class Location : Properties.ILocation, ILocation, IEquatable [JsonConstructor] public Location(int bottom, double confidence, int left, int? normalizedPixelPercentage, int right, int top) { + if (normalizedPixelPercentage < 0) + normalizedPixelPercentage = 3; _Confidence = confidence; _Bottom = bottom; _Left = left; @@ -63,11 +65,15 @@ public class Location : Properties.ILocation, ILocation, IEquatable public static int GetNormalizedPixelPercentage(int bottom, int height, int left, int right, int top, int width) { - double result; + int result; + double value; double xCenter = left + ((right - left) / 2); double yCenter = top + ((bottom - top) / 2); - result = ((yCenter * width) + xCenter) / (width * height); - return (int)(Math.Round((decimal)result, 4) * Stateless.Methods.ILocation.Factor); + value = ((yCenter * width) + xCenter) / (width * height); + if (value < 0) + value = 3; + result = (int)(Math.Round((decimal)value, 4) * Stateless.Methods.ILocation.Factor); + return result; } public bool Equals(Location? location) diff --git a/Tests/appsettings.Development.json b/Tests/appsettings.Development.json index f69f77a..81aad60 100644 --- a/Tests/appsettings.Development.json +++ b/Tests/appsettings.Development.json @@ -50,7 +50,7 @@ "WorkingDirectoryName": "PharesApps", "Windows": { "Configuration": { - "CheckJsonForDistanceResults": true, + "CheckJsonForDistanceResults": false, "CrossDirectoryMaxItemsInDistanceCollection": 7, "DateGroup": "2022-08-14", "DistanceFactor": 8, diff --git a/Tests/appsettings.json b/Tests/appsettings.json index e2f74f0..2dcb0dc 100644 --- a/Tests/appsettings.json +++ b/Tests/appsettings.json @@ -50,7 +50,7 @@ "WorkingDirectoryName": "PharesApps", "Windows": { "Configuration": { - "CheckJsonForDistanceResults": true, + "CheckJsonForDistanceResults": false, "CrossDirectoryMaxItemsInDistanceCollection": 7, "DateGroup": "2022-08-14", "DistanceFactor": 8, diff --git a/TestsWithFaceRecognitionDotNet/appsettings.Development.json b/TestsWithFaceRecognitionDotNet/appsettings.Development.json index f69f77a..81aad60 100644 --- a/TestsWithFaceRecognitionDotNet/appsettings.Development.json +++ b/TestsWithFaceRecognitionDotNet/appsettings.Development.json @@ -50,7 +50,7 @@ "WorkingDirectoryName": "PharesApps", "Windows": { "Configuration": { - "CheckJsonForDistanceResults": true, + "CheckJsonForDistanceResults": false, "CrossDirectoryMaxItemsInDistanceCollection": 7, "DateGroup": "2022-08-14", "DistanceFactor": 8, diff --git a/TestsWithFaceRecognitionDotNet/appsettings.json b/TestsWithFaceRecognitionDotNet/appsettings.json index e2f74f0..2dcb0dc 100644 --- a/TestsWithFaceRecognitionDotNet/appsettings.json +++ b/TestsWithFaceRecognitionDotNet/appsettings.json @@ -50,7 +50,7 @@ "WorkingDirectoryName": "PharesApps", "Windows": { "Configuration": { - "CheckJsonForDistanceResults": true, + "CheckJsonForDistanceResults": false, "CrossDirectoryMaxItemsInDistanceCollection": 7, "DateGroup": "2022-08-14", "DistanceFactor": 8,