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": [
"appsettings",
"Argb",
"ASPNETCORE",
"Barrick",
"bcdfghjklmnpqrstvwxyz",
"Beichler",
"Bohdi",
"cref",
"CUDA",
"Dlib",
"Exif",
"Getα",
"Greyscale",
"mmod",
"nosj",
"paramref",
"Phares",
"resnet",
"Serilog",
"Subfile",
"Subfiles",
"Unmanaged",
"Upsample",
"Vericruz"
],
"cSpell.enabled": true
"cSpell.enabled": true,
"files.exclude": {
"**/.git": false
},
}

View File

@ -35,7 +35,7 @@ public class Compare
string[] segments;
_AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(appSettings.MaxDegreeOfParallelism)} is null!");
throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism));
_RenameFindReplace = new();
_RenameBFindReplace = new();
_RenameCFindReplace = new();
@ -56,7 +56,7 @@ public class Compare
Model? model = null;
PredictorModel? predictorModel = 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)
{
segments = spelling.Split('|');
@ -372,14 +372,14 @@ public class Compare
private static void Verify(Models.Configuration configuration)
{
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)
{
long result;
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;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks;
@ -390,9 +390,9 @@ public class Compare
{
PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!");
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
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);
string fromPrepareForOld = "34720-637858334555170379.tsv";
string fromPrepareForOldFile = Path.Combine(_Configuration.PropertyConfiguration.RootDirectory, fromPrepareForOld);
@ -432,11 +432,11 @@ public class Compare
private void SaveDiffFilesOrSaveLogAndMoveFiles(Property.Models.Configuration configuration)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!");
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
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), "{}");
_Log.Information(aPropertySingletonDirectory);
_Log.Information("to");
@ -510,7 +510,7 @@ public class Compare
private void ChangeExtensionFromDeleteToJson(string aPropertySingletonDirectory)
{
if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!");
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
string searchPattern = "*.delete";
long ticks = DateTime.Now.Ticks;
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)
{
if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
bool result = false;
string corrected;
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)
{
if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
List<string> results = new();
string check;
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)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
int z = 0;
string fileName;
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)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
int stay = 0;
string fileName;
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)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
int stay = 0;
A_Property? property;
ConsoleKey? consoleKey = null;

View File

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

View File

