After testing E_Distance.SaveGroupedFaceEncodings

This commit is contained in:
Mike Phares 2022-08-07 12:29:46 -07:00
parent 2158b4cfc2
commit daf5f428b9
57 changed files with 2626 additions and 660 deletions

11
.vscode/settings.json vendored
View File

@ -1,23 +1,32 @@
{ {
"cSpell.words": [ "cSpell.words": [
"appsettings", "appsettings",
"Argb",
"ASPNETCORE", "ASPNETCORE",
"Barrick", "Barrick",
"bcdfghjklmnpqrstvwxyz", "bcdfghjklmnpqrstvwxyz",
"Beichler", "Beichler",
"Bohdi", "Bohdi",
"cref",
"CUDA", "CUDA",
"Dlib", "Dlib",
"Exif", "Exif",
"Getα", "Getα",
"Greyscale",
"mmod", "mmod",
"nosj", "nosj",
"paramref",
"Phares", "Phares",
"resnet", "resnet",
"Serilog", "Serilog",
"Subfile", "Subfile",
"Subfiles", "Subfiles",
"Unmanaged",
"Upsample",
"Vericruz" "Vericruz"
], ],
"cSpell.enabled": true "cSpell.enabled": true,
"files.exclude": {
"**/.git": false
},
} }

View File

@ -35,7 +35,7 @@ public class Compare
string[] segments; string[] segments;
_AppSettings = appSettings; _AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null) if (appSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(appSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism));
_RenameFindReplace = new(); _RenameFindReplace = new();
_RenameBFindReplace = new(); _RenameBFindReplace = new();
_RenameCFindReplace = new(); _RenameCFindReplace = new();
@ -56,7 +56,7 @@ public class Compare
Model? model = null; Model? model = null;
PredictorModel? predictorModel = null; PredictorModel? predictorModel = null;
if (propertyConfiguration.PopulatePropertyId is null) if (propertyConfiguration.PopulatePropertyId is null)
throw new Exception($"{nameof(propertyConfiguration.PopulatePropertyId)} is null!"); throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId));
foreach (string spelling in configuration.Spelling) foreach (string spelling in configuration.Spelling)
{ {
segments = spelling.Split('|'); segments = spelling.Split('|');
@ -372,14 +372,14 @@ public class Compare
private static void Verify(Models.Configuration configuration) private static void Verify(Models.Configuration configuration)
{ {
if (configuration.Spelling is null || !configuration.Spelling.Any()) if (configuration.Spelling is null || !configuration.Spelling.Any())
throw new Exception($"{nameof(configuration.Spelling)} should have at least one!"); throw new ArgumentNullException(nameof(configuration.Spelling));
} }
private long LogDelta(long ticks, string methodName) private long LogDelta(long ticks, string methodName)
{ {
long result; long result;
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks; result = DateTime.Now.Ticks;
@ -390,9 +390,9 @@ public class Compare
{ {
PropertyLogic result; PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration);
string fromPrepareForOld = "34720-637858334555170379.tsv"; string fromPrepareForOld = "34720-637858334555170379.tsv";
string fromPrepareForOldFile = Path.Combine(_Configuration.PropertyConfiguration.RootDirectory, fromPrepareForOld); string fromPrepareForOldFile = Path.Combine(_Configuration.PropertyConfiguration.RootDirectory, fromPrepareForOld);
@ -432,11 +432,11 @@ public class Compare
private void SaveDiffFilesOrSaveLogAndMoveFiles(Property.Models.Configuration configuration) private void SaveDiffFilesOrSaveLogAndMoveFiles(Property.Models.Configuration configuration)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}"); string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
_Log.Information(aPropertySingletonDirectory); _Log.Information(aPropertySingletonDirectory);
_Log.Information("to"); _Log.Information("to");
@ -510,7 +510,7 @@ public class Compare
private void ChangeExtensionFromDeleteToJson(string aPropertySingletonDirectory) private void ChangeExtensionFromDeleteToJson(string aPropertySingletonDirectory)
{ {
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
string searchPattern = "*.delete"; string searchPattern = "*.delete";
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
List<string> topDirectories = new(); List<string> topDirectories = new();
@ -647,7 +647,7 @@ public class Compare
private bool PossiblyCorrect(List<string> topDirectories, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection) private bool PossiblyCorrect(List<string> topDirectories, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection)
{ {
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
bool result = false; bool result = false;
string corrected; string corrected;
string correctedMoveTo; string correctedMoveTo;
@ -695,7 +695,7 @@ public class Compare
private List<string> GetMissingVerifyToSeasonCollection(List<string> _, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection) private List<string> GetMissingVerifyToSeasonCollection(List<string> _, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection)
{ {
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
List<string> results = new(); List<string> results = new();
string check; string check;
foreach ((int _, string sourceDirectory, string[] _, int _) in groupCollection) foreach ((int _, string sourceDirectory, string[] _, int _) in groupCollection)
@ -715,7 +715,7 @@ public class Compare
private void CreateWindowsShortcuts((long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] collection, bool keepAll) private void CreateWindowsShortcuts((long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] collection, bool keepAll)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
int z = 0; int z = 0;
string fileName; string fileName;
WindowsShortcut windowsShortcut; WindowsShortcut windowsShortcut;
@ -753,9 +753,9 @@ public class Compare
private void ThirdPassToMove(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List<PropertyHolder[]> propertyHolderCollections, string aPropertyContentCollectionDirectory) private void ThirdPassToMove(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List<PropertyHolder[]> propertyHolderCollections, string aPropertyContentCollectionDirectory)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
int stay = 0; int stay = 0;
string fileName; string fileName;
string id = " - Id"; string id = " - Id";
@ -831,7 +831,7 @@ public class Compare
private void FourthPassCreateWindowsShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List<PropertyHolder[]> propertyHolderCollections, bool saveToCollection, bool keepAll) private void FourthPassCreateWindowsShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, List<PropertyHolder[]> propertyHolderCollections, bool saveToCollection, bool keepAll)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
int stay = 0; int stay = 0;
A_Property? property; A_Property? property;
ConsoleKey? consoleKey = null; ConsoleKey? consoleKey = null;

View File

@ -31,7 +31,7 @@ public class DateGroup
{ } { }
_AppSettings = appSettings; _AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null) if (appSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(appSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism));
_IsEnvironment = isEnvironment; _IsEnvironment = isEnvironment;
_Exceptions = new List<string>(); _Exceptions = new List<string>();
_Log = Serilog.Log.ForContext<DateGroup>(); _Log = Serilog.Log.ForContext<DateGroup>();
@ -46,11 +46,11 @@ public class DateGroup
PredictorModel? predictorModel = null; PredictorModel? predictorModel = null;
_Configuration = configuration; _Configuration = configuration;
if (configuration.ByHash is null) if (configuration.ByHash is null)
throw new Exception($"{nameof(configuration.ByHash)} is null!"); throw new ArgumentNullException(nameof(configuration.ByHash));
if (configuration.ByCreateDateShortcut is null) if (configuration.ByCreateDateShortcut is null)
throw new Exception($"{nameof(configuration.ByCreateDateShortcut)} is null!"); throw new ArgumentNullException(nameof(configuration.ByCreateDateShortcut));
if (propertyConfiguration.PopulatePropertyId is null) if (propertyConfiguration.PopulatePropertyId is null)
throw new Exception($"{nameof(propertyConfiguration.PopulatePropertyId)} is null!"); throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId));
if (!_IsEnvironment.Development) if (!_IsEnvironment.Development)
throw new Exception("This program only allows development environments!"); throw new Exception("This program only allows development environments!");
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
@ -94,21 +94,21 @@ public class DateGroup
private static void Verify(Models.Configuration configuration) private static void Verify(Models.Configuration configuration)
{ {
if (configuration.ByCreateDateShortcut is null) if (configuration.ByCreateDateShortcut is null)
throw new Exception($"{nameof(configuration.ByCreateDateShortcut)} is null!"); throw new ArgumentNullException(nameof(configuration.ByCreateDateShortcut));
if (configuration.ByDay is null) if (configuration.ByDay is null)
throw new Exception($"{nameof(configuration.ByDay)} is null!"); throw new ArgumentNullException(nameof(configuration.ByDay));
if (configuration.ByHash is null) if (configuration.ByHash is null)
throw new Exception($"{nameof(configuration.ByHash)} is null!"); throw new ArgumentNullException(nameof(configuration.ByHash));
if (configuration.BySeason is null) if (configuration.BySeason is null)
throw new Exception($"{nameof(configuration.BySeason)} is null!"); throw new ArgumentNullException(nameof(configuration.BySeason));
if (configuration.ByWeek is null) if (configuration.ByWeek is null)
throw new Exception($"{nameof(configuration.ByWeek)} is null!"); throw new ArgumentNullException(nameof(configuration.ByWeek));
if (!configuration.ByCreateDateShortcut.Value && !configuration.ByDay.Value && !configuration.ByWeek.Value && !configuration.BySeason.Value && !configuration.ByHash.Value) if (!configuration.ByCreateDateShortcut.Value && !configuration.ByDay.Value && !configuration.ByWeek.Value && !configuration.BySeason.Value && !configuration.ByHash.Value)
throw new Exception("Change configuration!"); throw new Exception("Change configuration!");
if (configuration.KeepFullPath is null) if (configuration.KeepFullPath is null)
throw new Exception($"{nameof(configuration.KeepFullPath)} is null!"); throw new ArgumentNullException(nameof(configuration.KeepFullPath));
if (configuration?.PropertyConfiguration?.PopulatePropertyId is null) if (configuration?.PropertyConfiguration?.PopulatePropertyId is null)
throw new Exception($"{nameof(configuration.PropertyConfiguration.PopulatePropertyId)} must be set!"); throw new ArgumentNullException(nameof(configuration.PropertyConfiguration.PopulatePropertyId));
if (configuration.PropertyConfiguration.PopulatePropertyId.Value && !configuration.ByCreateDateShortcut.Value && !configuration.ByHash.Value) if (configuration.PropertyConfiguration.PopulatePropertyId.Value && !configuration.ByCreateDateShortcut.Value && !configuration.ByHash.Value)
throw new Exception("Change configuration!"); throw new Exception("Change configuration!");
if (!configuration.PropertyConfiguration.PopulatePropertyId.Value && configuration.ByHash.Value) if (!configuration.PropertyConfiguration.PopulatePropertyId.Value && configuration.ByHash.Value)
@ -153,7 +153,7 @@ public class DateGroup
{ {
long result; long result;
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks; result = DateTime.Now.Ticks;
@ -164,17 +164,17 @@ public class DateGroup
{ {
List<(string Source, string[] Destination)> results = new(); List<(string Source, string[] Destination)> results = new();
if (_Configuration.ByCreateDateShortcut is null) if (_Configuration.ByCreateDateShortcut is null)
throw new Exception($"{nameof(_Configuration.ByCreateDateShortcut)} is null!"); throw new ArgumentNullException(nameof(_Configuration.ByCreateDateShortcut));
if (_Configuration.ByDay is null) if (_Configuration.ByDay is null)
throw new Exception($"{nameof(_Configuration.ByDay)} is null!"); throw new ArgumentNullException(nameof(_Configuration.ByDay));
if (_Configuration.ByHash is null) if (_Configuration.ByHash is null)
throw new Exception($"{nameof(_Configuration.ByHash)} is null!"); throw new ArgumentNullException(nameof(_Configuration.ByHash));
if (_Configuration.BySeason is null) if (_Configuration.BySeason is null)
throw new Exception($"{nameof(_Configuration.BySeason)} is null!"); throw new ArgumentNullException(nameof(_Configuration.BySeason));
if (_Configuration.ByWeek is null) if (_Configuration.ByWeek is null)
throw new Exception($"{nameof(_Configuration.ByWeek)} is null!"); throw new ArgumentNullException(nameof(_Configuration.ByWeek));
if (_Configuration.KeepFullPath is null) if (_Configuration.KeepFullPath is null)
throw new Exception($"{nameof(_Configuration.KeepFullPath)} is null!"); throw new ArgumentNullException(nameof(_Configuration.KeepFullPath));
char flag; char flag;
string day; string day;
int season; int season;
@ -332,9 +332,9 @@ public class DateGroup
{ {
PropertyLogic result; PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration);
return result; return result;
} }
@ -343,9 +343,9 @@ public class DateGroup
{ {
List<(string Source, string[] Destination)> results = new(); List<(string Source, string[] Destination)> results = new();
if (_Configuration.KeepFullPath is null) if (_Configuration.KeepFullPath is null)
throw new Exception($"{nameof(_Configuration.KeepFullPath)} is null!"); throw new ArgumentNullException(nameof(_Configuration.KeepFullPath));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string? topDirectory; string? topDirectory;
string? checkDirectory; string? checkDirectory;
string sourceDirectory; string sourceDirectory;
@ -380,9 +380,9 @@ public class DateGroup
private void MoveFiles(List<string> topDirectories, List<Property.Models.DirectoryInfo> groupCollection) private void MoveFiles(List<string> topDirectories, List<Property.Models.DirectoryInfo> groupCollection)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string directoryName; string directoryName;
List<string> distinct = new(); List<string> distinct = new();
List<(string Source, string[] Destination)> fileMoveCollectionAll = GetFileMoveCollectionAll(topDirectories, groupCollection); List<(string Source, string[] Destination)> fileMoveCollectionAll = GetFileMoveCollectionAll(topDirectories, groupCollection);

View File

@ -8,23 +8,23 @@ internal sealed class FaceRecognitionModelV1
#region Methods #region Methods
public static Matrix<double> ComputeFaceDescriptor(LossMetric net, Image img, FullObjectDetection face, int numJitters) public static Matrix<double> ComputeFaceDescriptor(LossMetric net, Image img, FullObjectDetection face, int numberOfJitters)
{ {
FullObjectDetection[]? faces = new[] { face }; FullObjectDetection[]? faces = new[] { face };
return ComputeFaceDescriptors(net, img, faces, numJitters).First(); return ComputeFaceDescriptors(net, img, faces, numberOfJitters).First();
} }
public static IEnumerable<Matrix<double>> ComputeFaceDescriptors(LossMetric net, Image img, IEnumerable<FullObjectDetection> faces, int numJitters) public static IEnumerable<Matrix<double>> ComputeFaceDescriptors(LossMetric net, Image img, IEnumerable<FullObjectDetection> faces, int numberOfJitters)
{ {
Image[]? batchImage = new[] { img }; Image[]? batchImage = new[] { img };
IEnumerable<FullObjectDetection>[]? batchFaces = new[] { faces }; IEnumerable<FullObjectDetection>[]? batchFaces = new[] { faces };
return BatchComputeFaceDescriptors(net, batchImage, batchFaces, numJitters).First(); return BatchComputeFaceDescriptors(net, batchImage, batchFaces, numberOfJitters).First();
} }
public static IEnumerable<IEnumerable<Matrix<double>>> BatchComputeFaceDescriptors(LossMetric net, public static IEnumerable<IEnumerable<Matrix<double>>> BatchComputeFaceDescriptors(LossMetric net,
IList<Image> batchImages, IList<Image> batchImages,
IList<IEnumerable<FullObjectDetection>> batchFaces, IList<IEnumerable<FullObjectDetection>> batchFaces,
int numJitters) int numberOfJitters)
{ {
if (batchImages.Count != batchFaces.Count) if (batchImages.Count != batchFaces.Count)
throw new ArgumentException("The array of images and the array of array of locations must be of the same size"); throw new ArgumentException("The array of images and the array of array of locations must be of the same size");
@ -60,7 +60,7 @@ internal sealed class FaceRecognitionModelV1
for (int i = 0, count = batchImages.Count; i < count; i++) for (int i = 0, count = batchImages.Count; i < count; i++)
faceDescriptors.Add(new List<Matrix<double>>()); faceDescriptors.Add(new List<Matrix<double>>());
if (numJitters <= 1) if (numberOfJitters <= 1)
{ {
// extract descriptors and convert from float vectors to double vectors // extract descriptors and convert from float vectors to double vectors
OutputLabels<Matrix<float>>? descriptors = net.Operator(faceChips, 16); OutputLabels<Matrix<float>>? descriptors = net.Operator(faceChips, 16);
@ -80,7 +80,7 @@ internal sealed class FaceRecognitionModelV1
for (int i = 0; i < batchFaces.Count; ++i) for (int i = 0; i < batchFaces.Count; ++i)
for (int j = 0; j < batchFaces[i].Count(); ++j) for (int j = 0; j < batchFaces[i].Count(); ++j)
{ {
Matrix<RgbPixel>[]? tmp = JitterImage(faceChips[index++], numJitters).ToArray(); Matrix<RgbPixel>[]? tmp = JitterImage(faceChips[index++], numberOfJitters).ToArray();
using (OutputLabels<Matrix<float>>? tmp2 = net.Operator(tmp, 16)) using (OutputLabels<Matrix<float>>? tmp2 = net.Operator(tmp, 16))
using (MatrixOp? mat = DlibDotNet.Dlib.Mat(tmp2)) using (MatrixOp? mat = DlibDotNet.Dlib.Mat(tmp2))
{ {
@ -113,10 +113,10 @@ internal sealed class FaceRecognitionModelV1
private static readonly Rand _Rand = new(); private static readonly Rand _Rand = new();
private static IEnumerable<Matrix<RgbPixel>> JitterImage(Matrix<RgbPixel> img, int numJitters) private static IEnumerable<Matrix<RgbPixel>> JitterImage(Matrix<RgbPixel> img, int numberOfJitters)
{ {
List<Matrix<RgbPixel>>? crops = new(); List<Matrix<RgbPixel>>? crops = new();
for (int i = 0; i < numJitters; ++i) for (int i = 0; i < numberOfJitters; ++i)
crops.Add(DlibDotNet.Dlib.JitterImage(img, _Rand)); crops.Add(DlibDotNet.Dlib.JitterImage(img, _Rand));
return crops; return crops;

View File

@ -30,9 +30,9 @@ public sealed class FaceEncoding : DisposableObject, ISerializable
int? row = (int?)info.GetValue(nameof(_Encoding.Rows), typeof(int)); int? row = (int?)info.GetValue(nameof(_Encoding.Rows), typeof(int));
int? column = (int?)info.GetValue(nameof(_Encoding.Columns), typeof(int)); int? column = (int?)info.GetValue(nameof(_Encoding.Columns), typeof(int));
if (row is null) if (row is null)
throw new Exception($"{nameof(row)} is null"); throw new ArgumentNullException(nameof(row));
if (column is null) if (column is null)
throw new Exception($"{nameof(column)} is null"); throw new ArgumentNullException(nameof(column));
_Encoding = new Matrix<double>(array, row.Value, column.Value); _Encoding = new Matrix<double>(array, row.Value, column.Value);
} }

View File

@ -150,7 +150,7 @@ public sealed class FaceRecognition : DisposableObject
/// <param name="batchSize">The number of images to include in each GPU processing batch.</param> /// <param name="batchSize">The number of images to include in each GPU processing batch.</param>
/// <returns>An enumerable collection of array of found face locations.</returns> /// <returns>An enumerable collection of array of found face locations.</returns>
/// <exception cref="ArgumentNullException"><paramref name="images"/> is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="images"/> is null.</exception>
public IEnumerable<Location[]> BatchFaceLocations(IEnumerable<Image> images, int numberOfTimesToUpsample = 1, int batchSize = 128) public IEnumerable<Location[]> BatchFaceLocations(IEnumerable<Image> images, int numberOfTimesToUpsample, int batchSize = 128)
{ {
if (images == null) if (images == null)
throw new ArgumentNullException(nameof(images)); throw new ArgumentNullException(nameof(images));
@ -167,7 +167,7 @@ public sealed class FaceRecognition : DisposableObject
for (int index = 0; index < rawDetectionsBatched.Length; index++) for (int index = 0; index < rawDetectionsBatched.Length; index++)
{ {
MModRect[]? faces = rawDetectionsBatched[index].ToArray(); MModRect[]? faces = rawDetectionsBatched[index].ToArray();
Location[]? locations = faces.Select(rect => new Location(TrimBound(rect.Rect, image.Width, image.Height), rect.DetectionConfidence)).ToArray(); Location[]? locations = faces.Select(rect => new Location(rect.DetectionConfidence, TrimBound(rect.Rect, image.Width, image.Height), image.Width, image.Height)).ToArray();
foreach (MModRect? face in faces) foreach (MModRect? face in faces)
face.Dispose(); face.Dispose();
results.Add(locations); results.Add(locations);
@ -358,7 +358,7 @@ public sealed class FaceRecognition : DisposableObject
/// </summary> /// </summary>
/// <param name="image">The image contains faces. The image can contain multiple faces.</param> /// <param name="image">The image contains faces. The image can contain multiple faces.</param>
/// <param name="knownFaceLocation">The enumerable collection of location rectangle for faces. If specified null, method will find face locations.</param> /// <param name="knownFaceLocation">The enumerable collection of location rectangle for faces. If specified null, method will find face locations.</param>
/// <param name="numJitters">The number of times to re-sample the face when calculating encoding.</param> /// <param name="numberOfJitters">The number of times to re-sample the face when calculating encoding.</param>
/// <param name="predictorModel">The dimension of vector which be returned from detector.</param> /// <param name="predictorModel">The dimension of vector which be returned from detector.</param>
/// <param name="model">The model of face detector to detect in image. If <paramref name="knownFaceLocation"/> is not null, this value is ignored.</param> /// <param name="model">The model of face detector to detect in image. If <paramref name="knownFaceLocation"/> is not null, this value is ignored.</param>
/// <returns>An enumerable collection of face feature data corresponds to all faces in specified image.</returns> /// <returns>An enumerable collection of face feature data corresponds to all faces in specified image.</returns>
@ -366,11 +366,7 @@ public sealed class FaceRecognition : DisposableObject
/// <exception cref="InvalidOperationException"><paramref name="knownFaceLocation"/> contains no elements.</exception> /// <exception cref="InvalidOperationException"><paramref name="knownFaceLocation"/> contains no elements.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="image"/> or this object or custom face landmark detector is disposed.</exception> /// <exception cref="ObjectDisposedException"><paramref name="image"/> or this object or custom face landmark detector is disposed.</exception>
/// <exception cref="NotSupportedException"><see cref="PredictorModel.Custom"/> is not supported.</exception> /// <exception cref="NotSupportedException"><see cref="PredictorModel.Custom"/> is not supported.</exception>
public List<FaceEncoding> FaceEncodings(Image image, public List<FaceEncoding> FaceEncodings(Image image, int numberOfTimesToUpsample, IEnumerable<Location>? knownFaceLocation, int numberOfJitters, PredictorModel predictorModel, Model model)
IEnumerable<Location>? knownFaceLocation = null,
int numJitters = 1,
PredictorModel predictorModel = PredictorModel.Small,
Model model = Model.Hog)
{ {
if (image == null) if (image == null)
throw new ArgumentNullException(nameof(image)); throw new ArgumentNullException(nameof(image));
@ -383,12 +379,12 @@ public sealed class FaceRecognition : DisposableObject
image.ThrowIfDisposed(); image.ThrowIfDisposed();
ThrowIfDisposed(); ThrowIfDisposed();
IEnumerable<FullObjectDetection>? rawLandmarks = RawFaceLandmarks(image, knownFaceLocation, predictorModel, model); List<FullObjectDetection> rawLandmarks = RawFaceLandmarks(image, numberOfTimesToUpsample, knownFaceLocation, predictorModel, model);
List<FaceEncoding> results = new(); List<FaceEncoding> results = new();
foreach (FullObjectDetection? landmark in rawLandmarks) foreach (FullObjectDetection landmark in rawLandmarks)
{ {
FaceEncoding? ret = new(FaceRecognitionModelV1.ComputeFaceDescriptor(_FaceEncoder, image, landmark, numJitters)); FaceEncoding? ret = new(FaceRecognitionModelV1.ComputeFaceDescriptor(_FaceEncoder, image, landmark, numberOfJitters));
landmark.Dispose(); landmark.Dispose();
results.Add(ret); results.Add(ret);
} }
@ -396,6 +392,14 @@ public sealed class FaceRecognition : DisposableObject
return results; return results;
} }
private static FacePoint[] Join(IEnumerable<FacePoint> facePoints1, IEnumerable<FacePoint> facePoints2)
{
List<FacePoint> results = new();
results.AddRange(facePoints1);
results.AddRange(facePoints2);
return results.ToArray();
}
/// <summary> /// <summary>
/// Returns an enumerable collection of dictionary of face parts locations (eyes, nose, etc) for each face in the image. /// Returns an enumerable collection of dictionary of face parts locations (eyes, nose, etc) for each face in the image.
/// </summary> /// </summary>
@ -408,89 +412,53 @@ public sealed class FaceRecognition : DisposableObject
/// <exception cref="InvalidOperationException"><paramref name="faceLocations"/> contains no elements.</exception> /// <exception cref="InvalidOperationException"><paramref name="faceLocations"/> contains no elements.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="faceImage"/> or this object or custom face landmark detector is disposed.</exception> /// <exception cref="ObjectDisposedException"><paramref name="faceImage"/> or this object or custom face landmark detector is disposed.</exception>
/// <exception cref="NotSupportedException">The custom face landmark detector is not ready.</exception> /// <exception cref="NotSupportedException">The custom face landmark detector is not ready.</exception>
public List<Dictionary<FacePart, IEnumerable<FacePoint>>> FaceLandmark(Image faceImage, public List<(FacePart, FacePoint[])[]> GetFaceLandmarkCollection(Image faceImage, int numberOfTimesToUpsample, IEnumerable<Location>? faceLocations, PredictorModel predictorModel, Model model)
IEnumerable<Location>? faceLocations = null,
PredictorModel predictorModel = PredictorModel.Large,
Model model = Model.Hog)
{ {
List<(FacePart, FacePoint[])[]> results = new();
if (faceImage == null) if (faceImage == null)
throw new ArgumentNullException(nameof(faceImage)); throw new ArgumentNullException(nameof(faceImage));
if (faceLocations != null && !faceLocations.Any()) if (faceLocations != null && !faceLocations.Any())
throw new InvalidOperationException($"{nameof(faceLocations)} contains no elements."); throw new InvalidOperationException($"{nameof(faceLocations)} contains no elements.");
faceImage.ThrowIfDisposed(); faceImage.ThrowIfDisposed();
ThrowIfDisposed(); ThrowIfDisposed();
if (predictorModel == PredictorModel.Custom) if (predictorModel == PredictorModel.Custom)
throw new NotImplementedException();
List<FullObjectDetection> fullObjectDetections = RawFaceLandmarks(faceImage, numberOfTimesToUpsample, faceLocations, predictorModel, model);
List<FacePoint[]> landmarksCollection = fullObjectDetections.Select(landmark => Enumerable.Range(0, (int)landmark.Parts)
.Select(index => new FacePoint(index, landmark.GetPart((uint)index).X, landmark.GetPart((uint)index).Y)).ToArray()).ToList();
foreach (FullObjectDetection? landmark in fullObjectDetections)
landmark.Dispose();
List<(FacePart, FacePoint[])> collection;
foreach (FacePoint[] facePoints in landmarksCollection)
{ {
if (CustomFaceLandmarkDetector == null) collection = new();
throw new NotSupportedException("The custom face landmark detector is not ready.");
if (CustomFaceLandmarkDetector.IsDisposed)
throw new ObjectDisposedException($"{nameof(CustomFaceLandmarkDetector)}", "The custom face landmark detector is disposed.");
}
FullObjectDetection[]? landmarks = RawFaceLandmarks(faceImage, faceLocations, predictorModel, model).ToArray();
IEnumerable<FacePoint[]>? landmarkTuples = landmarks.Select(landmark => Enumerable.Range(0, (int)landmark.Parts)
.Select(index => new FacePoint(index, landmark.GetPart((uint)index).X, landmark.GetPart((uint)index).Y)).ToArray());
List<Dictionary<FacePart, IEnumerable<FacePoint>>> results = new();
try
{
// For a definition of each point index, see https://cdn-images-1.medium.com/max/1600/1*AbEg31EgkbXSQehuNJBlWg.png
switch (predictorModel) switch (predictorModel)
{ {
case PredictorModel.Custom:
throw new NotImplementedException();
case PredictorModel.Large: case PredictorModel.Large:
results.AddRange(landmarkTuples.Select(landmarkTuple => new Dictionary<FacePart, IEnumerable<FacePoint>> if (facePoints.Length != 68)
{ continue;
{ FacePart.Chin, Enumerable.Range(0,17).Select(i => landmarkTuple[i]).ToArray() }, collection.Add(new(FacePart.Chin, facePoints.Skip(0).Take(17).ToArray()));
{ FacePart.LeftEyebrow, Enumerable.Range(17,5).Select(i => landmarkTuple[i]).ToArray() }, collection.Add(new(FacePart.LeftEyebrow, facePoints.Skip(17).Take(5).ToArray()));
{ FacePart.RightEyebrow, Enumerable.Range(22,5).Select(i => landmarkTuple[i]).ToArray() }, collection.Add(new(FacePart.RightEyebrow, facePoints.Skip(22).Take(5).ToArray()));
{ FacePart.NoseBridge, Enumerable.Range(27,5).Select(i => landmarkTuple[i]).ToArray() }, collection.Add(new(FacePart.NoseBridge, facePoints.Skip(27).Take(5).ToArray()));
{ FacePart.NoseTip, Enumerable.Range(31,5).Select(i => landmarkTuple[i]).ToArray() }, collection.Add(new(FacePart.NoseTip, facePoints.Skip(31).Take(5).ToArray()));
{ FacePart.LeftEye, Enumerable.Range(36,6).Select(i => landmarkTuple[i]).ToArray() }, collection.Add(new(FacePart.LeftEye, facePoints.Skip(36).Take(6).ToArray()));
{ FacePart.RightEye, Enumerable.Range(42,6).Select(i => landmarkTuple[i]).ToArray() }, collection.Add(new(FacePart.RightEye, facePoints.Skip(42).Take(6).ToArray()));
{ FacePart.TopLip, Enumerable.Range(48,7).Select(i => landmarkTuple[i]) collection.Add(new(FacePart.TopLip, Join(facePoints.Skip(48).Take(7), facePoints.Skip(60).Take(5))));
.Concat( new [] { landmarkTuple[64] }) collection.Add(new(FacePart.BottomLip, Join(facePoints.Skip(55).Take(5), facePoints.Skip(65).Take(3))));
.Concat( new [] { landmarkTuple[63] })
.Concat( new [] { landmarkTuple[62] })
.Concat( new [] { landmarkTuple[61] })
.Concat( new [] { landmarkTuple[60] }) },
{ FacePart.BottomLip, Enumerable.Range(54,6).Select(i => landmarkTuple[i])
.Concat( new [] { landmarkTuple[48] })
.Concat( new [] { landmarkTuple[60] })
.Concat( new [] { landmarkTuple[67] })
.Concat( new [] { landmarkTuple[66] })
.Concat( new [] { landmarkTuple[65] })
.Concat( new [] { landmarkTuple[64] }) }
}));
break; break;
case PredictorModel.Small: case PredictorModel.Small:
results.AddRange(landmarkTuples.Select(landmarkTuple => new Dictionary<FacePart, IEnumerable<FacePoint>> if (facePoints.Length != 5)
{ continue;
{ FacePart.NoseTip, Enumerable.Range(4,1).Select(i => landmarkTuple[i]).ToArray() }, collection.Add(new(FacePart.RightEye, facePoints.Skip(0).Take(2).ToArray()));
{ FacePart.LeftEye, Enumerable.Range(2,2).Select(i => landmarkTuple[i]).ToArray() }, collection.Add(new(FacePart.LeftEye, facePoints.Skip(2).Take(2).ToArray()));
{ FacePart.RightEye, Enumerable.Range(0,2).Select(i => landmarkTuple[i]).ToArray() } collection.Add(new(FacePart.NoseTip, facePoints.Skip(4).Take(1).ToArray()));
}));
break; break;
case PredictorModel.Custom:
if (CustomFaceLandmarkDetector is null)
throw new Exception($"{nameof(CustomFaceLandmarkDetector)} is null");
results.AddRange(CustomFaceLandmarkDetector.GetLandmarks(landmarkTuples));
break;
default:
throw new ArgumentOutOfRangeException(nameof(predictorModel), predictorModel, null);
} }
results.Add(collection.ToArray());
} }
finally
{
foreach (FullObjectDetection? landmark in landmarks)
landmark.Dispose();
}
return results; return results;
} }
@ -503,7 +471,7 @@ public sealed class FaceRecognition : DisposableObject
/// <returns>An enumerable collection of face location correspond to all faces in specified image.</returns> /// <returns>An enumerable collection of face location correspond to all faces in specified image.</returns>
/// <exception cref="ArgumentNullException"><paramref name="image"/> is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="image"/> is null.</exception>
/// <exception cref="ObjectDisposedException"><paramref name="image"/> or this object is disposed.</exception> /// <exception cref="ObjectDisposedException"><paramref name="image"/> or this object is disposed.</exception>
public List<Location> FaceLocations(Image image, int numberOfTimesToUpsample = 1, Model model = Model.Hog) public List<Location> FaceLocations(Model model, Image image, int numberOfTimesToUpsample, bool sortByPixelPercentage)
{ {
if (image == null) if (image == null)
throw new ArgumentNullException(nameof(image)); throw new ArgumentNullException(nameof(image));
@ -517,9 +485,10 @@ public sealed class FaceRecognition : DisposableObject
Location? ret = TrimBound(face.Rect, image.Width, image.Height); Location? ret = TrimBound(face.Rect, image.Width, image.Height);
double confidence = face.DetectionConfidence; double confidence = face.DetectionConfidence;
face.Dispose(); face.Dispose();
results.Add(new Location(ret, confidence)); results.Add(new Location(confidence, ret, image.Width, image.Height));
} }
if (sortByPixelPercentage)
results = (from l in results orderby l.PixelPercentage select l).ToList();
return results; return results;
} }
@ -763,36 +732,33 @@ public sealed class FaceRecognition : DisposableObject
#region Helpers #region Helpers
private IEnumerable<FullObjectDetection> RawFaceLandmarks(Image faceImage, private List<FullObjectDetection> RawFaceLandmarks(Image faceImage, int numberOfTimesToUpsample, IEnumerable<Location>? faceLocations, PredictorModel predictorModel, Model model)
IEnumerable<Location>? faceLocations = null,
PredictorModel predictorModel = PredictorModel.Large,
Model model = Model.Hog)
{ {
IEnumerable<Location> rects; IEnumerable<Location> locations;
if (faceLocations == null) if (faceLocations == null)
{ {
List<Location>? list = new(); List<Location>? list = new();
IEnumerable<MModRect>? tmp = RawFaceLocations(faceImage, 1, model); IEnumerable<MModRect>? tmp = RawFaceLocations(faceImage, numberOfTimesToUpsample, model);
foreach (MModRect? mModRect in tmp) foreach (MModRect? mModRect in tmp)
{ {
list.Add(new Location(mModRect.DetectionConfidence, mModRect.Rect.Bottom, mModRect.Rect.Left, mModRect.Rect.Right, mModRect.Rect.Top)); list.Add(new Location(mModRect.DetectionConfidence, mModRect.Rect.Bottom, mModRect.Rect.Left, mModRect.Rect.Right, mModRect.Rect.Top, faceImage.Width, faceImage.Height));
mModRect.Dispose(); mModRect.Dispose();
} }
rects = list; locations = list;
} }
else else
{ {
rects = faceLocations; locations = faceLocations;
} }
List<FullObjectDetection>? results = new(); List<FullObjectDetection> results = new();
if (predictorModel == PredictorModel.Custom) if (predictorModel == PredictorModel.Custom)
{ {
if (CustomFaceLandmarkDetector is null) if (CustomFaceLandmarkDetector is null)
throw new Exception($"{nameof(CustomFaceLandmarkDetector)} is null"); throw new ArgumentNullException(nameof(CustomFaceLandmarkDetector));
foreach (Location? rect in rects) foreach (Location? rect in locations)
{ {
FullObjectDetection? ret = CustomFaceLandmarkDetector.Detect(faceImage, rect); FullObjectDetection? ret = CustomFaceLandmarkDetector.Detect(faceImage, rect);
results.Add(ret); results.Add(ret);
@ -808,7 +774,7 @@ public sealed class FaceRecognition : DisposableObject
break; break;
} }
foreach (Location? rect in rects) foreach (Location? rect in locations)
{ {
FullObjectDetection? ret = posePredictor.Detect(faceImage.Matrix, new DlibDotNet.Rectangle(rect.Left, rect.Top, rect.Right, rect.Bottom)); FullObjectDetection? ret = posePredictor.Detect(faceImage.Matrix, new DlibDotNet.Rectangle(rect.Left, rect.Top, rect.Right, rect.Bottom));
results.Add(ret); results.Add(ret);
@ -818,7 +784,7 @@ public sealed class FaceRecognition : DisposableObject
return results; return results;
} }
private IEnumerable<MModRect> RawFaceLocations(Image faceImage, int numberOfTimesToUpsample = 1, Model model = Model.Hog) private IEnumerable<MModRect> RawFaceLocations(Image faceImage, int numberOfTimesToUpsample, Model model)
{ {
switch (model) switch (model)
{ {
@ -838,9 +804,9 @@ public sealed class FaceRecognition : DisposableObject
} }
} }
private IEnumerable<IEnumerable<MModRect>> RawFaceLocationsBatched(IEnumerable<Image> faceImages, int numberOfTimesToUpsample = 1, int batchSize = 128) => CnnFaceDetectionModelV1.DetectMulti(_CnnFaceDetector, faceImages, numberOfTimesToUpsample, batchSize); private IEnumerable<IEnumerable<MModRect>> RawFaceLocationsBatched(IEnumerable<Image> faceImages, int numberOfTimesToUpsample, int batchSize = 128) => CnnFaceDetectionModelV1.DetectMulti(_CnnFaceDetector, faceImages, numberOfTimesToUpsample, batchSize);
private static Location TrimBound(DlibDotNet.Rectangle location, int width, int height) => new(Math.Max(location.Left, 0), Math.Max(location.Top, 0), Math.Min(location.Right, width), Math.Min(location.Bottom, height)); private static Location TrimBound(DlibDotNet.Rectangle location, int width, int height) => new(Math.Max(location.Left, 0), Math.Max(location.Top, 0), Math.Min(location.Right, width), Math.Min(location.Bottom, height), width, height);
#endregion #endregion

View File

@ -41,7 +41,7 @@ public class DlibDotNet
Person[] people; Person[] people;
_AppSettings = appSettings; _AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null) if (appSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(appSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism));
_IsEnvironment = isEnvironment; _IsEnvironment = isEnvironment;
_Exceptions = new List<string>(); _Exceptions = new List<string>();
_Log = Serilog.Log.ForContext<DlibDotNet>(); _Log = Serilog.Log.ForContext<DlibDotNet>();
@ -61,21 +61,21 @@ public class DlibDotNet
_Distance = new E_Distance(configuration); _Distance = new E_Distance(configuration);
_FaceLandmarks = new D2_FaceLandmarks(configuration); _FaceLandmarks = new D2_FaceLandmarks(configuration);
if (configuration.ForceMetadataLastWriteTimeToCreationTime is null) if (configuration.ForceMetadataLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(configuration.ForceMetadataLastWriteTimeToCreationTime)} is null!"); throw new ArgumentNullException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime));
if (configuration.ForceResizeLastWriteTimeToCreationTime is null) if (configuration.ForceResizeLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(configuration.ForceResizeLastWriteTimeToCreationTime)} is null!"); throw new ArgumentNullException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime));
if (configuration.IgnoreExtensions is null) if (configuration.IgnoreExtensions is null)
throw new Exception($"{nameof(configuration.IgnoreExtensions)} is null!"); throw new ArgumentNullException(nameof(configuration.IgnoreExtensions));
if (configuration.OutputQuality is null) if (configuration.OutputQuality is null)
throw new Exception($"{nameof(configuration.OutputQuality)} is null!"); throw new ArgumentNullException(nameof(configuration.OutputQuality));
if (configuration.OverrideForResizeImages is null) if (configuration.OverrideForResizeImages is null)
throw new Exception($"{nameof(configuration.OverrideForResizeImages)} is null!"); throw new ArgumentNullException(nameof(configuration.OverrideForResizeImages));
if (configuration.PropertiesChangedForMetadata is null) if (configuration.PropertiesChangedForMetadata is null)
throw new Exception($"{nameof(configuration.PropertiesChangedForMetadata)} is null!"); throw new ArgumentNullException(nameof(configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForResize is null) if (configuration.PropertiesChangedForResize is null)
throw new Exception($"{nameof(configuration.PropertiesChangedForResize)} is null!"); throw new ArgumentNullException(nameof(configuration.PropertiesChangedForResize));
if (configuration.Reverse is null) if (configuration.Reverse is null)
throw new Exception($"{nameof(configuration.Reverse)} is null!"); throw new ArgumentNullException(nameof(configuration.Reverse));
_Metadata = new(configuration.ForceMetadataLastWriteTimeToCreationTime.Value, configuration.PropertiesChangedForMetadata.Value); _Metadata = new(configuration.ForceMetadataLastWriteTimeToCreationTime.Value, configuration.PropertiesChangedForMetadata.Value);
if (args.Count > 0) if (args.Count > 0)
argZero = Path.GetFullPath(args[0]); argZero = Path.GetFullPath(args[0]);
@ -88,7 +88,7 @@ public class DlibDotNet
(Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(configuration); (Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(configuration);
_Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel); _Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel);
if (configuration.SkipSearch is null) if (configuration.SkipSearch is null)
throw new Exception($"{nameof(configuration.SkipSearch)} is null!"); throw new ArgumentNullException(nameof(configuration.SkipSearch));
if (!_ArgZeroIsConfigurationRootDirectory) if (!_ArgZeroIsConfigurationRootDirectory)
people = Array.Empty<Person>(); people = Array.Empty<Person>();
else else
@ -134,7 +134,7 @@ public class DlibDotNet
{ {
long result; long result;
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks; result = DateTime.Now.Ticks;
@ -188,7 +188,7 @@ public class DlibDotNet
private void Verify(Models.Configuration configuration) private void Verify(Models.Configuration configuration)
{ {
if (!configuration.OutputResolutions.Any() || string.IsNullOrEmpty(configuration.OutputResolutions[0]) || !configuration.ValidResolutions.Contains(configuration.OutputResolutions[0])) if (!configuration.OutputResolutions.Any() || string.IsNullOrEmpty(configuration.OutputResolutions[0]) || !configuration.ValidResolutions.Contains(configuration.OutputResolutions[0]))
throw new Exception($"{nameof(configuration.OutputResolutions)} must be a valid outputResolution!"); throw new ArgumentNullException(nameof(configuration.OutputResolutions), "must be a valid outputResolution!");
if ((from l in configuration.OutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) if ((from l in configuration.OutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any())
throw new Exception($"One or more {nameof(configuration.OutputResolutions)} are not in the ValidResolutions list!"); throw new Exception($"One or more {nameof(configuration.OutputResolutions)} are not in the ValidResolutions list!");
if ((from l in configuration.LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) if ((from l in configuration.LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any())
@ -202,79 +202,81 @@ public class DlibDotNet
if ((from l in configuration.SaveFaceLandmarkForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) if ((from l in configuration.SaveFaceLandmarkForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any())
throw new Exception($"One or more {nameof(configuration.SaveFaceLandmarkForOutputResolutions)} are not in the ValidResolutions list!"); throw new Exception($"One or more {nameof(configuration.SaveFaceLandmarkForOutputResolutions)} are not in the ValidResolutions list!");
if (configuration.CheckJsonForDistanceResults is null) if (configuration.CheckJsonForDistanceResults is null)
throw new Exception($"{nameof(configuration.CheckJsonForDistanceResults)} must be set!"); throw new ArgumentNullException(nameof(configuration.CheckJsonForDistanceResults));
if (configuration.CrossDirectoryMaxItemsInDistanceCollection is null) if (configuration.CrossDirectoryMaxItemsInDistanceCollection is null)
throw new Exception($"{nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection)} must be set!"); throw new ArgumentNullException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
if (configuration.DistanceFactor is null) if (configuration.DistanceFactor is null)
throw new Exception($"{nameof(configuration.DistanceFactor)} must be set!"); throw new ArgumentNullException(nameof(configuration.DistanceFactor));
if (configuration.ForceMetadataLastWriteTimeToCreationTime is null) if (configuration.ForceMetadataLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(configuration.ForceMetadataLastWriteTimeToCreationTime)} must be set!"); throw new ArgumentNullException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime));
if (configuration.ForceResizeLastWriteTimeToCreationTime is null) if (configuration.ForceResizeLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(configuration.ForceResizeLastWriteTimeToCreationTime)} must be set!"); throw new ArgumentNullException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime));
if (configuration.IgnoreExtensions is null) if (configuration.IgnoreExtensions is null)
throw new Exception($"{nameof(configuration.IgnoreExtensions)} must be set!"); throw new ArgumentNullException(nameof(configuration.IgnoreExtensions));
if (configuration.IgnoreRelativePaths is null) if (configuration.IgnoreRelativePaths is null)
throw new Exception($"{nameof(configuration.IgnoreRelativePaths)} must be set!"); throw new ArgumentNullException(nameof(configuration.IgnoreRelativePaths));
if (configuration.LoadOrCreateThenSaveIndex is null) if (configuration.LoadOrCreateThenSaveIndex is null)
throw new Exception($"{nameof(configuration.LoadOrCreateThenSaveIndex)} must be set!"); throw new ArgumentNullException(nameof(configuration.LoadOrCreateThenSaveIndex));
if (configuration.LocationConfidenceFactor is null) if (configuration.LocationConfidenceFactor is null)
throw new Exception($"{nameof(configuration.LocationConfidenceFactor)} must be set!"); throw new ArgumentNullException(nameof(configuration.LocationConfidenceFactor));
if (configuration.MappedMaxIndex is null) if (configuration.MappedMaxIndex is null)
throw new Exception($"{nameof(configuration.MappedMaxIndex)} must be set!"); throw new ArgumentNullException(nameof(configuration.MappedMaxIndex));
if (configuration.MappedMaxIndex.HasValue && configuration.LoadOrCreateThenSaveIndex.Value && !_IsEnvironment.DebuggerWasAttachedDuringConstructor) if (configuration.MappedMaxIndex.HasValue && configuration.LoadOrCreateThenSaveIndex.Value && !_IsEnvironment.DebuggerWasAttachedDuringConstructor)
throw new Exception($"{nameof(configuration.MappedMaxIndex)} only allowed when debugger is attached!"); throw new ArgumentNullException(nameof(configuration.MappedMaxIndex));
if (configuration.MaxItemsInDistanceCollection is null) if (configuration.MaxItemsInDistanceCollection is null)
throw new Exception($"{nameof(configuration.MaxItemsInDistanceCollection)} must be set!"); throw new ArgumentNullException(nameof(configuration.MaxItemsInDistanceCollection));
if (configuration.MixedYearRelativePaths is null) if (configuration.MixedYearRelativePaths is null)
throw new Exception($"{nameof(configuration.MixedYearRelativePaths)} must be set!"); throw new ArgumentNullException(nameof(configuration.MixedYearRelativePaths));
if (configuration.NumJitters is null) if (configuration.NumberOfJitters is null)
throw new Exception($"{nameof(configuration.NumJitters)} must be set!"); throw new ArgumentNullException(nameof(configuration.NumberOfJitters));
if (configuration.NumberOfTimesToUpsample is null)
throw new ArgumentNullException(nameof(configuration.NumberOfTimesToUpsample));
if (configuration.OutputQuality is null) if (configuration.OutputQuality is null)
throw new Exception($"{nameof(configuration.OutputQuality)} must be set!"); throw new ArgumentNullException(nameof(configuration.OutputQuality));
if (configuration.OutputResolutions is null) if (configuration.OutputResolutions is null)
throw new Exception($"{nameof(configuration.OutputResolutions)} must be set!"); throw new ArgumentNullException(nameof(configuration.OutputResolutions));
if (configuration.OverrideForFaceImages is null) if (configuration.OverrideForFaceImages is null)
throw new Exception($"{nameof(configuration.OverrideForFaceImages)} must be set!"); throw new ArgumentNullException(nameof(configuration.OverrideForFaceImages));
if (configuration.OverrideForFaceLandmarkImages is null) if (configuration.OverrideForFaceLandmarkImages is null)
throw new Exception($"{nameof(configuration.OverrideForFaceLandmarkImages)} must be set!"); throw new ArgumentNullException(nameof(configuration.OverrideForFaceLandmarkImages));
if (configuration.OverrideForResizeImages is null) if (configuration.OverrideForResizeImages is null)
throw new Exception($"{nameof(configuration.OverrideForResizeImages)} must be set!"); throw new ArgumentNullException(nameof(configuration.OverrideForResizeImages));
if (configuration.PaddingLoops is null) if (configuration.PaddingLoops is null)
throw new Exception($"{nameof(configuration.PaddingLoops)} must be set!"); throw new ArgumentNullException(nameof(configuration.PaddingLoops));
if (configuration.PropertiesChangedForDistance is null) if (configuration.PropertiesChangedForDistance is null)
throw new Exception($"{nameof(configuration.PropertiesChangedForDistance)} must be set!"); throw new ArgumentNullException(nameof(configuration.PropertiesChangedForDistance));
if (configuration.PropertiesChangedForFaces is null) if (configuration.PropertiesChangedForFaces is null)
throw new Exception($"{nameof(configuration.PropertiesChangedForFaces)} must be set!"); throw new ArgumentNullException(nameof(configuration.PropertiesChangedForFaces));
if (configuration.PropertiesChangedForIndex is null) if (configuration.PropertiesChangedForIndex is null)
throw new Exception($"{nameof(configuration.PropertiesChangedForIndex)} must be set!"); throw new ArgumentNullException(nameof(configuration.PropertiesChangedForIndex));
if (configuration.PropertiesChangedForMetadata is null) if (configuration.PropertiesChangedForMetadata is null)
throw new Exception($"{nameof(configuration.PropertiesChangedForMetadata)} must be set!"); throw new ArgumentNullException(nameof(configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForResize is null) if (configuration.PropertiesChangedForResize is null)
throw new Exception($"{nameof(configuration.PropertiesChangedForResize)} must be set!"); throw new ArgumentNullException(nameof(configuration.PropertiesChangedForResize));
if (configuration.Reverse is null) if (configuration.Reverse is null)
throw new Exception($"{nameof(configuration.Reverse)} must be set!"); throw new ArgumentNullException(nameof(configuration.Reverse));
if (configuration.SaveFaceLandmarkForOutputResolutions is null) if (configuration.SaveFaceLandmarkForOutputResolutions is null)
throw new Exception($"{nameof(configuration.SaveFaceLandmarkForOutputResolutions)} must be set!"); throw new ArgumentNullException(nameof(configuration.SaveFaceLandmarkForOutputResolutions));
if (configuration.SaveFullYearOfRandomFiles is null) if (configuration.SaveFullYearOfRandomFiles is null)
throw new Exception($"{nameof(configuration.SaveFullYearOfRandomFiles)} must be set!"); throw new ArgumentNullException(nameof(configuration.SaveFullYearOfRandomFiles));
if (configuration.SaveResizedSubfiles is null) if (configuration.SaveResizedSubfiles is null)
throw new Exception($"{nameof(configuration.SaveResizedSubfiles)} must be set!"); throw new ArgumentNullException(nameof(configuration.SaveResizedSubfiles));
if (configuration.SkipSearch is null) if (configuration.SkipSearch is null)
throw new Exception($"{nameof(configuration.SkipSearch)} must be set!"); throw new ArgumentNullException(nameof(configuration.SkipSearch));
if (configuration.TestDistanceResults is null) if (configuration.TestDistanceResults is null)
throw new Exception($"{nameof(configuration.TestDistanceResults)} must be set!"); throw new ArgumentNullException(nameof(configuration.TestDistanceResults));
if (configuration.ValidResolutions is null) if (configuration.ValidResolutions is null)
throw new Exception($"{nameof(configuration.ValidResolutions)} must be set!"); throw new ArgumentNullException(nameof(configuration.ValidResolutions));
if (string.IsNullOrEmpty(configuration.ModelDirectory) || !Directory.Exists(configuration.ModelDirectory)) if (string.IsNullOrEmpty(configuration.ModelDirectory) || !Directory.Exists(configuration.ModelDirectory))
throw new Exception($"{nameof(configuration.ModelDirectory)} must have a value and exits!"); throw new ArgumentNullException(nameof(configuration.ModelDirectory));
if (string.IsNullOrEmpty(configuration.ModelName)) if (string.IsNullOrEmpty(configuration.ModelName))
throw new Exception($"{nameof(configuration.ModelName)} must have a value!"); throw new ArgumentNullException(nameof(configuration.ModelName));
if (string.IsNullOrEmpty(configuration.OutputExtension)) if (string.IsNullOrEmpty(configuration.OutputExtension))
throw new Exception($"{nameof(configuration.OutputExtension)} must have a value!"); throw new ArgumentNullException(nameof(configuration.OutputExtension));
if (string.IsNullOrEmpty(configuration.PredictorModelName)) if (string.IsNullOrEmpty(configuration.PredictorModelName))
throw new Exception($"{nameof(configuration.PredictorModelName)} must have a value!"); throw new ArgumentNullException(nameof(configuration.PredictorModelName));
if (configuration.DistanceFactor.Value + configuration.LocationConfidenceFactor.Value != 10) if (configuration.DistanceFactor.Value + configuration.LocationConfidenceFactor.Value != 10)
throw new Exception($"{nameof(configuration.DistanceFactor)} and {nameof(configuration.LocationConfidenceFactor)} must add up to 10!"); throw new ArgumentNullException(nameof(configuration.DistanceFactor));
} }
private void VerifyExtra(List<string> args, Property.Models.Configuration propertyConfiguration, Models.Configuration configuration) private void VerifyExtra(List<string> args, Property.Models.Configuration propertyConfiguration, Models.Configuration configuration)
@ -306,15 +308,15 @@ public class DlibDotNet
private void FullParallelForWork(PropertyLogic propertyLogic, object @lock, string outputResolution, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileInfo?> propertyFileInfoCollection, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<D_Face>> imageFaceCollections, string sourceDirectory, int index, PropertyHolder propertyHolder) private void FullParallelForWork(PropertyLogic propertyLogic, object @lock, string outputResolution, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileInfo?> propertyFileInfoCollection, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<D_Face>> imageFaceCollections, string sourceDirectory, int index, PropertyHolder propertyHolder)
{ {
if (propertyHolder.ImageFileInfo is null) if (propertyHolder.ImageFileInfo is null)
throw new Exception($"{nameof(propertyHolder.ImageFileInfo)} is null!"); throw new ArgumentNullException(nameof(propertyHolder.ImageFileInfo));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration.SaveResizedSubfiles is null) if (_Configuration.SaveResizedSubfiles is null)
throw new Exception($"{nameof(_Configuration.SaveResizedSubfiles)} is null!"); throw new ArgumentNullException(nameof(_Configuration.SaveResizedSubfiles));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
if (_Configuration.PropertyConfiguration.WriteBitmapDataBytes is null) if (_Configuration.PropertyConfiguration.WriteBitmapDataBytes is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration.WriteBitmapDataBytes)} is null!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration.WriteBitmapDataBytes));
A_Property property; A_Property property;
List<D_Face> faceCollection; List<D_Face> faceCollection;
string original = "Original"; string original = "Original";
@ -395,9 +397,9 @@ public class DlibDotNet
{ {
int result = 0; int result = 0;
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(AppSettings.MaxDegreeOfParallelism));
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism.Value }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism.Value };
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
if (faceCollections.Count != filteredPropertyHolderCollection.Length || metadataCollection.Count != filteredPropertyHolderCollection.Length || resizeKeyValuePairs.Count != filteredPropertyHolderCollection.Length || propertyCollection.Count != filteredPropertyHolderCollection.Length) if (faceCollections.Count != filteredPropertyHolderCollection.Length || metadataCollection.Count != filteredPropertyHolderCollection.Length || resizeKeyValuePairs.Count != filteredPropertyHolderCollection.Length || propertyCollection.Count != filteredPropertyHolderCollection.Length)
@ -460,7 +462,7 @@ public class DlibDotNet
if (metadataIdLines.Any()) if (metadataIdLines.Any())
{ {
text = string.Join(Environment.NewLine, from l in metadataIdLines orderby l.Id select l.Line); text = string.Join(Environment.NewLine, from l in metadataIdLines orderby l.Id select l.Line);
_ = Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, text, compareBeforeWrite: true); _ = Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, text, updateDateWhenMatches: true, compareBeforeWrite: true);
} }
else else
{ {
@ -472,19 +474,18 @@ public class DlibDotNet
private void WriteGroup(Property.Models.Configuration configuration, PropertyLogic propertyLogic, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<List<D_Face>> faceCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, string sourceDirectory, string outputResolution, PropertyHolder[] filteredPropertyHolderCollection) private void WriteGroup(Property.Models.Configuration configuration, PropertyLogic propertyLogic, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<List<D_Face>> faceCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, string sourceDirectory, string outputResolution, PropertyHolder[] filteredPropertyHolderCollection)
{ {
if (_Configuration.PropertiesChangedForMetadata is null) if (_Configuration.PropertiesChangedForMetadata is null)
throw new Exception($"{nameof(_Configuration.PropertiesChangedForMetadata)} is null!"); throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForProperty is null) if (configuration.PropertiesChangedForProperty is null)
throw new Exception($"{nameof(configuration.PropertiesChangedForProperty)} is null!"); throw new ArgumentNullException(nameof(configuration.PropertiesChangedForProperty));
if (_Configuration.PropertiesChangedForResize is null) if (_Configuration.PropertiesChangedForResize is null)
throw new Exception($"{nameof(_Configuration.PropertiesChangedForResize)} is null!"); throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForResize));
if (_Configuration.PropertiesChangedForFaces is null) if (_Configuration.PropertiesChangedForFaces is null)
throw new Exception($"{nameof(_Configuration.PropertiesChangedForFaces)} is null!"); throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForFaces));
string key; string key;
string json; string json;
string checkFile; string checkFile;
PropertyHolder propertyHolder; PropertyHolder propertyHolder;
int sourceDirectoryLength = sourceDirectory.Length; int sourceDirectoryLength = sourceDirectory.Length;
int rootDirectoryLength = configuration.RootDirectory.Length;
_FilePropertiesKeyValuePairs.Add(sourceDirectory, new List<Tuple<string, A_Property>>()); _FilePropertiesKeyValuePairs.Add(sourceDirectory, new List<Tuple<string, A_Property>>());
JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = false }; JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = false };
if (!(from l in propertyCollection where l?.Width is null select true).Any()) if (!(from l in propertyCollection where l?.Width is null select true).Any())
@ -511,16 +512,6 @@ public class DlibDotNet
resizeKeyValuePairsCollections.Add(new KeyValuePair<string, Dictionary<string, int[]>>(key, resizeKeyValuePairs[i])); resizeKeyValuePairsCollections.Add(new KeyValuePair<string, Dictionary<string, int[]>>(key, resizeKeyValuePairs[i]));
metadataCollectionKeyValuePairs.Add(new KeyValuePair<string, List<KeyValuePair<string, string>>>(key, metadataCollection[i])); metadataCollectionKeyValuePairs.Add(new KeyValuePair<string, List<KeyValuePair<string, string>>>(key, metadataCollection[i]));
} }
if (_Metadata.AngleBracketCollection.Any())
{
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(_Metadata.AngleBracketCollection[0], level, "[{}]");
checkFile = Path.Combine(checkDirectory, fileName);
if (File.Exists(checkFile))
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
checkFile = Path.Combine(checkDirectory, fileName);
json = JsonSerializer.Serialize(metadataCollectionKeyValuePairs, writeIndentedJsonSerializerOptions);
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, compareBeforeWrite: true);
}
if (propertyLogic.AngleBracketCollection.Any()) if (propertyLogic.AngleBracketCollection.Any())
{ {
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(propertyLogic.AngleBracketCollection[0], level, "[{}]"); checkDirectory = Property.Models.Stateless.IPath.GetDirectory(propertyLogic.AngleBracketCollection[0], level, "[{}]");
@ -529,7 +520,17 @@ public class DlibDotNet
File.Move(checkFile, Path.Combine(checkDirectory, fileName)); File.Move(checkFile, Path.Combine(checkDirectory, fileName));
checkFile = Path.Combine(checkDirectory, fileName); checkFile = Path.Combine(checkDirectory, fileName);
json = JsonSerializer.Serialize(propertyCollectionKeyValuePairs, writeIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(propertyCollectionKeyValuePairs, writeIndentedJsonSerializerOptions);
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, compareBeforeWrite: true); _ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
}
if (_Metadata.AngleBracketCollection.Any())
{
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(_Metadata.AngleBracketCollection[0], level, "[{}]");
checkFile = Path.Combine(checkDirectory, fileName);
if (File.Exists(checkFile))
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
checkFile = Path.Combine(checkDirectory, fileName);
json = JsonSerializer.Serialize(metadataCollectionKeyValuePairs, writeIndentedJsonSerializerOptions);
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
} }
if (_Resize.AngleBracketCollection.Any()) if (_Resize.AngleBracketCollection.Any())
{ {
@ -539,7 +540,7 @@ public class DlibDotNet
File.Move(checkFile, Path.Combine(checkDirectory, fileName)); File.Move(checkFile, Path.Combine(checkDirectory, fileName));
checkFile = Path.Combine(checkDirectory, fileName); checkFile = Path.Combine(checkDirectory, fileName);
json = JsonSerializer.Serialize(resizeKeyValuePairsCollections, writeIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(resizeKeyValuePairsCollections, writeIndentedJsonSerializerOptions);
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, compareBeforeWrite: true); _ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
} }
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution) && _Faces.AngleBracketCollection.Any()) if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution) && _Faces.AngleBracketCollection.Any())
{ {
@ -549,7 +550,7 @@ public class DlibDotNet
File.Move(checkFile, Path.Combine(checkDirectory, fileName)); File.Move(checkFile, Path.Combine(checkDirectory, fileName));
checkFile = Path.Combine(checkDirectory, fileName); checkFile = Path.Combine(checkDirectory, fileName);
json = JsonSerializer.Serialize(faceCollectionsKeyValuePairs, writeIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(faceCollectionsKeyValuePairs, writeIndentedJsonSerializerOptions);
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, compareBeforeWrite: true); _ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
} }
} }
} }
@ -557,9 +558,9 @@ public class DlibDotNet
private void FullDoWork(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string argZero, Dictionary<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, List<PropertyHolder[]> propertyHolderCollections) private void FullDoWork(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string argZero, Dictionary<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, List<PropertyHolder[]> propertyHolderCollections)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
int g; int g;
int r; int r;
int exceptionCount; int exceptionCount;
@ -677,11 +678,11 @@ public class DlibDotNet
{ {
if (outputResolution == _Configuration.OutputResolutions[0] || _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) if (outputResolution == _Configuration.OutputResolutions[0] || _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
{ {
PropertyHolder.AddToNamed(propertyLogic, filteredPropertyHolderCollection);
for (int i = 0; i < faceCollections.Count; i++) for (int i = 0; i < faceCollections.Count; i++)
PropertyHolder.AddToFaces(filteredPropertyHolderCollection, (from l in faceCollections[i] select (object)l).ToArray()); filteredPropertyHolderCollection[i].Faces.AddRange(from l in faceCollections[i] select l);
PropertyHolder.AddToNamed(propertyLogic, filteredPropertyHolderCollection);
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
D_Face.SaveShortcuts(configuration, model, predictorModel, _Configuration.JuliePhares, peopleCollection, propertyLogic, outputResolution, filteredPropertyHolderCollection, faceCollections); D_Face.SaveShortcuts(configuration, model, predictorModel, _Configuration.JuliePhares, ticks, peopleCollection, propertyLogic, outputResolution, filteredPropertyHolderCollection);
} }
} }
if (exceptionCount == 0 && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)) if (exceptionCount == 0 && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution))
@ -707,7 +708,7 @@ public class DlibDotNet
{ {
propertyLogic.SaveAllCollection(); propertyLogic.SaveAllCollection();
if (propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.Any()) if (propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.Any())
E_Distance.SaveGroupedFaceEncodings(configuration, model, predictorModel, argZero, peopleCollection, outputResolution, propertyHolderCollections); E_Distance.SaveGroupedFaceEncodings(configuration, model, predictorModel, argZero, ticks, peopleCollection, outputResolution, propertyHolderCollections);
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any()) if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
break; break;
if (_Exceptions.Count == 0) if (_Exceptions.Count == 0)
@ -731,9 +732,9 @@ public class DlibDotNet
{ {
PropertyLogic result; PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration);
return result; return result;
} }

View File

@ -24,7 +24,8 @@ public class Configuration
[Display(Name = "Mixed Year Relative Paths"), Required] public string[] MixedYearRelativePaths { get; set; } [Display(Name = "Mixed Year Relative Paths"), Required] public string[] MixedYearRelativePaths { get; set; }
[Display(Name = "Model Directory"), Required] public string ModelDirectory { get; set; } [Display(Name = "Model Directory"), Required] public string ModelDirectory { get; set; }
[Display(Name = "Model Name"), Required] public string ModelName { get; set; } [Display(Name = "Model Name"), Required] public string ModelName { get; set; }
[Display(Name = "Num Jitters"), Required] public int? NumJitters { get; set; } [Display(Name = "Number Jitters"), Required] public int? NumberOfJitters { get; set; }
[Display(Name = "Number of Times To Up Sample"), Required] public int? NumberOfTimesToUpsample { get; set; }
[Display(Name = "Output Extension"), Required] public string OutputExtension { get; set; } [Display(Name = "Output Extension"), Required] public string OutputExtension { get; set; }
[Display(Name = "Output Quality"), Required] public int? OutputQuality { get; set; } [Display(Name = "Output Quality"), Required] public int? OutputQuality { get; set; }
[Display(Name = "Output Resolutions"), Required] public string[] OutputResolutions { get; set; } [Display(Name = "Output Resolutions"), Required] public string[] OutputResolutions { get; set; }
@ -68,7 +69,8 @@ public class Configuration
MixedYearRelativePaths = Array.Empty<string>(); MixedYearRelativePaths = Array.Empty<string>();
ModelDirectory = string.Empty; ModelDirectory = string.Empty;
ModelName = string.Empty; ModelName = string.Empty;
NumJitters = null; NumberOfJitters = null;
NumberOfTimesToUpsample = null;
OutputExtension = string.Empty; OutputExtension = string.Empty;
OutputQuality = null; OutputQuality = null;
OutputResolutions = Array.Empty<string>(); OutputResolutions = Array.Empty<string>();

View File

@ -24,7 +24,8 @@ public class Configuration
protected readonly string[] _MixedYearRelativePaths; protected readonly string[] _MixedYearRelativePaths;
protected readonly string _ModelDirectory; protected readonly string _ModelDirectory;
protected readonly string _ModelName; protected readonly string _ModelName;
protected readonly int? _NumJitters; protected readonly int? _NumberOfJitters;
protected readonly int? _NumberOfTimesToUpsample;
protected readonly string _OutputExtension; protected readonly string _OutputExtension;
protected readonly int? _OutputQuality; protected readonly int? _OutputQuality;
protected readonly string[] _OutputResolutions; protected readonly string[] _OutputResolutions;
@ -65,7 +66,8 @@ public class Configuration
public string[] MixedYearRelativePaths => _MixedYearRelativePaths; public string[] MixedYearRelativePaths => _MixedYearRelativePaths;
public string ModelDirectory => _ModelDirectory; public string ModelDirectory => _ModelDirectory;
public string ModelName => _ModelName; public string ModelName => _ModelName;
public int? NumJitters => _NumJitters; public int? NumberOfJitters => _NumberOfJitters;
public int? NumberOfTimesToUpsample => _NumberOfTimesToUpsample;
public string OutputExtension => _OutputExtension; public string OutputExtension => _OutputExtension;
public int? OutputQuality => _OutputQuality; public int? OutputQuality => _OutputQuality;
public string[] OutputResolutions => _OutputResolutions; public string[] OutputResolutions => _OutputResolutions;
@ -90,7 +92,7 @@ public class Configuration
public string[] ValidResolutions => _ValidResolutions; public string[] ValidResolutions => _ValidResolutions;
[JsonConstructor] [JsonConstructor]
public Configuration(bool? checkJsonForDistanceResults, int? crossDirectoryMaxItemsInDistanceCollection, int? distanceFactor, bool? forceMetadataLastWriteTimeToCreationTime, bool? forceResizeLastWriteTimeToCreationTime, string[] ignoreExtensions, string[] ignoreRelativePaths, string[] juliePhares, string[] loadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions, bool? loadOrCreateThenSaveIndex, int? locationConfidenceFactor, int? mappedMaxIndex, int? maxItemsInDistanceCollection, string[] mixedYearRelativePaths, string modelDirectory, string modelName, int? numJitters, string outputExtension, int? outputQuality, string[] outputResolutions, bool? overrideForFaceImages, bool? overrideForFaceLandmarkImages, bool? overrideForResizeImages, int? paddingLoops, string predictorModelName, bool? propertiesChangedForDistance, bool? propertiesChangedForFaces, bool? propertiesChangedForIndex, bool? propertiesChangedForMetadata, bool? propertiesChangedForResize, Property.Models.Configuration? propertyConfiguration, bool? reverse, string[] saveFaceLandmarkForOutputResolutions, bool? saveFullYearOfRandomFiles, bool? saveResizedSubfiles, string[] saveShortcutsForOutputResolutions, bool? skipSearch, bool? testDistanceResults, string[] validResolutions) public Configuration(bool? checkJsonForDistanceResults, int? crossDirectoryMaxItemsInDistanceCollection, int? distanceFactor, bool? forceMetadataLastWriteTimeToCreationTime, bool? forceResizeLastWriteTimeToCreationTime, string[] ignoreExtensions, string[] ignoreRelativePaths, string[] juliePhares, string[] loadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions, bool? loadOrCreateThenSaveIndex, int? locationConfidenceFactor, int? mappedMaxIndex, int? maxItemsInDistanceCollection, string[] mixedYearRelativePaths, string modelDirectory, string modelName, int? numberOfJitters, int? numberOfTimesToUpsample, string outputExtension, int? outputQuality, string[] outputResolutions, bool? overrideForFaceImages, bool? overrideForFaceLandmarkImages, bool? overrideForResizeImages, int? paddingLoops, string predictorModelName, bool? propertiesChangedForDistance, bool? propertiesChangedForFaces, bool? propertiesChangedForIndex, bool? propertiesChangedForMetadata, bool? propertiesChangedForResize, Property.Models.Configuration? propertyConfiguration, bool? reverse, string[] saveFaceLandmarkForOutputResolutions, bool? saveFullYearOfRandomFiles, bool? saveResizedSubfiles, string[] saveShortcutsForOutputResolutions, bool? skipSearch, bool? testDistanceResults, string[] validResolutions)
{ {
_CheckJsonForDistanceResults = checkJsonForDistanceResults; _CheckJsonForDistanceResults = checkJsonForDistanceResults;
_CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection; _CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
@ -110,7 +112,8 @@ public class Configuration
_MixedYearRelativePaths = mixedYearRelativePaths; _MixedYearRelativePaths = mixedYearRelativePaths;
_ModelDirectory = modelDirectory; _ModelDirectory = modelDirectory;
_ModelName = modelName; _ModelName = modelName;
_NumJitters = numJitters; _NumberOfJitters = numberOfJitters;
_NumberOfTimesToUpsample = numberOfTimesToUpsample;
_OutputExtension = outputExtension; _OutputExtension = outputExtension;
_OutputQuality = outputQuality; _OutputQuality = outputQuality;
_OutputResolutions = outputResolutions; _OutputResolutions = outputResolutions;

View File

@ -56,7 +56,7 @@ internal class A2_People
_ = Directory.CreateDirectory(directoryFullName); _ = Directory.CreateDirectory(directoryFullName);
jsonFile = Path.Combine(directoryFullName, $"{segments[1]}.json"); jsonFile = Path.Combine(directoryFullName, $"{segments[1]}.json");
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true)) if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true))
continue; continue;
} }
} }
@ -65,7 +65,7 @@ internal class A2_People
{ {
Person[] results; Person[] results;
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory; string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People)); string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People));
string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory)); string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory));

View File

@ -116,8 +116,10 @@ internal class D2_FaceLandmarks
string parentCheck; string parentCheck;
const int pointSize = 2; const int pointSize = 2;
FileInfo rotatedFileInfo; FileInfo rotatedFileInfo;
DateTime? dateTime = null;
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
List<string[]> imageFiles = new(); List<string[]> imageFiles = new();
bool updateDateWhenMatches = false;
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), propertyHolder.ImageFileNameWithoutExtension); string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), propertyHolder.ImageFileNameWithoutExtension);
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) }; string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
@ -155,6 +157,11 @@ internal class D2_FaceLandmarks
check = true; check = true;
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime) else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
check = true; check = true;
if (check && !updateDateWhenMatches)
{
updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
}
} }
if (check) if (check)
SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, propertyHolder.ResizedFileInfo); SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, propertyHolder.ResizedFileInfo);