@ -8,23 +8,23 @@ internal sealed class FaceRecognitionModelV1
#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 };
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 };
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,
IList<Image> batchImages,
IList<IEnumerable<FullObjectDetection>> batchFaces,
int numJitters)
int numberOfJitters)
{
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");
@ -60,7 +60,7 @@ internal sealed class FaceRecognitionModelV1
for (int i = 0, count = batchImages.Count; i < count; i++)
faceDescriptors.Add(new List<Matrix<double>>());
if (numJitters <= 1)
if (numberOfJitters <= 1)
{
// extract descriptors and convert from float vectors to double vectors
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 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 (MatrixOp? mat = DlibDotNet.Dlib.Mat(tmp2))
{
@ -113,10 +113,10 @@ internal sealed class FaceRecognitionModelV1
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();
for (int i = 0; i < numJitters; ++i)
for (int i = 0; i < numberOfJitters; ++i)
crops.Add(DlibDotNet.Dlib.JitterImage(img, _Rand));
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? column = (int?)info.GetValue(nameof(_Encoding.Columns), typeof(int));
if (row is null)
throw new Exception($"{nameof(row)} is null");
throw new ArgumentNullException(nameof(row));
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);
}

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>
/// <returns>An enumerable collection of array of found face locations.</returns>
/// <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)
throw new ArgumentNullException(nameof(images));
@ -167,7 +167,7 @@ public sealed class FaceRecognition : DisposableObject
for (int index = 0; index < rawDetectionsBatched.Length; index++)
{
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)
face.Dispose();
results.Add(locations);
@ -358,7 +358,7 @@ public sealed class FaceRecognition : DisposableObject
/// </summary>
/// <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="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="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>
@ -366,11 +366,7 @@ public sealed class FaceRecognition : DisposableObject
/// <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="NotSupportedException"><see cref="PredictorModel.Custom"/> is not supported.</exception>
public List<FaceEncoding> FaceEncodings(Image image,
IEnumerable<Location>? knownFaceLocation = null,
int numJitters = 1,
PredictorModel predictorModel = PredictorModel.Small,
Model model = Model.Hog)
public List<FaceEncoding> FaceEncodings(Image image, int numberOfTimesToUpsample, IEnumerable<Location>? knownFaceLocation, int numberOfJitters, PredictorModel predictorModel, Model model)
{
if (image == null)
throw new ArgumentNullException(nameof(image));
@ -383,12 +379,12 @@ public sealed class FaceRecognition : DisposableObject
image.ThrowIfDisposed();
ThrowIfDisposed();
IEnumerable<FullObjectDetection>? rawLandmarks = RawFaceLandmarks(image, knownFaceLocation, predictorModel, model);
List<FullObjectDetection> rawLandmarks = RawFaceLandmarks(image, numberOfTimesToUpsample, knownFaceLocation, predictorModel, model);
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();
results.Add(ret);
}
@ -396,6 +392,14 @@ public sealed class FaceRecognition : DisposableObject
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>
/// Returns an enumerable collection of dictionary of face parts locations (eyes, nose, etc) for each face in the image.
/// </summary>
@ -408,89 +412,53 @@ public sealed class FaceRecognition : DisposableObject
/// <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="NotSupportedException">The custom face landmark detector is not ready.</exception>
public List<Dictionary<FacePart, IEnumerable<FacePoint>>> FaceLandmark(Image faceImage,
IEnumerable<Location>? faceLocations = null,
PredictorModel predictorModel = PredictorModel.Large,
Model model = Model.Hog)
public List<(FacePart, FacePoint[])[]> GetFaceLandmarkCollection(Image faceImage, int numberOfTimesToUpsample, IEnumerable<Location>? faceLocations, PredictorModel predictorModel, Model model)
{
List<(FacePart, FacePoint[])[]> results = new();
if (faceImage == null)
throw new ArgumentNullException(nameof(faceImage));
if (faceLocations != null && !faceLocations.Any())
throw new InvalidOperationException($"{nameof(faceLocations)} contains no elements.");
faceImage.ThrowIfDisposed();
ThrowIfDisposed();
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)
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
collection = new();
switch (predictorModel)
{
case PredictorModel.Custom:
throw new NotImplementedException();
case PredictorModel.Large:
results.AddRange(landmarkTuples.Select(landmarkTuple => new Dictionary<FacePart, IEnumerable<FacePoint>>
{
{ FacePart.Chin, Enumerable.Range(0,17).Select(i => landmarkTuple[i]).ToArray() },
{ FacePart.LeftEyebrow, Enumerable.Range(17,5).Select(i => landmarkTuple[i]).ToArray() },
{ FacePart.RightEyebrow, Enumerable.Range(22,5).Select(i => landmarkTuple[i]).ToArray() },
{ FacePart.NoseBridge, Enumerable.Range(27,5).Select(i => landmarkTuple[i]).ToArray() },
{ FacePart.NoseTip, Enumerable.Range(31,5).Select(i => landmarkTuple[i]).ToArray() },
{ FacePart.LeftEye, Enumerable.Range(36,6).Select(i => landmarkTuple[i]).ToArray() },
{ FacePart.RightEye, Enumerable.Range(42,6).Select(i => landmarkTuple[i]).ToArray() },
{ FacePart.TopLip, Enumerable.Range(48,7).Select(i => landmarkTuple[i])
.Concat( new [] { landmarkTuple[64] })
.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] }) }
}));
if (facePoints.Length != 68)
continue;
collection.Add(new(FacePart.Chin, facePoints.Skip(0).Take(17).ToArray()));
collection.Add(new(FacePart.LeftEyebrow, facePoints.Skip(17).Take(5).ToArray()));
collection.Add(new(FacePart.RightEyebrow, facePoints.Skip(22).Take(5).ToArray()));
collection.Add(new(FacePart.NoseBridge, facePoints.Skip(27).Take(5).ToArray()));
collection.Add(new(FacePart.NoseTip, facePoints.Skip(31).Take(5).ToArray()));
collection.Add(new(FacePart.LeftEye, facePoints.Skip(36).Take(6).ToArray()));
collection.Add(new(FacePart.RightEye, facePoints.Skip(42).Take(6).ToArray()));
collection.Add(new(FacePart.TopLip, Join(facePoints.Skip(48).Take(7), facePoints.Skip(60).Take(5))));
collection.Add(new(FacePart.BottomLip, Join(facePoints.Skip(55).Take(5), facePoints.Skip(65).Take(3))));
break;
case PredictorModel.Small:
results.AddRange(landmarkTuples.Select(landmarkTuple => new Dictionary<FacePart, IEnumerable<FacePoint>>
{
{ FacePart.NoseTip, Enumerable.Range(4,1).Select(i => landmarkTuple[i]).ToArray() },
{ FacePart.LeftEye, Enumerable.Range(2,2).Select(i => landmarkTuple[i]).ToArray() },
{ FacePart.RightEye, Enumerable.Range(0,2).Select(i => landmarkTuple[i]).ToArray() }
}));
if (facePoints.Length != 5)
continue;
collection.Add(new(FacePart.RightEye, facePoints.Skip(0).Take(2).ToArray()));
collection.Add(new(FacePart.LeftEye, facePoints.Skip(2).Take(2).ToArray()));
collection.Add(new(FacePart.NoseTip, facePoints.Skip(4).Take(1).ToArray()));
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;
}
@ -503,7 +471,7 @@ public sealed class FaceRecognition : DisposableObject
/// <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="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)
throw new ArgumentNullException(nameof(image));
@ -517,9 +485,10 @@ public sealed class FaceRecognition : DisposableObject
Location? ret = TrimBound(face.Rect, image.Width, image.Height);
double confidence = face.DetectionConfidence;
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;
}
@ -763,36 +732,33 @@ public sealed class FaceRecognition : DisposableObject
#region Helpers
private IEnumerable<FullObjectDetection> RawFaceLandmarks(Image faceImage,
IEnumerable<Location>? faceLocations = null,
PredictorModel predictorModel = PredictorModel.Large,
Model model = Model.Hog)
private List<FullObjectDetection> RawFaceLandmarks(Image faceImage, int numberOfTimesToUpsample, IEnumerable<Location>? faceLocations, PredictorModel predictorModel, Model model)
{
IEnumerable<Location> rects;
IEnumerable<Location> locations;
if (faceLocations == null)
{
List<Location>? list = new();
IEnumerable<MModRect>? tmp = RawFaceLocations(faceImage, 1, model);
IEnumerable<MModRect>? tmp = RawFaceLocations(faceImage, numberOfTimesToUpsample, model);
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();
}
rects = list;
locations = list;
}
else
{
rects = faceLocations;
locations = faceLocations;
}
List<FullObjectDetection>? results = new();
List<FullObjectDetection> results = new();
if (predictorModel == PredictorModel.Custom)
{
if (CustomFaceLandmarkDetector is null)
throw new Exception($"{nameof(CustomFaceLandmarkDetector)} is null");
foreach (Location? rect in rects)
throw new ArgumentNullException(nameof(CustomFaceLandmarkDetector));
foreach (Location? rect in locations)
{
FullObjectDetection? ret = CustomFaceLandmarkDetector.Detect(faceImage, rect);
results.Add(ret);
@ -808,7 +774,7 @@ public sealed class FaceRecognition : DisposableObject
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));
results.Add(ret);
@ -818,7 +784,7 @@ public sealed class FaceRecognition : DisposableObject
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)
{
@ -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

View File

@ -41,7 +41,7 @@ public class DlibDotNet
Person[] people;
_AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(appSettings.MaxDegreeOfParallelism)} is null!");
throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism));
_IsEnvironment = isEnvironment;
_Exceptions = new List<string>();
_Log = Serilog.Log.ForContext<DlibDotNet>();
@ -61,21 +61,21 @@ public class DlibDotNet
_Distance = new E_Distance(configuration);
_FaceLandmarks = new D2_FaceLandmarks(configuration);
if (configuration.ForceMetadataLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(configuration.ForceMetadataLastWriteTimeToCreationTime)} is null!");
throw new ArgumentNullException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime));
if (configuration.ForceResizeLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(configuration.ForceResizeLastWriteTimeToCreationTime)} is null!");
throw new ArgumentNullException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime));
if (configuration.IgnoreExtensions is null)
throw new Exception($"{nameof(configuration.IgnoreExtensions)} is null!");
throw new ArgumentNullException(nameof(configuration.IgnoreExtensions));
if (configuration.OutputQuality is null)
throw new Exception($"{nameof(configuration.OutputQuality)} is null!");
throw new ArgumentNullException(nameof(configuration.OutputQuality));
if (configuration.OverrideForResizeImages is null)
throw new Exception($"{nameof(configuration.OverrideForResizeImages)} is null!");
throw new ArgumentNullException(nameof(configuration.OverrideForResizeImages));
if (configuration.PropertiesChangedForMetadata is null)
throw new Exception($"{nameof(configuration.PropertiesChangedForMetadata)} is null!");
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForResize is null)
throw new Exception($"{nameof(configuration.PropertiesChangedForResize)} is null!");
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForResize));
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);
if (args.Count > 0)
argZero = Path.GetFullPath(args[0]);
@ -88,7 +88,7 @@ public class DlibDotNet
(Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(configuration);
_Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel);
if (configuration.SkipSearch is null)
throw new Exception($"{nameof(configuration.SkipSearch)} is null!");
throw new ArgumentNullException(nameof(configuration.SkipSearch));
if (!_ArgZeroIsConfigurationRootDirectory)
people = Array.Empty<Person>();
else
@ -134,7 +134,7 @@ public class DlibDotNet
{
long result;
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;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks;
@ -188,7 +188,7 @@ public class DlibDotNet
private void Verify(Models.Configuration configuration)
{
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())
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())
@ -202,79 +202,81 @@ public class DlibDotNet
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!");
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)
throw new Exception($"{nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection)} must be set!");
throw new ArgumentNullException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
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)
throw new Exception($"{nameof(configuration.ForceMetadataLastWriteTimeToCreationTime)} must be set!");
throw new ArgumentNullException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime));
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)
throw new Exception($"{nameof(configuration.IgnoreExtensions)} must be set!");
throw new ArgumentNullException(nameof(configuration.IgnoreExtensions));
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)
throw new Exception($"{nameof(configuration.LoadOrCreateThenSaveIndex)} must be set!");
throw new ArgumentNullException(nameof(configuration.LoadOrCreateThenSaveIndex));
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)
throw new Exception($"{nameof(configuration.MappedMaxIndex)} must be set!");
throw new ArgumentNullException(nameof(configuration.MappedMaxIndex));
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)
throw new Exception($"{nameof(configuration.MaxItemsInDistanceCollection)} must be set!");
throw new ArgumentNullException(nameof(configuration.MaxItemsInDistanceCollection));
if (configuration.MixedYearRelativePaths is null)
throw new Exception($"{nameof(configuration.MixedYearRelativePaths)} must be set!");
if (configuration.NumJitters is null)
throw new Exception($"{nameof(configuration.NumJitters)} must be set!");
throw new ArgumentNullException(nameof(configuration.MixedYearRelativePaths));
if (configuration.NumberOfJitters is null)
throw new ArgumentNullException(nameof(configuration.NumberOfJitters));
if (configuration.NumberOfTimesToUpsample is null)
throw new ArgumentNullException(nameof(configuration.NumberOfTimesToUpsample));
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)
throw new Exception($"{nameof(configuration.OutputResolutions)} must be set!");
throw new ArgumentNullException(nameof(configuration.OutputResolutions));
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)
throw new Exception($"{nameof(configuration.OverrideForFaceLandmarkImages)} must be set!");
throw new ArgumentNullException(nameof(configuration.OverrideForFaceLandmarkImages));
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)
throw new Exception($"{nameof(configuration.PaddingLoops)} must be set!");
throw new ArgumentNullException(nameof(configuration.PaddingLoops));
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)
throw new Exception($"{nameof(configuration.PropertiesChangedForFaces)} must be set!");
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForFaces));
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)
throw new Exception($"{nameof(configuration.PropertiesChangedForMetadata)} must be set!");
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForMetadata));
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)
throw new Exception($"{nameof(configuration.Reverse)} must be set!");
throw new ArgumentNullException(nameof(configuration.Reverse));
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)
throw new Exception($"{nameof(configuration.SaveFullYearOfRandomFiles)} must be set!");
throw new ArgumentNullException(nameof(configuration.SaveFullYearOfRandomFiles));
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)
throw new Exception($"{nameof(configuration.SkipSearch)} must be set!");
throw new ArgumentNullException(nameof(configuration.SkipSearch));
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)
throw new Exception($"{nameof(configuration.ValidResolutions)} must be set!");
throw new ArgumentNullException(nameof(configuration.ValidResolutions));
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))
throw new Exception($"{nameof(configuration.ModelName)} must have a value!");
throw new ArgumentNullException(nameof(configuration.ModelName));
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))
throw new Exception($"{nameof(configuration.PredictorModelName)} must have a value!");
throw new ArgumentNullException(nameof(configuration.PredictorModelName));
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)
@ -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)
{
if (propertyHolder.ImageFileInfo is null)
throw new Exception($"{nameof(propertyHolder.ImageFileInfo)} is null!");
throw new ArgumentNullException(nameof(propertyHolder.ImageFileInfo));
if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!");
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
if (_Configuration.SaveResizedSubfiles is null)
throw new Exception($"{nameof(_Configuration.SaveResizedSubfiles)} is null!");
throw new ArgumentNullException(nameof(_Configuration.SaveResizedSubfiles));
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)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration.WriteBitmapDataBytes)} is null!");
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration.WriteBitmapDataBytes));
A_Property property;
List<D_Face> faceCollection;
string original = "Original";
@ -395,9 +397,9 @@ public class DlibDotNet
{
int result = 0;
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
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 };
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)
@ -460,7 +462,7 @@ public class DlibDotNet
if (metadataIdLines.Any())
{
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
{
@ -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)
{
if (_Configuration.PropertiesChangedForMetadata is null)
throw new Exception($"{nameof(_Configuration.PropertiesChangedForMetadata)} is null!");
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForProperty is null)
throw new Exception($"{nameof(configuration.PropertiesChangedForProperty)} is null!");
throw new ArgumentNullException(nameof(configuration.PropertiesChangedForProperty));
if (_Configuration.PropertiesChangedForResize is null)
throw new Exception($"{nameof(_Configuration.PropertiesChangedForResize)} is null!");
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForResize));
if (_Configuration.PropertiesChangedForFaces is null)
throw new Exception($"{nameof(_Configuration.PropertiesChangedForFaces)} is null!");
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForFaces));
string key;
string json;
string checkFile;
PropertyHolder propertyHolder;
int sourceDirectoryLength = sourceDirectory.Length;
int rootDirectoryLength = configuration.RootDirectory.Length;
_FilePropertiesKeyValuePairs.Add(sourceDirectory, new List<Tuple<string, A_Property>>());
JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = false };
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]));
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())
{
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(propertyLogic.AngleBracketCollection[0], level, "[{}]");
@ -529,7 +520,17 @@ public class DlibDotNet
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
checkFile = Path.Combine(checkDirectory, fileName);
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())
{
@ -539,7 +540,7 @@ public class DlibDotNet
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
checkFile = Path.Combine(checkDirectory, fileName);
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())
{
@ -549,7 +550,7 @@ public class DlibDotNet
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
checkFile = Path.Combine(checkDirectory, fileName);
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)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!");
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
int g;
int r;
int exceptionCount;
@ -677,11 +678,11 @@ public class DlibDotNet
{
if (outputResolution == _Configuration.OutputResolutions[0] || _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
{
PropertyHolder.AddToNamed(propertyLogic, filteredPropertyHolderCollection);
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))
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))
@ -707,7 +708,7 @@ public class DlibDotNet
{
propertyLogic.SaveAllCollection();
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())
break;
if (_Exceptions.Count == 0)
@ -731,9 +732,9 @@ public class DlibDotNet
{
PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!");
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
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);
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 = "Model Directory"), Required] public string ModelDirectory { 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 Quality"), Required] public int? OutputQuality { get; set; }
[Display(Name = "Output Resolutions"), Required] public string[] OutputResolutions { get; set; }
@ -68,7 +69,8 @@ public class Configuration
MixedYearRelativePaths = Array.Empty<string>();
ModelDirectory = string.Empty;
ModelName = string.Empty;
NumJitters = null;
NumberOfJitters = null;
NumberOfTimesToUpsample = null;
OutputExtension = string.Empty;
OutputQuality = null;
OutputResolutions = Array.Empty<string>();

View File

@ -24,7 +24,8 @@ public class Configuration
protected readonly string[] _MixedYearRelativePaths;
protected readonly string _ModelDirectory;
protected readonly string _ModelName;
protected readonly int? _NumJitters;
protected readonly int? _NumberOfJitters;
protected readonly int? _NumberOfTimesToUpsample;
protected readonly string _OutputExtension;
protected readonly int? _OutputQuality;
protected readonly string[] _OutputResolutions;
@ -65,7 +66,8 @@ public class Configuration
public string[] MixedYearRelativePaths => _MixedYearRelativePaths;
public string ModelDirectory => _ModelDirectory;
public string ModelName => _ModelName;
public int? NumJitters => _NumJitters;
public int? NumberOfJitters => _NumberOfJitters;
public int? NumberOfTimesToUpsample => _NumberOfTimesToUpsample;
public string OutputExtension => _OutputExtension;
public int? OutputQuality => _OutputQuality;
public string[] OutputResolutions => _OutputResolutions;
@ -90,7 +92,7 @@ public class Configuration
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? 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;
_CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
@ -110,7 +112,8 @@ public class Configuration
_MixedYearRelativePaths = mixedYearRelativePaths;
_ModelDirectory = modelDirectory;
_ModelName = modelName;
_NumJitters = numJitters;
_NumberOfJitters = numberOfJitters;
_NumberOfTimesToUpsample = numberOfTimesToUpsample;
_OutputExtension = outputExtension;
_OutputQuality = outputQuality;
_OutputResolutions = outputResolutions;

View File

@ -56,7 +56,7 @@ internal class A2_People
_ = Directory.CreateDirectory(directoryFullName);
jsonFile = Path.Combine(directoryFullName, $"{segments[1]}.json");
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;
}
}
@ -65,7 +65,7 @@ internal class A2_People
{
Person[] results;
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 peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People));
string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory));

View File

@ -116,8 +116,10 @@ internal class D2_FaceLandmarks
string parentCheck;
const int pointSize = 2;
FileInfo rotatedFileInfo;
DateTime? dateTime = null;
long ticks = DateTime.Now.Ticks;
List<string[]> imageFiles = new();
bool updateDateWhenMatches = false;
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) };
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;
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
check = true;
if (check && !updateDateWhenMatches)
{
updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
}
}
if (check)
SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, propertyHolder.ResizedFileInfo);

View File

@ -233,10 +233,12 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
if (!faceCollection[i].Populated || faceCollection[i]?.Location is null)
continue;
location = new Location(faceCollection[i].Location.Confidence,
faceCollection[i].Location.Bottom,
faceCollection[i].Location.Left,
faceCollection[i].Location.Right,
faceCollection[i].Location.Top);
faceCollection[i].Location.Bottom,
faceCollection[i].Location.Left,
faceCollection[i].Location.Right,
faceCollection[i].Location.Top,
source.Width,
source.Height);
width = location.Right - location.Left;
height = location.Bottom - location.Top;
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();
if (_Configuration.PaddingLoops is null)
throw new Exception();
if (_Configuration.NumJitters is null)
throw new Exception();
if (_Configuration.NumberOfJitters is null)
throw new ArgumentNullException(nameof(_Configuration.NumberOfJitters));
if (_Configuration.NumberOfTimesToUpsample is null)
throw new ArgumentNullException(nameof(_Configuration.NumberOfTimesToUpsample));
List<Location> locations;
const int numberOfTimesToUpSample = 1;
FaceRecognitionDotNet.Image? unknownImage = null;
if (resizedFileInfo.Exists)
{
@ -270,7 +273,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
else
{
FaceRecognition faceRecognition = FaceRecognition.Create(_ModelParameter);
locations = faceRecognition.FaceLocations(unknownImage, numberOfTimesToUpSample, _Model);
locations = faceRecognition.FaceLocations(_Model, unknownImage, _Configuration.NumberOfTimesToUpsample.Value, sortByPixelPercentage: true);
if (!locations.Any())
results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i: null, location: null));
else
@ -279,10 +282,10 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
int width;
int height;
int padding;
int leftEyeX;
int leftEyeY;
int rightEyeX;
int rightEyeY;
int? leftEyeX;
int? leftEyeY;
int? rightEyeX;
int? rightEyeY;
Bitmap rotated;
string faceFile;
Location location;
@ -291,12 +294,11 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
D_Face? face = null;
Rectangle rectangle;
double[] rawEncoding;
IEnumerable<FacePoint> facePoints;
Shared.Models.FaceEncoding faceEncoding;
FaceRecognitionDotNet.Image? knownImage;
FaceRecognitionDotNet.Image? rotatedImage;
List<(FacePart, FacePoint[])[]> facesLandmarks;
List<FaceRecognitionDotNet.FaceEncoding> faceEncodings;
List<Dictionary<FacePart, IEnumerable<FacePoint>>> faceLandmarks;
using Bitmap source = unknownImage.ToBitmap();
padding = (int)((source.Width + source.Height) / 2 * .01);
for (int i = 0; i < locations.Count; i++)
@ -304,16 +306,22 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
for (int p = 0; p <= _Configuration.PaddingLoops.Value; p++)
{
location = new(locations[i].Confidence,
locations[i].Bottom + (padding * p),
locations[i].Left - (padding * p),
locations[i].Right + (padding * p),
locations[i].Top - (padding * p));
face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i, location);
locations[i].Bottom + (padding * p),
locations[i].Left - (padding * p),
locations[i].Right + (padding * p),
locations[i].Top - (padding * p),
source.Width,
source.Height);
face = new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i, location);
width = location.Right - location.Left;
height = location.Bottom - location.Top;
rectangle = new Rectangle(location.Left, location.Top, width, height);
using (preRotated = new Bitmap(width, height))
{
leftEyeX = null;
leftEyeY = null;
rightEyeX = null;
rightEyeY = null;
using (graphics = Graphics.FromImage(preRotated))
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
// 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))
{
if (knownImage is null || knownImage.IsDisposed)
throw new Exception($"{nameof(knownImage)} is null");
faceLandmarks = faceRecognition.FaceLandmark(knownImage, faceLocations: null, _PredictorModel, _Model);
throw new ArgumentNullException(nameof(knownImage));
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;
else if (faceLandmarks.Count != 1)
else if (facesLandmarks.Count != 1)
continue;
foreach (KeyValuePair<FacePart, IEnumerable<FacePoint>> keyValuePair in faceLandmarks[0])
face.FaceLandmarks.Add(keyValuePair.Key.ToString(), keyValuePair.Value.ToArray());
if (!faceLandmarks[0].ContainsKey(FacePart.LeftEye) || !faceLandmarks[0].ContainsKey(FacePart.RightEye))
foreach ((FacePart facePart, FacePoint[] facePoints) in facesLandmarks[0])
{
face.FaceLandmarks.Add(facePart.ToString(), facePoints);
if (facePart is not FacePart.LeftEye and not FacePart.RightEye)
continue;
if (facePart is FacePart.LeftEye)
{
leftEyeX = (int)(from l in facePoints select l.X).Average();
leftEyeY = (int)(from l in facePoints select l.Y).Average();
}
if (facePart is FacePart.RightEye)
{
rightEyeX = (int)(from l in facePoints select l.X).Average();
rightEyeY = (int)(from l in facePoints select l.Y).Average();
}
}
if (rightEyeX is null || leftEyeX is null || rightEyeY is null || leftEyeY is null)
continue;
facePoints = faceLandmarks[0][FacePart.LeftEye];
leftEyeX = (int)(from l in facePoints select l.X).Average();
leftEyeY = (int)(from l in facePoints select l.Y).Average();
facePoints = faceLandmarks[0][FacePart.RightEye];
rightEyeX = (int)(from l in facePoints select l.X).Average();
rightEyeY = (int)(from l in facePoints select l.Y).Average();
α = Shared.Models.Stateless.Methods.IFace.Getα(rightEyeX, leftEyeX, rightEyeY, leftEyeY);
α = Shared.Models.Stateless.Methods.IFace.Getα(rightEyeX.Value, leftEyeX.Value, rightEyeY.Value, leftEyeY.Value);
using (rotated = RotateBitmap(preRotated, (float)α.Value))
{
// rotated.Save(Path.Combine(_Configuration.RootDirectory, $"{p} - rotated.jpg"));
using (rotatedImage = FaceRecognition.LoadImage(rotated))
{
if (rotatedImage is null || rotatedImage.IsDisposed)
throw new Exception($"{nameof(rotatedImage)} is null");
faceEncodings = faceRecognition.FaceEncodings(rotatedImage, knownFaceLocation: null, _Configuration.NumJitters.Value, _PredictorModel, _Model);
throw new ArgumentNullException(nameof(rotatedImage));
faceEncodings = faceRecognition.FaceEncodings(rotatedImage, _Configuration.NumberOfTimesToUpsample.Value, knownFaceLocation: null, _Configuration.NumberOfJitters.Value, _PredictorModel, _Model);
}
if (faceEncodings.Count == 0 && p < _Configuration.PaddingLoops.Value)
continue;
@ -366,10 +382,12 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
if (face is null || !face.Populated)
{
location = new(locations[i].Confidence,
locations[i].Bottom,
locations[i].Left,
locations[i].Right,
locations[i].Top);
locations[i].Bottom,
locations[i].Left,
locations[i].Right,
locations[i].Top,
source.Width,
source.Height);
face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, propertyHolder.RelativePath, i, location);
results.Add(face);
}
@ -427,7 +445,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
{
results = JsonSerializer.Deserialize<List<D_Face>>(json);
if (results is null)
throw new Exception($"{nameof(results)} is null");
throw new ArgumentNullException(nameof(results));
for (int i = 0; i < results.Count; i++)
{
face = results[i];
@ -448,14 +466,18 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
if (results is not null && checkForOutputResolutionChange)
{
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);
}
else if (results is null)
{
results = GetFaces(resizedFileInfo, propertyHolder, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, facesDirectory);
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));
}
return results;
@ -505,109 +527,20 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
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)
{
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)
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)
{
Person person;
string fileName;
string fullName;
WindowsShortcut windowsShortcut;
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
List<(PropertyHolder, (string, D_Face?, (string, string, string, string))[])> collections = GetCollection(configuration, model, predictorModel, propertyLogic, outputResolution, filteredPropertyHolderCollection, faceCollections);
foreach ((PropertyHolder propertyHolder, (string personKey, D_Face? face, (string, string, string, string))[] collection) in collections)
string dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), $"({ticks})");
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)
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))
continue;
@ -619,7 +552,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
if (!string.IsNullOrEmpty(personKey) && peopleCollection.ContainsKey(personKey))
{
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);
}
}

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)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
bool all = false;
FileSystem fileSystem;
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)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
string requestPath = "/RootResultsDirectory";
string? rootResultsDirectory = Path.GetDirectoryName(Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(B_Metadata)));
if (string.IsNullOrEmpty(rootResultsDirectory))
@ -95,9 +95,9 @@ internal class E2_Navigate
{
string result;
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
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, ">?"));
string? newDirectoryName = _Console.ReadLine();
_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)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
string[] subFiles;
ConsoleKey consoleKey;
string[] subDirectories;