View File

@ -236,7 +236,9 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
faceCollection[i].Location.Bottom, faceCollection[i].Location.Bottom,
faceCollection[i].Location.Left, faceCollection[i].Location.Left,
faceCollection[i].Location.Right, faceCollection[i].Location.Right,
faceCollection[i].Location.Top); faceCollection[i].Location.Top,
source.Width,
source.Height);
width = location.Right - location.Left; width = location.Right - location.Left;
height = location.Bottom - location.Top; height = location.Bottom - location.Top;
rectangle = new Rectangle(location.Left, location.Top, width, height); rectangle = new Rectangle(location.Left, location.Top, width, height);
@ -254,10 +256,11 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
List<D_Face> results = new(); List<D_Face> results = new();
if (_Configuration.PaddingLoops is null) if (_Configuration.PaddingLoops is null)
throw new Exception(); throw new Exception();
if (_Configuration.NumJitters is null) if (_Configuration.NumberOfJitters is null)
throw new Exception(); throw new ArgumentNullException(nameof(_Configuration.NumberOfJitters));
if (_Configuration.NumberOfTimesToUpsample is null)
throw new ArgumentNullException(nameof(_Configuration.NumberOfTimesToUpsample));
List<Location> locations; List<Location> locations;
const int numberOfTimesToUpSample = 1;
FaceRecognitionDotNet.Image? unknownImage = null; FaceRecognitionDotNet.Image? unknownImage = null;
if (resizedFileInfo.Exists) if (resizedFileInfo.Exists)
{ {
@ -270,7 +273,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
else else
{ {
FaceRecognition faceRecognition = FaceRecognition.Create(_ModelParameter); FaceRecognition faceRecognition = FaceRecognition.Create(_ModelParameter);
locations = faceRecognition.FaceLocations(unknownImage, numberOfTimesToUpSample, _Model); locations = faceRecognition.FaceLocations(_Model, unknownImage, _Configuration.NumberOfTimesToUpsample.Value, sortByPixelPercentage: true);
if (!locations.Any()) if (!locations.Any())
results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i: null, location: null)); results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i: null, location: null));
else else
@ -279,10 +282,10 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
int width; int width;
int height; int height;
int padding; int padding;
int leftEyeX; int? leftEyeX;
int leftEyeY; int? leftEyeY;
int rightEyeX; int? rightEyeX;
int rightEyeY; int? rightEyeY;
Bitmap rotated; Bitmap rotated;
string faceFile; string faceFile;
Location location; Location location;
@ -291,12 +294,11 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
D_Face? face = null; D_Face? face = null;
Rectangle rectangle; Rectangle rectangle;
double[] rawEncoding; double[] rawEncoding;
IEnumerable<FacePoint> facePoints;
Shared.Models.FaceEncoding faceEncoding; Shared.Models.FaceEncoding faceEncoding;
FaceRecognitionDotNet.Image? knownImage; FaceRecognitionDotNet.Image? knownImage;
FaceRecognitionDotNet.Image? rotatedImage; FaceRecognitionDotNet.Image? rotatedImage;
List<(FacePart, FacePoint[])[]> facesLandmarks;
List<FaceRecognitionDotNet.FaceEncoding> faceEncodings; List<FaceRecognitionDotNet.FaceEncoding> faceEncodings;
List<Dictionary<FacePart, IEnumerable<FacePoint>>> faceLandmarks;
using Bitmap source = unknownImage.ToBitmap(); using Bitmap source = unknownImage.ToBitmap();
padding = (int)((source.Width + source.Height) / 2 * .01); padding = (int)((source.Width + source.Height) / 2 * .01);
for (int i = 0; i < locations.Count; i++) for (int i = 0; i < locations.Count; i++)
@ -307,13 +309,19 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
locations[i].Bottom + (padding * p), locations[i].Bottom + (padding * p),
locations[i].Left - (padding * p), locations[i].Left - (padding * p),
locations[i].Right + (padding * p), locations[i].Right + (padding * p),
locations[i].Top - (padding * p)); locations[i].Top - (padding * p),
face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i, location); source.Width,
source.Height);
face = new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i, location);
width = location.Right - location.Left; width = location.Right - location.Left;
height = location.Bottom - location.Top; height = location.Bottom - location.Top;
rectangle = new Rectangle(location.Left, location.Top, width, height); rectangle = new Rectangle(location.Left, location.Top, width, height);
using (preRotated = new Bitmap(width, height)) using (preRotated = new Bitmap(width, height))
{ {
leftEyeX = null;
leftEyeY = null;
rightEyeX = null;
rightEyeY = null;
using (graphics = Graphics.FromImage(preRotated)) using (graphics = Graphics.FromImage(preRotated))
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel); graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
// source.Save(Path.Combine(_Configuration.RootDirectory, "source.jpg")); // source.Save(Path.Combine(_Configuration.RootDirectory, "source.jpg"));
@ -321,32 +329,40 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
using (knownImage = FaceRecognition.LoadImage(preRotated)) using (knownImage = FaceRecognition.LoadImage(preRotated))
{ {
if (knownImage is null || knownImage.IsDisposed) if (knownImage is null || knownImage.IsDisposed)
throw new Exception($"{nameof(knownImage)} is null"); throw new ArgumentNullException(nameof(knownImage));
faceLandmarks = faceRecognition.FaceLandmark(knownImage, faceLocations: null, _PredictorModel, _Model); facesLandmarks = faceRecognition.GetFaceLandmarkCollection(knownImage, _Configuration.NumberOfTimesToUpsample.Value, faceLocations: null, _PredictorModel, _Model);
} }
if (faceLandmarks.Count == 0 && p < _Configuration.PaddingLoops.Value) if (facesLandmarks.Count == 0 && p < _Configuration.PaddingLoops.Value)
continue; continue;
else if (faceLandmarks.Count != 1) else if (facesLandmarks.Count != 1)
continue; continue;
foreach (KeyValuePair<FacePart, IEnumerable<FacePoint>> keyValuePair in faceLandmarks[0]) foreach ((FacePart facePart, FacePoint[] facePoints) in facesLandmarks[0])
face.FaceLandmarks.Add(keyValuePair.Key.ToString(), keyValuePair.Value.ToArray()); {
if (!faceLandmarks[0].ContainsKey(FacePart.LeftEye) || !faceLandmarks[0].ContainsKey(FacePart.RightEye)) face.FaceLandmarks.Add(facePart.ToString(), facePoints);
if (facePart is not FacePart.LeftEye and not FacePart.RightEye)
continue; continue;
facePoints = faceLandmarks[0][FacePart.LeftEye]; if (facePart is FacePart.LeftEye)
{
leftEyeX = (int)(from l in facePoints select l.X).Average(); leftEyeX = (int)(from l in facePoints select l.X).Average();
leftEyeY = (int)(from l in facePoints select l.Y).Average(); leftEyeY = (int)(from l in facePoints select l.Y).Average();
facePoints = faceLandmarks[0][FacePart.RightEye]; }
if (facePart is FacePart.RightEye)
{
rightEyeX = (int)(from l in facePoints select l.X).Average(); rightEyeX = (int)(from l in facePoints select l.X).Average();
rightEyeY = (int)(from l in facePoints select l.Y).Average(); rightEyeY = (int)(from l in facePoints select l.Y).Average();
α = Shared.Models.Stateless.Methods.IFace.Getα(rightEyeX, leftEyeX, rightEyeY, leftEyeY); }
}
if (rightEyeX is null || leftEyeX is null || rightEyeY is null || leftEyeY is null)
continue;
α = Shared.Models.Stateless.Methods.IFace.Getα(rightEyeX.Value, leftEyeX.Value, rightEyeY.Value, leftEyeY.Value);
using (rotated = RotateBitmap(preRotated, (float)α.Value)) using (rotated = RotateBitmap(preRotated, (float)α.Value))
{ {
// rotated.Save(Path.Combine(_Configuration.RootDirectory, $"{p} - rotated.jpg")); // rotated.Save(Path.Combine(_Configuration.RootDirectory, $"{p} - rotated.jpg"));
using (rotatedImage = FaceRecognition.LoadImage(rotated)) using (rotatedImage = FaceRecognition.LoadImage(rotated))
{ {
if (rotatedImage is null || rotatedImage.IsDisposed) if (rotatedImage is null || rotatedImage.IsDisposed)
throw new Exception($"{nameof(rotatedImage)} is null"); throw new ArgumentNullException(nameof(rotatedImage));
faceEncodings = faceRecognition.FaceEncodings(rotatedImage, knownFaceLocation: null, _Configuration.NumJitters.Value, _PredictorModel, _Model); faceEncodings = faceRecognition.FaceEncodings(rotatedImage, _Configuration.NumberOfTimesToUpsample.Value, knownFaceLocation: null, _Configuration.NumberOfJitters.Value, _PredictorModel, _Model);
} }
if (faceEncodings.Count == 0 && p < _Configuration.PaddingLoops.Value) if (faceEncodings.Count == 0 && p < _Configuration.PaddingLoops.Value)
continue; continue;
@ -369,7 +385,9 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
locations[i].Bottom, locations[i].Bottom,
locations[i].Left, locations[i].Left,
locations[i].Right, locations[i].Right,
locations[i].Top); locations[i].Top,
source.Width,
source.Height);
face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i, location); face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i, location);
results.Add(face); results.Add(face);
} }
@ -427,7 +445,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
{ {
results = JsonSerializer.Deserialize<List<D_Face>>(json); results = JsonSerializer.Deserialize<List<D_Face>>(json);
if (results is null) if (results is null)
throw new Exception($"{nameof(results)} is null"); throw new ArgumentNullException(nameof(results));
for (int i = 0; i < results.Count; i++) for (int i = 0; i < results.Count; i++)
{ {
face = results[i]; face = results[i];
@ -448,14 +466,18 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
if (results is not null && checkForOutputResolutionChange) if (results is not null && checkForOutputResolutionChange)
{ {
json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true)) bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime); File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
} }
else if (results is null) else if (results is null)
{ {
results = GetFaces(resizedFileInfo, propertyHolder, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, facesDirectory); results = GetFaces(resizedFileInfo, propertyHolder, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, facesDirectory);
json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true)) bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now));
} }
return results; return results;
@ -505,109 +527,20 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
SaveFaces(faceCollection, propertyHolder.ResizedFileInfo, imageFiles); SaveFaces(faceCollection, propertyHolder.ResizedFileInfo, imageFiles);
} }
private static List<(PropertyHolder, (string, D_Face?, (string, string, string, string))[])> GetCollection(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic, string outputResolution, PropertyHolder[] filteredPropertyHolderCollection, List<List<D_Face>> faceCollections) internal static void SaveShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string[] juliePhares, long ticks, Dictionary<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, string outputResolution, PropertyHolder[] filteredPropertyHolderCollection)
{
List<(PropertyHolder, (string, D_Face?, (string, string, string, string))[])> results = new();
string[] keys;
string directory;
string personKey;
bool? isWrongYear;
TimeSpan timeSpan;
DateTime? birthDate;
string copyFileName;
string copyDirectory;
string? relativePath;
string isWrongYearFlag;
string shortcutFileName;
string subDirectoryName;
List<int> indices = new();
List<D_Face> faceCollection;
PropertyHolder propertyHolder;
List<(string, D_Face?, (string, string, string, string))> collection;
string dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "(_)");
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++)
{
indices.Clear();
personKey = string.Empty;
copyFileName = string.Empty;
copyDirectory = string.Empty;
propertyHolder = filteredPropertyHolderCollection[i];
if (propertyHolder.ImageFileInfo is null)
continue;
relativePath = Path.GetDirectoryName($"C:{propertyHolder.RelativePath}");
if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3)
continue;
if (propertyHolder.Property?.Id is null || propertyHolder.MinimumDateTime is null || propertyHolder.ResizedFileInfo is null)
continue;
collection = new();
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(propertyHolder.Property.Id.Value))
{
faceCollection = new();
directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}");
}
else
{
faceCollection = faceCollections[i];
keys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value];
(isWrongYear, _) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileInfo.FullName, propertyHolder.MinimumDateTime.Value);
isWrongYearFlag = PropertyHolder.GetWrongYearFlag(isWrongYear);
subDirectoryName = $"{isWrongYearFlag}{propertyHolder.MinimumDateTime.Value:yyyy}";
if (!faceCollection.Any())
directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}", subDirectoryName);
else if (keys.Length != 1)
directory = Path.Combine(dFacesContentDirectory, $"Not Supported{relativePath[2..]}", subDirectoryName);
else if (faceCollection.Count != 1)
directory = Path.Combine(dFacesContentDirectory, $"Many{relativePath[2..]}", subDirectoryName);
else
{
indices.Add(0);
personKey = keys[0];
if (isWrongYear is not null && !isWrongYear.Value && personKey[..2] is "19" or "20")
{
birthDate = Shared.Models.Stateless.Methods.IPersonBirthday.Get(personKey);
if (birthDate.HasValue)
{
timeSpan = new(propertyHolder.MinimumDateTime.Value.Ticks - birthDate.Value.Ticks);
if (timeSpan.Ticks < 0)
subDirectoryName = "!---";
else
subDirectoryName = $"^{Math.Floor(timeSpan.TotalDays / 365):000}";
}
}
directory = Path.Combine(dFacesContentDirectory, "Shortcuts", personKey, subDirectoryName);
if (faceCollection[0].FaceEncoding is not null)
copyDirectory = Path.Combine(dFacesContentDirectory, "Images", personKey, subDirectoryName);
else
copyDirectory = Path.Combine(dFacesContentDirectory, "ImagesBut", personKey, subDirectoryName);
copyFileName = Path.Combine(copyDirectory, $"{propertyHolder.Property.Id.Value}{propertyHolder.ResizedFileInfo.Extension}");
}
}
shortcutFileName = Path.Combine(directory, $"{propertyHolder.Property.Id.Value}.lnk");
if (string.IsNullOrEmpty(personKey) || !indices.Any())
collection.Add(new(personKey, null, (directory, copyDirectory, copyFileName, shortcutFileName)));
else
{
foreach (int index in indices)
collection.Add(new(personKey, faceCollection[index], (directory, copyDirectory, copyFileName, shortcutFileName)));
}
results.Add(new(propertyHolder, collection.ToArray()));
}
return results;
}
internal static void SaveShortcuts(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string[] juliePhares, Dictionary<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, string outputResolution, PropertyHolder[] filteredPropertyHolderCollection, List<List<D_Face>> faceCollections)
{ {
Person person; Person person;
string fileName; string fileName;
string fullName; string fullName;
WindowsShortcut windowsShortcut; WindowsShortcut windowsShortcut;
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]"; const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
List<(PropertyHolder, (string, D_Face?, (string, string, string, string))[])> collections = GetCollection(configuration, model, predictorModel, propertyLogic, outputResolution, filteredPropertyHolderCollection, faceCollections); string dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), $"({ticks})");
foreach ((PropertyHolder propertyHolder, (string personKey, D_Face? face, (string, string, string, string))[] collection) in collections) List<(PropertyHolder, (string, Shared.Models.Properties.IFace?, (string, string, string, string))[])> collections = PropertyHolder.GetCollection(propertyLogic, filteredPropertyHolderCollection, dFacesContentDirectory);
foreach ((PropertyHolder propertyHolder, (string personKey, Shared.Models.Properties.IFace? _, (string, string, string, string))[] collection) in collections)
{ {
if (collection.Length != 1) if (collection.Length != 1)
continue; continue;
foreach ((string personKey, D_Face? face, (string directory, string copyDirectory, string copyFileName, string shortcutFileName)) in collection) foreach ((string personKey, Shared.Models.Properties.IFace? _, (string directory, string copyDirectory, string copyFileName, string shortcutFileName)) in collection)
{ {
if (string.IsNullOrEmpty(personKey)) if (string.IsNullOrEmpty(personKey))
continue; continue;
@ -619,7 +552,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
if (!string.IsNullOrEmpty(personKey) && peopleCollection.ContainsKey(personKey)) if (!string.IsNullOrEmpty(personKey) && peopleCollection.ContainsKey(personKey))
{ {
person = peopleCollection[personKey][0]; person = peopleCollection[personKey][0];
fullName = Regex.Replace($"{Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name)}.txt", pattern, string.Empty); fullName = string.Concat(Regex.Replace(Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name), pattern, string.Empty), ".txt");
File.WriteAllText(Path.Combine(directory, fullName), string.Empty); File.WriteAllText(Path.Combine(directory, fullName), string.Empty);
} }
} }

View File

@ -38,7 +38,7 @@ internal class E2_Navigate
private void DisplayTags(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string[] directories, Dictionary<ConsoleKey, int> directoryKeyValuePairs, string[] files, Dictionary<ConsoleKey, int> fileKeyValuePairs) private void DisplayTags(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string[] directories, Dictionary<ConsoleKey, int> directoryKeyValuePairs, string[] files, Dictionary<ConsoleKey, int> fileKeyValuePairs)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
bool all = false; bool all = false;
FileSystem fileSystem; FileSystem fileSystem;
string requestPath = "/RootResultsDirectory"; string requestPath = "/RootResultsDirectory";
@ -71,7 +71,7 @@ internal class E2_Navigate
private void DisplayFaces(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string selectedFileFullName) private void DisplayFaces(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string selectedFileFullName)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
string requestPath = "/RootResultsDirectory"; string requestPath = "/RootResultsDirectory";
string? rootResultsDirectory = Path.GetDirectoryName(Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(B_Metadata))); string? rootResultsDirectory = Path.GetDirectoryName(Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(B_Metadata)));
if (string.IsNullOrEmpty(rootResultsDirectory)) if (string.IsNullOrEmpty(rootResultsDirectory))
@ -95,9 +95,9 @@ internal class E2_Navigate
{ {
string result; string result;
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
_Log.Warn(string.Concat("What is the new name for [", Path.GetFileName(subSourceDirectory), "]<", subSourceDirectory, ">?")); _Log.Warn(string.Concat("What is the new name for [", Path.GetFileName(subSourceDirectory), "]<", subSourceDirectory, ">?"));
string? newDirectoryName = _Console.ReadLine(); string? newDirectoryName = _Console.ReadLine();
_Log.Warn("Are you sure y[es] || n[o]?"); _Log.Warn("Are you sure y[es] || n[o]?");
@ -135,7 +135,7 @@ internal class E2_Navigate
internal void Navigate(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution) internal void Navigate(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
string[] subFiles; string[] subFiles;
ConsoleKey consoleKey; ConsoleKey consoleKey;
string[] subDirectories; string[] subDirectories;

View File

@ -115,7 +115,7 @@ internal class E3_Rename
{ {
List<string[]> results = new(); List<string[]> results = new();
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
bool add; bool add;
string to; string to;
bool exists; bool exists;
@ -230,7 +230,7 @@ internal class E3_Rename
internal void DirectoryRename(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string relativePath, string newDirectoryName) internal void DirectoryRename(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string relativePath, string newDirectoryName)
{ {
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string json; string json;
FileInfo current; FileInfo current;
FileInfo fileInfo; FileInfo fileInfo;
@ -299,7 +299,7 @@ internal class E3_Rename
if (json.Contains(oldValue)) if (json.Contains(oldValue))
{ {
json = json.Replace(oldValue, newValue); json = json.Replace(oldValue, newValue);
if (!Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true)) if (!Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
continue; continue;
File.SetLastWriteTime(fileInfo.FullName, fileInfo.LastWriteTime); File.SetLastWriteTime(fileInfo.FullName, fileInfo.LastWriteTime);
} }

View File

@ -128,7 +128,7 @@ internal class E_Distance
return result; return result;
} }
private void LoadOrCreateThenSaveDistanceResultsForOutputResolutionsLoop(Property.Models.Configuration configuration, List<List<D_Face>> faceCollections, int subFilesCount, int i, List<D_Face> faceCollection, List<int[]> locationIndicesCollection, List<Tuple<string, DateTime>> subFileTuples, List<FaceEncoding> faceEncodingCollection, List<FaceEncoding> faceEncodingCollections, string fileNameWithoutExtension, string jsonDirectory, string tvsDirectory) private void LoadOrCreateThenSaveDistanceResultsForOutputResolutionsLoop(Property.Models.Configuration configuration, List<List<D_Face>> faceCollections, int subFilesCount, int i, List<D_Face> faceCollection, List<int[]> locationIndicesCollection, List<Tuple<string, DateTime>> subFileTuples, List<FaceEncoding> faceEncodingCollection, List<FaceEncoding> faceEncodingCollections, string fileNameWithoutExtension, string jsonDirectory, string tvsDirectory, bool updateDateWhenMatches, DateTime? updateToWhenMatches)
{ {
string text; string text;
string json; string json;
@ -144,7 +144,7 @@ internal class E_Distance
orderedFaceCollection = GetOrderedNoFaceCollection(faceCollections, i, faceCollection[j]); orderedFaceCollection = GetOrderedNoFaceCollection(faceCollections, i, faceCollection[j]);
json = JsonSerializer.Serialize(orderedFaceCollection, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(orderedFaceCollection, _WriteIndentedJsonSerializerOptions);
jsonFile = Path.Combine(jsonDirectory, $"{j} - {fileNameWithoutExtension}.json"); jsonFile = Path.Combine(jsonDirectory, $"{j} - {fileNameWithoutExtension}.json");
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true)) if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: updateToWhenMatches))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
} }
else else
@ -162,16 +162,16 @@ internal class E_Distance
indicesAndValues = GetValues(faceCollections, locationIndicesCollection, faceDistances); indicesAndValues = GetValues(faceCollections, locationIndicesCollection, faceDistances);
orderedFaceCollection = GetOrderedFaceCollection(faceCollections, locationIndicesCollection, indicesAndValues); orderedFaceCollection = GetOrderedFaceCollection(faceCollections, locationIndicesCollection, indicesAndValues);
text = GetText(fileNameWithoutExtension, faceCollections, locationIndicesCollection, indicesAndValues); text = GetText(fileNameWithoutExtension, faceCollections, locationIndicesCollection, indicesAndValues);
if (Property.Models.Stateless.IPath.WriteAllText(tvsFile, text, compareBeforeWrite: true)) if (Property.Models.Stateless.IPath.WriteAllText(tvsFile, text, updateDateWhenMatches, compareBeforeWrite: true))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
json = JsonSerializer.Serialize(orderedFaceCollection, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(orderedFaceCollection, _WriteIndentedJsonSerializerOptions);
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true)) if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
} }
} }
} }
private void LoadOrCreateThenSaveDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, PropertyHolder[] filteredPropertyHolderCollection, List<List<D_Face>> faceCollections, List<string[]> directories) private void LoadOrCreateThenSaveDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, PropertyHolder[] filteredPropertyHolderCollection, List<List<D_Face>> faceCollections, List<string[]> directories, bool updateDateWhenMatches, DateTime? updateToWhenMatches)
{ {
FileInfo? fileInfo; FileInfo? fileInfo;
string fileNameWithoutExtension; string fileNameWithoutExtension;
@ -190,7 +190,7 @@ internal class E_Distance
if (fileInfo is null) if (fileInfo is null)
continue; continue;
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName); fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
LoadOrCreateThenSaveDistanceResultsForOutputResolutionsLoop(configuration, faceCollections, filteredPropertyHolderCollection.Length, i, faceCollections[i], locationIndicesCollection, subFileTuples, faceEncodingCollection, faceEncodingCollections[i], fileNameWithoutExtension, directories[i][0], directories[i][1]); LoadOrCreateThenSaveDistanceResultsForOutputResolutionsLoop(configuration, faceCollections, filteredPropertyHolderCollection.Length, i, faceCollections[i], locationIndicesCollection, subFileTuples, faceEncodingCollection, faceEncodingCollections[i], fileNameWithoutExtension, directories[i][0], directories[i][1], updateDateWhenMatches, updateToWhenMatches);
} }
} }
@ -204,8 +204,10 @@ internal class E_Distance
FileInfo? fileInfo; FileInfo? fileInfo;
bool check = false; bool check = false;
string parentCheck; string parentCheck;
DateTime? dateTime = null;
FileInfo[] fileInfoCollection; FileInfo[] fileInfoCollection;
string fileNameWithoutExtension; string fileNameWithoutExtension;
bool updateDateWhenMatches = false;
List<string[]> directories = new(); List<string[]> directories = new();
System.IO.DirectoryInfo directoryInfo; System.IO.DirectoryInfo directoryInfo;
System.IO.DirectoryInfo tvsDirectoryInfo; System.IO.DirectoryInfo tvsDirectoryInfo;
@ -264,9 +266,14 @@ internal class E_Distance
check = true; check = true;
else if (dateTimes.Any() && dateTimes.Max() > directoryInfo.LastWriteTime) else if (dateTimes.Any() && dateTimes.Max() > directoryInfo.LastWriteTime)
check = true; check = true;
if (check && !updateDateWhenMatches)
{
updateDateWhenMatches = dateTimes.Any() && directoryInfo.Exists && dateTimes.Max() > directoryInfo.LastWriteTime;
dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
}
} }
if (check) if (check)
LoadOrCreateThenSaveDistanceResultsForOutputResolutions(configuration, filteredPropertyHolderCollection, faceCollections, directories); LoadOrCreateThenSaveDistanceResultsForOutputResolutions(configuration, filteredPropertyHolderCollection, faceCollections, directories, updateDateWhenMatches, updateToWhenMatches: dateTime);
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(directoryInfoCollection[0].Replace("<>", "()")); _ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(directoryInfoCollection[0].Replace("<>", "()"));
} }
@ -335,7 +342,7 @@ internal class E_Distance
_ = Directory.CreateDirectory(jsonDirectory); _ = Directory.CreateDirectory(jsonDirectory);
string json = JsonSerializer.Serialize(faceAndFaceDistanceCollection, _WriteIndentedJsonSerializerOptions); string json = JsonSerializer.Serialize(faceAndFaceDistanceCollection, _WriteIndentedJsonSerializerOptions);
string jsonFile = Path.Combine(jsonDirectory, $"{k} - {fileNameWithoutExtension}.nosj"); string jsonFile = Path.Combine(jsonDirectory, $"{k} - {fileNameWithoutExtension}.nosj");
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true); _ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
} }
private static Tuple<Shared.Models.Face, double> Get(FaceEncoding faceEncoding, (string, List<Shared.Models.Face>, List<FaceEncoding>) match) private static Tuple<Shared.Models.Face, double> Get(FaceEncoding faceEncoding, (string, List<Shared.Models.Face>, List<FaceEncoding>) match)
@ -350,7 +357,7 @@ internal class E_Distance
internal void LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution) internal void LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
string? relativePath; string? relativePath;
Shared.Models.Face face; Shared.Models.Face face;
ParallelOptions parallelOptions = new(); ParallelOptions parallelOptions = new();
@ -401,87 +408,89 @@ internal class E_Distance
} }
} }
private static Dictionary<string, List<(string personKey, D_Face face)>> Convert(string argZero, List<PropertyHolder[]> propertyHolderCollections) public static double GetStandardDeviation(IEnumerable<double> values, double average)
{ {
Dictionary<string, List<(string personKey, D_Face face)>> results = new(); double result = 0;
string key; if (!values.Any())
string personKey; throw new Exception("Collection must have at least one value!");
bool? isWrongYear; double sum = values.Sum(l => (l - average) * (l - average));
TimeSpan? timeSpan; result = Math.Sqrt(sum / values.Count());
string isWrongYearFlag; return result;
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
{
if (!propertyHolderCollection.Any())
continue;
if (!propertyHolderCollection[0].SourceDirectory.StartsWith(argZero))
continue;
foreach (PropertyHolder propertyHolder in propertyHolderCollection)
{
if (propertyHolder.ImageFileInfo is null || propertyHolder.Property is null || !propertyHolder.Named.Any())
continue;
if (propertyHolder.Named.Count != 1 || propertyHolder.Faces.Count != 1)
continue;
for (int i = 0; i < propertyHolder.Named.Count; i++)
{
if (propertyHolder.MinimumDateTime is null)
continue;
if (propertyHolder.Faces[i] is not D_Face face)
continue;
timeSpan = propertyHolder.Named[i].TimeSpan;
personKey = propertyHolder.Named[i].PersonKey;
isWrongYear = propertyHolder.Named[i].IsWrongYear;
isWrongYearFlag = PropertyHolder.GetWrongYearFlag(isWrongYear);
if (timeSpan is null)
key = $"{personKey}\t{isWrongYearFlag}{propertyHolder.MinimumDateTime.Value:yyyy}";
else if (timeSpan.Value.Ticks < 0)
key = $"{personKey}\t{isWrongYearFlag}!---";
else
key = $"{personKey}\t^{Math.Floor(timeSpan.Value.TotalDays / 365):000}";
if (!results.ContainsKey(key))
results.Add(key, new());
results[key].Add(new(personKey, face));
}
}
}
return results;
} }
internal static void SaveGroupedFaceEncodings(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string argZero, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string outputResolution, List<PropertyHolder[]> propertyHolderCollections) internal static void SaveGroupedFaceEncodings(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string argZero, long ticks, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string outputResolution, List<PropertyHolder[]> propertyHolderCollections)
{ {
double lcl;
double ucl;
string json; string json;
double average;
int lowestIndex;
string checkFile; string checkFile;
string directory; string personKey;
double lowestAverage;
double standardDeviation;
FaceEncoding faceEncoding;
List<double> faceDistances;
List<double[]> rawEncodings;
Shared.Models.Person person; Shared.Models.Person person;
List<FaceEncoding> faceEncodings;
List<string> checkDirectories = new(); List<string> checkDirectories = new();
List<Shared.Models.Properties.IFace> collection;
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]"; const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
Dictionary<string, List<(string personKey, D_Face face)>> keyValuePairs = Convert(argZero, propertyHolderCollections); string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), $"[{ticks}]");
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[_]"); List<(string, Shared.Models.PersonBirthday, Shared.Models.Properties.IFace)[]> collection = PropertyHolder.GetCollection(argZero, propertyHolderCollections, eDistanceCollectionDirectory);
foreach (KeyValuePair<string, List<(string personKey, D_Face face)>> keyValuePair in keyValuePairs) foreach ((string, Shared.Models.PersonBirthday, Shared.Models.Properties.IFace)[] group in collection)
{ {
collection = new(); lowestIndex = 0;
rawEncodings = new();
faceEncodings = new();
checkDirectories.Clear(); checkDirectories.Clear();
checkFile = string.Empty; checkFile = string.Empty;
foreach ((string personKey, D_Face face) in keyValuePair.Value) lowestAverage = double.MaxValue;
foreach ((string directory, Shared.Models.PersonBirthday personBirthday, Shared.Models.Properties.IFace @interface) in group)
{ {
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
if (string.IsNullOrEmpty(personKey) || !peopleCollection.ContainsKey(personKey)) if (string.IsNullOrEmpty(personKey) || !peopleCollection.ContainsKey(personKey))
continue; continue;
if (@interface is not D_Face face || !face.Populated)
continue;
person = peopleCollection[personKey][0]; person = peopleCollection[personKey][0];
directory = Path.Combine(eDistanceCollectionDirectory, $"{personKey}{keyValuePair.Key}"); faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
checkFile = Path.Combine(directory, Regex.Replace($"{Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name)}.json", pattern, string.Empty)); checkFile = string.Concat(directory, " - ", Regex.Replace(Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name), pattern, string.Empty), ".json");
checkDirectories.Add(directory); checkDirectories.Add(directory);
collection.Add(face); faceEncodings.Add(faceEncoding);
} }
if (!string.IsNullOrEmpty(checkFile) && checkDirectories.Any()) if (string.IsNullOrEmpty(checkFile) || !checkDirectories.Any() || faceEncodings.Count < 2)
{ continue;
foreach (string checkDirectory in checkDirectories) foreach (string checkDirectory in checkDirectories.Distinct())
{ {
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory); _ = Directory.CreateDirectory(checkDirectory);
} }
json = JsonSerializer.Serialize(collection, new JsonSerializerOptions { WriteIndented = true }); for (int i = 0; i < faceEncodings.Count; i++)
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, compareBeforeWrite: true); {
faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncodings[i]);
average = faceDistances.Average();
if (average > lowestAverage)
continue;
lowestIndex = i;
lowestAverage = average;
} }
faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncodings[lowestIndex]);
average = faceDistances.Average();
if (average != lowestAverage)
continue;
standardDeviation = GetStandardDeviation(faceDistances, average);
lcl = average - (standardDeviation * 3);
ucl = average + (standardDeviation * 3);
for (int i = 0; i < faceEncodings.Count; i++)
{
if (faceDistances[i] < lcl || faceDistances[i] > ucl)
continue;
rawEncodings.Add(faceEncodings[i].GetRawEncoding());
}
// outOfControl = faceEncodings.Count - rawEncodings.Count;
json = JsonSerializer.Serialize(rawEncodings, new JsonSerializerOptions { WriteIndented = true });
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
} }
} }

View File

@ -29,7 +29,7 @@ internal class F_Random
{ {
bool result = false; bool result = false;
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string? checkDirectory = Path.GetFullPath(directory); string? checkDirectory = Path.GetFullPath(directory);
for (int i = 0; i < int.MaxValue; i++) for (int i = 0; i < int.MaxValue; i++)
{ {
@ -73,7 +73,7 @@ internal class F_Random
relativePaths = (from l in relativePaths orderby random.NextDouble() select l).ToList(); relativePaths = (from l in relativePaths orderby random.NextDouble() select l).ToList();
jsonFile = Path.Combine(fRandomCollectionDirectory, $"{dateTime.AddDays(i):MM-dd}.json"); jsonFile = Path.Combine(fRandomCollectionDirectory, $"{dateTime.AddDays(i):MM-dd}.json");
json = JsonSerializer.Serialize(relativePaths, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(relativePaths, _WriteIndentedJsonSerializerOptions);
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: false); _ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
if (!_Configuration.SaveFullYearOfRandomFiles.Value) if (!_Configuration.SaveFullYearOfRandomFiles.Value)
break; break;
} }
@ -83,7 +83,7 @@ internal class F_Random
ignoreRelativePaths = (from l in ignoreRelativePaths orderby random.NextDouble() select l).ToList(); ignoreRelativePaths = (from l in ignoreRelativePaths orderby random.NextDouble() select l).ToList();
jsonFile = Path.Combine(fRandomCollectionDirectory, "01-01.txt"); jsonFile = Path.Combine(fRandomCollectionDirectory, "01-01.txt");
json = JsonSerializer.Serialize(ignoreRelativePaths, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(ignoreRelativePaths, _WriteIndentedJsonSerializerOptions);
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: false); _ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
} }
} }

View File

@ -103,7 +103,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
json = JsonSerializer.Serialize(resultKeyValuePairs, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(resultKeyValuePairs, _WriteIndentedJsonSerializerOptions);
if (!isEnvironment.DebuggerWasAttachedDuringConstructor) if (!isEnvironment.DebuggerWasAttachedDuringConstructor)
throw new Exception("Only allowed when debugger is attached during constructor!"); throw new Exception("Only allowed when debugger is attached during constructor!");
_ = Property.Models.Stateless.IPath.WriteAllText(named.FullName, json, compareBeforeWrite: true); _ = Property.Models.Stateless.IPath.WriteAllText(named.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true);
} }
} }
@ -221,7 +221,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
_ = Directory.CreateDirectory(directoryFullName); _ = Directory.CreateDirectory(directoryFullName);
jsonFile = string.Concat(g2IdentifyCollectionDirectory, keyValuePair.Key, ".json"); jsonFile = string.Concat(g2IdentifyCollectionDirectory, keyValuePair.Key, ".json");
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true)) if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true))
continue; continue;
} }
} }

View File

@ -99,7 +99,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
dateTime = (from l in dateTimes where l.HasValue select l.Value).Min(); dateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
indexInfo = new(dateTime, maxIndexPlusOne, tuple.Item1); indexInfo = new(dateTime, maxIndexPlusOne, tuple.Item1);
json = JsonSerializer.Serialize(indexInfo, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(indexInfo, _WriteIndentedJsonSerializerOptions);
if (!Property.Models.Stateless.IPath.WriteAllText(tuple.Item2, json, compareBeforeWrite: true)) if (!Property.Models.Stateless.IPath.WriteAllText(tuple.Item2, json, updateDateWhenMatches: true, compareBeforeWrite: true))
continue; continue;
} }
} }
@ -114,7 +114,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
indices = (from l in tuple.Item2 select l.Value).ToArray(); indices = (from l in tuple.Item2 select l.Value).ToArray();
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, tuple.Item1, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: string.Empty, collectionDescription: "Unknown A"); directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, tuple.Item1, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: string.Empty, collectionDescription: "Unknown A");
json = JsonSerializer.Serialize(indices, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(indices, _WriteIndentedJsonSerializerOptions);
if (!Property.Models.Stateless.IPath.WriteAllText(string.Concat(directoryInfoCollection[0].Replace("<>", "[]"), ".json"), json, compareBeforeWrite: true)) if (!Property.Models.Stateless.IPath.WriteAllText(string.Concat(directoryInfoCollection[0].Replace("<>", "[]"), ".json"), json, updateDateWhenMatches: true, compareBeforeWrite: true))
continue; continue;
} }
} }

View File

@ -65,7 +65,8 @@
"MaxItemsInDistanceCollection": 50, "MaxItemsInDistanceCollection": 50,
"ModelDirectory": "C:/GitHub/dlib-models", "ModelDirectory": "C:/GitHub/dlib-models",
"ModelName": "Hog", "ModelName": "Hog",
"NumJitters": 1, "NumberOfJitters": 1,
"NumberOfTimesToUpsample": 1,
"OutputExtension": ".jpg", "OutputExtension": ".jpg",
"OutputQuality": 95, "OutputQuality": 95,
"OverrideForFaceImages": false, "OverrideForFaceImages": false,

View File

@ -65,7 +65,8 @@
"MaxItemsInDistanceCollection": 50, "MaxItemsInDistanceCollection": 50,
"ModelDirectory": "L:/GitHub/dlib-models", "ModelDirectory": "L:/GitHub/dlib-models",
"ModelName": "Hog", "ModelName": "Hog",
"NumJitters": 1, "NumberOfJitters": 1,
"NumberOfTimesToUpsample": 1,
"OutputExtension": ".jpg", "OutputExtension": ".jpg",
"OutputQuality": 95, "OutputQuality": 95,
"OverrideForFaceImages": false, "OverrideForFaceImages": false,

View File

@ -65,7 +65,8 @@
"MaxItemsInDistanceCollection": 50, "MaxItemsInDistanceCollection": 50,
"ModelDirectory": "C:/GitHub/dlib-models", "ModelDirectory": "C:/GitHub/dlib-models",
"ModelName": "Hog", "ModelName": "Hog",
"NumJitters": 1, "NumberOfJitters": 1,
"NumberOfTimesToUpsample": 1,
"OutputExtension": ".jpg", "OutputExtension": ".jpg",
"OutputQuality": 95, "OutputQuality": 95,
"OverrideForFaceImages": false, "OverrideForFaceImages": false,

View File