View File

@ -115,7 +115,7 @@ internal class E3_Rename
{
List<string[]> results = new();
if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
bool add;
string to;
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)
{
if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string json;
FileInfo current;
FileInfo fileInfo;
@ -299,7 +299,7 @@ internal class E3_Rename
if (json.Contains(oldValue))
{
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;
File.SetLastWriteTime(fileInfo.FullName, fileInfo.LastWriteTime);
}

View File

@ -128,7 +128,7 @@ internal class E_Distance
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 json;
@ -144,7 +144,7 @@ internal class E_Distance
orderedFaceCollection = GetOrderedNoFaceCollection(faceCollections, i, faceCollection[j]);
json = JsonSerializer.Serialize(orderedFaceCollection, _WriteIndentedJsonSerializerOptions);
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));
}
else
@ -162,16 +162,16 @@ internal class E_Distance
indicesAndValues = GetValues(faceCollections, locationIndicesCollection, faceDistances);
orderedFaceCollection = GetOrderedFaceCollection(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));
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));
}
}
}
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;
string fileNameWithoutExtension;
@ -190,7 +190,7 @@ internal class E_Distance
if (fileInfo is null)
continue;
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;
bool check = false;
string parentCheck;
DateTime? dateTime = null;
FileInfo[] fileInfoCollection;
string fileNameWithoutExtension;
bool updateDateWhenMatches = false;
List<string[]> directories = new();
System.IO.DirectoryInfo directoryInfo;
System.IO.DirectoryInfo tvsDirectoryInfo;
@ -264,9 +266,14 @@ internal class E_Distance
check = true;
else if (dateTimes.Any() && dateTimes.Max() > directoryInfo.LastWriteTime)
check = true;
if (check && !updateDateWhenMatches)
{
updateDateWhenMatches = dateTimes.Any() && directoryInfo.Exists && dateTimes.Max() > directoryInfo.LastWriteTime;
dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
}
}
if (check)
LoadOrCreateThenSaveDistanceResultsForOutputResolutions(configuration, filteredPropertyHolderCollection, faceCollections, directories);
LoadOrCreateThenSaveDistanceResultsForOutputResolutions(configuration, filteredPropertyHolderCollection, faceCollections, directories, updateDateWhenMatches, updateToWhenMatches: dateTime);
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(directoryInfoCollection[0].Replace("<>", "()"));
}
@ -335,7 +342,7 @@ internal class E_Distance
_ = Directory.CreateDirectory(jsonDirectory);
string json = JsonSerializer.Serialize(faceAndFaceDistanceCollection, _WriteIndentedJsonSerializerOptions);
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)
@ -350,7 +357,7 @@ internal class E_Distance
internal void LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
string? relativePath;
Shared.Models.Face face;
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();
string key;
string personKey;
bool? isWrongYear;
TimeSpan? timeSpan;
string isWrongYearFlag;
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;
double result = 0;
if (!values.Any())
throw new Exception("Collection must have at least one value!");
double sum = values.Sum(l => (l - average) * (l - average));
result = Math.Sqrt(sum / values.Count());
return result;
}
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;
double average;
int lowestIndex;
string checkFile;
string directory;
string personKey;
double lowestAverage;
double standardDeviation;
FaceEncoding faceEncoding;
List<double> faceDistances;
List<double[]> rawEncodings;
Shared.Models.Person person;
List<FaceEncoding> faceEncodings;
List<string> checkDirectories = new();
List<Shared.Models.Properties.IFace> collection;
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), "[_]");
foreach (KeyValuePair<string, List<(string personKey, D_Face face)>> keyValuePair in keyValuePairs)
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), $"[{ticks}]");
List<(string, Shared.Models.PersonBirthday, Shared.Models.Properties.IFace)[]> collection = PropertyHolder.GetCollection(argZero, propertyHolderCollections, eDistanceCollectionDirectory);
foreach ((string, Shared.Models.PersonBirthday, Shared.Models.Properties.IFace)[] group in collection)
{
collection = new();
lowestIndex = 0;
rawEncodings = new();
faceEncodings = new();
checkDirectories.Clear();
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))
continue;
if (@interface is not D_Face face || !face.Populated)
continue;
person = peopleCollection[personKey][0];
directory = Path.Combine(eDistanceCollectionDirectory, $"{personKey}{keyValuePair.Key}");
checkFile = Path.Combine(directory, Regex.Replace($"{Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name)}.json", pattern, string.Empty));
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
checkFile = string.Concat(directory, " - ", Regex.Replace(Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name), pattern, string.Empty), ".json");
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.Distinct())
{
foreach (string checkDirectory in checkDirectories)
{
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
json = JsonSerializer.Serialize(collection, new JsonSerializerOptions { WriteIndented = true });
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, compareBeforeWrite: true);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
for (int i = 0; i < faceEncodings.Count; i++)
{
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;
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);
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();
jsonFile = Path.Combine(fRandomCollectionDirectory, $"{dateTime.AddDays(i):MM-dd}.json");
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)
break;
}
@ -83,7 +83,7 @@ internal class F_Random
ignoreRelativePaths = (from l in ignoreRelativePaths orderby random.NextDouble() select l).ToList();
jsonFile = Path.Combine(fRandomCollectionDirectory, "01-01.txt");
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);
if (!isEnvironment.DebuggerWasAttachedDuringConstructor)
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);
jsonFile = string.Concat(g2IdentifyCollectionDirectory, keyValuePair.Key, ".json");
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;
}
}

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();
indexInfo = new(dateTime, maxIndexPlusOne, tuple.Item1);
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;
}
}
@ -114,7 +114,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
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");
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;
}
}