@ -39,7 +39,7 @@ public class B_Metadata
{ {
Dictionary<string, List<KeyValuePair<string, string>>> results = new(); Dictionary<string, List<KeyValuePair<string, string>>> results = new();
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
try try
{ {
object? @object; object? @object;
@ -137,7 +137,9 @@ public class B_Metadata
{ {
dictionary = GetMetadataCollection(propertyHolder.ImageFileInfo.FullName); dictionary = GetMetadataCollection(propertyHolder.ImageFileInfo.FullName);
json = JsonSerializer.Serialize(dictionary, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(dictionary, _WriteIndentedJsonSerializerOptions);
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true)) bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
{ {
if (!_ForceMetadataLastWriteTimeToCreationTime && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime)) if (!_ForceMetadataLastWriteTimeToCreationTime && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(B_Metadata), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(B_Metadata), DateTime.Now));

View File

@ -28,7 +28,7 @@ public class NotCopyCopy
{ } { }
_AppSettings = appSettings; _AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null) if (appSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(appSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism));
_IsEnvironment = isEnvironment; _IsEnvironment = isEnvironment;
_Exceptions = new List<string>(); _Exceptions = new List<string>();
_Log = Serilog.Log.ForContext<NotCopyCopy>(); _Log = Serilog.Log.ForContext<NotCopyCopy>();
@ -43,7 +43,7 @@ public class NotCopyCopy
PredictorModel? predictorModel = null; PredictorModel? predictorModel = null;
_Configuration = configuration; _Configuration = configuration;
if (propertyConfiguration.PopulatePropertyId is null) if (propertyConfiguration.PopulatePropertyId is null)
throw new Exception($"{nameof(propertyConfiguration.PopulatePropertyId)} is null!"); throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId));
if (!_IsEnvironment.Development) if (!_IsEnvironment.Development)
throw new Exception("This program only allows development environments!"); throw new Exception("This program only allows development environments!");
PropertyLogic propertyLogic = GetPropertyLogic(); PropertyLogic propertyLogic = GetPropertyLogic();
@ -100,22 +100,22 @@ public class NotCopyCopy
private static void Verify(Models.Configuration configuration) private static void Verify(Models.Configuration configuration)
{ {
if (Path.GetPathRoot(configuration.SelectedSource) == configuration.SelectedSource) if (Path.GetPathRoot(configuration.SelectedSource) == configuration.SelectedSource)
throw new Exception($"{nameof(configuration.SelectedSource)} should have at least one level!"); throw new ArgumentNullException(nameof(configuration.SelectedSource));
if (string.IsNullOrEmpty(configuration.CompareSource) || !Directory.Exists(configuration.CompareSource)) if (string.IsNullOrEmpty(configuration.CompareSource) || !Directory.Exists(configuration.CompareSource))
throw new Exception($"{nameof(configuration.CompareSource)} must have a value and exits!"); throw new ArgumentNullException(nameof(configuration.CompareSource));
if (string.IsNullOrEmpty(configuration.EmptyDestination) || Directory.Exists(configuration.EmptyDestination)) if (string.IsNullOrEmpty(configuration.EmptyDestination) || Directory.Exists(configuration.EmptyDestination))
throw new Exception($"{nameof(configuration.EmptyDestination)} can't exit!"); throw new ArgumentNullException(nameof(configuration.EmptyDestination));
if (string.IsNullOrEmpty(configuration.SelectedSource) || !Directory.Exists(configuration.SelectedSource)) if (string.IsNullOrEmpty(configuration.SelectedSource) || !Directory.Exists(configuration.SelectedSource))
throw new Exception($"{nameof(configuration.SelectedSource)} must have a value and exits!"); throw new ArgumentNullException(nameof(configuration.SelectedSource));
if (configuration.SelectedSource.Length != configuration.CompareSource.Length) if (configuration.SelectedSource.Length != configuration.CompareSource.Length)
throw new Exception($"{nameof(configuration.SelectedSource)} and {nameof(configuration.CompareSource)} must be the same length!"); throw new ArgumentNullException(nameof(configuration.SelectedSource));
} }
private long LogDelta(long ticks, string methodName) private long LogDelta(long ticks, string methodName)
{ {
long result; long result;
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks; result = DateTime.Now.Ticks;
@ -126,9 +126,9 @@ public class NotCopyCopy
{ {
PropertyLogic result; PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration);
return result; return result;
} }
@ -137,7 +137,7 @@ public class NotCopyCopy
{ {
List<(string Source, string[] Destination)> results = new(); List<(string Source, string[] Destination)> results = new();
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string key; string key;
string fileName; string fileName;
A_Property? property; A_Property? property;

View File

@ -30,7 +30,7 @@ public class PrepareForOld
string spellingB; string spellingB;
_AppSettings = appSettings; _AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null) if (appSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(appSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism));
_SpellingFindReplace = new(); _SpellingFindReplace = new();
_IsEnvironment = isEnvironment; _IsEnvironment = isEnvironment;
_Exceptions = new List<string>(); _Exceptions = new List<string>();
@ -42,7 +42,7 @@ public class PrepareForOld
Models.Configuration configuration = Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory, propertyConfiguration); Models.Configuration configuration = Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory, propertyConfiguration);
Verify(configuration); Verify(configuration);
if (propertyConfiguration.IgnoreExtensions is null) if (propertyConfiguration.IgnoreExtensions is null)
throw new Exception($"{nameof(propertyConfiguration.IgnoreExtensions)} is null!"); throw new ArgumentNullException(nameof(propertyConfiguration.IgnoreExtensions));
for (int i = 0; i < configuration.Spelling.Length; i++) for (int i = 0; i < configuration.Spelling.Length; i++)
{ {
spellingA = configuration.Spelling[i]; spellingA = configuration.Spelling[i];
@ -109,7 +109,7 @@ public class PrepareForOld
private static void Verify(Models.Configuration configuration) private static void Verify(Models.Configuration configuration)
{ {
if (configuration.Spelling is null || !configuration.Spelling.Any()) if (configuration.Spelling is null || !configuration.Spelling.Any())
throw new Exception($"{nameof(configuration.Spelling)} should have at least one!"); throw new ArgumentNullException(nameof(configuration.Spelling));
} }
private static List<Models.SaveTabSeparatedValues.ImageExifInfo> GetExifCollection(string infoDirectory, string infoDirectoryExtra, bool checkDistinct) private static List<Models.SaveTabSeparatedValues.ImageExifInfo> GetExifCollection(string infoDirectory, string infoDirectoryExtra, bool checkDistinct)
@ -141,7 +141,7 @@ public class PrepareForOld
{ {
List<(int Index, long Ticks, string RelativeDirectory, string FileNameWithoutExtension, string Extension, string RegexResult)> results = new(); List<(int Index, long Ticks, string RelativeDirectory, string FileNameWithoutExtension, string Extension, string RegexResult)> results = new();
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
long ticks; long ticks;
string json; string json;
string extension; string extension;
@ -224,14 +224,14 @@ public class PrepareForOld
private void SaveTabSeparatedValues(Property.Models.Configuration configuration, string aPropertySingletonDirectory) private void SaveTabSeparatedValues(Property.Models.Configuration configuration, string aPropertySingletonDirectory)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new Exception($"{nameof(rootDirectoryParent)} is null!"); throw new ArgumentNullException(nameof(rootDirectoryParent));
int z = 0; int z = 0;
int mappedIndex; int mappedIndex;
int? propertyId; int? propertyId;
@ -414,7 +414,7 @@ public class PrepareForOld
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
Dictionary<int, string[]>? source = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json); Dictionary<int, string[]>? source = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
if (source is null) if (source is null)
throw new Exception($"{nameof(source)} is null!"); throw new ArgumentNullException(nameof(source));
{ {
int propertyId; int propertyId;
foreach (KeyValuePair<int, string[]> keyValuePair in source) foreach (KeyValuePair<int, string[]> keyValuePair in source)
@ -469,12 +469,12 @@ public class PrepareForOld
private void ReSaveJsonFiles() private void ReSaveJsonFiles()
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new Exception($"{nameof(rootDirectoryParent)} is null!"); throw new ArgumentNullException(nameof(rootDirectoryParent));
int z = 0; int z = 0;
int propertyId; int propertyId;
List<int> missingIndices = new(); List<int> missingIndices = new();
@ -523,14 +523,14 @@ public class PrepareForOld
private void CopyMissingImagesLogs() private void CopyMissingImagesLogs()
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory);
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new Exception($"{nameof(rootDirectoryParent)} is null!"); throw new ArgumentNullException(nameof(rootDirectoryParent));
int z = 0; int z = 0;
int propertyId; int propertyId;
Dictionary<int, int> findReplace = new(); Dictionary<int, int> findReplace = new();
@ -591,14 +591,14 @@ public class PrepareForOld
private void VerifyAgainstIndexInfoJsonFiles(Property.Models.Configuration configuration, string aPropertySingletonDirectory) private void VerifyAgainstIndexInfoJsonFiles(Property.Models.Configuration configuration, string aPropertySingletonDirectory)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.PropertyConfiguration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new Exception($"{nameof(rootDirectoryParent)} is null!"); throw new ArgumentNullException(nameof(rootDirectoryParent));
int z = 0; int z = 0;
int? propertyId; int? propertyId;
long? propertyTicks; long? propertyTicks;

View File

@ -33,7 +33,7 @@ public class PropertyCompareLogic
{ {
List<PropertyCompare> results = new(); List<PropertyCompare> results = new();
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
int index; int index;
string value; string value;
long[] distinctNumberValues; long[] distinctNumberValues;
@ -81,7 +81,7 @@ public class PropertyCompareLogic
{ {
List<string[]> fromThenToCollection = new(); List<string[]> fromThenToCollection = new();
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
int z = 0; int z = 0;
string to; string to;
string from; string from;
@ -177,7 +177,7 @@ public class PropertyCompareLogic
string json = File.ReadAllText(jsonFile); string json = File.ReadAllText(jsonFile);
A_Property? property = JsonSerializer.Deserialize<A_Property>(json); A_Property? property = JsonSerializer.Deserialize<A_Property>(json);
if (property?.Id is null) if (property?.Id is null)
throw new Exception($"{nameof(property)} is null!"); throw new ArgumentNullException(nameof(property));
DateTime minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(property); DateTime minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(property);
corrected = string.Concat(relativeDirectory, jsonFileNameWithoutExtension); corrected = string.Concat(relativeDirectory, jsonFileNameWithoutExtension);
if (_SpellingFindReplace is not null && (from l in _SpellingFindReplace where corrected.Contains(l.Find) select true).Any()) if (_SpellingFindReplace is not null && (from l in _SpellingFindReplace where corrected.Contains(l.Find) select true).Any())
@ -251,7 +251,7 @@ public class PropertyCompareLogic
{ {
List<PropertyCompare> results = new(); List<PropertyCompare> results = new();
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
string[] files; string[] files;
int totalSeconds; int totalSeconds;
string directory; string directory;
@ -319,7 +319,7 @@ public class PropertyCompareLogic
private void MoveFiles(string[] directories, List<string[]> fromThenToCollection) private void MoveFiles(string[] directories, List<string[]> fromThenToCollection)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
int z; int z;
string to; string to;
string from; string from;
@ -406,7 +406,7 @@ public class PropertyCompareLogic
public void SaveDiffFiles(string aPropertyCollectionDirectory, int loadLessThan, PropertyCompare[] propertyCompares, PropertyCompare[]? diffPropertyCompares) public void SaveDiffFiles(string aPropertyCollectionDirectory, int loadLessThan, PropertyCompare[] propertyCompares, PropertyCompare[]? diffPropertyCompares)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
string text; string text;
string[] lines; string[] lines;
string fileName; string fileName;
@ -459,7 +459,7 @@ public class PropertyCompareLogic
public void SaveLogAndMoveFiles(string aPropertyCollectionDirectory, int loadLessThan, PropertyCompare[] propertyCompares, PropertyCompare[]? diffPropertyCompares, int i) public void SaveLogAndMoveFiles(string aPropertyCollectionDirectory, int loadLessThan, PropertyCompare[] propertyCompares, PropertyCompare[]? diffPropertyCompares, int i)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
List<string> lines; List<string> lines;
string checkDirectory; string checkDirectory;
string[] toDirectories; string[] toDirectories;
@ -498,7 +498,7 @@ public class PropertyCompareLogic
public void WithSubdirectory(string propertyDirectory, bool subDirectoriesAny, string fileName, bool renameCompare, bool deleteArg) public void WithSubdirectory(string propertyDirectory, bool subDirectoriesAny, string fileName, bool renameCompare, bool deleteArg)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
List<string[]> fileCollection = new(); List<string[]> fileCollection = new();
if (renameCompare && deleteArg) if (renameCompare && deleteArg)
throw new Exception(); throw new Exception();

View File

@ -65,37 +65,37 @@ public class Configuration
public static void Verify(Configuration? propertyConfiguration) public static void Verify(Configuration? propertyConfiguration)
{ {
if (propertyConfiguration is null) if (propertyConfiguration is null)
throw new Exception($"{nameof(propertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(propertyConfiguration));
if (propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime is null) if (propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime)} must be set!"); throw new ArgumentNullException(nameof(propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime));
if (propertyConfiguration.IgnoreExtensions is null || !propertyConfiguration.IgnoreExtensions.Any()) if (propertyConfiguration.IgnoreExtensions is null || !propertyConfiguration.IgnoreExtensions.Any())
throw new Exception($"{nameof(propertyConfiguration.IgnoreExtensions)} must be set!"); throw new ArgumentNullException(nameof(propertyConfiguration.IgnoreExtensions));
if (propertyConfiguration.PopulatePropertyId is null) if (propertyConfiguration.PopulatePropertyId is null)
throw new Exception($"{nameof(propertyConfiguration.PopulatePropertyId)} must be set!"); throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId));
if (propertyConfiguration.PropertiesChangedForProperty is null) if (propertyConfiguration.PropertiesChangedForProperty is null)
throw new Exception($"{nameof(propertyConfiguration.PropertiesChangedForProperty)} must be set!"); throw new ArgumentNullException(nameof(propertyConfiguration.PropertiesChangedForProperty));
if (propertyConfiguration.PropertyContentCollectionFiles is null) if (propertyConfiguration.PropertyContentCollectionFiles is null)
throw new Exception($"{nameof(propertyConfiguration.PropertyContentCollectionFiles)} must be set!"); throw new ArgumentNullException(nameof(propertyConfiguration.PropertyContentCollectionFiles));
if (propertyConfiguration.ValidImageFormatExtensions is null || !propertyConfiguration.ValidImageFormatExtensions.Any()) if (propertyConfiguration.ValidImageFormatExtensions is null || !propertyConfiguration.ValidImageFormatExtensions.Any())
throw new Exception($"{nameof(propertyConfiguration.ValidImageFormatExtensions)} must be set!"); throw new ArgumentNullException(nameof(propertyConfiguration.ValidImageFormatExtensions));
if (propertyConfiguration.ValidMetadataExtensions is null || !propertyConfiguration.ValidMetadataExtensions.Any()) if (propertyConfiguration.ValidMetadataExtensions is null || !propertyConfiguration.ValidMetadataExtensions.Any())
throw new Exception($"{nameof(propertyConfiguration.ValidMetadataExtensions)} must be set!"); throw new ArgumentNullException(nameof(propertyConfiguration.ValidMetadataExtensions));
if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any()) if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any())
throw new Exception($"{nameof(propertyConfiguration.VerifyToSeason)} must be set!"); throw new ArgumentNullException(nameof(propertyConfiguration.VerifyToSeason));
if (propertyConfiguration.WriteBitmapDataBytes is null) if (propertyConfiguration.WriteBitmapDataBytes is null)
throw new Exception($"{nameof(propertyConfiguration.WriteBitmapDataBytes)} must be set!"); throw new ArgumentNullException(nameof(propertyConfiguration.WriteBitmapDataBytes));
if (Path.GetPathRoot(propertyConfiguration.RootDirectory) == propertyConfiguration.RootDirectory) if (Path.GetPathRoot(propertyConfiguration.RootDirectory) == propertyConfiguration.RootDirectory)
throw new Exception($"{nameof(propertyConfiguration.RootDirectory)} should have at least one level!"); throw new ArgumentNullException(nameof(propertyConfiguration.RootDirectory));
if (propertyConfiguration is null) if (propertyConfiguration is null)
throw new Exception($"{nameof(propertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(propertyConfiguration));
if (string.IsNullOrEmpty(propertyConfiguration.DateGroup)) if (string.IsNullOrEmpty(propertyConfiguration.DateGroup))
throw new Exception($"{nameof(propertyConfiguration.DateGroup)} must have a value!"); throw new ArgumentNullException(nameof(propertyConfiguration.DateGroup));
if (string.IsNullOrEmpty(propertyConfiguration.FileNameDirectorySeparator)) if (string.IsNullOrEmpty(propertyConfiguration.FileNameDirectorySeparator))
throw new Exception($"{nameof(propertyConfiguration.FileNameDirectorySeparator)} must have a value!"); throw new ArgumentNullException(nameof(propertyConfiguration.FileNameDirectorySeparator));
if (string.IsNullOrEmpty(propertyConfiguration.Pattern)) if (string.IsNullOrEmpty(propertyConfiguration.Pattern))
throw new Exception($"{nameof(propertyConfiguration.Pattern)} must have a value!"); throw new ArgumentNullException(nameof(propertyConfiguration.Pattern));
if (string.IsNullOrEmpty(propertyConfiguration.RootDirectory) || !Directory.Exists(propertyConfiguration.RootDirectory)) if (string.IsNullOrEmpty(propertyConfiguration.RootDirectory) || !Directory.Exists(propertyConfiguration.RootDirectory))
throw new Exception($"{nameof(propertyConfiguration.RootDirectory)} must have a value and exits!"); throw new ArgumentNullException(nameof(propertyConfiguration.RootDirectory));
} }
public void ChangeRootDirectory(string rootDirectory) => _RootDirectory = rootDirectory; public void ChangeRootDirectory(string rootDirectory) => _RootDirectory = rootDirectory;

View File

@ -1,4 +1,6 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Properties;
namespace View_by_Distance.Property.Models; namespace View_by_Distance.Property.Models;
@ -7,13 +9,13 @@ public class PropertyHolder
protected readonly bool? _Abandoned; protected readonly bool? _Abandoned;
protected readonly bool? _Changed; protected readonly bool? _Changed;
protected List<object> _Faces; protected List<IFace> _Faces;
protected readonly FileInfo? _ImageFileInfo; protected readonly FileInfo? _ImageFileInfo;
protected readonly string _ImageFileNameWithoutExtension; protected readonly string _ImageFileNameWithoutExtension;
protected readonly int _G; protected readonly int _G;
protected DateTime? _MinimumDateTime; protected DateTime? _MinimumDateTime;
protected bool? _Moved; protected bool? _Moved;
protected List<(bool?, string, TimeSpan?)> _Named; protected List<(bool?, DateTime, PersonBirthday, double?)> _Named;
protected readonly bool? _NoJson; protected readonly bool? _NoJson;
protected A_Property? _Property; protected A_Property? _Property;
protected readonly int _R; protected readonly int _R;
@ -24,14 +26,14 @@ public class PropertyHolder
protected bool? _ValidImageFormatExtension; protected bool? _ValidImageFormatExtension;
public bool? Abandoned => _Abandoned; public bool? Abandoned => _Abandoned;
public bool? Changed => _Changed; public bool? Changed => _Changed;
public List<object> Faces => _Faces; public List<IFace> Faces => _Faces;
public FileInfo? ImageFileInfo => _ImageFileInfo; public FileInfo? ImageFileInfo => _ImageFileInfo;
public string ImageFileNameWithoutExtension => _ImageFileNameWithoutExtension; public string ImageFileNameWithoutExtension => _ImageFileNameWithoutExtension;
public int G => _G; public int G => _G;
public DateTime? MinimumDateTime => _MinimumDateTime; public DateTime? MinimumDateTime => _MinimumDateTime;
public bool? Moved => _Moved; public bool? Moved => _Moved;
public bool? NoJson => _NoJson; public bool? NoJson => _NoJson;
public List<(bool? IsWrongYear, string PersonKey, TimeSpan? TimeSpan)> Named => _Named; public List<(bool? isWrongYear, DateTime minimumDateTime, PersonBirthday personBirthday, double? pixelPercentage)> Named => _Named;
public A_Property? Property => _Property; public A_Property? Property => _Property;
public int R => _R; public int R => _R;
public string RelativePath => _RelativePath; public string RelativePath => _RelativePath;
@ -96,20 +98,15 @@ public class PropertyHolder
_MinimumDateTime = Stateless.A_Property.GetMinimumDateTime(property); _MinimumDateTime = Stateless.A_Property.GetMinimumDateTime(property);
} }
public static void AddToFaces(PropertyHolder[] filteredPropertyHolderCollection, object[] faces)
{
foreach (PropertyHolder propertyHolder in filteredPropertyHolderCollection)
propertyHolder.Faces.AddRange(faces);
}
public static void AddToNamed(PropertyLogic propertyLogic, PropertyHolder[] filteredPropertyHolderCollection) public static void AddToNamed(PropertyLogic propertyLogic, PropertyHolder[] filteredPropertyHolderCollection)
{ {
bool? isWrongYear; bool? isWrongYear;
TimeSpan? timeSpan; string[] segments;
DateTime? birthDate;
string[] personKeys; string[] personKeys;
double? pixelPercentage;
DateTime minimumDateTime; DateTime minimumDateTime;
PropertyHolder propertyHolder; PropertyHolder propertyHolder;
PersonBirthday? personBirthday;
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++) for (int i = 0; i < filteredPropertyHolderCollection.Length; i++)
{ {
propertyHolder = filteredPropertyHolderCollection[i]; propertyHolder = filteredPropertyHolderCollection[i];
@ -122,21 +119,187 @@ public class PropertyHolder
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(propertyHolder.Property); minimumDateTime = Stateless.A_Property.GetMinimumDateTime(propertyHolder.Property);
personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value]; personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value];
(isWrongYear, _) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileInfo.FullName, minimumDateTime); (isWrongYear, _) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileInfo.FullName, minimumDateTime);
foreach (string personKey in personKeys) for (int j = 0; j < personKeys.Length; j++)
{ {
if (isWrongYear is null || isWrongYear.Value || personKey[..2] is not "19" and not "20") segments = Shared.Models.Stateless.Methods.IPersonBirthday.GetSegments(personKeys[j]);
timeSpan = null; personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKeys[j]);
if (personBirthday is null)
continue;
if (segments.Length <= 1 || !double.TryParse(segments[1], out double value))
pixelPercentage = null;
else else
{ pixelPercentage = value;
birthDate = Shared.Models.Stateless.Methods.IPersonBirthday.Get(personKey); propertyHolder.Named.Add(new(isWrongYear, minimumDateTime, personBirthday, pixelPercentage));
if (birthDate is null)
timeSpan = null;
else
timeSpan = new(minimumDateTime.Ticks - birthDate.Value.Ticks);
}
propertyHolder.Named.Add(new(isWrongYear, personKey, timeSpan));
} }
} }
} }
public static List<(PropertyHolder, (string, IFace?, (string, string, string, string))[])> GetCollection(PropertyLogic propertyLogic, PropertyHolder[] filteredPropertyHolderCollection, string dFacesContentDirectory)
{
List<(PropertyHolder, (string, IFace?, (string, string, string, string))[])> results = new();
string[] keys;
string directory;
string personKey;
bool? isWrongYear;
string[] segments;
const int zero = 0;
TimeSpan? timeSpan;
string copyFileName;
string copyDirectory;
string? relativePath;
string isWrongYearFlag;
string shortcutFileName;
string subDirectoryName;
List<int> indices = new();
List<IFace> faceCollection;
PropertyHolder propertyHolder;
PersonBirthday? personBirthday;
List<(string, IFace?, (string, string, string, string))> collection;
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++)
{
indices.Clear();
personKey = string.Empty;
copyFileName = string.Empty;
copyDirectory = string.Empty;
propertyHolder = filteredPropertyHolderCollection[i];
if (propertyHolder.ImageFileInfo is null)
continue;
relativePath = Path.GetDirectoryName($"C:{propertyHolder.RelativePath}");
if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3)
continue;
if (propertyHolder.Property?.Id is null || propertyHolder.MinimumDateTime is null || propertyHolder.ResizedFileInfo is null)
continue;
collection = new();
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(propertyHolder.Property.Id.Value))
{
faceCollection = new();
directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}");
}
else
{
faceCollection = propertyHolder.Faces;
keys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value];
(isWrongYear, _) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileInfo.FullName, propertyHolder.MinimumDateTime.Value);
isWrongYearFlag = GetWrongYearFlag(isWrongYear);
subDirectoryName = $"{isWrongYearFlag}{propertyHolder.MinimumDateTime.Value:yyyy}";
if (!faceCollection.Any())
directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}", subDirectoryName);
else if (keys.Length != 1)
directory = Path.Combine(dFacesContentDirectory, $"Not Supported{relativePath[2..]}", subDirectoryName);
else if (faceCollection.Count != 1)
directory = Path.Combine(dFacesContentDirectory, $"Many{relativePath[2..]}", subDirectoryName);
else
{
indices.Add(zero);
segments = Shared.Models.Stateless.Methods.IPersonBirthday.GetSegments(keys[zero]);
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(keys[zero]);
if (personBirthday is null)
continue;
timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(propertyHolder.MinimumDateTime.Value, isWrongYear, personBirthday);
if (timeSpan.HasValue)
{
if (timeSpan.Value.Ticks < 0)
subDirectoryName = "!---";
else
subDirectoryName = $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}";
}
personKey = segments[zero];
directory = Path.Combine(dFacesContentDirectory, "Shortcuts", personKey, subDirectoryName);
if (faceCollection[zero].Populated)
copyDirectory = Path.Combine(dFacesContentDirectory, "Images", personKey, subDirectoryName);
else
copyDirectory = Path.Combine(dFacesContentDirectory, "ImagesBut", personKey, subDirectoryName);
copyFileName = Path.Combine(copyDirectory, $"{propertyHolder.Property.Id.Value}{propertyHolder.ResizedFileInfo.Extension}");
}
}
shortcutFileName = Path.Combine(directory, $"{propertyHolder.Property.Id.Value}.lnk");
if (string.IsNullOrEmpty(personKey) || !indices.Any())
collection.Add(new(personKey, null, (directory, copyDirectory, copyFileName, shortcutFileName)));
else
{
foreach (int index in indices)
collection.Add(new(personKey, faceCollection[index], (directory, copyDirectory, copyFileName, shortcutFileName)));
}
results.Add(new(propertyHolder, collection.ToArray()));
}
return results;
}
private static Dictionary<string, List<(string[], PersonBirthday, IFace)>> GetKeyValuePairs(string argZero, List<PropertyHolder[]> propertyHolderCollections, string eDistanceCollectionDirectory)
{
Dictionary<string, List<(string[], PersonBirthday, IFace)>> results = new();
string key;
string personKey;
TimeSpan? timeSpan;
string[] directories;
string isWrongYearFlag;
string facePopulatedKey;
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
{
if (!propertyHolderCollection.Any())
continue;
if (!propertyHolderCollection[0].SourceDirectory.StartsWith(argZero))
continue;
foreach (PropertyHolder propertyHolder in propertyHolderCollection)
{
if (propertyHolder.ImageFileInfo is null || propertyHolder.Property is null || !propertyHolder.Named.Any())
continue;
foreach ((bool? isWrongYear, DateTime minimumDateTime, PersonBirthday personBirthday, double? pixelPercentage) in propertyHolder.Named)
{
if (propertyHolder.MinimumDateTime is null)
continue;
if (pixelPercentage is null && (propertyHolder.Named.Count != 1 || propertyHolder.Faces.Count != 1))
continue;
foreach (IFace face in propertyHolder.Faces)
{
if (pixelPercentage.HasValue && pixelPercentage.Value != face.Location.PixelPercentage)
continue;
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
if (face.Populated)
facePopulatedKey = "Images";
else
facePopulatedKey = "ImagesBut";
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0)
directories = new string[] { string.Empty, facePopulatedKey, personKey, "!---" };
else if (timeSpan.HasValue)
directories = new string[] { string.Empty, facePopulatedKey, personKey, $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}" };
else
{
isWrongYearFlag = GetWrongYearFlag(isWrongYear);
directories = new string[] { string.Empty, facePopulatedKey, personKey, $"{isWrongYearFlag}{propertyHolder.MinimumDateTime.Value:yyyy}" };
}
key = string.Join('\t', directories);
if (!results.ContainsKey(key))
results.Add(key, new());
directories[0] = eDistanceCollectionDirectory;
results[key].Add(new(directories, personBirthday, face));
if (pixelPercentage is null)
break;
}
}
}
}
return results;
}
public static List<(string, PersonBirthday, IFace)[]> GetCollection(string argZero, List<PropertyHolder[]> propertyHolderCollections, string eDistanceCollectionDirectory)
{
List<(string, PersonBirthday, IFace)[]> results = new();
string directory;
List<(string, PersonBirthday, IFace)> group;
Dictionary<string, List<(string[], PersonBirthday, IFace)>> keyValuePairs = GetKeyValuePairs(argZero, propertyHolderCollections, eDistanceCollectionDirectory);
foreach (KeyValuePair<string, List<(string[], PersonBirthday, IFace)>> keyValuePair in keyValuePairs)
{
group = new();
foreach ((string[] directories, PersonBirthday personBirthday, IFace face) in keyValuePair.Value)
{
directory = Path.Combine(directories);
group.Add(new(directory, personBirthday, face));
}
results.Add(group.ToArray());
}
return results;
}
} }

View File

@ -57,7 +57,7 @@ public class PropertyLogic
Dictionary<int, string[]>? sixCharacterNamedFaceInfo; Dictionary<int, string[]>? sixCharacterNamedFaceInfo;
string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new Exception($"{nameof(rootDirectoryParent)} is null!"); throw new ArgumentNullException(nameof(rootDirectoryParent));
files = Directory.GetFiles(rootDirectoryParent, "*DeterministicHashCode*.json", SearchOption.TopDirectoryOnly); files = Directory.GetFiles(rootDirectoryParent, "*DeterministicHashCode*.json", SearchOption.TopDirectoryOnly);
if (files.Length != 1) if (files.Length != 1)
namedFaceInfoDeterministicHashCodeIndices = new(); namedFaceInfoDeterministicHashCodeIndices = new();
@ -66,7 +66,7 @@ public class PropertyLogic
json = File.ReadAllText(files[0]); json = File.ReadAllText(files[0]);
namedFaceInfoDeterministicHashCodeIndices = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json); namedFaceInfoDeterministicHashCodeIndices = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
if (namedFaceInfoDeterministicHashCodeIndices is null) if (namedFaceInfoDeterministicHashCodeIndices is null)
throw new Exception($"{nameof(namedFaceInfoDeterministicHashCodeIndices)} is null!"); throw new ArgumentNullException(nameof(namedFaceInfoDeterministicHashCodeIndices));
} }
if (namedFaceInfoDeterministicHashCodeIndices.Any()) if (namedFaceInfoDeterministicHashCodeIndices.Any())
sixCharacterNamedFaceInfo = new(); sixCharacterNamedFaceInfo = new();
@ -80,7 +80,7 @@ public class PropertyLogic
json = File.ReadAllText(files[0]); json = File.ReadAllText(files[0]);
sixCharacterNamedFaceInfo = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json); sixCharacterNamedFaceInfo = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
if (sixCharacterNamedFaceInfo is null) if (sixCharacterNamedFaceInfo is null)
throw new Exception($"{nameof(sixCharacterNamedFaceInfo)} is null!"); throw new ArgumentNullException(nameof(sixCharacterNamedFaceInfo));
} }
} }
files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly); files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly);
@ -91,7 +91,7 @@ public class PropertyLogic
json = File.ReadAllText(files[0]); json = File.ReadAllText(files[0]);
keyValuePairs = JsonSerializer.Deserialize<Dictionary<int, int[]>>(json); keyValuePairs = JsonSerializer.Deserialize<Dictionary<int, int[]>>(json);
if (keyValuePairs is null) if (keyValuePairs is null)
throw new Exception($"{nameof(keyValuePairs)} is null!"); throw new ArgumentNullException(nameof(keyValuePairs));
} }
foreach (string propertyContentCollectionFile in configuration.PropertyContentCollectionFiles) foreach (string propertyContentCollectionFile in configuration.PropertyContentCollectionFiles)
{ {
@ -103,7 +103,7 @@ public class PropertyLogic
json = File.ReadAllText(fullPath); json = File.ReadAllText(fullPath);
collection = JsonSerializer.Deserialize<List<KeyValuePair<int, int[]>>>(json); collection = JsonSerializer.Deserialize<List<KeyValuePair<int, int[]>>>(json);
if (collection is null) if (collection is null)
throw new Exception($"{nameof(collection)} is null!"); throw new ArgumentNullException(nameof(collection));
foreach (KeyValuePair<int, int[]> keyValuePair in collection) foreach (KeyValuePair<int, int[]> keyValuePair in collection)
{ {
if (indicesFromNew.ContainsKey(keyValuePair.Key)) if (indicesFromNew.ContainsKey(keyValuePair.Key))
@ -127,7 +127,7 @@ public class PropertyLogic
{ {
long result; long result;
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds; double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)"); _Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks; result = DateTime.Now.Ticks;
@ -172,9 +172,9 @@ public class PropertyLogic
{ {
A_Property result; A_Property result;
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_Configuration.WriteBitmapDataBytes is null) if (_Configuration.WriteBitmapDataBytes is null)
throw new Exception($"{nameof(_Configuration.WriteBitmapDataBytes)} is null!"); throw new ArgumentNullException(nameof(_Configuration.WriteBitmapDataBytes));
long ticks; long ticks;
byte[] bytes; byte[] bytes;
string value; string value;
@ -340,11 +340,11 @@ public class PropertyLogic
{ {
A_Property? result; A_Property? result;
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime is null) if (_Configuration.ForcePropertyLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime)} is null!"); throw new ArgumentNullException(nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime));
if (_Configuration.PopulatePropertyId is null) if (_Configuration.PopulatePropertyId is null)
throw new Exception($"{nameof(_Configuration.PopulatePropertyId)} is null!"); throw new ArgumentNullException(nameof(_Configuration.PopulatePropertyId));
if (_Configuration.PropertiesChangedForProperty is null) if (_Configuration.PropertiesChangedForProperty is null)
throw new Exception($"{nameof(_Configuration.PropertiesChangedForProperty)} is null!"); throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForProperty));
string json; string json;
int? id = null; int? id = null;
List<int> indices = new(); List<int> indices = new();
@ -464,7 +464,7 @@ public class PropertyLogic
throw new ArgumentException($"{propertyHolder.ImageFileInfo} is null!"); throw new ArgumentException($"{propertyHolder.ImageFileInfo} is null!");
result = GetImageProperty(angleBracket, propertyHolder.ImageFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices); result = GetImageProperty(angleBracket, propertyHolder.ImageFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
if (populateId && IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true)) if (populateId && IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
{ {
if (!_Configuration.ForcePropertyLastWriteTimeToCreationTime.Value && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime)) if (!_Configuration.ForcePropertyLastWriteTimeToCreationTime.Value && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now)); filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
@ -479,7 +479,7 @@ public class PropertyLogic
else if (hasWrongYearProperty) else if (hasWrongYearProperty)
{ {
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
if (IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true)) if (IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
{ {
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime); File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
fileInfo.Refresh(); fileInfo.Refresh();
@ -493,7 +493,7 @@ public class PropertyLogic
{ {
bool result = false; bool result = false;
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
int season; int season;
string[] matches; string[] matches;
string deleteFile; string deleteFile;
@ -603,41 +603,10 @@ public class PropertyLogic
return result; return result;
} }
private void WriteGroup(int sourceDirectoryLength, PropertyHolder[] filteredPropertyHolderCollection, string angleBracket)
{
if (!(from l in filteredPropertyHolderCollection where l?.Property?.Width is null select true).Any())
{
string key;
string json;
string checkFile;
string checkDirectory;
List<KeyValuePair<string, A_Property>> propertyCollectionKeyValuePairs = new();
JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = false };
(int level, List<string> directories) = IPath.Get(_Configuration.RootDirectory, filteredPropertyHolderCollection[0].SourceDirectory);
string fileName = string.Concat(string.Join(_Configuration.FileNameDirectorySeparator, directories), ".json");
foreach (PropertyHolder propertyHolder in filteredPropertyHolderCollection)
{
if (propertyHolder.Property is null)
continue;
if (propertyHolder.ImageFileInfo is null)
continue;
key = IPath.GetRelativePath(propertyHolder.ImageFileInfo.FullName, sourceDirectoryLength);
propertyCollectionKeyValuePairs.Add(new KeyValuePair<string, A_Property>(key, propertyHolder.Property));
}
checkDirectory = IPath.GetDirectory(angleBracket, level, "[{}]");
checkFile = Path.Combine(checkDirectory, fileName);
if (File.Exists(checkFile))
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
checkFile = Path.Combine(checkDirectory, fileName);
json = JsonSerializer.Serialize(propertyCollectionKeyValuePairs, writeIndentedJsonSerializerOptions);
_ = IPath.WriteAllText(checkFile, json, compareBeforeWrite: true);
}
}
private void ParallelForWork(bool firstPass, string angleBracket, string sourceDirectory, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, PropertyHolder propertyHolder) private void ParallelForWork(bool firstPass, string angleBracket, string sourceDirectory, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, PropertyHolder propertyHolder)
{ {
if (propertyHolder.ImageFileInfo is null) if (propertyHolder.ImageFileInfo is null)
throw new Exception($"{nameof(propertyHolder.ImageFileInfo)} is null!"); throw new ArgumentNullException(nameof(propertyHolder.ImageFileInfo));
A_Property property; A_Property property;
List<string> parseExceptions = new(); List<string> parseExceptions = new();
string extensionLowered = propertyHolder.ImageFileInfo.Extension.ToLower(); string extensionLowered = propertyHolder.ImageFileInfo.Extension.ToLower();
@ -708,18 +677,18 @@ public class PropertyLogic
public void ParallelWork(Configuration configuration, Model? model, PredictorModel? predictorModel, long ticks, List<PropertyHolder[]> propertyHolderCollections, bool firstPass) public void ParallelWork(Configuration configuration, Model? model, PredictorModel? predictorModel, long ticks, List<PropertyHolder[]> propertyHolderCollections, bool firstPass)
{ {
if (_Log is null) if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!"); throw new ArgumentNullException(nameof(_Log));
if (_Configuration.PopulatePropertyId is null) if (_Configuration.PopulatePropertyId is null)
throw new Exception($"{nameof(_Configuration.PopulatePropertyId)} is null!"); throw new ArgumentNullException(nameof(_Configuration.PopulatePropertyId));
int g; int g;
int r; int r;
int totalSeconds; int totalSeconds;
bool? anyFilesMoved;
string angleBracket; string angleBracket;
string sourceDirectory; string sourceDirectory;
List<Exception> exceptions = new(); List<Exception> exceptions = new();
PropertyHolder[] filteredPropertyHolderCollection; PropertyHolder[] filteredPropertyHolderCollection;
List<Tuple<string, DateTime>> sourceDirectoryChanges = new(); List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
int sourceDirectoryLength = configuration.RootDirectory.Length;
int propertyHolderCollectionsCount = propertyHolderCollections.Count; int propertyHolderCollectionsCount = propertyHolderCollections.Count;
string propertyRoot = IResult.GetResultsGroupDirectory(configuration, nameof(A_Property)); string propertyRoot = IResult.GetResultsGroupDirectory(configuration, nameof(A_Property));
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections) foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
@ -745,13 +714,10 @@ public class PropertyLogic
throw new Exception(string.Concat("All in [", sourceDirectory, "]failed!")); throw new Exception(string.Concat("All in [", sourceDirectory, "]failed!"));
if (exceptions.Count != 0) if (exceptions.Count != 0)
_ExceptionsDirectories.Add(sourceDirectory); _ExceptionsDirectories.Add(sourceDirectory);
bool? anyFilesMoved;
if (!firstPass || exceptions.Count != 0) if (!firstPass || exceptions.Count != 0)
anyFilesMoved = null; anyFilesMoved = null;
else else
anyFilesMoved = AnyFilesMoved(sourceDirectory, filteredPropertyHolderCollection); anyFilesMoved = AnyFilesMoved(sourceDirectory, filteredPropertyHolderCollection);
if (exceptions.Count == 0 && !firstPass && _Configuration.PopulatePropertyId.Value && (anyFilesMoved is null || !anyFilesMoved.Value))
WriteGroup(sourceDirectoryLength, filteredPropertyHolderCollection, angleBracket);
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any()) if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
{ {
for (int y = 0; y < int.MaxValue; y++) for (int y = 0; y < int.MaxValue; y++)
@ -843,7 +809,7 @@ public class PropertyLogic
string[] keys; string[] keys;
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new Exception($"{nameof(rootDirectoryParent)} is null!"); throw new ArgumentNullException(nameof(rootDirectoryParent));
Dictionary<int, string[]> namedFaceInfoDeterministicHashCodeIndices = new(); Dictionary<int, string[]> namedFaceInfoDeterministicHashCodeIndices = new();
List<(int, string[])> allCollection = _AllCollection.OrderBy(l => l.Item1).ToList(); List<(int, string[])> allCollection = _AllCollection.OrderBy(l => l.Item1).ToList();
foreach ((int deterministicHashCode, string[] values) in allCollection) foreach ((int deterministicHashCode, string[] values) in allCollection)
@ -859,7 +825,7 @@ public class PropertyLogic
} }
string json = JsonSerializer.Serialize(namedFaceInfoDeterministicHashCodeIndices, new JsonSerializerOptions { WriteIndented = true }); string json = JsonSerializer.Serialize(namedFaceInfoDeterministicHashCodeIndices, new JsonSerializerOptions { WriteIndented = true });
string checkFile = Path.Combine(rootDirectoryParent, "NamedFaceInfoDeterministicHashCodeIndices.json"); string checkFile = Path.Combine(rootDirectoryParent, "NamedFaceInfoDeterministicHashCodeIndices.json");
_ = IPath.WriteAllText(checkFile, json, compareBeforeWrite: true); _ = IPath.WriteAllText(checkFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
} }
} }

View File

@ -119,7 +119,7 @@ public static class A_Property
public static List<(int g, string sourceDirectory, FileInfo[] sourceDirectoryFiles, int r)> GetFileInfoGroupCollection(Models.Configuration configuration, bool reverse, string searchPattern, List<string> topDirectories) public static List<(int g, string sourceDirectory, FileInfo[] sourceDirectoryFiles, int r)> GetFileInfoGroupCollection(Models.Configuration configuration, bool reverse, string searchPattern, List<string> topDirectories)
{ {
if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null) if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null)
throw new Exception($"{nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass)} is null!"); throw new ArgumentNullException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass));
List<(int g, string sourceDirectory, FileInfo[] sourceDirectoryFiles, int r)> results = new(); List<(int g, string sourceDirectory, FileInfo[] sourceDirectoryFiles, int r)> results = new();
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)>? collection = GetGroupCollection(configuration.RootDirectory, searchPattern, topDirectories, configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value, reverse); List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)>? collection = GetGroupCollection(configuration.RootDirectory, searchPattern, topDirectories, configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value, reverse);
foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) in collection) foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) in collection)