View File

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

View File

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

View File

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

View File

@ -39,7 +39,7 @@ public class B_Metadata
{
Dictionary<string, List<KeyValuePair<string, string>>> results = new();
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
try
{
object? @object;
@ -137,7 +137,9 @@ public class B_Metadata
{
dictionary = GetMetadataCollection(propertyHolder.ImageFileInfo.FullName);
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))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(B_Metadata), DateTime.Now));

View File

@ -28,7 +28,7 @@ public class NotCopyCopy
{ }
_AppSettings = appSettings;
if (appSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(appSettings.MaxDegreeOfParallelism)} is null!");
throw new ArgumentNullException(nameof(appSettings.MaxDegreeOfParallelism));
_IsEnvironment = isEnvironment;
_Exceptions = new List<string>();
_Log = Serilog.Log.ForContext<NotCopyCopy>();
@ -43,7 +43,7 @@ public class NotCopyCopy
PredictorModel? predictorModel = null;
_Configuration = configuration;
if (propertyConfiguration.PopulatePropertyId is null)
throw new Exception($"{nameof(propertyConfiguration.PopulatePropertyId)} is null!");
throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId));
if (!_IsEnvironment.Development)
throw new Exception("This program only allows development environments!");
PropertyLogic propertyLogic = GetPropertyLogic();
@ -100,22 +100,22 @@ public class NotCopyCopy
private static void Verify(Models.Configuration configuration)
{
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))
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))
throw new Exception($"{nameof(configuration.EmptyDestination)} can't exit!");
throw new ArgumentNullException(nameof(configuration.EmptyDestination));
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)
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)
{
long result;
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;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks;
@ -126,9 +126,9 @@ public class NotCopyCopy
{
PropertyLogic result;
if (_AppSettings.MaxDegreeOfParallelism is null)
throw new Exception($"{nameof(_AppSettings.MaxDegreeOfParallelism)} is null!");
throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism));
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);
return result;
}
@ -137,7 +137,7 @@ public class NotCopyCopy
{
List<(string Source, string[] Destination)> results = new();
if (_Configuration?.PropertyConfiguration is null)
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration));
string key;
string fileName;
A_Property? property;

View File

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

View File

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

View File

@ -65,37 +65,37 @@ public class Configuration
public static void Verify(Configuration? propertyConfiguration)
{
if (propertyConfiguration is null)
throw new Exception($"{nameof(propertyConfiguration)} must be set!");
throw new ArgumentNullException(nameof(propertyConfiguration));
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())
throw new Exception($"{nameof(propertyConfiguration.IgnoreExtensions)} must be set!");
throw new ArgumentNullException(nameof(propertyConfiguration.IgnoreExtensions));
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)
throw new Exception($"{nameof(propertyConfiguration.PropertiesChangedForProperty)} must be set!");
throw new ArgumentNullException(nameof(propertyConfiguration.PropertiesChangedForProperty));
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())
throw new Exception($"{nameof(propertyConfiguration.ValidImageFormatExtensions)} must be set!");
throw new ArgumentNullException(nameof(propertyConfiguration.ValidImageFormatExtensions));
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())
throw new Exception($"{nameof(propertyConfiguration.VerifyToSeason)} must be set!");
throw new ArgumentNullException(nameof(propertyConfiguration.VerifyToSeason));
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)
throw new Exception($"{nameof(propertyConfiguration.RootDirectory)} should have at least one level!");
throw new ArgumentNullException(nameof(propertyConfiguration.RootDirectory));
if (propertyConfiguration is null)
throw new Exception($"{nameof(propertyConfiguration)} must be set!");
throw new ArgumentNullException(nameof(propertyConfiguration));
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))
throw new Exception($"{nameof(propertyConfiguration.FileNameDirectorySeparator)} must have a value!");
throw new ArgumentNullException(nameof(propertyConfiguration.FileNameDirectorySeparator));
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))
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;

View File

@ -1,4 +1,6 @@
using System.Text.Json.Serialization;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Properties;
namespace View_by_Distance.Property.Models;
@ -7,13 +9,13 @@ public class PropertyHolder
protected readonly bool? _Abandoned;
protected readonly bool? _Changed;
protected List<object> _Faces;
protected List<IFace> _Faces;
protected readonly FileInfo? _ImageFileInfo;
protected readonly string _ImageFileNameWithoutExtension;
protected readonly int _G;
protected DateTime? _MinimumDateTime;
protected bool? _Moved;
protected List<(bool?, string, TimeSpan?)> _Named;
protected List<(bool?, DateTime, PersonBirthday, double?)> _Named;
protected readonly bool? _NoJson;
protected A_Property? _Property;
protected readonly int _R;
@ -24,14 +26,14 @@ public class PropertyHolder
protected bool? _ValidImageFormatExtension;
public bool? Abandoned => _Abandoned;
public bool? Changed => _Changed;
public List<object> Faces => _Faces;
public List<IFace> Faces => _Faces;
public FileInfo? ImageFileInfo => _ImageFileInfo;
public string ImageFileNameWithoutExtension => _ImageFileNameWithoutExtension;
public int G => _G;
public DateTime? MinimumDateTime => _MinimumDateTime;
public bool? Moved => _Moved;
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 int R => _R;
public string RelativePath => _RelativePath;
@ -96,20 +98,15 @@ public class PropertyHolder
_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)
{
bool? isWrongYear;
TimeSpan? timeSpan;
DateTime? birthDate;
string[] segments;
string[] personKeys;
double? pixelPercentage;
DateTime minimumDateTime;
PropertyHolder propertyHolder;
PersonBirthday? personBirthday;
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++)
{
propertyHolder = filteredPropertyHolderCollection[i];
@ -122,21 +119,187 @@ public class PropertyHolder
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(propertyHolder.Property);
personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value];
(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")
timeSpan = null;
segments = Shared.Models.Stateless.Methods.IPersonBirthday.GetSegments(personKeys[j]);
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
{
birthDate = Shared.Models.Stateless.Methods.IPersonBirthday.Get(personKey);
if (birthDate is null)
timeSpan = null;
else
timeSpan = new(minimumDateTime.Ticks - birthDate.Value.Ticks);
}
propertyHolder.Named.Add(new(isWrongYear, personKey, timeSpan));
pixelPercentage = value;
propertyHolder.Named.Add(new(isWrongYear, minimumDateTime, personBirthday, pixelPercentage));
}
}
}
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;
string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent))
throw new Exception($"{nameof(rootDirectoryParent)} is null!");
throw new ArgumentNullException(nameof(rootDirectoryParent));
files = Directory.GetFiles(rootDirectoryParent, "*DeterministicHashCode*.json", SearchOption.TopDirectoryOnly);
if (files.Length != 1)
namedFaceInfoDeterministicHashCodeIndices = new();
@ -66,7 +66,7 @@ public class PropertyLogic
json = File.ReadAllText(files[0]);
namedFaceInfoDeterministicHashCodeIndices = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
if (namedFaceInfoDeterministicHashCodeIndices is null)
throw new Exception($"{nameof(namedFaceInfoDeterministicHashCodeIndices)} is null!");
throw new ArgumentNullException(nameof(namedFaceInfoDeterministicHashCodeIndices));
}
if (namedFaceInfoDeterministicHashCodeIndices.Any())
sixCharacterNamedFaceInfo = new();
@ -80,7 +80,7 @@ public class PropertyLogic
json = File.ReadAllText(files[0]);
sixCharacterNamedFaceInfo = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
if (sixCharacterNamedFaceInfo is null)
throw new Exception($"{nameof(sixCharacterNamedFaceInfo)} is null!");
throw new ArgumentNullException(nameof(sixCharacterNamedFaceInfo));
}
}
files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly);
@ -91,7 +91,7 @@ public class PropertyLogic
json = File.ReadAllText(files[0]);
keyValuePairs = JsonSerializer.Deserialize<Dictionary<int, int[]>>(json);
if (keyValuePairs is null)
throw new Exception($"{nameof(keyValuePairs)} is null!");
throw new ArgumentNullException(nameof(keyValuePairs));
}
foreach (string propertyContentCollectionFile in configuration.PropertyContentCollectionFiles)
{
@ -103,7 +103,7 @@ public class PropertyLogic
json = File.ReadAllText(fullPath);
collection = JsonSerializer.Deserialize<List<KeyValuePair<int, int[]>>>(json);
if (collection is null)
throw new Exception($"{nameof(collection)} is null!");
throw new ArgumentNullException(nameof(collection));
foreach (KeyValuePair<int, int[]> keyValuePair in collection)
{
if (indicesFromNew.ContainsKey(keyValuePair.Key))
@ -127,7 +127,7 @@ public class PropertyLogic
{
long result;
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;
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
result = DateTime.Now.Ticks;
@ -172,9 +172,9 @@ public class PropertyLogic
{
A_Property result;
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
if (_Configuration.WriteBitmapDataBytes is null)
throw new Exception($"{nameof(_Configuration.WriteBitmapDataBytes)} is null!");
throw new ArgumentNullException(nameof(_Configuration.WriteBitmapDataBytes));
long ticks;
byte[] bytes;
string value;
@ -340,11 +340,11 @@ public class PropertyLogic
{
A_Property? result;
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime)} is null!");
throw new ArgumentNullException(nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime));
if (_Configuration.PopulatePropertyId is null)
throw new Exception($"{nameof(_Configuration.PopulatePropertyId)} is null!");
throw new ArgumentNullException(nameof(_Configuration.PopulatePropertyId));
if (_Configuration.PropertiesChangedForProperty is null)
throw new Exception($"{nameof(_Configuration.PropertiesChangedForProperty)} is null!");
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForProperty));
string json;
int? id = null;
List<int> indices = new();
@ -464,7 +464,7 @@ public class PropertyLogic
throw new ArgumentException($"{propertyHolder.ImageFileInfo} is null!");
result = GetImageProperty(angleBracket, propertyHolder.ImageFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
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))
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
@ -479,7 +479,7 @@ public class PropertyLogic
else if (hasWrongYearProperty)
{
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);
fileInfo.Refresh();
@ -493,7 +493,7 @@ public class PropertyLogic
{
bool result = false;
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
int season;
string[] matches;
string deleteFile;
@ -603,41 +603,10 @@ public class PropertyLogic
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)
{
if (propertyHolder.ImageFileInfo is null)
throw new Exception($"{nameof(propertyHolder.ImageFileInfo)} is null!");
throw new ArgumentNullException(nameof(propertyHolder.ImageFileInfo));
A_Property property;
List<string> parseExceptions = new();
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)
{
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
throw new ArgumentNullException(nameof(_Log));
if (_Configuration.PopulatePropertyId is null)
throw new Exception($"{nameof(_Configuration.PopulatePropertyId)} is null!");
throw new ArgumentNullException(nameof(_Configuration.PopulatePropertyId));
int g;
int r;
int totalSeconds;
bool? anyFilesMoved;
string angleBracket;
string sourceDirectory;
List<Exception> exceptions = new();
PropertyHolder[] filteredPropertyHolderCollection;
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
int sourceDirectoryLength = configuration.RootDirectory.Length;
int propertyHolderCollectionsCount = propertyHolderCollections.Count;
string propertyRoot = IResult.GetResultsGroupDirectory(configuration, nameof(A_Property));
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
@ -745,13 +714,10 @@ public class PropertyLogic
throw new Exception(string.Concat("All in [", sourceDirectory, "]failed!"));
if (exceptions.Count != 0)
_ExceptionsDirectories.Add(sourceDirectory);
bool? anyFilesMoved;
if (!firstPass || exceptions.Count != 0)
anyFilesMoved = null;
else
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())
{
for (int y = 0; y < int.MaxValue; y++)
@ -843,7 +809,7 @@ public class PropertyLogic
string[] keys;
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent))
throw new Exception($"{nameof(rootDirectoryParent)} is null!");
throw new ArgumentNullException(nameof(rootDirectoryParent));
Dictionary<int, string[]> namedFaceInfoDeterministicHashCodeIndices = new();
List<(int, string[])> allCollection = _AllCollection.OrderBy(l => l.Item1).ToList();
foreach ((int deterministicHashCode, string[] values) in allCollection)
@ -859,7 +825,7 @@ public class PropertyLogic
}
string json = JsonSerializer.Serialize(namedFaceInfoDeterministicHashCodeIndices, new JsonSerializerOptions { WriteIndented = true });
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)
{
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, 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)

View File