View File

@ -12,8 +12,8 @@ public interface IPath
List<string> TestStatic_GetDirectoryNames(string directory); List<string> TestStatic_GetDirectoryNames(string directory);
static List<string> GetDirectoryNames(string directory) => XPath.GetDirectoryNames(directory); static List<string> GetDirectoryNames(string directory) => XPath.GetDirectoryNames(directory);
bool TestStatic_WriteAllText(string path, string contents, bool compareBeforeWrite); bool TestStatic_WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite);
static bool WriteAllText(string path, string contents, bool compareBeforeWrite) => XPath.WriteAllText(path, contents, compareBeforeWrite); static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches = null) => XPath.WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite, updateToWhenMatches);
(int level, List<string> directories) TestStatic_Get(string rootDirectory, string sourceDirectory); (int level, List<string> directories) TestStatic_Get(string rootDirectory, string sourceDirectory);
static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory) => XPath.Get(rootDirectory, sourceDirectory); static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory) => XPath.Get(rootDirectory, sourceDirectory);

View File

@ -46,7 +46,7 @@ internal class XPath
return result; return result;
} }
internal static bool WriteAllText(string path, string contents, bool compareBeforeWrite) internal static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches)
{ {
bool result; bool result;
string text; string text;
@ -59,6 +59,13 @@ internal class XPath
else else
text = File.ReadAllText(path); text = File.ReadAllText(path);
result = text != contents; result = text != contents;
if (!result && updateDateWhenMatches)
{
if (updateToWhenMatches is null)
File.SetLastWriteTime(path, DateTime.Now);
else
File.SetLastWriteTime(path, updateToWhenMatches.Value);
}
} }
if (result) if (result)
{ {
@ -85,7 +92,7 @@ internal class XPath
string? pathRoot = Path.GetPathRoot(directory); string? pathRoot = Path.GetPathRoot(directory);
string extension = Path.GetExtension(directory); string extension = Path.GetExtension(directory);
if (string.IsNullOrEmpty(pathRoot)) if (string.IsNullOrEmpty(pathRoot))
throw new Exception($"{nameof(pathRoot)} is null!"); throw new ArgumentNullException(nameof(pathRoot));
if (Directory.Exists(directory)) if (Directory.Exists(directory))
results.Add(Path.GetFileName(directory)); results.Add(Path.GetFileName(directory));
else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory)) else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory))

View File

@ -485,7 +485,9 @@ public class C_Resize
{ {
results = GetImageResizes(property, metadataCollection, original); results = GetImageResizes(property, metadataCollection, original);
json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true)) bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
{ {
if (!_ForceResizeLastWriteTimeToCreationTime && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime)) if (!_ForceResizeLastWriteTimeToCreationTime && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));

View File

@ -1,4 +1,3 @@
using System.Drawing;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using View_by_Distance.Shared.Models.Methods; using View_by_Distance.Shared.Models.Methods;
@ -8,37 +7,40 @@ namespace View_by_Distance.Shared.Models;
public class Location : Properties.ILocation, ILocation, IEquatable<Location> public class Location : Properties.ILocation, ILocation, IEquatable<Location>
{ {
public double Confidence => _Confidence;
protected double _Confidence; protected double _Confidence;
protected int _Bottom; protected int _Bottom;
protected int _Left; protected int _Left;
protected double? _PixelPercentage;
protected int _Right; protected int _Right;
protected int _Top; protected int _Top;
public double Confidence => _Confidence;
public int Bottom => _Bottom; public int Bottom => _Bottom;
public int Left => _Left; public int Left => _Left;
public double? PixelPercentage => _PixelPercentage;
public int Right => _Right; public int Right => _Right;
public int Top => _Top; public int Top => _Top;
[JsonConstructor] [JsonConstructor]
public Location(double confidence, int bottom, int left, int right, int top) public Location(double confidence, int bottom, int left, double? pixelPercentage, int right, int top)
{ {
_Confidence = confidence; _Confidence = confidence;
_Bottom = bottom; _Bottom = bottom;
_Left = left; _Left = left;
_PixelPercentage = pixelPercentage;
_Right = right; _Right = right;
_Top = top; _Top = top;
} }
public Location(int left, int top, int right, int bottom) : public Location(double confidence, int bottom, int left, int right, int top, int width, int height) :
this(-1.0d, bottom, left, right, top) this(confidence, bottom, left, GetPixelPercentage(bottom, left, right, top, width, height), right, top)
{ } { }
public Location(Rectangle rectangle, double confidence) : public Location(double confidence, Location location, int width, int height) :
this(-1.0d, rectangle.Bottom, rectangle.Left, rectangle.Right, rectangle.Top) this(confidence, location.Bottom, location.Left, location.Right, location.Top, width, height)
{ } { }
public Location(Location location, double confidence) : public Location(int left, int top, int right, int bottom, int width, int height) :
this(-1.0d, location.Bottom, location.Left, location.Right, location.Top) this(-1.0d, bottom, left, right, top, width, height)
{ } { }
public override bool Equals(object? obj) => Equals(obj as Location); public override bool Equals(object? obj) => Equals(obj as Location);
@ -59,6 +61,15 @@ public class Location : Properties.ILocation, ILocation, IEquatable<Location>
return hashCode; return hashCode;
} }
public static double GetPixelPercentage(int left, int top, int right, int bottom, int width, int height)
{
double result;
double xCenter = left + ((right - left) / 2);
double yCenter = top + ((bottom - top) / 2);
result = ((yCenter * width) + xCenter) / (width * height);
return (double)Math.Round((decimal)result, 4);
}
public bool Equals(Location? location) public bool Equals(Location? location)
{ {
return location is not null return location is not null

View File

@ -26,7 +26,7 @@
// public int? mappedMaxIndex; // public int? mappedMaxIndex;
// public int? maxImagesInDirectoryForTopLevelFirstPass; // public int? maxImagesInDirectoryForTopLevelFirstPass;
// public int? maxItemsInDistanceCollection; // public int? maxItemsInDistanceCollection;
// public int? numJitters; // public int? numberOfJitters;
// public int? outputQuality; // public int? outputQuality;
// public int? paddingLoops; // public int? paddingLoops;
// public string dateGroup; // public string dateGroup;

View File

@ -9,51 +9,46 @@ public enum FacePart
/// <summary> /// <summary>
/// Specifies the chin. /// Specifies the chin.
/// </summary> /// </summary>
Chin, Chin = 0,
/// <summary> /// <summary>
/// Specifies the left eyebrow. /// Specifies the left eyebrow.
/// </summary> /// </summary>
LeftEyebrow, LeftEyebrow = 17,
/// <summary> /// <summary>
/// Specifies the right eyebrow. /// Specifies the right eyebrow.
/// </summary> /// </summary>
RightEyebrow, RightEyebrow = 22,
/// <summary> /// <summary>
/// Specifies the nose bridge. /// Specifies the nose bridge.
/// </summary> /// </summary>
NoseBridge, NoseBridge = 27,
/// <summary> /// <summary>
/// Specifies the nose tip. /// Specifies the nose tip.
/// </summary> /// </summary>
NoseTip, NoseTip = 31,
/// <summary> /// <summary>
/// Specifies the left eye. /// Specifies the left eye.
/// </summary> /// </summary>
LeftEye, LeftEye = 36,
/// <summary> /// <summary>
/// Specifies the right eye. /// Specifies the right eye.
/// </summary> /// </summary>
RightEye, RightEye = 42,
/// <summary> /// <summary>
/// Specifies the top lip. /// Specifies the top lip.
/// </summary> /// </summary>
TopLip, TopLip = 48,
/// <summary> /// <summary>
/// Specifies the bottom lip. /// Specifies the bottom lip.
/// </summary> /// </summary>
BottomLip, BottomLip = 55
/// <summary>
/// Specifies the nose.
/// </summary>
Nose,
} }

View File

@ -12,17 +12,23 @@ public interface IPersonBirthday
string TestStatic_GetFormat() => PersonBirthday.GetFormat(); string TestStatic_GetFormat() => PersonBirthday.GetFormat();
static string GetFormat() => PersonBirthday.GetFormat(); static string GetFormat() => PersonBirthday.GetFormat();
Models.PersonBirthday TestStatic_GetNextBirthDate(Properties.IStorage storage) => PersonBirthday.GetNextBirthDate(storage); string[] TestStatic_GetSegments(string personKey) => PersonBirthday.GetSegments(personKey);
static Models.PersonBirthday GetNextBirthDate(Properties.IStorage storage) => PersonBirthday.GetNextBirthDate(storage); static string[] GetSegments(string personKey) => PersonBirthday.GetSegments(personKey);
DateTime? TestStatic_GetDateTime(string personKey) => PersonBirthday.GetDateTime(personKey);
static DateTime? GetDateTime(string personKey) => PersonBirthday.GetDateTime(personKey);
string TestStatic_GetFileName(Models.PersonBirthday personBirthday) => PersonBirthday.GetFileName(personBirthday);
static string GetFileName(Models.PersonBirthday personBirthday) => PersonBirthday.GetFileName(personBirthday);
Models.PersonBirthday? TestStatic_GetPersonBirthday(string personKey) => PersonBirthday.GetPersonBirthday(personKey);
static Models.PersonBirthday? GetPersonBirthday(string personKey) => PersonBirthday.GetPersonBirthday(personKey);
string TestStatic_GetFormatted(Models.PersonBirthday personBirthday) => PersonBirthday.GetFormatted(personBirthday); string TestStatic_GetFormatted(Models.PersonBirthday personBirthday) => PersonBirthday.GetFormatted(personBirthday);
static string GetFormatted(Models.PersonBirthday personBirthday) => PersonBirthday.GetFormatted(personBirthday); static string GetFormatted(Models.PersonBirthday personBirthday) => PersonBirthday.GetFormatted(personBirthday);
DateTime? TestStatic_Get(string personKey) => PersonBirthday.Get(personKey); Models.PersonBirthday TestStatic_GetNextBirthDate(Properties.IStorage storage) => PersonBirthday.GetNextBirthDate(storage);
static DateTime? Get(string personKey) => PersonBirthday.Get(personKey); static Models.PersonBirthday GetNextBirthDate(Properties.IStorage storage) => PersonBirthday.GetNextBirthDate(storage);
string TestStatic_GetFileName(Models.PersonBirthday personBirthday) => PersonBirthday.GetFileName(personBirthday);
static string GetFileName(Models.PersonBirthday personBirthday) => PersonBirthday.GetFileName(personBirthday);
bool TestStatic_DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday personBirthday) => DoesBirthDateExits(storage, personBirthday); bool TestStatic_DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday personBirthday) => DoesBirthDateExits(storage, personBirthday);
static bool DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday personBirthday) => DoesBirthDateExits(storage, personBirthday); static bool DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday personBirthday) => DoesBirthDateExits(storage, personBirthday);
@ -30,4 +36,7 @@ public interface IPersonBirthday
string TestStatic_GetFileFullName(Properties.IStorage storage, Models.PersonBirthday personBirthday) => PersonBirthday.GetFileFullName(storage, personBirthday); string TestStatic_GetFileFullName(Properties.IStorage storage, Models.PersonBirthday personBirthday) => PersonBirthday.GetFileFullName(storage, personBirthday);
static string GetFileFullName(Properties.IStorage storage, Models.PersonBirthday personBirthday) => PersonBirthday.GetFileFullName(storage, personBirthday); static string GetFileFullName(Properties.IStorage storage, Models.PersonBirthday personBirthday) => PersonBirthday.GetFileFullName(storage, personBirthday);
TimeSpan? TestStatic_Get(DateTime minimumDateTime, bool? isWrongYear, Models.PersonBirthday personBirthday) => PersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
static TimeSpan? GetTimeSpan(DateTime minimumDateTime, bool? isWrongYear, Models.PersonBirthday personBirthday) => PersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
} }

View File

@ -5,8 +5,8 @@ public interface IStorage
// ... // ...
bool TestStatic_WriteAllText(string path, string contents, bool compareBeforeWrite); bool TestStatic_WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite);
static bool WriteAllText(string path, string contents, bool compareBeforeWrite) => Storage.WriteAllText(path, contents, compareBeforeWrite); static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite) => Storage.WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite);
(string RootResultsDirectoryAbsoluteUri, string C_ResizeContentDirectory, string D_FacesContentDirectory, string E_DistanceCollectionDirectory) TestStatic_GetTuple(Properties.IStorage storage); (string RootResultsDirectoryAbsoluteUri, string C_ResizeContentDirectory, string D_FacesContentDirectory, string E_DistanceCollectionDirectory) TestStatic_GetTuple(Properties.IStorage storage);
static (string RootResultsDirectoryAbsoluteUri, string C_ResizeContentDirectory, string D_FacesContentDirectory, string E_DistanceCollectionDirectory) GetTuple(Properties.IStorage storage) => new(new Uri(storage.RootResultsDirectory).AbsoluteUri, Path.Combine(storage.ResizeRootDirectory, "()"), Path.Combine(storage.FaceRootDirectory, "()"), Path.Combine(storage.DistanceResultRootDirectory, "[]")); static (string RootResultsDirectoryAbsoluteUri, string C_ResizeContentDirectory, string D_FacesContentDirectory, string E_DistanceCollectionDirectory) GetTuple(Properties.IStorage storage) => new(new Uri(storage.RootResultsDirectory).AbsoluteUri, Path.Combine(storage.ResizeRootDirectory, "()"), Path.Combine(storage.FaceRootDirectory, "()"), Path.Combine(storage.DistanceResultRootDirectory, "[]"));

View File

@ -130,7 +130,7 @@ internal abstract class Person
{ {
string fileName = IPerson.GetFileFullName(storage, person); string fileName = IPerson.GetFileFullName(storage, person);
string json = JsonSerializer.Serialize(person, new JsonSerializerOptions { WriteIndented = true }); string json = JsonSerializer.Serialize(person, new JsonSerializerOptions { WriteIndented = true });
_ = IStorage.WriteAllText(fileName, json, compareBeforeWrite: true); _ = IStorage.WriteAllText(fileName, json, updateDateWhenMatches: true, compareBeforeWrite: true);
} }
private static List<Models.Person> GetPeopleFromText(Properties.IStorage storage, string localKnownPeopleFile) private static List<Models.Person> GetPeopleFromText(Properties.IStorage storage, string localKnownPeopleFile)
@ -189,7 +189,7 @@ internal abstract class Person
_ = Directory.CreateDirectory(directory); _ = Directory.CreateDirectory(directory);
string? rootDirectoryParent = Path.GetDirectoryName(storage.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(storage.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new Exception($"{nameof(rootDirectoryParent)} is null!"); throw new ArgumentNullException(nameof(rootDirectoryParent));
if (!Directory.Exists(rootDirectoryParent)) if (!Directory.Exists(rootDirectoryParent))
localKnownPeopleFile = string.Empty; localKnownPeopleFile = string.Empty;
else else

View File

@ -10,10 +10,33 @@ internal abstract class PersonBirthday
// ... // ...
internal static string GetFormat() => "yyyy-MM-dd_HH"; internal static string GetFormat() => "yyyy-MM-dd_HH";
internal static Models.PersonBirthday GetNextBirthDate(Properties.IStorage storage) => throw new Exception(storage.ToString()); // Person.GetNextBirthDate(storage); internal static string[] GetSegments(string personKey) => personKey.Split('\t');
internal static string GetFormatted(Models.PersonBirthday personBirthday) => personBirthday.Value.ToString(GetFormat()); internal static string GetFormatted(Models.PersonBirthday personBirthday) => personBirthday.Value.ToString(GetFormat());
internal static string GetFileName(Models.PersonBirthday personBirthday) => $"{personBirthday.Value.ToString(GetFormat())}.json"; internal static string GetFileName(Models.PersonBirthday personBirthday) => $"{personBirthday.Value.ToString(GetFormat())}.json";
internal static bool DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday personBirthday) => File.Exists(GetFileFullName(storage, personBirthday)); internal static bool DoesBirthDateExits(Properties.IStorage storage, Models.PersonBirthday personBirthday) => File.Exists(GetFileFullName(storage, personBirthday));
internal static Models.PersonBirthday GetNextBirthDate(Properties.IStorage storage) => throw new Exception(storage.ToString()); // Person.GetNextBirthDate(storage);
internal static string GetFileFullName(Properties.IStorage storage, Models.PersonBirthday personBirthday) => Path.Combine(storage.PeopleRootDirectory, "{}", GetFileName(personBirthday)); internal static string GetFileFullName(Properties.IStorage storage, Models.PersonBirthday personBirthday) => Path.Combine(storage.PeopleRootDirectory, "{}", GetFileName(personBirthday));
internal static DateTime? Get(string personKey) => DateTime.TryParseExact(personKey, GetFormat(), CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTime) ? dateTime : null; internal static DateTime? GetDateTime(string personKey) => DateTime.TryParseExact(personKey, GetFormat(), CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTime) ? dateTime : null;
internal static Models.PersonBirthday? GetPersonBirthday(string personKey)
{
Models.PersonBirthday? result;
string[] segments = GetSegments(personKey);
DateTime? dateTime = GetDateTime(segments[0]);
if (dateTime is null)
result = null;
else
result = new(dateTime.Value);
return result;
}
internal static TimeSpan? GetTimeSpan(DateTime minimumDateTime, bool? isWrongYear, Models.PersonBirthday personBirthday)
{
TimeSpan? timeSpan;
if (isWrongYear is null || isWrongYear.Value || personBirthday.Value.Year < 1900)
timeSpan = null;
else
timeSpan = new(minimumDateTime.Ticks - personBirthday.Value.Ticks);
return timeSpan;
}
} }

View File

@ -5,7 +5,7 @@ internal abstract class Storage
// ... // ...
internal static bool WriteAllText(string path, string contents, bool compareBeforeWrite) internal static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite)
{ {
bool result; bool result;
string text; string text;
@ -18,9 +18,24 @@ internal abstract class Storage
else else
text = File.ReadAllText(path); text = File.ReadAllText(path);
result = text != contents; result = text != contents;
if (!result && updateDateWhenMatches)
File.SetLastWriteTime(path, DateTime.Now);
} }
if (result) if (result)
{
if (path.Contains("()"))
File.WriteAllText(path, contents); File.WriteAllText(path, contents);
else if (path.Contains("{}") && !path.EndsWith(".json"))
File.WriteAllText(path, contents);
else if (path.Contains("[]") && !path.EndsWith(".json"))
File.WriteAllText(path, contents);
else if (path.Contains("{}") && path.EndsWith(".json") && contents[0] == '{')
File.WriteAllText(path, contents);
else if (path.Contains("[]") && path.EndsWith(".json") && contents[0] == '[')
File.WriteAllText(path, contents);
else
File.WriteAllText(path, contents);
}
return result; return result;
} }

View File

@ -24,7 +24,8 @@ public class Configuration
[Display(Name = "Mixed Year Relative Paths"), Required] public string[] MixedYearRelativePaths { get; set; } [Display(Name = "Mixed Year Relative Paths"), Required] public string[] MixedYearRelativePaths { get; set; }
[Display(Name = "Model Directory"), Required] public string ModelDirectory { get; set; } [Display(Name = "Model Directory"), Required] public string ModelDirectory { get; set; }
[Display(Name = "Model Name"), Required] public string ModelName { get; set; } [Display(Name = "Model Name"), Required] public string ModelName { get; set; }
[Display(Name = "Num Jitters"), Required] public int? NumJitters { get; set; } [Display(Name = "Number Jitters"), Required] public int? NumberOfJitters { get; set; }
[Display(Name = "Number of Times To Up Sample"), Required] public int? NumberOfTimesToUpsample { get; set; }
[Display(Name = "Output Extension"), Required] public string OutputExtension { get; set; } [Display(Name = "Output Extension"), Required] public string OutputExtension { get; set; }
[Display(Name = "Output Quality"), Required] public int? OutputQuality { get; set; } [Display(Name = "Output Quality"), Required] public int? OutputQuality { get; set; }
[Display(Name = "Output Resolutions"), Required] public string[] OutputResolutions { get; set; } [Display(Name = "Output Resolutions"), Required] public string[] OutputResolutions { get; set; }
@ -68,7 +69,8 @@ public class Configuration
MixedYearRelativePaths = Array.Empty<string>(); MixedYearRelativePaths = Array.Empty<string>();
ModelDirectory = string.Empty; ModelDirectory = string.Empty;
ModelName = string.Empty; ModelName = string.Empty;
NumJitters = null; NumberOfJitters = null;
NumberOfTimesToUpsample = null;
OutputExtension = string.Empty; OutputExtension = string.Empty;
OutputQuality = null; OutputQuality = null;
OutputResolutions = Array.Empty<string>(); OutputResolutions = Array.Empty<string>();

View File

@ -24,7 +24,8 @@ public class Configuration
protected readonly string[] _MixedYearRelativePaths; protected readonly string[] _MixedYearRelativePaths;
protected readonly string _ModelDirectory; protected readonly string _ModelDirectory;
protected readonly string _ModelName; protected readonly string _ModelName;
protected readonly int? _NumJitters; protected readonly int? _NumberOfJitters;
protected readonly int? _NumberOfTimesToUpsample;
protected readonly string _OutputExtension; protected readonly string _OutputExtension;
protected readonly int? _OutputQuality; protected readonly int? _OutputQuality;
protected readonly string[] _OutputResolutions; protected readonly string[] _OutputResolutions;
@ -65,7 +66,8 @@ public class Configuration
public string[] MixedYearRelativePaths => _MixedYearRelativePaths; public string[] MixedYearRelativePaths => _MixedYearRelativePaths;
public string ModelDirectory => _ModelDirectory; public string ModelDirectory => _ModelDirectory;
public string ModelName => _ModelName; public string ModelName => _ModelName;
public int? NumJitters => _NumJitters; public int? NumberOfJitters => _NumberOfJitters;
public int? NumberOfTimesToUpsample => _NumberOfTimesToUpsample;
public string OutputExtension => _OutputExtension; public string OutputExtension => _OutputExtension;
public int? OutputQuality => _OutputQuality; public int? OutputQuality => _OutputQuality;
public string[] OutputResolutions => _OutputResolutions; public string[] OutputResolutions => _OutputResolutions;
@ -90,7 +92,7 @@ public class Configuration
public string[] ValidResolutions => _ValidResolutions; public string[] ValidResolutions => _ValidResolutions;
[JsonConstructor] [JsonConstructor]
public Configuration(bool? checkJsonForDistanceResults, int? crossDirectoryMaxItemsInDistanceCollection, int? distanceFactor, bool? forceMetadataLastWriteTimeToCreationTime, bool? forceResizeLastWriteTimeToCreationTime, string[] ignoreExtensions, string[] ignoreRelativePaths, string[] juliePhares, string[] loadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions, bool? loadOrCreateThenSaveIndex, int? locationConfidenceFactor, int? mappedMaxIndex, int? maxItemsInDistanceCollection, string[] mixedYearRelativePaths, string modelDirectory, string modelName, int? numJitters, string outputExtension, int? outputQuality, string[] outputResolutions, bool? overrideForFaceImages, bool? overrideForFaceLandmarkImages, bool? overrideForResizeImages, int? paddingLoops, string predictorModelName, bool? propertiesChangedForDistance, bool? propertiesChangedForFaces, bool? propertiesChangedForIndex, bool? propertiesChangedForMetadata, bool? propertiesChangedForResize, Property.Models.Configuration? propertyConfiguration, bool? reverse, string[] saveFaceLandmarkForOutputResolutions, bool? saveFullYearOfRandomFiles, bool? saveResizedSubfiles, string[] saveShortcutsForOutputResolutions, bool? skipSearch, bool? testDistanceResults, string[] validResolutions) public Configuration(bool? checkJsonForDistanceResults, int? crossDirectoryMaxItemsInDistanceCollection, int? distanceFactor, bool? forceMetadataLastWriteTimeToCreationTime, bool? forceResizeLastWriteTimeToCreationTime, string[] ignoreExtensions, string[] ignoreRelativePaths, string[] juliePhares, string[] loadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions, bool? loadOrCreateThenSaveIndex, int? locationConfidenceFactor, int? mappedMaxIndex, int? maxItemsInDistanceCollection, string[] mixedYearRelativePaths, string modelDirectory, string modelName, int? numberOfJitters, int? numberOfTimesToUpsample, string outputExtension, int? outputQuality, string[] outputResolutions, bool? overrideForFaceImages, bool? overrideForFaceLandmarkImages, bool? overrideForResizeImages, int? paddingLoops, string predictorModelName, bool? propertiesChangedForDistance, bool? propertiesChangedForFaces, bool? propertiesChangedForIndex, bool? propertiesChangedForMetadata, bool? propertiesChangedForResize, Property.Models.Configuration? propertyConfiguration, bool? reverse, string[] saveFaceLandmarkForOutputResolutions, bool? saveFullYearOfRandomFiles, bool? saveResizedSubfiles, string[] saveShortcutsForOutputResolutions, bool? skipSearch, bool? testDistanceResults, string[] validResolutions)
{ {
_CheckJsonForDistanceResults = checkJsonForDistanceResults; _CheckJsonForDistanceResults = checkJsonForDistanceResults;
_CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection; _CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
@ -110,7 +112,8 @@ public class Configuration
_MixedYearRelativePaths = mixedYearRelativePaths; _MixedYearRelativePaths = mixedYearRelativePaths;
_ModelDirectory = modelDirectory; _ModelDirectory = modelDirectory;
_ModelName = modelName; _ModelName = modelName;
_NumJitters = numJitters; _NumberOfJitters = numberOfJitters;
_NumberOfTimesToUpsample = numberOfTimesToUpsample;
_OutputExtension = outputExtension; _OutputExtension = outputExtension;
_OutputQuality = outputQuality; _OutputQuality = outputQuality;
_OutputResolutions = outputResolutions; _OutputResolutions = outputResolutions;

View File

@ -76,9 +76,9 @@ public class UnitTestResize
{ {
Property.Models.PropertyLogic result; Property.Models.PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null) if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!"); throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null) if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!"); throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration);
return result; return result;
} }
@ -91,17 +91,17 @@ public class UnitTestResize
string sourceFileName = "Fall 2005 (113).jpg"; string sourceFileName = "Fall 2005 (113).jpg";
string sourceDirectoryName = "=2005.3 Fall"; string sourceDirectoryName = "=2005.3 Fall";
if (_Configuration.ForceMetadataLastWriteTimeToCreationTime is null) if (_Configuration.ForceMetadataLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime)} is null!"); throw new ArgumentNullException(nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime));
if (_Configuration.ForceResizeLastWriteTimeToCreationTime is null) if (_Configuration.ForceResizeLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime)} is null!"); throw new ArgumentNullException(nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime));
if (_Configuration.OutputQuality is null) if (_Configuration.OutputQuality is null)
throw new Exception($"{nameof(_Configuration.OutputQuality)} is null!"); throw new ArgumentNullException(nameof(_Configuration.OutputQuality));
if (_Configuration.OverrideForResizeImages is null) if (_Configuration.OverrideForResizeImages is null)
throw new Exception($"{nameof(_Configuration.OverrideForResizeImages)} is null!"); throw new ArgumentNullException(nameof(_Configuration.OverrideForResizeImages));
if (_Configuration.PropertiesChangedForMetadata is null) if (_Configuration.PropertiesChangedForMetadata is null)
throw new Exception($"{nameof(_Configuration.PropertiesChangedForMetadata)} is null!"); throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForMetadata));
if (_Configuration.PropertiesChangedForResize is null) if (_Configuration.PropertiesChangedForResize is null)
throw new Exception($"{nameof(_Configuration.PropertiesChangedForResize)} is null!"); throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForResize));
int g = 1; int g = 1;
int r = 1; int r = 1;
Model? model = null; Model? model = null;

View File

@ -65,7 +65,8 @@
"MaxItemsInDistanceCollection": 50, "MaxItemsInDistanceCollection": 50,
"ModelDirectory": "C:/GitHub/dlib-models", "ModelDirectory": "C:/GitHub/dlib-models",
"ModelName": "Hog", "ModelName": "Hog",
"NumJitters": 1, "NumberOfJitters": 1,
"NumberOfTimesToUpsample": 1,
"OutputExtension": ".jpg", "OutputExtension": ".jpg",
"OutputQuality": 95, "OutputQuality": 95,
"OverrideForFaceImages": false, "OverrideForFaceImages": false,

View File

@ -65,7 +65,8 @@
"MaxItemsInDistanceCollection": 50, "MaxItemsInDistanceCollection": 50,
"ModelDirectory": "C:/GitHub/dlib-models", "ModelDirectory": "C:/GitHub/dlib-models",
"ModelName": "Hog", "ModelName": "Hog",
"NumJitters": 1, "NumberOfJitters": 1,
"NumberOfTimesToUpsample": 1,
"OutputExtension": ".jpg", "OutputExtension": ".jpg",
"OutputQuality": 95, "OutputQuality": 95,
"OverrideForFaceImages": false, "OverrideForFaceImages": false,

View File

@ -0,0 +1,35 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.TestsWithFaceRecognitionDotNet.Models;
public class AppSettings
{
protected string _Company;
protected string _WorkingDirectoryName;
protected int? _MaxDegreeOfParallelism;
public string Company => _Company;
public string WorkingDirectoryName => _WorkingDirectoryName;
public int? MaxDegreeOfParallelism => _MaxDegreeOfParallelism;
// public AppSettings()
// {
// }
[JsonConstructor]
public AppSettings(string company, string workingDirectoryName, int? maxDegreeOfParallelism)
{
_Company = company;
_WorkingDirectoryName = workingDirectoryName;
_MaxDegreeOfParallelism = maxDegreeOfParallelism;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,26 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
namespace View_by_Distance.TestsWithFaceRecognitionDotNet.Models.Binder;
public class AppSettings
{
[Display(Name = "Company"), Required] public string Company { get; set; }
[Display(Name = "Working Directory Name"), Required] public string WorkingDirectoryName { get; set; }
[Display(Name = "Max Degree Of Parallelism"), Required] public int? MaxDegreeOfParallelism { get; set; }
public AppSettings()
{
Company = string.Empty;
WorkingDirectoryName = string.Empty;
MaxDegreeOfParallelism = -1;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,103 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
namespace View_by_Distance.TestsWithFaceRecognitionDotNet.Models.Binder;
public class Configuration
{
[Display(Name = "Check Json For Distance Results"), Required] public bool? CheckJsonForDistanceResults { get; set; }
[Display(Name = "CrossDirectory Max Items In Distance Collection"), Required] public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; }
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
[Display(Name = "Force Metadata Last Write Time to Creation Time"), Required] public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; }
[Display(Name = "Force Resize Last Write Time to Creation Time"), Required] public bool? ForceResizeLastWriteTimeToCreationTime { get; set; }
[Display(Name = "Ignore Extensions"), Required] public string[] IgnoreExtensions { get; set; }
[Display(Name = "Ignore Relative Paths"), Required] public string[] IgnoreRelativePaths { get; set; }
[Display(Name = "Julie Phares Copy Birthdays"), Required] public string[] JuliePhares { get; set; }
[Display(Name = "Load Or Create Then Save Directory Distance Results"), Required] public string[] LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions { get; set; }
[Display(Name = "Load Or Create Then Save Distance Results"), Required] public string[] LoadOrCreateThenSaveDistanceResultsForOutputResolutions { get; set; }
[Display(Name = "Load Or Create Then Save Image Faces Results"), Required] public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
[Display(Name = "Load Or Create Then Save Index"), Required] public bool? LoadOrCreateThenSaveIndex { get; set; }
[Display(Name = "Location Confidence Factor"), Required] public int? LocationConfidenceFactor { get; set; }
[Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; }
[Display(Name = "Max Items In Distance Collection"), Required] public int? MaxItemsInDistanceCollection { get; set; }
[Display(Name = "Mixed Year Relative Paths"), Required] public string[] MixedYearRelativePaths { get; set; }
[Display(Name = "Model Directory"), Required] public string ModelDirectory { get; set; }
[Display(Name = "Model Name"), Required] public string ModelName { get; set; }
[Display(Name = "Number Jitters"), Required] public int? NumberOfJitters { get; set; }
[Display(Name = "Number of Times To Up Sample"), Required] public int? NumberOfTimesToUpsample { get; set; }
[Display(Name = "Output Extension"), Required] public string OutputExtension { get; set; }
[Display(Name = "Output Quality"), Required] public int? OutputQuality { get; set; }
[Display(Name = "Output Resolutions"), Required] public string[] OutputResolutions { get; set; }
[Display(Name = "Override For Face Images"), Required] public bool? OverrideForFaceImages { get; set; }
[Display(Name = "Override For Face Landmark Images"), Required] public bool? OverrideForFaceLandmarkImages { get; set; }
[Display(Name = "Override For Resize Images"), Required] public bool? OverrideForResizeImages { get; set; }
[Display(Name = "Padding Loops"), Required] public int? PaddingLoops { get; set; }
[Display(Name = "Predictor Model Name"), Required] public string PredictorModelName { get; set; }
[Display(Name = "Properties Changed For Distance"), Required] public bool? PropertiesChangedForDistance { get; set; }
[Display(Name = "Properties Changed For Faces"), Required] public bool? PropertiesChangedForFaces { get; set; }
[Display(Name = "Properties Changed For Index"), Required] public bool? PropertiesChangedForIndex { get; set; }
[Display(Name = "Properties Changed For Metadata"), Required] public bool? PropertiesChangedForMetadata { get; set; }
[Display(Name = "Properties Changed For Resize"), Required] public bool? PropertiesChangedForResize { get; set; }
[Display(Name = "Property Configuration"), Required] public Property.Models.Configuration? PropertyConfiguration { get; set; }
[Display(Name = "Reverse"), Required] public bool? Reverse { get; set; }
[Display(Name = "Save Face Landmark For Output Resolutions"), Required] public string[] SaveFaceLandmarkForOutputResolutions { get; set; }
[Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; }
[Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; }
[Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; }
[Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; }
[Display(Name = "Test Distance Results"), Required] public bool? TestDistanceResults { get; set; }
[Display(Name = "Valid Resolutions"), Required] public string[] ValidResolutions { get; set; }
public Configuration()
{
CheckJsonForDistanceResults = null;
CrossDirectoryMaxItemsInDistanceCollection = null;
DistanceFactor = null;
ForceMetadataLastWriteTimeToCreationTime = null;
ForceResizeLastWriteTimeToCreationTime = null;
IgnoreExtensions = Array.Empty<string>();
IgnoreRelativePaths = Array.Empty<string>();
JuliePhares = Array.Empty<string>();
LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions = Array.Empty<string>();
LoadOrCreateThenSaveDistanceResultsForOutputResolutions = Array.Empty<string>();
LoadOrCreateThenSaveImageFacesResultsForOutputResolutions = Array.Empty<string>();
LoadOrCreateThenSaveIndex = null;
LocationConfidenceFactor = null;
MappedMaxIndex = null;
MaxItemsInDistanceCollection = null;
MixedYearRelativePaths = Array.Empty<string>();
ModelDirectory = string.Empty;
ModelName = string.Empty;
NumberOfJitters = null;
NumberOfTimesToUpsample = null;
OutputExtension = string.Empty;
OutputQuality = null;
OutputResolutions = Array.Empty<string>();
OverrideForFaceImages = null;
OverrideForFaceLandmarkImages = null;
OverrideForResizeImages = null;
PaddingLoops = null;
PredictorModelName = string.Empty;
PropertiesChangedForDistance = null;
PropertiesChangedForFaces = null;
PropertiesChangedForIndex = null;
PropertiesChangedForMetadata = null;
PropertiesChangedForResize = null;
Reverse = null;
SaveFaceLandmarkForOutputResolutions = Array.Empty<string>();
SaveFullYearOfRandomFiles = null;
SaveResizedSubfiles = null;
SaveShortcutsForOutputResolutions = Array.Empty<string>();
SkipSearch = null;
TestDistanceResults = null;
ValidResolutions = Array.Empty<string>();
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,151 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.TestsWithFaceRecognitionDotNet.Models;
public class Configuration
{
protected readonly bool? _CheckJsonForDistanceResults;
protected readonly int? _CrossDirectoryMaxItemsInDistanceCollection;
protected readonly int? _DistanceFactor;
protected readonly bool? _ForceMetadataLastWriteTimeToCreationTime;
protected readonly bool? _ForceResizeLastWriteTimeToCreationTime;
protected readonly string[] _IgnoreExtensions;
protected readonly string[] _IgnoreRelativePaths;
protected readonly string[] _JuliePhares;
protected readonly string[] _LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions;
protected readonly string[] _LoadOrCreateThenSaveDistanceResultsForOutputResolutions;
protected readonly string[] _LoadOrCreateThenSaveImageFacesResultsForOutputResolutions;
protected readonly bool? _LoadOrCreateThenSaveIndex;
protected readonly int? _LocationConfidenceFactor;
protected readonly int? _MappedMaxIndex;
protected readonly int? _MaxItemsInDistanceCollection;
protected readonly string[] _MixedYearRelativePaths;
protected readonly string _ModelDirectory;
protected readonly string _ModelName;
protected readonly int? _NumberOfJitters;
protected readonly int? _NumberOfTimesToUpsample;
protected readonly string _OutputExtension;
protected readonly int? _OutputQuality;
protected readonly string[] _OutputResolutions;
protected readonly bool? _OverrideForFaceImages;
protected readonly bool? _OverrideForFaceLandmarkImages;
protected readonly bool? _OverrideForResizeImages;
protected readonly int? _PaddingLoops;
protected readonly string _PredictorModelName;
protected readonly bool? _PropertiesChangedForDistance;
protected readonly bool? _PropertiesChangedForFaces;
protected readonly bool? _PropertiesChangedForIndex;
protected readonly bool? _PropertiesChangedForMetadata;
protected readonly bool? _PropertiesChangedForResize;
protected Property.Models.Configuration? _PropertyConfiguration;
protected readonly bool? _Reverse;
protected readonly string[] _SaveFaceLandmarkForOutputResolutions;
protected readonly bool? _SaveFullYearOfRandomFiles;
protected readonly bool? _SaveResizedSubfiles;
protected readonly string[] _SaveShortcutsForOutputResolutions;
protected readonly bool? _SkipSearch;
protected readonly bool? _TestDistanceResults;
protected readonly string[] _ValidResolutions;
public bool? CheckJsonForDistanceResults => _CheckJsonForDistanceResults;
public int? CrossDirectoryMaxItemsInDistanceCollection => _CrossDirectoryMaxItemsInDistanceCollection;
public int? DistanceFactor => _DistanceFactor;
public bool? ForceMetadataLastWriteTimeToCreationTime => _ForceMetadataLastWriteTimeToCreationTime;
public bool? ForceResizeLastWriteTimeToCreationTime => _ForceResizeLastWriteTimeToCreationTime;
public string[] IgnoreExtensions => _IgnoreExtensions;
public string[] IgnoreRelativePaths => _IgnoreRelativePaths;
public string[] JuliePhares => _JuliePhares;
public string[] LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions => _LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions;
public string[] LoadOrCreateThenSaveDistanceResultsForOutputResolutions => _LoadOrCreateThenSaveDistanceResultsForOutputResolutions;
public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions => _LoadOrCreateThenSaveImageFacesResultsForOutputResolutions;
public bool? LoadOrCreateThenSaveIndex => _LoadOrCreateThenSaveIndex;
public int? LocationConfidenceFactor => _LocationConfidenceFactor;
public int? MappedMaxIndex => _MappedMaxIndex;
public int? MaxItemsInDistanceCollection => _MaxItemsInDistanceCollection;
public string[] MixedYearRelativePaths => _MixedYearRelativePaths;
public string ModelDirectory => _ModelDirectory;
public string ModelName => _ModelName;
public int? NumberOfJitters => _NumberOfJitters;
public int? NumberOfTimesToUpsample => _NumberOfTimesToUpsample;
public string OutputExtension => _OutputExtension;
public int? OutputQuality => _OutputQuality;
public string[] OutputResolutions => _OutputResolutions;
public bool? OverrideForFaceImages => _OverrideForFaceImages;
public bool? OverrideForFaceLandmarkImages => _OverrideForFaceLandmarkImages;
public bool? OverrideForResizeImages => _OverrideForResizeImages;
public int? PaddingLoops => _PaddingLoops;
public string PredictorModelName => _PredictorModelName;
public bool? PropertiesChangedForDistance => _PropertiesChangedForDistance;
public bool? PropertiesChangedForFaces => _PropertiesChangedForFaces;
public bool? PropertiesChangedForIndex => _PropertiesChangedForIndex;
public bool? PropertiesChangedForMetadata => _PropertiesChangedForMetadata;
public bool? PropertiesChangedForResize => _PropertiesChangedForResize;
public Property.Models.Configuration? PropertyConfiguration => _PropertyConfiguration;
public bool? Reverse => _Reverse;
public string[] SaveFaceLandmarkForOutputResolutions => _SaveFaceLandmarkForOutputResolutions;
public bool? SaveFullYearOfRandomFiles => _SaveFullYearOfRandomFiles;
public bool? SaveResizedSubfiles => _SaveResizedSubfiles;
public string[] SaveShortcutsForOutputResolutions => _SaveShortcutsForOutputResolutions;
public bool? SkipSearch => _SkipSearch;
public bool? TestDistanceResults => _TestDistanceResults;
public string[] ValidResolutions => _ValidResolutions;
[JsonConstructor]
public Configuration(bool? checkJsonForDistanceResults, int? crossDirectoryMaxItemsInDistanceCollection, int? distanceFactor, bool? forceMetadataLastWriteTimeToCreationTime, bool? forceResizeLastWriteTimeToCreationTime, string[] ignoreExtensions, string[] ignoreRelativePaths, string[] juliePhares, string[] loadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions, bool? loadOrCreateThenSaveIndex, int? locationConfidenceFactor, int? mappedMaxIndex, int? maxItemsInDistanceCollection, string[] mixedYearRelativePaths, string modelDirectory, string modelName, int? numberOfJitters, int? numberOfTimesToUpsample, string outputExtension, int? outputQuality, string[] outputResolutions, bool? overrideForFaceImages, bool? overrideForFaceLandmarkImages, bool? overrideForResizeImages, int? paddingLoops, string predictorModelName, bool? propertiesChangedForDistance, bool? propertiesChangedForFaces, bool? propertiesChangedForIndex, bool? propertiesChangedForMetadata, bool? propertiesChangedForResize, Property.Models.Configuration? propertyConfiguration, bool? reverse, string[] saveFaceLandmarkForOutputResolutions, bool? saveFullYearOfRandomFiles, bool? saveResizedSubfiles, string[] saveShortcutsForOutputResolutions, bool? skipSearch, bool? testDistanceResults, string[] validResolutions)
{
_CheckJsonForDistanceResults = checkJsonForDistanceResults;
_CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
_DistanceFactor = distanceFactor;
_ForceMetadataLastWriteTimeToCreationTime = forceMetadataLastWriteTimeToCreationTime;
_ForceResizeLastWriteTimeToCreationTime = forceResizeLastWriteTimeToCreationTime;
_IgnoreExtensions = ignoreExtensions;
_IgnoreRelativePaths = ignoreRelativePaths;
_JuliePhares = juliePhares;
_LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions = loadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions;
_LoadOrCreateThenSaveDistanceResultsForOutputResolutions = loadOrCreateThenSaveDistanceResultsForOutputResolutions;
_LoadOrCreateThenSaveImageFacesResultsForOutputResolutions = loadOrCreateThenSaveImageFacesResultsForOutputResolutions;
_LoadOrCreateThenSaveIndex = loadOrCreateThenSaveIndex;
_LocationConfidenceFactor = locationConfidenceFactor;
_MappedMaxIndex = mappedMaxIndex;
_MaxItemsInDistanceCollection = maxItemsInDistanceCollection;
_MixedYearRelativePaths = mixedYearRelativePaths;
_ModelDirectory = modelDirectory;
_ModelName = modelName;
_NumberOfJitters = numberOfJitters;
_NumberOfTimesToUpsample = numberOfTimesToUpsample;
_OutputExtension = outputExtension;
_OutputQuality = outputQuality;
_OutputResolutions = outputResolutions;
_OverrideForFaceImages = overrideForFaceImages;
_OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages;
_OverrideForResizeImages = overrideForResizeImages;
_PaddingLoops = paddingLoops;
_PredictorModelName = predictorModelName;
_PropertiesChangedForDistance = propertiesChangedForDistance;
_PropertiesChangedForFaces = propertiesChangedForFaces;
_PropertiesChangedForIndex = propertiesChangedForIndex;
_PropertiesChangedForMetadata = propertiesChangedForMetadata;
_PropertiesChangedForResize = propertiesChangedForResize;
_PropertyConfiguration = propertyConfiguration;
_Reverse = reverse;
_SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions;
_SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles;
_SaveResizedSubfiles = saveResizedSubfiles;
_SaveShortcutsForOutputResolutions = saveShortcutsForOutputResolutions;
_SkipSearch = skipSearch;
_TestDistanceResults = testDistanceResults;
_ValidResolutions = validResolutions;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
public void Set(Property.Models.Configuration configuration) => _PropertyConfiguration = configuration;
public void Update() => _PropertyConfiguration?.Update();
}

View File

@ -0,0 +1,40 @@
using Microsoft.Extensions.Configuration;
using System.Text.Json;
namespace View_by_Distance.TestsWithFaceRecognitionDotNet.Models.Stateless;
public abstract class AppSettings
{
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
{
Models.AppSettings? result;
Binder.AppSettings appSettings = configurationRoot.Get<Binder.AppSettings>();
string json = JsonSerializer.Serialize(appSettings, new JsonSerializerOptions() { WriteIndented = true });
result = JsonSerializer.Deserialize<Models.AppSettings>(json);
if (result is null)
throw new Exception(json);
if (string.IsNullOrEmpty(result.Company))
throw new Exception(json);
string jsonThis = result.ToString();
if (jsonThis != json)
{
int? check = null;
int min = new int[] { json.Length, jsonThis.Length }.Min();
for (int i = 0; i < min; i++)
{
if (json[i] == jsonThis[i])
continue;
check = i;
break;
}
if (check is null)
throw new Exception();
string a = json[..check.Value].Split(',')[^1];
string b = json[check.Value..].Split(',')[0];
throw new Exception($"{a}{b}");
}
return result;
}
}

View File

@ -0,0 +1,44 @@
using Microsoft.Extensions.Configuration;
using Phares.Shared;
using System.Text.Json;
namespace View_by_Distance.TestsWithFaceRecognitionDotNet.Models.Stateless;
public abstract class Configuration
{
public static Models.Configuration Get(IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, string workingDirectory, Property.Models.Configuration propertyConfiguration)
{
Models.Configuration? result;
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
string section = string.Concat(environmentName, ":", nameof(Binder.Configuration));
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
Binder.Configuration configuration = configurationSection.Get<Binder.Configuration>();
string json = JsonSerializer.Serialize(configuration, new JsonSerializerOptions() { WriteIndented = true });
result = JsonSerializer.Deserialize<Models.Configuration>(json);
if (result is null)
throw new Exception(json);
string jsonThis = result.ToString();
result.Set(propertyConfiguration);
result.Update();
if (jsonThis != json)
{
int? check = null;
int min = new int[] { json.Length, jsonThis.Length }.Min();
for (int i = 0; i < min; i++)
{
if (json[i] == jsonThis[i])
continue;
check = i;
break;
}
if (check is null)
throw new Exception();
string a = json[..check.Value].Split(',')[^1];
string b = json[check.Value..].Split(',')[0];
throw new Exception($"{a}{b}");
}
return result;
}
}

View File

@ -0,0 +1,53 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
</PropertyGroup>
<PropertyGroup Condition="'$(IsWindows)'=='true'">
<DefineConstants>Windows</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsOSX)'=='true'">
<DefineConstants>OSX</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinux)'=='true'">
<DefineConstants>Linux</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.3.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
<ProjectReference Include="..\Property\Property.csproj" />
<ProjectReference Include="..\Metadata\Metadata.csproj" />
<ProjectReference Include="..\Resize\Resize.csproj" />
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />
<ProjectReference Include="..\Property-Compare\Property-Compare.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="appsettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,71 @@
using Microsoft.Extensions.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Phares.Shared;
using Serilog;
using System.Diagnostics;
using System.Reflection;
using View_by_Distance.Shared.Models.Stateless.Methods;
using View_by_Distance.TestsWithFaceRecognitionDotNet.Models;
namespace View_by_Distance.TestsWithFaceRecognitionDotNet;
[TestClass]
public class UnitTestExample
{
private readonly ILogger _Logger;
private readonly AppSettings _AppSettings;
private readonly string _WorkingDirectory;
private readonly Configuration _Configuration;
private readonly IsEnvironment _IsEnvironment;
private readonly IConfigurationRoot _ConfigurationRoot;
private readonly Property.Models.Configuration _PropertyConfiguration;
public UnitTestExample()
{
ILogger logger;
AppSettings appSettings;
string workingDirectory;
Configuration configuration;
IsEnvironment isEnvironment;
IConfigurationRoot configurationRoot;
LoggerConfiguration loggerConfiguration = new();
Property.Models.Configuration propertyConfiguration;
Assembly assembly = Assembly.GetExecutingAssembly();
bool debuggerWasAttachedAtLineZero = Debugger.IsAttached || assembly.Location.Contains(@"\bin\Debug");
isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero);
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile(isEnvironment.AppSettingsFileName);
configurationRoot = configurationBuilder.Build();
appSettings = Models.Stateless.AppSettings.Get(configurationRoot);
workingDirectory = IWorkingDirectory.GetWorkingDirectory(assembly.GetName().Name, appSettings.WorkingDirectoryName);
Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory);
_ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, configurationRoot);
Log.Logger = loggerConfiguration.CreateLogger();
logger = Log.ForContext<UnitTestExample>();
propertyConfiguration = Property.Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory);
configuration = Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory, propertyConfiguration);
logger.Information("Complete");
_Logger = logger;
_AppSettings = appSettings;
_Configuration = configuration;
_IsEnvironment = isEnvironment;
_WorkingDirectory = workingDirectory;
_ConfigurationRoot = configurationRoot;
_PropertyConfiguration = propertyConfiguration;
}
[TestMethod]
public void TestMethodNull()
{
Assert.IsFalse(_Logger is null);
Assert.IsFalse(_AppSettings is null);
Assert.IsFalse(_Configuration is null);
Assert.IsFalse(_IsEnvironment is null);
Assert.IsFalse(_WorkingDirectory is null);
Assert.IsFalse(_ConfigurationRoot is null);
Assert.IsFalse(_PropertyConfiguration is null);
}
}

View File

@ -0,0 +1,253 @@
using Microsoft.Extensions.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Phares.Shared;
using Serilog;
using System.Diagnostics;
using System.Drawing.Imaging;
using System.Reflection;
using View_by_Distance.FaceRecognitionDotNet;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Resize.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless;
using View_by_Distance.Shared.Models.Stateless.Methods;
using View_by_Distance.TestsWithFaceRecognitionDotNet.Models;
namespace View_by_Distance.TestsWithFaceRecognitionDotNet;
[TestClass]
public class UnitTestFace
{
private readonly ILogger _Logger;
private readonly AppSettings _AppSettings;
private readonly string _WorkingDirectory;
private readonly Configuration _Configuration;
private readonly IsEnvironment _IsEnvironment;
private readonly IConfigurationRoot _ConfigurationRoot;
private readonly Property.Models.Configuration _PropertyConfiguration;
public UnitTestFace()
{
ILogger logger;
AppSettings appSettings;
string workingDirectory;
Configuration configuration;
IsEnvironment isEnvironment;
IConfigurationRoot configurationRoot;
LoggerConfiguration loggerConfiguration = new();
Property.Models.Configuration propertyConfiguration;
Assembly assembly = Assembly.GetExecutingAssembly();
bool debuggerWasAttachedAtLineZero = Debugger.IsAttached || assembly.Location.Contains(@"\bin\Debug");
isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero);
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile(isEnvironment.AppSettingsFileName);
configurationRoot = configurationBuilder.Build();
appSettings = Models.Stateless.AppSettings.Get(configurationRoot);
workingDirectory = IWorkingDirectory.GetWorkingDirectory(assembly.GetName().Name, appSettings.WorkingDirectoryName);
Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory);
_ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, configurationRoot);
Log.Logger = loggerConfiguration.CreateLogger();
logger = Log.ForContext<UnitTestFace>();
propertyConfiguration = Property.Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory);
configuration = Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory, propertyConfiguration);
logger.Information("Complete");
_Logger = logger;
_AppSettings = appSettings;
_Configuration = configuration;
_IsEnvironment = isEnvironment;
_WorkingDirectory = workingDirectory;
_ConfigurationRoot = configurationRoot;
_PropertyConfiguration = propertyConfiguration;
}
[TestMethod]
public void TestMethodNull()
{
Assert.IsFalse(_Logger is null);
Assert.IsFalse(_AppSettings is null);
Assert.IsFalse(_Configuration is null);
Assert.IsFalse(_IsEnvironment is null);
Assert.IsFalse(_WorkingDirectory is null);
Assert.IsFalse(_ConfigurationRoot is null);
Assert.IsFalse(_PropertyConfiguration is null);
}
private Property.Models.PropertyLogic GetPropertyLogic()
{
Property.Models.PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null)
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration?.PropertyConfiguration is null)
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration);
return result;
}
private static (Model model, PredictorModel predictorModel, ModelParameter modelParameter) GetModel(Configuration configuration)
{
(Model, PredictorModel, ModelParameter) result;
Array array;
Model? model = null;
PredictorModel? predictorModel = null;
array = Enum.GetValues(typeof(Model));
foreach (Model check in array)
{
if (configuration.ModelName.Contains(check.ToString()))
{
model = check;
break;
}
}
if (model is null)
throw new Exception("Destination directory must have Model name!");
model = model.Value;
array = Enum.GetValues(typeof(PredictorModel));
foreach (PredictorModel check in array)
{
if (configuration.PredictorModelName.Contains(check.ToString()))
{
predictorModel = check;
break;
}
}
if (predictorModel is null)
throw new Exception("Destination directory must have Predictor Model name!");
predictorModel = predictorModel.Value;
ModelParameter modelParameter = new()
{
CnnFaceDetectorModel = File.ReadAllBytes(Path.Combine(configuration.ModelDirectory, "mmod_human_face_detector.dat")),
FaceRecognitionModel = File.ReadAllBytes(Path.Combine(configuration.ModelDirectory, "dlib_face_recognition_resnet_model_v1.dat")),
PosePredictor5FaceLandmarksModel = File.ReadAllBytes(Path.Combine(configuration.ModelDirectory, "shape_predictor_5_face_landmarks.dat")),
PosePredictor68FaceLandmarksModel = File.ReadAllBytes(Path.Combine(configuration.ModelDirectory, "shape_predictor_68_face_landmarks.dat"))
};
result = new(model.Value, predictorModel.Value, modelParameter);
return result;
}
[TestMethod]
public void TestGetPixelPercentage()
{
double pixelPercentage;
pixelPercentage = Location.GetPixelPercentage(1, 1, 10, 10, 100, 100);
Assert.IsTrue(pixelPercentage == 0.0505d);
pixelPercentage = Location.GetPixelPercentage(50, 50, 60, 60, 100, 100);
Assert.IsTrue(pixelPercentage == 0.5555d);
}
[TestMethod]
public void TestMethodFace()
{
string sourceFileName = "IMG_0067.jpg";
string sourceDirectoryName = "Mackenzie Prom 2017";
// string sourceFileName = "Fall 2005 (113).jpg";
// string sourceDirectoryName = "=2005.3 Fall";
// string sourceFileName = "DSCN0534.jpg";
// string sourceDirectoryName = "Logan Swimming Lessons 2013";
// string sourceFileName = "DSC_4913.jpg";
// string sourceDirectoryName = "Disneyland 2014";
// string sourceFileName = "Logan Michael Sept 08 (193).jpg";
// string sourceDirectoryName = "=2008.2 Summer Logan Michael";
if (_Configuration.ForceMetadataLastWriteTimeToCreationTime is null)
throw new ArgumentNullException(nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime));
if (_Configuration.ForceResizeLastWriteTimeToCreationTime is null)
throw new ArgumentNullException(nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime));
if (_Configuration.OutputQuality is null)
throw new ArgumentNullException(nameof(_Configuration.OutputQuality));
if (_Configuration.OverrideForResizeImages is null)
throw new ArgumentNullException(nameof(_Configuration.OverrideForResizeImages));
if (_Configuration.PropertiesChangedForMetadata is null)
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForMetadata));
if (_Configuration.PropertiesChangedForResize is null)
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForResize));
if (_Configuration.NumberOfJitters is null)
throw new ArgumentNullException(nameof(_Configuration.NumberOfJitters));
if (_Configuration.NumberOfTimesToUpsample is null)
throw new ArgumentNullException(nameof(_Configuration.NumberOfTimesToUpsample));
int g = 1;
int r = 1;
string original = "Original";
List<string> parseExceptions = new();
Property.Models.A_Property? property = null;
Property.Models.PropertyHolder propertyHolder;
Dictionary<string, int[]> imageResizeKeyValuePairs;
List<Tuple<string, DateTime>> subFileTuples = new();
List<KeyValuePair<string, string>> metadataCollection;
int length = _PropertyConfiguration.RootDirectory.Length;
string outputResolution = _Configuration.OutputResolutions[0];
Property.Models.PropertyLogic propertyLogic = GetPropertyLogic();
(Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(_Configuration);
string sourceDirectory = Path.Combine(_PropertyConfiguration.RootDirectory, sourceDirectoryName);
_Logger.Information(_Configuration.ModelDirectory);
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_PropertyConfiguration, nameof(Property.Models.A_Property), "{}");
B_Metadata metadata = new(_Configuration.ForceMetadataLastWriteTimeToCreationTime.Value, _Configuration.PropertiesChangedForMetadata.Value);
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters) = C_Resize.GetTuple(_Configuration.OutputExtension, _Configuration.OutputQuality.Value);
C_Resize resize = new(_Configuration.ForceResizeLastWriteTimeToCreationTime.Value, _Configuration.OverrideForResizeImages.Value, _Configuration.PropertiesChangedForResize.Value, _Configuration.ValidResolutions, imageCodecInfo, encoderParameters);
propertyLogic.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(_PropertyConfiguration,
model,
predictorModel,
sourceDirectory,
nameof(Property.Models.A_Property),
outputResolution,
includeResizeGroup: false,
includeModel: false,
includePredictorModel: false,
contentDescription: string.Empty,
singletonDescription: "Properties for each image",
collectionDescription: string.Empty));
metadata.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(_PropertyConfiguration,
model,
predictorModel,
sourceDirectory,
nameof(B_Metadata),
outputResolution,
includeResizeGroup: false,
includeModel: false,
includePredictorModel: false,
contentDescription: string.Empty,
singletonDescription: "Metadata as key value pairs",
collectionDescription: string.Empty));
resize.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(_PropertyConfiguration,
model,
predictorModel,
sourceDirectory,
nameof(C_Resize),
outputResolution,
includeResizeGroup: true,
includeModel: false,
includePredictorModel: false,
contentDescription: "Resized image",
singletonDescription: "Resize dimensions for each resolution",
collectionDescription: string.Empty));
string sourceDirectoryFile = ".json";
FileInfo fileInfo = new(Path.Combine(sourceDirectory, sourceFileName));
string relativePath = Property.Models.Stateless.IPath.GetRelativePath(fileInfo.FullName, length);
sourceDirectory = Path.Combine(aPropertySingletonDirectory, sourceDirectoryName);
propertyHolder = new(g, sourceDirectory, sourceDirectoryFile, relativePath, r, fileInfo, property, false, false, null, null);
Assert.IsNotNull(propertyHolder.ImageFileInfo);
property = propertyLogic.GetProperty(propertyLogic.AngleBracketCollection[0], propertyHolder, subFileTuples, parseExceptions);
(int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, propertyHolder);
imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, propertyHolder);
FileInfo resizedFileInfo = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(propertyHolder.ImageFileInfo.FullName)));
propertyHolder.SetResizedFileInfo(resizedFileInfo);
resize.SaveResizedSubfile(outputResolution, subFileTuples, propertyHolder, original, property, imageResizeKeyValuePairs);
resizedFileInfo.Refresh();
Assert.IsNotNull(propertyHolder.ResizedFileInfo);
Image? image = FaceRecognition.LoadImageFile(propertyHolder.ResizedFileInfo.FullName);
Assert.IsNotNull(image);
FaceRecognition faceRecognition = FaceRecognition.Create(modelParameter);
List<Location> locations = faceRecognition.FaceLocations(model, image, _Configuration.NumberOfTimesToUpsample.Value, sortByPixelPercentage: true);
Assert.IsTrue(locations.Count == 2);
List<(FacePart, FacePoint[])[]> faceLandmarks = faceRecognition.GetFaceLandmarkCollection(image, _Configuration.NumberOfTimesToUpsample.Value, locations, predictorModel, model);
Assert.IsTrue(faceLandmarks.Count == 2);
faceLandmarks = faceRecognition.GetFaceLandmarkCollection(image, _Configuration.NumberOfTimesToUpsample.Value, faceLocations: null, predictorModel, model);
Assert.IsTrue(faceLandmarks.Count == 2);
List<FaceRecognitionDotNet.FaceEncoding> faceEncodings = faceRecognition.FaceEncodings(image, _Configuration.NumberOfTimesToUpsample.Value, knownFaceLocation: null, _Configuration.NumberOfJitters.Value, predictorModel, model);
Assert.IsTrue(faceEncodings.Count == 2);
List<double> faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncodings[0]);
Assert.IsTrue(faceDistances.Count == 2);
Assert.IsNotNull(sourceFileName);
}
}