@ -12,8 +12,8 @@ public interface IPath
List<string> TestStatic_GetDirectoryNames(string directory);
static List<string> GetDirectoryNames(string directory) => XPath.GetDirectoryNames(directory);
bool TestStatic_WriteAllText(string path, string contents, bool compareBeforeWrite);
static bool WriteAllText(string path, string contents, bool compareBeforeWrite) => XPath.WriteAllText(path, contents, compareBeforeWrite);
bool TestStatic_WriteAllText(string path, string contents, bool updateDateWhenMatches, bool 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);
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;
}
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;
string text;
@ -59,6 +59,13 @@ internal class XPath
else
text = File.ReadAllText(path);
result = text != contents;
if (!result && updateDateWhenMatches)
{
if (updateToWhenMatches is null)
File.SetLastWriteTime(path, DateTime.Now);
else
File.SetLastWriteTime(path, updateToWhenMatches.Value);
}
}
if (result)
{
@ -85,7 +92,7 @@ internal class XPath
string? pathRoot = Path.GetPathRoot(directory);
string extension = Path.GetExtension(directory);
if (string.IsNullOrEmpty(pathRoot))
throw new Exception($"{nameof(pathRoot)} is null!");
throw new ArgumentNullException(nameof(pathRoot));
if (Directory.Exists(directory))
results.Add(Path.GetFileName(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);
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))
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.Serialization;
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 double Confidence => _Confidence;
protected double _Confidence;
protected int _Bottom;
protected int _Left;
protected double? _PixelPercentage;
protected int _Right;
protected int _Top;
public double Confidence => _Confidence;
public int Bottom => _Bottom;
public int Left => _Left;
public double? PixelPercentage => _PixelPercentage;
public int Right => _Right;
public int Top => _Top;
[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;
_Bottom = bottom;
_Left = left;
_PixelPercentage = pixelPercentage;
_Right = right;
_Top = top;
}
public Location(int left, int top, int right, int bottom) :
this(-1.0d, bottom, left, right, top)
public Location(double confidence, int bottom, int left, int right, int top, int width, int height) :
this(confidence, bottom, left, GetPixelPercentage(bottom, left, right, top, width, height), right, top)
{ }
public Location(Rectangle rectangle, double confidence) :
this(-1.0d, rectangle.Bottom, rectangle.Left, rectangle.Right, rectangle.Top)
public Location(double confidence, Location location, int width, int height) :
this(confidence, location.Bottom, location.Left, location.Right, location.Top, width, height)
{ }
public Location(Location location, double confidence) :
this(-1.0d, location.Bottom, location.Left, location.Right, location.Top)
public Location(int left, int top, int right, int bottom, int width, int height) :
this(-1.0d, bottom, left, right, top, width, height)
{ }
public override bool Equals(object? obj) => Equals(obj as Location);
@ -59,6 +61,15 @@ public class Location : Properties.ILocation, ILocation, IEquatable<Location>
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)
{
return location is not null

View File

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

View File

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

View File

@ -12,17 +12,23 @@ public interface IPersonBirthday
string TestStatic_GetFormat() => PersonBirthday.GetFormat();
static string GetFormat() => PersonBirthday.GetFormat();
Models.PersonBirthday TestStatic_GetNextBirthDate(Properties.IStorage storage) => PersonBirthday.GetNextBirthDate(storage);
static Models.PersonBirthday GetNextBirthDate(Properties.IStorage storage) => PersonBirthday.GetNextBirthDate(storage);
string[] TestStatic_GetSegments(string personKey) => PersonBirthday.GetSegments(personKey);
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);
static string GetFormatted(Models.PersonBirthday personBirthday) => PersonBirthday.GetFormatted(personBirthday);
DateTime? TestStatic_Get(string personKey) => PersonBirthday.Get(personKey);
static DateTime? Get(string personKey) => PersonBirthday.Get(personKey);
string TestStatic_GetFileName(Models.PersonBirthday personBirthday) => PersonBirthday.GetFileName(personBirthday);
static string GetFileName(Models.PersonBirthday personBirthday) => PersonBirthday.GetFileName(personBirthday);
Models.PersonBirthday TestStatic_GetNextBirthDate(Properties.IStorage storage) => PersonBirthday.GetNextBirthDate(storage);
static Models.PersonBirthday GetNextBirthDate(Properties.IStorage storage) => PersonBirthday.GetNextBirthDate(storage);
bool TestStatic_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);
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);
static bool WriteAllText(string path, string contents, bool compareBeforeWrite) => Storage.WriteAllText(path, contents, compareBeforeWrite);
bool TestStatic_WriteAllText(string path, string contents, bool updateDateWhenMatches, bool 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);
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 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)
@ -189,7 +189,7 @@ internal abstract class Person
_ = Directory.CreateDirectory(directory);
string? rootDirectoryParent = Path.GetDirectoryName(storage.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent))
throw new Exception($"{nameof(rootDirectoryParent)} is null!");
throw new ArgumentNullException(nameof(rootDirectoryParent));
if (!Directory.Exists(rootDirectoryParent))
localKnownPeopleFile = string.Empty;
else

View File

@ -10,10 +10,33 @@ internal abstract class PersonBirthday
// ...
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 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 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 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;
string text;
@ -18,9 +18,24 @@ internal abstract class Storage
else
text = File.ReadAllText(path);
result = text != contents;
if (!result && updateDateWhenMatches)
File.SetLastWriteTime(path, DateTime.Now);
}
if (result)
File.WriteAllText(path, contents);
{
if (path.Contains("()"))
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;
}

View File

@ -24,7 +24,8 @@ public class Configuration
[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 = "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 Quality"), Required] public int? OutputQuality { get; set; }
[Display(Name = "Output Resolutions"), Required] public string[] OutputResolutions { get; set; }
@ -68,7 +69,8 @@ public class Configuration
MixedYearRelativePaths = Array.Empty<string>();
ModelDirectory = string.Empty;
ModelName = string.Empty;
NumJitters = null;
NumberOfJitters = null;
NumberOfTimesToUpsample = null;
OutputExtension = string.Empty;
OutputQuality = null;
OutputResolutions = Array.Empty<string>();

View File

@ -24,7 +24,8 @@ public class Configuration
protected readonly string[] _MixedYearRelativePaths;
protected readonly string _ModelDirectory;
protected readonly string _ModelName;
protected readonly int? _NumJitters;
protected readonly int? _NumberOfJitters;
protected readonly int? _NumberOfTimesToUpsample;
protected readonly string _OutputExtension;
protected readonly int? _OutputQuality;
protected readonly string[] _OutputResolutions;
@ -65,7 +66,8 @@ public class Configuration
public string[] MixedYearRelativePaths => _MixedYearRelativePaths;
public string ModelDirectory => _ModelDirectory;
public string ModelName => _ModelName;
public int? NumJitters => _NumJitters;
public int? NumberOfJitters => _NumberOfJitters;
public int? NumberOfTimesToUpsample => _NumberOfTimesToUpsample;
public string OutputExtension => _OutputExtension;
public int? OutputQuality => _OutputQuality;
public string[] OutputResolutions => _OutputResolutions;
@ -90,7 +92,7 @@ public class Configuration
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? 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;
_CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
@ -110,7 +112,8 @@ public class Configuration
_MixedYearRelativePaths = mixedYearRelativePaths;
_ModelDirectory = modelDirectory;
_ModelName = modelName;
_NumJitters = numJitters;
_NumberOfJitters = numberOfJitters;
_NumberOfTimesToUpsample = numberOfTimesToUpsample;
_OutputExtension = outputExtension;
_OutputQuality = outputQuality;
_OutputResolutions = outputResolutions;

View File

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

View File

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

View File

@ -65,7 +65,8 @@
"MaxItemsInDistanceCollection": 50,
"ModelDirectory": "C:/GitHub/dlib-models",
"ModelName": "Hog",
"NumJitters": 1,
"NumberOfJitters": 1,
"NumberOfTimesToUpsample": 1,
"OutputExtension": ".jpg",
"OutputQuality": 95,
"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
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceRecognitionDotNet", "FaceRecognitionDotNet\FaceRecognitionDotNet.csproj", "{FAD03DA9-E8B1-4BBE-B8D0-2ADD2F2BC758}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestsWithFaceRecognitionDotNet", "TestsWithFaceRecognitionDotNet\TestsWithFaceRecognitionDotNet.csproj", "{A67D73C7-A1A1-4443-B681-776339CFA08A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
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}.Release|Any CPU.ActiveCfg = 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
EndGlobal