View File

@ -0,0 +1,526 @@
{
"Company": "Mike Phares",
"Linux": {},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Log4netProvider": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"MaxDegreeOfParallelism": 6,
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "Debug",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "%workingDirectory% - Log/log-.txt",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}",
"rollingInterval": "Hour"
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithThreadId"
],
"Properties": {
"Application": "Sample"
}
},
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"CheckJsonForDistanceResults": true,
"CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-07-27",
"DistanceFactor": 8,
"FileNameDirectorySeparator": ".Z.",
"ForceMetadataLastWriteTimeToCreationTime": true,
"ForcePropertyLastWriteTimeToCreationTime": false,
"ForceResizeLastWriteTimeToCreationTime": true,
"LoadOrCreateThenSaveIndex": false,
"LocationConfidenceFactor": 2,
"MappedMaxIndex": 1034720,
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
"MaxItemsInDistanceCollection": 50,
"ModelDirectory": "C:/GitHub/dlib-models",
"ModelName": "Hog",
"NumberOfJitters": 1,
"NumberOfTimesToUpsample": 1,
"OutputExtension": ".jpg",
"OutputQuality": 95,
"OverrideForFaceImages": false,
"OverrideForFaceLandmarkImages": false,
"OverrideForResizeImages": false,
"PaddingLoops": 5,
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PredictorModelName": "Large",
"PopulatePropertyId": true,
"PropertiesChangedForDistance": false,
"PropertiesChangedForFaces": false,
"PropertiesChangedForIndex": false,
"PropertiesChangedForMetadata": false,
"PropertiesChangedForProperty": false,
"PropertiesChangedForResize": false,
"Reverse": false,
"xRootDirectory": "C:/Tmp/phares/Pictures",
"RootDirectory": "F:/Tmp/Phares/Compare/Images 2022-07-27 - f642c5669a1d89d598a2efd70da9dc7129d02c15 - III",
"SaveFullYearOfRandomFiles": true,
"SaveResizedSubFiles": true,
"SkipSearch": false,
"TestDistanceResults": true,
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",
".GIF"
],
"JuliePhares": [
"1500-01-16_00",
"1500-01-19_00",
"1500-01-20_00",
"1500-01-21_00",
"1500-01-25_00",
"1500-01-26_00",
"1500-01-27_00",
"1500-02-13_00",
"1500-02-17_00",
"1500-02-24_00",
"1500-02-25_00",
"1500-04-03_00",
"1500-04-06_00",
"1500-04-19_00",
"1500-05-03_00",
"1500-05-18_00",
"1500-05-28_00",
"1500-06-16_00",
"1500-06-26_00",
"1500-06-27_00",
"1500-07-07_00",
"1500-07-16_00",
"1720-09-30_05",
"1500-07-26_00",
"1500-08-03_00",
"1500-08-23_00",
"1500-08-24_00",
"1500-09-16_00",
"1500-09-21_00",
"1500-09-28_00",
"1500-10-14_00",
"1500-11-07_00",
"1500-11-09_00",
"1720-09-28_20",
"1501-01-08_00",
"1501-01-12_00",
"1501-01-13_00",
"1501-01-30_00",
"1501-03-09_00",
"1501-03-14_00",
"1501-03-22_00",
"1501-04-07_00",
"1501-04-10_00",
"1501-04-19_00",
"1501-05-06_00",
"1956-09-19_00",
"2012-09-17_00",
"1998-05-21_00",
"1960-03-01_00",
"1976-03-08_00",
"2007-09-07_00",
"2000-04-07_00",
"1980-01-17_00",
"1958-01-30_00",
"1976-01-05_00",
"1982-05-02_00"
],
"LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions": [
"1920 x 1080"
],
"LoadOrCreateThenSaveDistanceResultsForOutputResolutions": [
"1920 x 1080"
],
"LoadOrCreateThenSaveImageFacesResultsForOutputResolutions": [
"1920 x 1080"
],
"OutputResolutions": [
"176 x 176",
"256 x 256",
"353 x 353",
"1024 x 768",
"1920 x 1080"
],
"PropertyContentCollectionFiles": [],
"SaveFaceLandmarkForOutputResolutions": [
"176 x 176",
"256 x 256"
],
"SaveShortcutsForOutputResolutions": [
"1920 x 1080"
],
"ValidImageFormatExtensions": [
".bmp",
".BMP",
".gif",
".GIF",
".jpeg",
".JPEG",
".jpg",
".JPG",
".png",
".PNG",
".tiff",
".TIFF"
],
"ValidMetadataExtensions": [
".3gp",
".3GP",
".amr",
".AMR",
".avi",
".AVI",
".bmp",
".BMP",
".gif",
".GIF",
".ico",
".ICO",
".jpeg",
".JPEG",
".jpg",
".JPG",
".m4v",
".M4V",
".mov",
".MOV",
".mp4",
".MP4",
".mta",
".MTA",
".png",
".PNG",
".tiff",
".TIFF"
],
"ValidResolutions": [
"176 x 176",
"256 x 256",
"353 x 353",
"1024 x 768",
"1280 x 720",
"1280 x 800",
"1376 x 768",
"1600 x 1200",
"1920 x 1080",
"2256 x 1496",
"3840 x 2160",
"7680 x 4320"
],
"VerifyToSeason": [
". 2000",
". 2001",
". 2002",
". 2003",
". 2004",
". 2005",
". 2006",
". 2007",
". 2008",
". 2009",
". 2010",
". 2011",
". 2012",
". 2013",
". 2014",
". 2015",
". 2016",
". 2017",
". 2018",
". 2019",
". 2020",
". 2021",
". 2022",
". 2023",
". 2024",
". 2025",
". 2026",
". 2027",
". 2028",
". 2029",
"=2000.0 Winter",
"=2002.1 Spring",
"=2002.4 Winter",
"=2003.0 Winter",
"=2003.1 Spring",
"=2003.3 Fall",
"=2003.4 Winter",
"=2004.0 Winter",
"=2005.1 Spring",
"=2005.2 Summer",
"=2005.3 Fall",
"=2005.4 Winter",
"=2006.0 Winter",
"=2006.1 Spring",
"=2006.3 Fall",
"=2007.0 Winter",
"=2007.2 Summer Logan Michael",
"=2007.2 Summer",
"=2007.3 Fall Logan Michael",
"=2007.4 Winter Logan Michael",
"=2008.0 Winter Logan Michael",
"=2008.1 Spring Logan Michael",
"=2008.2 Summer Logan Michael",
"=2008.2 Summer",
"=2008.3 Fall Logan Michael",
"=2009.0 Winter Logan Michael",
"=2009.0 Winter",
"=2009.1 Spring Logan Michael",
"=2009.1 Spring",
"=2009.2 Summer Logan Michael",
"=2009.2 Summer",
"=2009.3 Fall Logan Michael",
"=2009.3 Fall",
"=2009.4 Winter Logan Michael",
"=2009.4 Winter",
"=2010.0 Winter Logan Michael",
"=2010.0 Winter",
"=2010.1 Spring Logan Michael",
"=2010.1 Spring",
"=2010.2 Summer",
"=2010.3 Fall Logan Michael",
"=2010.3 Fall",
"=2010.4 Winter",
"=2011.0 Winter",
"=2011.1 Spring",
"=2011.2 Summer",
"=2011.3 Fall",
"=2011.4 Winter",
"=2012.0 Winter Chelsea 2012",
"=2012.0 Winter Chelsea",
"=2012.0 Winter",
"=2012.1 Spring Chelsea",
"=2012.1 Spring",
"=2012.2 Summer Chelsea",
"=2012.2 Summer",
"=2012.3 Fall Chelsea",
"=2012.3 Fall",
"=2012.4 Winter Chelsea",
"=2012.4 Winter",
"=2013.0 Winter Chelsea 2013",
"=2013.0 Winter Chelsea",
"=2013.0 Winter",
"=2013.1 Spring",
"=2013.2 Summer Chelsea",
"=2013.2 Summer",
"=2013.3 Fall Chelsea",
"=2013.3 Fall",
"=2013.4 Winter",
"=2014.0 Winter",
"=2014.1 Spring",
"=2014.2 Summer",
"=2014.3 Fall",
"=2014.4 Winter",
"=2015.0 Winter",
"=2015.1 Spring",
"=2015.2 Summer",
"=2015.3 Fall",
"=2015.4 Winter",
"=2016.0 Winter",
"=2016.1 Spring",
"=2016.2 Summer",
"=2016.3 Fall",
"=2016.4 Winter",
"=2017.1 Spring",
"=2017.2 Summer",
"=2017.3 Fall",
"=2017.4 Winter",
"=2018.0 Winter",
"=2018.1 Spring",
"=2018.3 Fall",
"=2018.4 Winter",
"=2019.0 Winter",
"=2019.1 Spring",
"=2019.2 Summer",
"=2019.3 Fall",
"=2019.4 Winter",
"=2020.0 Winter",
"=2020.1 Spring",
"=2020.2 Summer",
"=2020.3 Fall",
"=2020.4 Winter",
"=2021.1 Spring",
"=2021.2 Summer",
"=2021.3 Fall",
"=2021.4 Winter",
"=2022.0 Winter",
"=2022.1 Spring",
"Anthem 2015",
"April 2010",
"April 2013",
"December 2006",
"December 2010",
"Fall 2005",
"Fall 2015",
"Fall 2016",
"Fall 2017",
"Fall 2018",
"Fall 2019",
"Fall 2020",
"Fall 2021",
"February 2010",
"January 2015",
"July 2010",
"June 2010",
"Kids 2005",
"March 2013",
"May 2010",
"May 2011",
"May 2013",
"October 2005",
"October 2014",
"Spring 2013",
"Spring 2014",
"Spring 2016",
"Spring 2018",
"Spring 2019",
"Spring 2020",
"Summer 2011",
"Summer 2012",
"Summer 2013",
"Summer 2014",
"Summer 2015",
"Summer 2016",
"Summer 2017",
"Summer 2018",
"Summer 2020",
"Summer 2021",
"Winter 2015",
"Winter 2016",
"Winter 2017",
"Winter 2018",
"Winter 2019-2020",
"Winter 2020",
"zzz =2005.0 Winter Tracy Pictures",
"zzz =2005.1 Spring Tracy Pictures",
"zzz =2005.2 Summer Tracy Pictures",
"zzz =2005.3 Fall Tracy Pictures",
"zzz =2005.4 Winter Tracy Pictures",
"zzz =2006.1 Spring Tracy Pictures",
"zzz =2007.0 Winter Tracy Pictures",
"zzz =2007.2 Summer Tracy Pictures",
"zzz =2008.0 Winter Tracy Pictures",
"zzz =2008.2 Summer Tracy Pictures",
"zzz =2009.0 Winter Tracy Pictures",
"zzz =2009.2 Summer Tracy Pictures",
"zzz =2009.3 Fall Tracy Pictures",
"zzz =2009.4 Winter Tracy Pictures",
"zzz =2010.0 Winter Tracy Pictures",
"zzz =2010.1 Spring Tracy Pictures",
"zzz =2010.2 Summer Tracy Pictures",
"zzz =2010.3 Fall Tracy Pictures",
"zzz =2011.0 Winter Tracy Pictures",
"zzz =2011.1 Spring Tracy Pictures",
"zzz =2011.2 Summer Tracy Pictures",
"zzz =2011.3 Fall Tracy Pictures",
"zzz =2011.4 Winter Tracy Pictures",
"zzz =2012.0 Winter Tracy Pictures",
"zzz =2012.1 Spring Tracy Pictures",
"zzz =2012.2 Summer Tracy Pictures",
"zzz =2012.3 Fall Tracy Pictures",
"zzz =2012.4 Winter Tracy Pictures",
"zzz =2013.0 Winter Tracy Pictures",
"zzz =2013.1 Spring Tracy Pictures",
"zzz =2013.2 Summer Tracy Pictures",
"zzz =2013.3 Fall Tracy Pictures",
"zzz =2013.4 Winter Tracy Pictures",
"zzz =2014.0 Winter Tracy Pictures",
"zzz =2014.1 Spring Tracy Pictures",
"zzz =2014.2 Summer Tracy Pictures",
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures"
],
"MixedYearRelativePaths": [
"Edited",
"Phares Slides",
"Rex Memorial",
"Scanned Grandma's Quilt",
"Scanned Pictures Of Kids",
"Scanned Prints",
"Slide in Name Order Originals (622)",
"Slides Pictures"
],
"IgnoreRelativePaths": [
"3757 W Whitman 2017",
"501 Playful Meadows 2006",
"501 Playful Meadows 2007",
"501 Playful Meadows 2008",
"501 Playful Meadows 2009",
"501 Playful Meadows 2010",
"501 Playful Meadows 2013",
"501 Playful Meadows 2015",
"6309 Evesham 2003",
"6309 Evesham 2004",
"Crystal's Wedding 2003",
"Danny's Wedding 2009",
"Door images 2019",
"Family Pictures 2006",
"Family Pictures 2007",
"Family Pictures 2011",
"Family Pictures 2013",
"GrandPrix 2004",
"Kids School Pictures 2004",
"Kristy 2002",
"Kristy Parents Wedding 2005",
"Logan Ultrasound 2007",
"Mandy's Dogs 2008",
"Motorcycles 2010",
"Motorcycles 2013",
"Motorcycles 2014",
"Phares Slides",
"Portrait Innovations April 2008",
"Portrait Innovations December 2007",
"Portrait Innovations June 2008",
"Portrait Innovations March 2012",
"The guys house 2000",
"Tracy Pictures 2005",
"Tracy Pictures 2006",
"Tracy Pictures 2007",
"Tracy Pictures 2008",
"Tracy Pictures 2009",
"Tracy Pictures 2010",
"Tracy Pictures 2011",
"Tracy Pictures 2012",
"Tracy Pictures 2013 Jan-July",
"Tracy Pictures 2013 July- Dec",
"Tracy Pictures 2014",
"Tracy Pictures 2015",
"Tracy Took The Kids 2006",
"Tracy's Bday 2012",
"Tracy's Wedding 2002",
"Trip to Colorado 10 2002",
"Trip to Colorado June 2002",
"Tub 2002",
"Vericruz 2011"
]
}
}
}

View File

@ -0,0 +1,525 @@
{
"Company": "Mike Phares",
"Linux": {},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Log4netProvider": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"MaxDegreeOfParallelism": 12,
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "Debug",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "%workingDirectory% - Log/log-.txt",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}",
"rollingInterval": "Hour"
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithThreadId"
],
"Properties": {
"Application": "Sample"
}
},
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"CheckJsonForDistanceResults": true,
"CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-07-27",
"DistanceFactor": 8,
"FileNameDirectorySeparator": ".Z.",
"ForceMetadataLastWriteTimeToCreationTime": false,
"ForcePropertyLastWriteTimeToCreationTime": false,
"ForceResizeLastWriteTimeToCreationTime": false,
"LoadOrCreateThenSaveIndex": false,
"LocationConfidenceFactor": 2,
"MappedMaxIndex": 1034720,
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
"MaxItemsInDistanceCollection": 50,
"ModelDirectory": "C:/GitHub/dlib-models",
"ModelName": "Hog",
"NumberOfJitters": 1,
"NumberOfTimesToUpsample": 1,
"OutputExtension": ".jpg",
"OutputQuality": 95,
"OverrideForFaceImages": false,
"OverrideForFaceLandmarkImages": false,
"OverrideForResizeImages": false,
"PaddingLoops": 5,
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PopulatePropertyId": true,
"PredictorModelName": "Large",
"PropertiesChangedForDistance": false,
"PropertiesChangedForFaces": false,
"PropertiesChangedForIndex": false,
"PropertiesChangedForMetadata": false,
"PropertiesChangedForProperty": false,
"PropertiesChangedForResize": false,
"Reverse": false,
"RootDirectory": "D:/Images",
"SaveFullYearOfRandomFiles": true,
"SaveResizedSubFiles": true,
"SkipSearch": false,
"TestDistanceResults": true,
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",
".GIF"
],
"JuliePhares": [
"1500-01-16_00",
"1500-01-19_00",
"1500-01-20_00",
"1500-01-21_00",
"1500-01-25_00",
"1500-01-26_00",
"1500-01-27_00",
"1500-02-13_00",
"1500-02-17_00",
"1500-02-24_00",
"1500-02-25_00",
"1500-04-03_00",
"1500-04-06_00",
"1500-04-19_00",
"1500-05-03_00",
"1500-05-18_00",
"1500-05-28_00",
"1500-06-16_00",
"1500-06-26_00",
"1500-06-27_00",
"1500-07-07_00",
"1500-07-16_00",
"1720-09-30_05",
"1500-07-26_00",
"1500-08-03_00",
"1500-08-23_00",
"1500-08-24_00",
"1500-09-16_00",
"1500-09-21_00",
"1500-09-28_00",
"1500-10-14_00",
"1500-11-07_00",
"1500-11-09_00",
"1720-09-28_20",
"1501-01-08_00",
"1501-01-12_00",
"1501-01-13_00",
"1501-01-30_00",
"1501-03-09_00",
"1501-03-14_00",
"1501-03-22_00",
"1501-04-07_00",
"1501-04-10_00",
"1501-04-19_00",
"1501-05-06_00",
"1956-09-19_00",
"2012-09-17_00",
"1998-05-21_00",
"1960-03-01_00",
"1976-03-08_00",
"2007-09-07_00",
"2000-04-07_00",
"1980-01-17_00",
"1958-01-30_00",
"1976-01-05_00",
"1982-05-02_00"
],
"LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions": [
"1920 x 1080"
],
"LoadOrCreateThenSaveDistanceResultsForOutputResolutions": [
"1920 x 1080"
],
"LoadOrCreateThenSaveImageFacesResultsForOutputResolutions": [
"1920 x 1080"
],
"OutputResolutions": [
"176 x 176",
"256 x 256",
"353 x 353",
"1024 x 768",
"1920 x 1080"
],
"PropertyContentCollectionFiles": [],
"SaveFaceLandmarkForOutputResolutions": [
"176 x 176",
"256 x 256"
],
"SaveShortcutsForOutputResolutions": [
"1920 x 1080"
],
"ValidImageFormatExtensions": [
".bmp",
".BMP",
".gif",
".GIF",
".jpeg",
".JPEG",
".jpg",
".JPG",
".png",
".PNG",
".tiff",
".TIFF"
],
"ValidMetadataExtensions": [
".3gp",
".3GP",
".amr",
".AMR",
".avi",
".AVI",
".bmp",
".BMP",
".gif",
".GIF",
".ico",
".ICO",
".jpeg",
".JPEG",
".jpg",
".JPG",
".m4v",
".M4V",
".mov",
".MOV",
".mp4",
".MP4",
".mta",
".MTA",
".png",
".PNG",
".tiff",
".TIFF"
],
"ValidResolutions": [
"176 x 176",
"256 x 256",
"353 x 353",
"1024 x 768",
"1280 x 720",
"1280 x 800",
"1376 x 768",
"1600 x 1200",
"1920 x 1080",
"2256 x 1496",
"3840 x 2160",
"7680 x 4320"
],
"VerifyToSeason": [
". 2000",
". 2001",
". 2002",
". 2003",
". 2004",
". 2005",
". 2006",
". 2007",
". 2008",
". 2009",
". 2010",
". 2011",
". 2012",
". 2013",
". 2014",
". 2015",
". 2016",
". 2017",
". 2018",
". 2019",
". 2020",
". 2021",
". 2022",
". 2023",
". 2024",
". 2025",
". 2026",
". 2027",
". 2028",
". 2029",
"=2000.0 Winter",
"=2002.1 Spring",
"=2002.4 Winter",
"=2003.0 Winter",
"=2003.1 Spring",
"=2003.3 Fall",
"=2003.4 Winter",
"=2004.0 Winter",
"=2005.1 Spring",
"=2005.2 Summer",
"=2005.3 Fall",
"=2005.4 Winter",
"=2006.0 Winter",
"=2006.1 Spring",
"=2006.3 Fall",
"=2007.0 Winter",
"=2007.2 Summer Logan Michael",
"=2007.2 Summer",
"=2007.3 Fall Logan Michael",
"=2007.4 Winter Logan Michael",
"=2008.0 Winter Logan Michael",
"=2008.1 Spring Logan Michael",
"=2008.2 Summer Logan Michael",
"=2008.2 Summer",
"=2008.3 Fall Logan Michael",
"=2009.0 Winter Logan Michael",
"=2009.0 Winter",
"=2009.1 Spring Logan Michael",
"=2009.1 Spring",
"=2009.2 Summer Logan Michael",
"=2009.2 Summer",
"=2009.3 Fall Logan Michael",
"=2009.3 Fall",
"=2009.4 Winter Logan Michael",
"=2009.4 Winter",
"=2010.0 Winter Logan Michael",
"=2010.0 Winter",
"=2010.1 Spring Logan Michael",
"=2010.1 Spring",
"=2010.2 Summer",
"=2010.3 Fall Logan Michael",
"=2010.3 Fall",
"=2010.4 Winter",
"=2011.0 Winter",
"=2011.1 Spring",
"=2011.2 Summer",
"=2011.3 Fall",
"=2011.4 Winter",
"=2012.0 Winter Chelsea 2012",
"=2012.0 Winter Chelsea",
"=2012.0 Winter",
"=2012.1 Spring Chelsea",
"=2012.1 Spring",
"=2012.2 Summer Chelsea",
"=2012.2 Summer",
"=2012.3 Fall Chelsea",
"=2012.3 Fall",
"=2012.4 Winter Chelsea",
"=2012.4 Winter",
"=2013.0 Winter Chelsea 2013",
"=2013.0 Winter Chelsea",
"=2013.0 Winter",
"=2013.1 Spring",
"=2013.2 Summer Chelsea",
"=2013.2 Summer",
"=2013.3 Fall Chelsea",
"=2013.3 Fall",
"=2013.4 Winter",
"=2014.0 Winter",
"=2014.1 Spring",
"=2014.2 Summer",
"=2014.3 Fall",
"=2014.4 Winter",
"=2015.0 Winter",
"=2015.1 Spring",
"=2015.2 Summer",
"=2015.3 Fall",
"=2015.4 Winter",
"=2016.0 Winter",
"=2016.1 Spring",
"=2016.2 Summer",
"=2016.3 Fall",
"=2016.4 Winter",
"=2017.1 Spring",
"=2017.2 Summer",
"=2017.3 Fall",
"=2017.4 Winter",
"=2018.0 Winter",
"=2018.1 Spring",
"=2018.3 Fall",
"=2018.4 Winter",
"=2019.0 Winter",
"=2019.1 Spring",
"=2019.2 Summer",
"=2019.3 Fall",
"=2019.4 Winter",
"=2020.0 Winter",
"=2020.1 Spring",
"=2020.2 Summer",
"=2020.3 Fall",
"=2020.4 Winter",
"=2021.1 Spring",
"=2021.2 Summer",
"=2021.3 Fall",
"=2021.4 Winter",
"=2022.0 Winter",
"=2022.1 Spring",
"Anthem 2015",
"April 2010",
"April 2013",
"December 2006",
"December 2010",
"Fall 2005",
"Fall 2015",
"Fall 2016",
"Fall 2017",
"Fall 2018",
"Fall 2019",
"Fall 2020",
"Fall 2021",
"February 2010",
"January 2015",
"July 2010",
"June 2010",
"Kids 2005",
"March 2013",
"May 2010",
"May 2011",
"May 2013",
"October 2005",
"October 2014",
"Spring 2013",
"Spring 2014",
"Spring 2016",
"Spring 2018",
"Spring 2019",
"Spring 2020",
"Summer 2011",
"Summer 2012",
"Summer 2013",
"Summer 2014",
"Summer 2015",
"Summer 2016",
"Summer 2017",
"Summer 2018",
"Summer 2020",
"Summer 2021",
"Winter 2015",
"Winter 2016",
"Winter 2017",
"Winter 2018",
"Winter 2019-2020",
"Winter 2020",
"zzz =2005.0 Winter Tracy Pictures",
"zzz =2005.1 Spring Tracy Pictures",
"zzz =2005.2 Summer Tracy Pictures",
"zzz =2005.3 Fall Tracy Pictures",
"zzz =2005.4 Winter Tracy Pictures",
"zzz =2006.1 Spring Tracy Pictures",
"zzz =2007.0 Winter Tracy Pictures",
"zzz =2007.2 Summer Tracy Pictures",
"zzz =2008.0 Winter Tracy Pictures",
"zzz =2008.2 Summer Tracy Pictures",
"zzz =2009.0 Winter Tracy Pictures",
"zzz =2009.2 Summer Tracy Pictures",
"zzz =2009.3 Fall Tracy Pictures",
"zzz =2009.4 Winter Tracy Pictures",
"zzz =2010.0 Winter Tracy Pictures",
"zzz =2010.1 Spring Tracy Pictures",
"zzz =2010.2 Summer Tracy Pictures",
"zzz =2010.3 Fall Tracy Pictures",
"zzz =2011.0 Winter Tracy Pictures",
"zzz =2011.1 Spring Tracy Pictures",
"zzz =2011.2 Summer Tracy Pictures",
"zzz =2011.3 Fall Tracy Pictures",
"zzz =2011.4 Winter Tracy Pictures",
"zzz =2012.0 Winter Tracy Pictures",
"zzz =2012.1 Spring Tracy Pictures",
"zzz =2012.2 Summer Tracy Pictures",
"zzz =2012.3 Fall Tracy Pictures",
"zzz =2012.4 Winter Tracy Pictures",
"zzz =2013.0 Winter Tracy Pictures",
"zzz =2013.1 Spring Tracy Pictures",
"zzz =2013.2 Summer Tracy Pictures",
"zzz =2013.3 Fall Tracy Pictures",
"zzz =2013.4 Winter Tracy Pictures",
"zzz =2014.0 Winter Tracy Pictures",
"zzz =2014.1 Spring Tracy Pictures",
"zzz =2014.2 Summer Tracy Pictures",
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures"
],
"MixedYearRelativePaths": [
"Edited",
"Phares Slides",
"Rex Memorial",
"Scanned Grandma's Quilt",
"Scanned Pictures Of Kids",
"Scanned Prints",
"Slide in Name Order Originals (622)",
"Slides Pictures"
],
"IgnoreRelativePaths": [
"3757 W Whitman 2017",
"501 Playful Meadows 2006",
"501 Playful Meadows 2007",
"501 Playful Meadows 2008",
"501 Playful Meadows 2009",
"501 Playful Meadows 2010",
"501 Playful Meadows 2013",
"501 Playful Meadows 2015",
"6309 Evesham 2003",
"6309 Evesham 2004",
"Crystal's Wedding 2003",
"Danny's Wedding 2009",
"Door images 2019",
"Family Pictures 2006",
"Family Pictures 2007",
"Family Pictures 2011",
"Family Pictures 2013",
"GrandPrix 2004",
"Kids School Pictures 2004",
"Kristy 2002",
"Kristy Parents Wedding 2005",
"Logan Ultrasound 2007",
"Mandy's Dogs 2008",
"Motorcycles 2010",
"Motorcycles 2013",
"Motorcycles 2014",
"Phares Slides",
"Portrait Innovations April 2008",
"Portrait Innovations December 2007",
"Portrait Innovations June 2008",
"Portrait Innovations March 2012",
"The guys house 2000",
"Tracy Pictures 2005",
"Tracy Pictures 2006",
"Tracy Pictures 2007",
"Tracy Pictures 2008",
"Tracy Pictures 2009",
"Tracy Pictures 2010",
"Tracy Pictures 2011",
"Tracy Pictures 2012",
"Tracy Pictures 2013 Jan-July",
"Tracy Pictures 2013 July- Dec",
"Tracy Pictures 2014",
"Tracy Pictures 2015",
"Tracy Took The Kids 2006",
"Tracy's Bday 2012",
"Tracy's Wedding 2002",
"Trip to Colorado 10 2002",
"Trip to Colorado June 2002",
"Tub 2002",
"Vericruz 2011"
]
}
}
}

View File

@ -27,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceRecognitionDotNet", "FaceRecognitionDotNet\FaceRecognitionDotNet.csproj", "{FAD03DA9-E8B1-4BBE-B8D0-2ADD2F2BC758}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceRecognitionDotNet", "FaceRecognitionDotNet\FaceRecognitionDotNet.csproj", "{FAD03DA9-E8B1-4BBE-B8D0-2ADD2F2BC758}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestsWithFaceRecognitionDotNet", "TestsWithFaceRecognitionDotNet\TestsWithFaceRecognitionDotNet.csproj", "{A67D73C7-A1A1-4443-B681-776339CFA08A}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -84,5 +86,9 @@ Global
{FAD03DA9-E8B1-4BBE-B8D0-2ADD2F2BC758}.Debug|Any CPU.Build.0 = Debug|Any CPU {FAD03DA9-E8B1-4BBE-B8D0-2ADD2F2BC758}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FAD03DA9-E8B1-4BBE-B8D0-2ADD2F2BC758}.Release|Any CPU.ActiveCfg = Release|Any CPU {FAD03DA9-E8B1-4BBE-B8D0-2ADD2F2BC758}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FAD03DA9-E8B1-4BBE-B8D0-2ADD2F2BC758}.Release|Any CPU.Build.0 = Release|Any CPU {FAD03DA9-E8B1-4BBE-B8D0-2ADD2F2BC758}.Release|Any CPU.Build.0 = Release|Any CPU
{A67D73C7-A1A1-4443-B681-776339CFA08A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A67D73C7-A1A1-4443-B681-776339CFA08A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A67D73C7-A1A1-4443-B681-776339CFA08A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A67D73C7-A1A1-4443-B681-776339CFA08A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal