Get Unable to Match Count and Rename Matches

This commit is contained in:
Mike Phares 2022-09-24 16:39:15 -07:00
parent e64c713926
commit 751a61529c
32 changed files with 983 additions and 668 deletions

View File

@ -10,30 +10,53 @@ namespace View_by_Distance.Distance.Models;
public class E_Distance : Shared.Models.Methods.IFaceDistance public class E_Distance : Shared.Models.Methods.IFaceDistance
{ {
public static void SaveFaceDistances(Property.Models.Configuration propertyConfiguration, string eResultsFullGroupDirectory, SortingContainer[] sortingContainers) private readonly Serilog.ILogger? _Log;
private readonly string _ResultAllInOne;
private readonly int _FaceDistancePermyriad;
private readonly double _FaceDistanceTolerance;
private readonly int _SortingDaysDeltaTolerance;
private readonly bool _DistanceMoveUnableToMatch;
private readonly int _DistancePixelDistanceTolerance;
private readonly double _FaceDistanceMinimumConfidence;
private readonly int _SortingMaximumPerFaceShouldBeHigh;
public E_Distance(bool distanceMoveUnableToMatch, int distancePixelDistanceTolerance, double faceDistanceMinimumConfidence, int faceDistancePermyriad, double faceDistanceTolerance, string resultAllInOne, int sortingDaysDeltaTolerance, int sortingMaximumPerFaceShouldBeHigh)
{ {
string eDistanceContentCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, "([])"); _ResultAllInOne = resultAllInOne;
_Log = Serilog.Log.ForContext<E_Distance>();
_FaceDistancePermyriad = faceDistancePermyriad;
_FaceDistanceTolerance = faceDistanceTolerance;
_DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
_SortingDaysDeltaTolerance = sortingDaysDeltaTolerance;
_FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
_DistancePixelDistanceTolerance = distancePixelDistanceTolerance;
_SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
}
public static void SaveFaceDistances(Property.Models.Configuration configuration, SortingContainer[] sortingContainers)
{
string eDistanceContentCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(E_Distance), "([])");
if (!Directory.Exists(eDistanceContentCollectionDirectory)) if (!Directory.Exists(eDistanceContentCollectionDirectory))
_ = Directory.CreateDirectory(eDistanceContentCollectionDirectory); _ = Directory.CreateDirectory(eDistanceContentCollectionDirectory);
#pragma warning disable #pragma warning disable
string[] results = (from l in sortingContainers select string.Concat(l.Sorting.WithinRange, '\t', l.Sorting.DistancePermyriad, '\t', l.Sorting.DaysDelta, '\t', l.Sorting.Id, '\t', l.Sorting.NormalizedPixelPercentage, '\t', l.Sorting.Older, '\t', l.Face.Mapping.MappingFromItem.Id, '\t', l.Face.Mapping.MappingFromLocation.NormalizedPixelPercentage)).ToArray(); string[] results = (from l in sortingContainers select string.Concat(l.Sorting.WithinRange, '\t', l.Sorting.DistancePermyriad, '\t', l.Sorting.DaysDelta, '\t', l.Sorting.Id, '\t', l.Sorting.NormalizedPixelPercentage, '\t', l.Sorting.Older, '\t', l.Face.Mapping.MappingFromItem.Id, '\t', l.Face.Mapping.MappingFromLocation.NormalizedPixelPercentage)).ToArray();
#pragma warning restore #pragma warning restore
string eDistanceContentFileName = Path.Combine(eDistanceContentCollectionDirectory, $"{propertyConfiguration.ResultAllInOne}.tvs"); string eDistanceContentFileName = Path.Combine(eDistanceContentCollectionDirectory, $"{configuration.ResultAllInOne}.tvs");
File.WriteAllLines(eDistanceContentFileName, results); File.WriteAllLines(eDistanceContentFileName, results);
} }
private static List<Sorting> GetSortingCollection(Configuration configuration, MapLogic mapLogic, List<FaceDistance> faceDistanceEncodings, int faceDistanceContainersLength, int i, FaceDistance faceDistanceEncoding) private List<Sorting> GetSortingCollection(MapLogic mapLogic, List<FaceDistance> faceDistanceEncodings, int faceDistanceContainersLength, int i, FaceDistance faceDistanceEncoding)
{ {
List<Sorting> results; List<Sorting> results;
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding); List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
if (faceDistanceLengths.Count != faceDistanceContainersLength) if (faceDistanceLengths.Count != faceDistanceContainersLength)
throw new NotSupportedException(); throw new NotSupportedException();
bool anyLowerThanTolerance = (from l in faceDistanceLengths where l.Length is not null && l.Length.Value != 0 && l.Length.Value < configuration.FaceDistanceTolerance select true).Any(); bool anyLowerThanTolerance = (from l in faceDistanceLengths where l.Length is not null && l.Length.Value != 0 && l.Length.Value < _FaceDistanceTolerance select true).Any();
results = mapLogic.GetSortingCollection(i, faceDistanceEncoding, faceDistanceLengths, anyLowerThanTolerance); results = mapLogic.GetSortingCollection(i, faceDistanceEncoding, faceDistanceLengths, anyLowerThanTolerance);
return results; return results;
} }
private static List<SortingContainer> GetSortingContainers(Configuration configuration, Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection) private List<SortingContainer> GetSortingContainers(Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection)
{ {
List<SortingContainer> results = new(); List<SortingContainer> results = new();
SortingContainer sortingContainer; SortingContainer sortingContainer;
@ -42,11 +65,11 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
{ {
if (face.Mapping is null || faceDistanceEncoding.NormalizedPixelPercentage is null) if (face.Mapping is null || faceDistanceEncoding.NormalizedPixelPercentage is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (face.Mapping.MappingFromLocation.Confidence < configuration.FaceDistanceMinimumConfidence || sorting.DistancePermyriad > configuration.FaceDistancePermyriad || sorting.DaysDelta > configuration.SortingDaysDeltaTolerance) if (face.Mapping.MappingFromLocation.Confidence < _FaceDistanceMinimumConfidence || sorting.DistancePermyriad > _FaceDistancePermyriad || sorting.DaysDelta > _SortingDaysDeltaTolerance)
continue; continue;
sortingContainer = new(face, sorting); sortingContainer = new(face, sorting);
results.Add(sortingContainer); results.Add(sortingContainer);
if (results.Count >= configuration.SortingMaximumPerFaceShouldBeHigh) if (results.Count >= _SortingMaximumPerFaceShouldBeHigh)
break; break;
} }
return results; return results;
@ -64,7 +87,16 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
return faceDistanceEncodings; return faceDistanceEncodings;
} }
private static FaceDistanceContainer[] GetFaceDistanceContainers(List<Face> selectedFilteredFaces) private static FaceDistanceContainer[] GetOrderedFaceDistanceContainers(List<FaceDistanceContainer> collection)
{
FaceDistanceContainer[] results;
results = (from l in collection orderby l.FaceDistance.Encoding is not null select l).ToArray();
if (results.Any() && results[0].FaceDistance.Encoding is null)
throw new Exception("Sorting failed!");
return results;
}
private static FaceDistanceContainer[] GetOrderedFaceDistanceContainers(Face[] selectedFilteredFaces)
{ {
FaceDistanceContainer[] results; FaceDistanceContainer[] results;
FaceDistance faceDistance; FaceDistance faceDistance;
@ -80,23 +112,22 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
faceDistanceContainer = new(face, faceDistance); faceDistanceContainer = new(face, faceDistance);
collection.Add(faceDistanceContainer); collection.Add(faceDistanceContainer);
} }
results = (from l in collection orderby l.FaceDistance.Encoding is not null select l).ToArray(); results = GetOrderedFaceDistanceContainers(collection);
if (results.Any() && results[0].FaceDistance.Encoding is null)
throw new Exception("Sorting failed!");
return results; return results;
} }
public static SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, MapLogic mapLogic, List<Face> selectedFilteredFaces) public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, long ticks, MapLogic mapLogic, Face[] selectedFilteredFaces)
{ {
SortingContainer[] results; SortingContainer[] results;
List<SortingContainer> collection = new(); List<SortingContainer> collection = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
FaceDistanceContainer[] faceDistanceContainers = GetFaceDistanceContainers(selectedFilteredFaces); FaceDistanceContainer[] faceDistanceContainers = GetOrderedFaceDistanceContainers(selectedFilteredFaces);
List<FaceDistance> faceDistanceEncodings = GetFaceDistanceEncodings(faceDistanceContainers); List<FaceDistance> faceDistanceEncodings = GetFaceDistanceEncodings(faceDistanceContainers);
string message = $") {faceDistanceContainers.Length:000} Get Sorting Containers Then Set Face Mapping Sorting Collection - {totalSeconds} total second(s)"; string message = $") {faceDistanceContainers.Length:000} Get Sorting Containers Then Set Face Mapping Sorting Collection - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
selectedFilteredFaces.Clear(); foreach (Face face in selectedFilteredFaces)
face.ClearFaceDistance();
using ProgressBar progressBar = new(faceDistanceContainers.Length, message, options); using ProgressBar progressBar = new(faceDistanceContainers.Length, message, options);
_ = Parallel.For(0, faceDistanceContainers.Length, parallelOptions, (i, state) => _ = Parallel.For(0, faceDistanceContainers.Length, parallelOptions, (i, state) =>
{ {
@ -105,8 +136,8 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
if (face.Mapping is null) if (face.Mapping is null)
throw new NotSupportedException(); throw new NotSupportedException();
FaceDistance faceDistanceEncoding = faceDistanceContainers[i].FaceDistance; FaceDistance faceDistanceEncoding = faceDistanceContainers[i].FaceDistance;
List<Sorting> sortingCollection = GetSortingCollection(configuration, mapLogic, faceDistanceEncodings, faceDistanceContainers.Length, i, faceDistanceEncoding); List<Sorting> sortingCollection = GetSortingCollection(mapLogic, faceDistanceEncodings, faceDistanceContainers.Length, i, faceDistanceEncoding);
List<SortingContainer> sortingContainers = GetSortingContainers(configuration, face, faceDistanceEncoding, sortingCollection); List<SortingContainer> sortingContainers = GetSortingContainers(face, faceDistanceEncoding, sortingCollection);
lock (collection) lock (collection)
collection.AddRange(sortingContainers); collection.AddRange(sortingContainers);
lock (face) lock (face)
@ -116,49 +147,73 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
return results; return results;
} }
public static List<Face> GetSelectedFilteredFaces(List<Face> distinctFilteredFaces) public static Face[] GetSelectedFilteredFaces(List<Face> distinctFilteredFaces)
{ {
List<Face> results; Face[] results = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromItem.MinimumDateTime descending select l).ToArray();
Face[] orderedFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromItem.MinimumDateTime descending select l).ToArray();
results = orderedFilteredFaces.ToList();
return results; return results;
} }
public static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, List<Face> selectedFilteredFaces) public static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, Face[] selectedFilteredFaces)
{ {
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
string message = $") {selectedFilteredFaces.Count:000} Load Face Encoding - {totalSeconds} total second(s)"; string message = $") {selectedFilteredFaces.Length:000} Load Face Encoding - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(selectedFilteredFaces.Count, message, options); using ProgressBar progressBar = new(selectedFilteredFaces.Length, message, options);
_ = Parallel.For(0, selectedFilteredFaces.Count, parallelOptions, (i, state) => _ = Parallel.For(0, selectedFilteredFaces.Length, parallelOptions, (i, state) =>
{ {
progressBar.Tick();
FaceDistance faceDistance;
Face face = selectedFilteredFaces[i]; Face face = selectedFilteredFaces[i];
FaceRecognitionDotNet.FaceEncoding faceEncoding;
if (face.FaceEncoding is null || face.Mapping is null) if (face.FaceEncoding is null || face.Mapping is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
return;
progressBar.Tick();
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
faceDistance = new(face.Mapping.MappingFromLocation.Confidence, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedPixelPercentage); FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.Confidence, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
lock (face) lock (face)
face.FaceDistanceAdd(faceDistance); face.SetFaceDistance(faceDistance);
}); });
} }
List<Face> Shared.Models.Methods.IFaceDistance.GetMatchingFaces(double faceDistanceTolerance, string checkFile, List<Face> faces) private static FaceDistanceContainer[] GetOrderedFaceDistanceContainers(MappingFromItem mappingFromItem, List<Face> faces)
{ {
List<Face> results = new(); FaceDistanceContainer[] results;
FaceDistance faceDistance;
int normalizedPixelPercentage;
FaceDistanceContainer faceDistanceContainer;
List<FaceDistanceContainer> collection = new();
foreach (Face face in faces)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
throw new NotSupportedException();
normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
faceDistance = new(face.Location.Confidence, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedPixelPercentage);
else
{
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
faceDistance = new(face.Location.Confidence, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedPixelPercentage);
lock (faces)
face.SetFaceDistance(faceDistance);
}
faceDistanceContainer = new(face, faceDistance);
collection.Add(faceDistanceContainer);
}
results = GetOrderedFaceDistanceContainers(collection);
return results;
}
private static List<(Face Face, double Length)> GetValues(double faceDistanceTolerance, MappingFromItem mappingFromItem, List<Face> faces, string json)
{
List<(Face Face, double Length)> results = new();
Face face; Face face;
FaceDistance faceDistanceLength; FaceDistance faceDistanceLength;
string json = File.ReadAllText(checkFile);
List<(Face Face, double Length)> collection = new();
Shared.Models.FaceEncoding? modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json); Shared.Models.FaceEncoding? modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
if (modelsFaceEncoding is null) if (modelsFaceEncoding is null)
throw new NotSupportedException(); throw new NotSupportedException();
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding); FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
FaceDistance faceDistanceEncoding = new(faceRecognitionDotNetFaceEncoding); FaceDistance faceDistanceEncoding = new(faceRecognitionDotNetFaceEncoding);
FaceDistanceContainer[] faceDistanceContainers = GetFaceDistanceContainers(faces); FaceDistanceContainer[] faceDistanceContainers = GetOrderedFaceDistanceContainers(mappingFromItem, faces);
int faceDistanceContainersLength = faceDistanceContainers.Length; int faceDistanceContainersLength = faceDistanceContainers.Length;
if (faceDistanceContainersLength != faces.Count) if (faceDistanceContainersLength != faces.Count)
throw new NotSupportedException(); throw new NotSupportedException();
@ -172,12 +227,19 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
{ {
face = faces[i]; face = faces[i];
faceDistanceLength = faceDistanceLengths[i]; faceDistanceLength = faceDistanceLengths[i];
if (face.Mapping is null || faceDistanceLength.Length is null) if (faceDistanceLength.Length is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (faceDistanceLength.Length.Value > faceDistanceTolerance) if (faceDistanceLength.Length.Value > faceDistanceTolerance)
continue; continue;
collection.Add(new(face, faceDistanceLength.Length.Value)); results.Add(new(face, faceDistanceLength.Length.Value));
} }
return results;
}
private static List<Face> GetMatchingFaces(double faceDistanceTolerance, MappingFromItem mappingFromItem, List<Face> faces, string json)
{
List<Face> results = new();
List<(Face Face, double Length)> collection = GetValues(faceDistanceTolerance, mappingFromItem, faces, json);
if (collection.Any()) if (collection.Any())
{ {
collection = (from l in collection orderby l.Length select l).ToList(); collection = (from l in collection orderby l.Length select l).ToList();
@ -237,4 +299,320 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
} }
} }
private void MoveUnableToMatch(string eDistanceContentDirectory, string file)
{
bool result;
string? fileName = Path.GetFileName(file);
string? directoryName = Path.GetDirectoryName(file);
if (fileName is null || directoryName is null)
result = false;
else
{
if (string.IsNullOrEmpty(directoryName) || string.IsNullOrEmpty(directoryName) || !directoryName.Contains(eDistanceContentDirectory))
result = false;
else
{
List<string> directoryNames = new();
string? checkDirectoryName = directoryName;
for (int i = 0; i < int.MaxValue; i++)
{
if (string.IsNullOrEmpty(checkDirectoryName))
continue;
directoryNames.Add(Path.GetFileName(checkDirectoryName));
checkDirectoryName = Path.GetDirectoryName(checkDirectoryName);
if (string.IsNullOrEmpty(checkDirectoryName))
continue;
if (checkDirectoryName == eDistanceContentDirectory)
break;
}
if (string.IsNullOrEmpty(checkDirectoryName) || !directoryNames.Any() || !long.TryParse(directoryNames[^1][1..^1], out long directoryTicks))
{
result = false;
File.Delete(file);
}
else
{
checkDirectoryName = Path.Combine(checkDirectoryName, $"({directoryTicks}{_FaceDistanceTolerance.ToString()[1..]})");
for (int i = directoryNames.Count - 1 - 1; i > -1; i--)
checkDirectoryName = Path.Combine(checkDirectoryName, directoryNames[i]);
if (!Directory.Exists(checkDirectoryName))
_ = Directory.CreateDirectory(checkDirectoryName);
File.Move(file, Path.Combine(checkDirectoryName, fileName));
result = true;
}
}
}
if (result)
{ }
}
public static string? GetFaceEncoding(string file)
{
string? result;
List<string> results = new();
const string comment = "Comment: ";
if (File.Exists(file))
{
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file);
foreach (MetadataExtractor.Directory directory in directories)
{
if (directory.Name != "PNG-tEXt")
continue;
foreach (MetadataExtractor.Tag tag in directory.Tags)
{
if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description))
continue;
if (!tag.Description.StartsWith(comment))
continue;
results.Add(tag.Description);
}
}
}
result = results.Any() ? results[0][comment.Length..] : null;
return result;
}
private static Face[] GetMatchingFaces(int pixelDistanceTolerance, List<Face> faces)
{
Face[] results;
int? x;
int? y;
double distance;
double center = 2f;
double xCenterValue;
double yCenterValue;
string normalizedPixelPercentagePadded;
List<(double Order, Face Face)> collection = new();
foreach (Face face in faces)
{
if (face.Location is null || face.OutputResolution is null || face.Mapping is null)
throw new NotSupportedException();
xCenterValue = (face.Location.Left + face.Location.Right) / center;
yCenterValue = (face.Location.Top + face.Location.Bottom) / center;
if (xCenterValue < face.Location.Left || xCenterValue > face.Location.Right)
throw new Exception();
if (yCenterValue < face.Location.Top || yCenterValue > face.Location.Bottom)
throw new Exception();
normalizedPixelPercentagePadded = Shared.Models.Stateless.Methods.ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
(x, y) = Shared.Models.Stateless.Methods.ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution.Width, face.OutputResolution.Height, normalizedPixelPercentagePadded);
if (x is null || y is null)
throw new NotSupportedException();
distance = Math.Sqrt(Math.Pow(xCenterValue - x.Value, 2) + Math.Pow(yCenterValue - y.Value, 2));
collection.Add(new(distance, face));
}
results = (from l in collection orderby l.Order where l.Order < pixelDistanceTolerance select l.Face).ToArray();
if (results.Any())
{
if (results.Any())
{ }
}
return results;
}
private static string[] GetMatchingDuplicates(string[] mappedFaceFiles, List<string> duplicateMappedFaceFiles, string mappedFaceFile)
{
string[] results;
string checkFile;
FileInfo fileInfo = new(mappedFaceFile);
List<(long Length, string FullName)> collection = new();
if (fileInfo.Exists)
collection.Add(new(fileInfo.Length, fileInfo.FullName));
string fileName = Path.GetFileName(mappedFaceFile);
foreach (string file in mappedFaceFiles)
{
if (duplicateMappedFaceFiles.Contains(file))
continue;
if (file == mappedFaceFile || !file.EndsWith(fileName))
continue;
fileInfo = new(file);
if (!fileInfo.Exists)
continue;
collection.Add(new(fileInfo.Length, fileInfo.FullName));
}
collection = collection.OrderBy(l => l.Length).ToList();
for (int i = 0; i < collection.Count - 1; i++)
{
checkFile = string.Concat(collection[i].FullName, ".dup");
if (File.Exists(checkFile))
continue;
File.Move(collection[i].FullName, checkFile);
}
results = (from l in collection select l.FullName).ToArray();
return results;
}
private static List<Face> GetMatchingFaces(List<Face> faces, string? json)
{
List<Face> results = new();
string check;
foreach (Face face in faces)
{
if (json is null || face.FaceEncoding is null)
continue;
if (!json.Contains(face.FaceEncoding.RawEncoding[0].ToString()))
continue;
check = JsonSerializer.Serialize(face.FaceEncoding);
if (check != json)
continue;
results.Add(face);
}
return results;
}
private static FileInfo? CheckFileThenGetFileInfo(string facesFileNameExtension, Item item, string mappedFaceDirectory, string mappedFaceFile, List<Face> checkFaces)
{
FileInfo? result = null;
string checkFile;
string deterministicHashCodeKey;
foreach (Face face in checkFaces)
{
if (checkFaces.Count != 1)
break;
if (item.Property?.Id is null || item.ImageFileHolder is null)
throw new NotSupportedException();
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
throw new NotSupportedException();
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
checkFile = Path.Combine(mappedFaceDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}");
if (checkFile == mappedFaceFile)
continue;
result = new FileInfo(checkFile);
if (!result.Exists)
continue;
File.Delete(result.FullName);
result = null;
}
return result;
}
public (int, int) GetUnableToMatchCountAndRenameMatches(string facesFileNameExtension, string eDistanceContentDirectory, List<string[]> duplicateMappedFaceFilesCollection, Item item, List<Face> faces, string[] mappedFaceFiles)
{
int result = 0;
int? id;
string? json;
bool debugCheck;
int renamed = 0;
bool? isWrongYear;
FileInfo? fileInfo;
DateTime minimumDateTime;
string? mappedFaceDirectory;
List<Face> checkFaces = new();
List<int> debugChecks = new();
int? normalizedPixelPercentage;
MappingFromItem mappingFromItem;
int normalizedPixelPercentageLoop;
List<int> normalizedPixelPercentages;
List<string> duplicateMappedFaceFiles = new();
Dictionary<int, List<int>> idToNormalizedPixelPercentages = new();
foreach (string mappedFaceFile in mappedFaceFiles)
{
mappedFaceDirectory = Path.GetDirectoryName(mappedFaceFile);
if (mappedFaceDirectory is null)
throw new NotSupportedException();
if (item.Property?.Id is null)
throw new NotSupportedException();
if (duplicateMappedFaceFiles.Contains(mappedFaceFile))
continue;
(id, normalizedPixelPercentage, _) = Shared.Models.Stateless.Methods.IMapping.GetReversedDeterministicHashCodeKey(
Shared.Models.Stateless.ILocation.Digits,
facesFileNameExtension,
mappedFaceFile);
if (id is null || normalizedPixelPercentage is null)
{
result++;
continue;
}
if (id.Value != item.Property.Id.Value)
continue;
if (item.Property?.Id is null || item.ImageFileHolder is null || item.ResizedFileHolder is null)
continue;
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
mappingFromItem = new(item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.ResizedFileHolder);
json = null;
debugCheck = false;
checkFaces.Clear();
debugChecks.Clear();
if (!idToNormalizedPixelPercentages.ContainsKey(id.Value))
idToNormalizedPixelPercentages.Add(id.Value, new());
normalizedPixelPercentages = idToNormalizedPixelPercentages[id.Value];
foreach (Face face in faces)
{
if (face.Location is null || face.OutputResolution is null)
throw new NotSupportedException();
normalizedPixelPercentageLoop = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
debugChecks.Add(normalizedPixelPercentageLoop);
if (normalizedPixelPercentage.Value != normalizedPixelPercentageLoop)
continue;
if (normalizedPixelPercentages.Contains(normalizedPixelPercentageLoop))
{
duplicateMappedFaceFiles.AddRange(GetMatchingDuplicates(mappedFaceFiles, duplicateMappedFaceFiles, mappedFaceFile));
continue;
}
debugCheck = true;
checkFaces.Add(face);
if (!debugCheck)
debugChecks.Add(normalizedPixelPercentageLoop);
}
if (checkFaces.Count != 1)
{
checkFaces.Clear();
json = GetFaceEncoding(mappedFaceFile);
if (json is null)
{
result++;
if (_DistanceMoveUnableToMatch)
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile);
continue;
}
checkFaces.AddRange(GetMatchingFaces(faces, json));
}
if (checkFaces.Count != 1 && !string.IsNullOrEmpty(json))
{
checkFaces.Clear();
if (json is null)
{
result++;
if (_DistanceMoveUnableToMatch)
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile);
continue;
}
checkFaces.AddRange(GetMatchingFaces(_FaceDistanceTolerance, mappingFromItem, faces, json));
}
if (checkFaces.Count != 1 && _DistancePixelDistanceTolerance > 0)
{
checkFaces.Clear();
checkFaces.AddRange(GetMatchingFaces(_DistancePixelDistanceTolerance, faces));
}
if (!checkFaces.Any() && faces.Count == 1)
checkFaces.AddRange(faces);
if (!checkFaces.Any())
{
result++;
if (_DistanceMoveUnableToMatch)
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile);
continue;
}
if (checkFaces.Count != 1)
{
result++;
if (_DistanceMoveUnableToMatch)
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile);
continue;
}
normalizedPixelPercentages.Add(normalizedPixelPercentage.Value);
fileInfo = CheckFileThenGetFileInfo(facesFileNameExtension, item, mappedFaceDirectory, mappedFaceFile, checkFaces);
if (fileInfo is null)
continue;
File.Move(mappedFaceFile, fileInfo.FullName);
renamed++;
}
if (duplicateMappedFaceFiles.Any())
{
lock (duplicateMappedFaceFilesCollection)
duplicateMappedFaceFilesCollection.Add(duplicateMappedFaceFiles.ToArray());
}
return new(result, renamed);
}
} }

View File

@ -28,27 +28,25 @@ public class D_Face
private readonly Model _Model; private readonly Model _Model;
private readonly string _ArgZero; private readonly string _ArgZero;
private readonly int _NumberOfJitters;
private readonly Serilog.ILogger? _Log; private readonly Serilog.ILogger? _Log;
private readonly bool _OverrideForFaceImages;
private readonly bool _RetryImagesWithoutAFace;
private readonly Configuration _Configuration; private readonly Configuration _Configuration;
private readonly int _NumberOfTimesToUpsample;
private readonly ImageCodecInfo _ImageCodecInfo; private readonly ImageCodecInfo _ImageCodecInfo;
private readonly ModelParameter _ModelParameter; private readonly ModelParameter _ModelParameter;
private readonly PredictorModel _PredictorModel; private readonly PredictorModel _PredictorModel;
private readonly bool _CheckDFaceAndUpWriteDates;
private readonly bool _PropertiesChangedForFaces;
private readonly ConstructorInfo _ConstructorInfo; private readonly ConstructorInfo _ConstructorInfo;
private readonly int _FaceDistanceHiddenImageFactor;
private readonly EncoderParameters _EncoderParameters; private readonly EncoderParameters _EncoderParameters;
private readonly ImageCodecInfo _HiddenImageCodecInfo; private readonly ImageCodecInfo _HiddenImageCodecInfo;
private readonly bool _ForceFaceLastWriteTimeToCreationTime;
private readonly EncoderParameters _HiddenEncoderParameters; private readonly EncoderParameters _HiddenEncoderParameters;
private readonly JsonSerializerOptions _WriteIndentedAndWhenWritingNull; private readonly JsonSerializerOptions _WriteIndentedAndWhenWritingNull;
private readonly bool _CheckDFaceAndUpWriteDates;
private readonly int _FaceDistanceHiddenImageFactor;
private readonly bool _ForceFaceLastWriteTimeToCreationTime;
private readonly int _LocationDigits;
private readonly int _LocationFactor;
private readonly int _NumberOfJitters;
private readonly int _NumberOfTimesToUpsample;
private readonly bool _OverrideForFaceImages;
private readonly bool _PropertiesChangedForFaces;
public D_Face( public D_Face(
string argZero, string argZero,
bool checkDFaceAndUpWriteDates, bool checkDFaceAndUpWriteDates,
@ -61,13 +59,12 @@ public class D_Face
string hiddenFileNameExtension, string hiddenFileNameExtension,
ImageCodecInfo hiddenImageCodecInfo, ImageCodecInfo hiddenImageCodecInfo,
ImageCodecInfo imageCodecInfo, ImageCodecInfo imageCodecInfo,
int locationDigits,
int locationFactor,
Model model, Model model,
ModelParameter modelParameter, ModelParameter modelParameter,
int numberOfJitters, int numberOfJitters,
int numberOfTimesToUpsample, int numberOfTimesToUpsample,
bool overrideForFaceImages, bool overrideForFaceImages,
bool retryImagesWithoutAFace,
PredictorModel predictorModel, PredictorModel predictorModel,
bool propertiesChangedForFaces) bool propertiesChangedForFaces)
{ {
@ -75,8 +72,6 @@ public class D_Face
_ArgZero = argZero; _ArgZero = argZero;
_Configuration = configuration; _Configuration = configuration;
_ImageCodecInfo = imageCodecInfo; _ImageCodecInfo = imageCodecInfo;
_LocationDigits = locationDigits;
_LocationFactor = locationFactor;
_ModelParameter = modelParameter; _ModelParameter = modelParameter;
_PredictorModel = predictorModel; _PredictorModel = predictorModel;
_NumberOfJitters = numberOfJitters; _NumberOfJitters = numberOfJitters;
@ -86,6 +81,7 @@ public class D_Face
AngleBracketCollection = new List<string>(); AngleBracketCollection = new List<string>();
_HiddenImageCodecInfo = hiddenImageCodecInfo; _HiddenImageCodecInfo = hiddenImageCodecInfo;
_OverrideForFaceImages = overrideForFaceImages; _OverrideForFaceImages = overrideForFaceImages;
_RetryImagesWithoutAFace = retryImagesWithoutAFace;
_HiddenEncoderParameters = hiddenEncoderParameters; _HiddenEncoderParameters = hiddenEncoderParameters;
_HiddenFileNameExtension = hiddenFileNameExtension; _HiddenFileNameExtension = hiddenFileNameExtension;
_NumberOfTimesToUpsample = numberOfTimesToUpsample; _NumberOfTimesToUpsample = numberOfTimesToUpsample;
@ -145,15 +141,15 @@ public class D_Face
{ {
if (fileInfo is null) if (fileInfo is null)
continue; continue;
if (face.FaceEncoding is null || face?.Location?.NormalizedPixelPercentage is null || face?.OutputResolution is null) if (face.FaceEncoding is null || face?.Location is null || face?.OutputResolution is null)
continue; continue;
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, _LocationDigits, _LocationFactor, source.Height, source.Width, collection.Count); location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, ILocation.Digits, ILocation.Factor, source.Height, source.Width, collection.Count);
if (location is null) if (location is null)
continue; continue;
width = location.Right - location.Left; width = location.Right - location.Left;
height = location.Bottom - location.Top; height = location.Bottom - location.Top;
json = JsonSerializer.Serialize(face.FaceEncoding); json = JsonSerializer.Serialize(face.FaceEncoding);
pixel = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, _LocationDigits, _LocationFactor, face.OutputResolution); pixel = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, ILocation.Digits, ILocation.Factor, face.OutputResolution);
rectangle = new Rectangle(location.Left, location.Top, width, height); rectangle = new Rectangle(location.Left, location.Top, width, height);
using (bitmap = new(width, height)) using (bitmap = new(width, height))
{ {
@ -165,7 +161,7 @@ public class D_Face
} }
if (File.Exists(fileName)) if (File.Exists(fileName))
File.Delete(fileName); File.Delete(fileName);
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(_FaceDistanceHiddenImageFactor, face.Location, _LocationDigits, _LocationFactor, source.Height, source.Width, collection.Count); location = Shared.Models.Stateless.Methods.ILocation.GetLocation(_FaceDistanceHiddenImageFactor, face.Location, ILocation.Digits, ILocation.Factor, source.Height, source.Width, collection.Count);
if (location is null) if (location is null)
continue; continue;
width = location.Right - location.Left; width = location.Right - location.Left;
@ -199,22 +195,22 @@ public class D_Face
{ unknownImage = null; } { unknownImage = null; }
} }
if (unknownImage is null) if (unknownImage is null)
results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null)); results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, location: null));
else else
{ {
List<(int, Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection; List<(Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection;
FaceRecognition faceRecognition = new(_NumberOfTimesToUpsample, _NumberOfJitters, _PredictorModel, _Model, _ModelParameter); FaceRecognition faceRecognition = new(_NumberOfTimesToUpsample, _NumberOfJitters, _PredictorModel, _Model, _ModelParameter);
collection = faceRecognition.GetCollection(unknownImage, includeFaceEncoding: true, includeFaceParts: true, sortByNormalizedPixelPercentage: true); collection = faceRecognition.GetCollection(unknownImage, includeFaceEncoding: true, includeFaceParts: true);
if (!collection.Any()) if (!collection.Any())
results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null)); results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, location: null));
else else
{ {
double[] rawEncoding; double[] rawEncoding;
Shared.Models.Face face; Shared.Models.Face face;
Shared.Models.FaceEncoding convertedFaceEncoding; Shared.Models.FaceEncoding convertedFaceEncoding;
foreach ((int locationIndex, Location location, FaceRecognitionDotNet.FaceEncoding? faceEncoding, Dictionary<FacePart, FacePoint[]>? faceParts) in collection) foreach ((Location location, FaceRecognitionDotNet.FaceEncoding? faceEncoding, Dictionary<FacePart, FacePoint[]>? faceParts) in collection)
{ {
face = new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, locationIndex, location); face = new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, location);
if (faceEncoding is not null) if (faceEncoding is not null)
{ {
rawEncoding = faceEncoding.GetRawEncoding(); rawEncoding = faceEncoding.GetRawEncoding();
@ -246,8 +242,6 @@ public class D_Face
if (string.IsNullOrEmpty(dResultsFullGroupDirectory)) if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
throw new NullReferenceException(nameof(dResultsFullGroupDirectory)); throw new NullReferenceException(nameof(dResultsFullGroupDirectory));
string json; string json;
int?[] normalizedPixelPercentageCollection;
int normalizedPixelPercentageDistinctCount;
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) }; string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{item.ImageFileHolder.NameWithoutExtension}.json"); string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{item.ImageFileHolder.NameWithoutExtension}.json");
@ -296,13 +290,6 @@ public class D_Face
results = JsonSerializer.Deserialize<List<Shared.Models.Face>>(json); results = JsonSerializer.Deserialize<List<Shared.Models.Face>>(json);
if (results is null) if (results is null)
throw new NullReferenceException(nameof(results)); throw new NullReferenceException(nameof(results));
if (!_ForceFaceLastWriteTimeToCreationTime)
{
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
throw new Exception($"Not distinct! <{fileInfo.FullName}>");
}
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), fileInfo.LastWriteTime)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), fileInfo.LastWriteTime));
} }
catch (Exception) catch (Exception)
@ -311,22 +298,22 @@ public class D_Face
parseExceptions.Add(nameof(D_Face)); parseExceptions.Add(nameof(D_Face));
} }
} }
if (results is null) if (results is null || (_RetryImagesWithoutAFace && results.Count == 1 && results[0].FaceEncoding is null))
{ {
bool wasNull = results is null;
results = GetFaces(item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation); results = GetFaces(item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation);
json = JsonSerializer.Serialize(results, _WriteIndentedAndWhenWritingNull); if (wasNull || (!wasNull && results.Any(l => l.FaceEncoding is not null)))
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime; {
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max(); json = JsonSerializer.Serialize(results, _WriteIndentedAndWhenWritingNull);
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime)) bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now)); DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now));
}
} }
if (_ForceFaceLastWriteTimeToCreationTime) if (_ForceFaceLastWriteTimeToCreationTime)
{ {
results = (from l in results select new Shared.Models.Face(_LocationDigits, _LocationFactor, results.Count, l)).ToList(); results = (from l in results select new Shared.Models.Face(ILocation.Digits, ILocation.Factor, results.Count, l)).ToList();
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
throw new Exception($"Not distinct! <{fileInfo.FullName}>");
json = JsonSerializer.Serialize(results, _WriteIndentedAndWhenWritingNull); json = JsonSerializer.Serialize(results, _WriteIndentedAndWhenWritingNull);
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime; bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max(); DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
@ -340,7 +327,7 @@ public class D_Face
return results; return results;
} }
public void SaveFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Shared.Models.Face> faceCollection) public void SaveFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Shared.Models.Face> faces)
{ {
if (item.ImageFileHolder is null) if (item.ImageFileHolder is null)
throw new NullReferenceException(nameof(item.ImageFileHolder)); throw new NullReferenceException(nameof(item.ImageFileHolder));
@ -349,22 +336,22 @@ public class D_Face
FileInfo fileInfo; FileInfo fileInfo;
bool check = false; bool check = false;
string parentCheck; string parentCheck;
string deterministicHashCodeKeyDisplay; string deterministicHashCodeKey;
List<(Shared.Models.Face, FileInfo?, string)> collection = new(); List<(Shared.Models.Face, FileInfo?, string)> collection = new();
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) }; string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension); string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (!Directory.Exists(facesDirectory)) if (!Directory.Exists(facesDirectory))
_ = Directory.CreateDirectory(facesDirectory); _ = Directory.CreateDirectory(facesDirectory);
foreach (Shared.Models.Face face in faceCollection) foreach (Shared.Models.Face face in faces)
{ {
if (item.Property?.Id is null || face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null) if (item.Property?.Id is null || face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
{ {
collection.Add(new(face, null, string.Empty)); collection.Add(new(face, null, string.Empty));
continue; continue;
} }
deterministicHashCodeKeyDisplay = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value); deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, ILocation.Digits, ILocation.Factor, face.OutputResolution);
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKeyDisplay}{item.ImageFileHolder.ExtensionLowered}{_FileNameExtension}")); fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
if (!fileInfo.Exists) if (!fileInfo.Exists)
{ {
if (fileInfo.Directory?.Parent is null) if (fileInfo.Directory?.Parent is null)
@ -373,7 +360,7 @@ public class D_Face
if (File.Exists(parentCheck)) if (File.Exists(parentCheck))
File.Delete(parentCheck); File.Delete(parentCheck);
} }
collection.Add(new(face, fileInfo, Path.Combine(facesDirectory, $"{deterministicHashCodeKeyDisplay}{item.ImageFileHolder.ExtensionLowered}{_HiddenFileNameExtension}"))); collection.Add(new(face, fileInfo, Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_HiddenFileNameExtension}")));
if (_OverrideForFaceImages) if (_OverrideForFaceImages)
check = true; check = true;
else if (!fileInfo.Exists) else if (!fileInfo.Exists)

View File

@ -144,7 +144,7 @@ public class D2_FaceParts
Bitmap rotated; Bitmap rotated;
foreach ((Shared.Models.Face face, string fileName, string rotatedFileName) in collection) foreach ((Shared.Models.Face face, string fileName, string rotatedFileName) in collection)
{ {
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null) if (face.FaceEncoding is null || face.Location is null)
continue; continue;
try try
{ {
@ -215,8 +215,8 @@ public class D2_FaceParts
FileInfo rotatedFileInfo; FileInfo rotatedFileInfo;
DateTime? dateTime = null; DateTime? dateTime = null;
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
string deterministicHashCodeKey;
bool updateDateWhenMatches = false; bool updateDateWhenMatches = false;
string deterministicHashCodeKeyDisplay;
List<(Shared.Models.Face, string, string)> collection = new(); List<(Shared.Models.Face, string, string)> collection = new();
string[] changesFrom = new string[] { nameof(Property.Models.A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) }; string[] changesFrom = new string[] { nameof(Property.Models.A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
@ -224,13 +224,13 @@ public class D2_FaceParts
_ = Directory.CreateDirectory(facesDirectory); _ = Directory.CreateDirectory(facesDirectory);
foreach (Shared.Models.Face face in faceCollection) foreach (Shared.Models.Face face in faceCollection)
{ {
if (item.Property?.Id is null || face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null) if (item.Property?.Id is null || face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
{ {
collection.Add(new(face, string.Empty, string.Empty)); collection.Add(new(face, string.Empty, string.Empty));
continue; continue;
} }
deterministicHashCodeKeyDisplay = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value); deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKeyDisplay}{item.ImageFileHolder.ExtensionLowered}{_FileNameExtension}")); fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
if (!fileInfo.Exists) if (!fileInfo.Exists)
{ {
if (fileInfo.Directory?.Parent is null) if (fileInfo.Directory?.Parent is null)
@ -241,7 +241,7 @@ public class D2_FaceParts
} }
if (string.IsNullOrEmpty(fileInfo.DirectoryName)) if (string.IsNullOrEmpty(fileInfo.DirectoryName))
continue; continue;
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKeyDisplay} - R{item.ImageFileHolder.ExtensionLowered}{_FileNameExtension}")); rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKey} - R{item.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
collection.Add(new(face, fileInfo.FullName, rotatedFileInfo.FullName)); collection.Add(new(face, fileInfo.FullName, rotatedFileInfo.FullName));
if (check) if (check)
continue; continue;

View File

@ -134,7 +134,7 @@ public class FaceRecognition : DisposableObject
} }
} }
public List<Location> FaceLocations(Image image, bool sortByNormalizedPixelPercentage) public List<Location> FaceLocations(Image image)
{ {
if (image is null) if (image is null)
throw new NullReferenceException(nameof(image)); throw new NullReferenceException(nameof(image));
@ -150,14 +150,6 @@ public class FaceRecognition : DisposableObject
mModRect.Dispose(); mModRect.Dispose();
results.Add(location); results.Add(location);
} }
if (sortByNormalizedPixelPercentage)
{
results = (from l in results orderby l.NormalizedPixelPercentage select l).ToList();
int?[] normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.ILocation.GetInts(results);
int normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
throw new Exception("Not distinct!");
}
return results; return results;
} }
@ -187,7 +179,7 @@ public class FaceRecognition : DisposableObject
return results; return results;
} }
private List<Location> GetLocations(Image image, bool sortByNormalizedPixelPercentage) private List<Location> GetLocations(Image image)
{ {
List<Location> results = new(); List<Location> results = new();
MModRect[] mModRects = GetMModRects(image); MModRect[] mModRects = GetMModRects(image);
@ -203,33 +195,25 @@ public class FaceRecognition : DisposableObject
results.Add(location); results.Add(location);
} }
} }
if (sortByNormalizedPixelPercentage)
{
results = (from l in results orderby l.NormalizedPixelPercentage select l).ToList();
int?[] normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.ILocation.GetInts(results);
int normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
throw new Exception("Not distinct!");
}
return results; return results;
} }
public List<(int, Location, FaceEncoding?, Dictionary<FacePart, FacePoint[]>?)> GetCollection(Image image, bool includeFaceEncoding, bool includeFaceParts, bool sortByNormalizedPixelPercentage) public List<(Location, FaceEncoding?, Dictionary<FacePart, FacePoint[]>?)> GetCollection(Image image, bool includeFaceEncoding, bool includeFaceParts)
{ {
List<(int, Location, FaceEncoding?, Dictionary<FacePart, FacePoint[]>?)> results = new(); List<(Location, FaceEncoding?, Dictionary<FacePart, FacePoint[]>?)> results = new();
if (image is null) if (image is null)
throw new NullReferenceException(nameof(image)); throw new NullReferenceException(nameof(image));
image.ThrowIfDisposed(); image.ThrowIfDisposed();
ThrowIfDisposed(); ThrowIfDisposed();
if (_PredictorModel == PredictorModel.Custom) if (_PredictorModel == PredictorModel.Custom)
throw new NotSupportedException("FaceRecognition.PredictorModel.Custom is not supported."); throw new NotSupportedException("FaceRecognition.PredictorModel.Custom is not supported.");
List<Location> locations = GetLocations(image, sortByNormalizedPixelPercentage); List<Location> locations = GetLocations(image);
List<FullObjectDetection> fullObjectDetections = GetFullObjectDetections(image, locations); List<FullObjectDetection> fullObjectDetections = GetFullObjectDetections(image, locations);
if (fullObjectDetections.Count != locations.Count) if (fullObjectDetections.Count != locations.Count)
throw new Exception(); throw new Exception();
List<(int LocationIndex, Location Location, List<FaceEncoding?> FaceEncodings, List<List<(FacePart, FacePoint[])>> FaceParts)> collection = new(); List<(Location Location, List<FaceEncoding?> FaceEncodings, List<List<(FacePart, FacePoint[])>> FaceParts)> collection = new();
for (int i = 0; i < locations.Count; i++) foreach (Location location in locations)
collection.Add(new(i, locations[i], new(), new())); collection.Add(new(location, new(), new()));
if (locations.Count != collection.Count) if (locations.Count != collection.Count)
throw new Exception(); throw new Exception();
if (!includeFaceEncoding) if (!includeFaceEncoding)
@ -266,18 +250,18 @@ public class FaceRecognition : DisposableObject
fullObjectDetection.Dispose(); fullObjectDetection.Dispose();
const int indexZero = 0; const int indexZero = 0;
Dictionary<FacePart, FacePoint[]> keyValuePairs; Dictionary<FacePart, FacePoint[]> keyValuePairs;
foreach ((int locationIndex, Location location, List<FaceEncoding?> faceEncodings, List<List<(FacePart, FacePoint[])>> faceParts) in collection) foreach ((Location location, List<FaceEncoding?> faceEncodings, List<List<(FacePart, FacePoint[])>> faceParts) in collection)
{ {
if (faceEncodings.Count != 1 || faceParts.Count != 1) if (faceEncodings.Count != 1 || faceParts.Count != 1)
continue; continue;
if (!faceParts[indexZero].Any()) if (!faceParts[indexZero].Any())
results.Add(new(locationIndex, location, faceEncodings[indexZero], null)); results.Add(new(location, faceEncodings[indexZero], null));
else else
{ {
keyValuePairs = new(); keyValuePairs = new();
foreach ((FacePart facePart, FacePoint[] facePoints) in faceParts[indexZero]) foreach ((FacePart facePart, FacePoint[] facePoints) in faceParts[indexZero])
keyValuePairs.Add(facePart, facePoints); keyValuePairs.Add(facePart, facePoints);
results.Add(new(locationIndex, location, faceEncodings[indexZero], keyValuePairs)); results.Add(new(location, faceEncodings[indexZero], keyValuePairs));
} }
} }
return results; return results;

View File

@ -28,6 +28,7 @@ public partial class DlibDotNet
private readonly F_Random _Random; private readonly F_Random _Random;
private readonly E3_Rename _Rename; private readonly E3_Rename _Rename;
private readonly IConsole _Console; private readonly IConsole _Console;
private readonly E_Distance _Distance;
private readonly B_Metadata _Metadata; private readonly B_Metadata _Metadata;
private readonly Serilog.ILogger? _Log; private readonly Serilog.ILogger? _Log;
private readonly D2_FaceParts _FaceParts; private readonly D2_FaceParts _FaceParts;
@ -67,10 +68,19 @@ public partial class DlibDotNet
Verify(configuration); Verify(configuration);
VerifyExtra(args, propertyConfiguration, configuration); VerifyExtra(args, propertyConfiguration, configuration);
_Configuration = configuration; _Configuration = configuration;
_Index = new G_Index(configuration); _Index = new(configuration);
_Random = new F_Random(configuration); _Random = new(configuration);
_Rename = new(configuration);
_MapConfiguration = Get(configuration); _MapConfiguration = Get(configuration);
_Rename = new E3_Rename(configuration); _Distance = new(
configuration.DistanceMoveUnableToMatch,
configuration.DistancePixelDistanceTolerance,
configuration.FaceDistanceMinimumConfidence,
configuration.FaceDistancePermyriad,
configuration.FaceDistanceTolerance,
configuration.PropertyConfiguration.ResultAllInOne,
configuration.SortingDaysDeltaTolerance,
configuration.SortingMaximumPerFaceShouldBeHigh);
if (configuration.IgnoreExtensions is null) if (configuration.IgnoreExtensions is null)
throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
string propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(propertyConfiguration, nameof(A_Property), create: false); string propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(propertyConfiguration, nameof(A_Property), create: false);
@ -95,13 +105,12 @@ public partial class DlibDotNet
hiddenFileNameExtension, hiddenFileNameExtension,
hiddenImageCodecInfo, hiddenImageCodecInfo,
imageCodecInfo, imageCodecInfo,
configuration.LocationDigits,
configuration.LocationFactor,
model, model,
modelParameter, modelParameter,
configuration.NumberOfJitters, configuration.NumberOfJitters,
configuration.NumberOfTimesToUpsample, configuration.NumberOfTimesToUpsample,
configuration.OverrideForFaceImages, configuration.OverrideForFaceImages,
configuration.RetryImagesWithoutAFace,
predictorModel, predictorModel,
configuration.PropertiesChangedForFaces); configuration.PropertiesChangedForFaces);
} }
@ -323,11 +332,9 @@ public partial class DlibDotNet
configuration.FaceDistancePermyriad, configuration.FaceDistancePermyriad,
configuration.FaceDistanceMinimumConfidence, configuration.FaceDistanceMinimumConfidence,
configuration.FaceDistanceTolerance, configuration.FaceDistanceTolerance,
configuration.LocationDigits,
configuration.LocationFactor,
configuration.MapLogicSigma, configuration.MapLogicSigma,
configuration.MappingDefaultName, configuration.MappingDefaultName,
configuration.MappingMoveUnableToMatch, configuration.DistanceMoveUnableToMatch,
configuration.MappingSaveNotMapped, configuration.MappingSaveNotMapped,
configuration.MappingSaveMapped, configuration.MappingSaveMapped,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping, configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
@ -342,22 +349,7 @@ public partial class DlibDotNet
return result; return result;
} }
private void FullParallelForWork( private void FullParallelForWork(A_Property propertyLogic, string[] mappedFaceFiles, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string eDistanceContentDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Shared.Models.Face>?> imageFaceCollections, List<string[]> duplicateMappedFaceFilesCollection, Container container, int index, Item item)
A_Property propertyLogic,
string outputResolution,
string bResultsFullGroupDirectory,
string cResultsFullGroupDirectory,
string dResultsFullGroupDirectory,
string d2ResultsFullGroupDirectory,
List<Tuple<string, DateTime>> sourceDirectoryChanges,
List<FileHolder?> propertyFileHolderCollection,
List<Shared.Models.Property?> propertyCollection,
List<List<KeyValuePair<string, string>>> metadataCollections,
List<Dictionary<string, int[]>> resizeKeyValuePairs,
List<List<Shared.Models.Face>?> imageFaceCollections,
Container container,
int index,
Item item)
{ {
if (item.ImageFileHolder is null) if (item.ImageFileHolder is null)
throw new NullReferenceException(nameof(item.ImageFileHolder)); throw new NullReferenceException(nameof(item.ImageFileHolder));
@ -366,8 +358,8 @@ public partial class DlibDotNet
Shared.Models.Property property; Shared.Models.Property property;
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
DateTime dateTime = DateTime.Now; DateTime dateTime = DateTime.Now;
List<Shared.Models.Face>? faces;
List<string> parseExceptions = new(); List<string> parseExceptions = new();
List<Shared.Models.Face>? faceCollection;
Dictionary<string, int[]> imageResizeKeyValuePairs; Dictionary<string, int[]> imageResizeKeyValuePairs;
List<Tuple<string, DateTime>> subFileTuples = new(); List<Tuple<string, DateTime>> subFileTuples = new();
List<KeyValuePair<string, string>> metadataCollection; List<KeyValuePair<string, string>> metadataCollection;
@ -420,46 +412,35 @@ public partial class DlibDotNet
File.WriteAllBytes(path, bytes); File.WriteAllBytes(path, bytes);
} }
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution)) if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
faceCollection = null; faces = null;
else else
{ {
int[] outputResolutionCollection = imageResizeKeyValuePairs[outputResolution]; int[] outputResolutionCollection = imageResizeKeyValuePairs[outputResolution];
int outputResolutionWidth = outputResolutionCollection[0]; int outputResolutionWidth = outputResolutionCollection[0];
int outputResolutionHeight = outputResolutionCollection[1]; int outputResolutionHeight = outputResolutionCollection[1];
int outputResolutionOrientation = outputResolutionCollection[2]; int outputResolutionOrientation = outputResolutionCollection[2];
faceCollection = _Faces.GetFaces( faces = _Faces.GetFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation);
dResultsFullGroupDirectory,
subFileTuples,
parseExceptions,
item,
property,
outputResolutionWidth,
outputResolutionHeight,
outputResolutionOrientation);
if (_AppSettings.MaxDegreeOfParallelism < 2) if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D_Face.GetFaces)); ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
_Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faceCollection); _Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faces);
if (_AppSettings.MaxDegreeOfParallelism < 2) if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D_Face.SaveFaces)); ticks = LogDelta(ticks, nameof(D_Face.SaveFaces));
int?[] normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(faceCollection); _ = _Distance.GetUnableToMatchCountAndRenameMatches(_Faces.FileNameExtension, eDistanceContentDirectory, duplicateMappedFaceFilesCollection, item, faces, mappedFaceFiles);
int normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count(); if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length || _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
{ {
throw new NotImplementedException();
bool saveRotated = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution); // bool saveRotated = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution);
string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath( // string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory);
_Configuration.PropertyConfiguration, // string facesDirectory = Path.GetFullPath(Path.Combine($"{Path.Combine(d2FacePartsContentDirectory, "()")}{sourceDirectorySegment}", item.ImageFileHolder.NameWithoutExtension));
container.SourceDirectory); // _FaceParts.SaveFaceLandmarkImages(facesDirectory, subFileTuples, parseExceptions, item, faceCollection, saveRotated);
string facesDirectory = Path.GetFullPath(Path.Combine($"{Path.Combine(d2ResultsFullGroupDirectory, "()")}{sourceDirectorySegment}", item.ImageFileHolder.NameWithoutExtension)); // if (_AppSettings.MaxDegreeOfParallelism < 2)
_FaceParts.SaveFaceLandmarkImages(facesDirectory, subFileTuples, parseExceptions, item, faceCollection, saveRotated); // ticks = LogDelta(ticks, nameof(D2_FaceParts.SaveFaceLandmarkImages));
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D2_FaceParts.SaveFaceLandmarkImages));
} }
} }
lock (sourceDirectoryChanges) lock (sourceDirectoryChanges)
{ {
imageFaceCollections[index] = faces;
propertyCollection[index] = property; propertyCollection[index] = property;
imageFaceCollections[index] = faceCollection;
metadataCollections[index] = metadataCollection; metadataCollections[index] = metadataCollection;
resizeKeyValuePairs[index] = imageResizeKeyValuePairs; resizeKeyValuePairs[index] = imageResizeKeyValuePairs;
propertyFileHolderCollection[index] = item.ImageFileHolder; propertyFileHolderCollection[index] = item.ImageFileHolder;
@ -467,23 +448,7 @@ public partial class DlibDotNet
} }
} }
private int FullParallelWork( private int FullParallelWork(int maxDegreeOfParallelism, A_Property propertyLogic, string[] mappedFaceFiles, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string eDistanceContentDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Shared.Models.Face>?> imageFaceCollections, List<string[]> duplicateMappedFaceFilesCollection, Container container, Item[] filteredItems, string message)
int maxDegreeOfParallelism,
A_Property propertyLogic,
string outputResolution,
string bResultsFullGroupDirectory,
string cResultsFullGroupDirectory,
string dResultsFullGroupDirectory,
string d2ResultsFullGroupDirectory,
List<Tuple<string, DateTime>> sourceDirectoryChanges,
List<FileHolder?> propertyFileHolderCollection,
List<Shared.Models.Property?> propertyCollection,
List<List<KeyValuePair<string, string>>> metadataCollection,
List<Dictionary<string, int[]>> resizeKeyValuePairs,
List<List<Shared.Models.Face>?> imageFaceCollections,
Container container,
Item[] filteredItems,
string message)
{ {
if (_Log is null) if (_Log is null)
throw new NullReferenceException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
@ -511,17 +476,19 @@ public partial class DlibDotNet
{ {
FullParallelForWork( FullParallelForWork(
propertyLogic, propertyLogic,
mappedFaceFiles,
outputResolution, outputResolution,
bResultsFullGroupDirectory, bResultsFullGroupDirectory,
cResultsFullGroupDirectory, cResultsFullGroupDirectory,
dResultsFullGroupDirectory, dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory, eDistanceContentDirectory,
sourceDirectoryChanges, sourceDirectoryChanges,
propertyFileHolderCollection, propertyFileHolderCollection,
propertyCollection, propertyCollection,
metadataCollection, metadataCollection,
resizeKeyValuePairs, resizeKeyValuePairs,
imageFaceCollections, imageFaceCollections,
duplicateMappedFaceFilesCollection,
container, container,
index: i, index: i,
filteredItems[i]); filteredItems[i]);
@ -595,9 +562,9 @@ public partial class DlibDotNet
if (!(from l in propertyCollection where l?.Width is null select true).Any()) if (!(from l in propertyCollection where l?.Width is null select true).Any())
{ {
string checkDirectory; string checkDirectory;
List<KeyValuePair<string, List<Shared.Models.Face>?>> imageFaceCollectionsKeyValuePairs = new();
List<KeyValuePair<string, Shared.Models.Property>> propertyCollectionKeyValuePairs = new(); List<KeyValuePair<string, Shared.Models.Property>> propertyCollectionKeyValuePairs = new();
List<KeyValuePair<string, Dictionary<string, int[]>>> resizeKeyValuePairsCollections = new(); List<KeyValuePair<string, Dictionary<string, int[]>>> resizeKeyValuePairsCollections = new();
List<KeyValuePair<string, List<Shared.Models.Face>?>> imageFaceCollectionsKeyValuePairs = new();
List<KeyValuePair<string, List<KeyValuePair<string, string>>>> metadataCollectionKeyValuePairs = new(); List<KeyValuePair<string, List<KeyValuePair<string, string>>>> metadataCollectionKeyValuePairs = new();
(int level, List<string> directories) = Shared.Models.Stateless.Methods.IPath.Get( (int level, List<string> directories) = Shared.Models.Stateless.Methods.IPath.Get(
_Configuration.PropertyConfiguration.RootDirectory, _Configuration.PropertyConfiguration.RootDirectory,
@ -616,9 +583,9 @@ public partial class DlibDotNet
_FileKeyValuePairs.Add(new KeyValuePair<string, string>(container.SourceDirectory, key)); _FileKeyValuePairs.Add(new KeyValuePair<string, string>(container.SourceDirectory, key));
_FilePropertiesKeyValuePairs[container.SourceDirectory].Add(new Tuple<string, Shared.Models.Property>(key, propertyCollection[i])); _FilePropertiesKeyValuePairs[container.SourceDirectory].Add(new Tuple<string, Shared.Models.Property>(key, propertyCollection[i]));
} }
imageFaceCollectionsKeyValuePairs.Add(new KeyValuePair<string, List<Shared.Models.Face>?>(key, imageFaceCollections[i]));
propertyCollectionKeyValuePairs.Add(new KeyValuePair<string, Shared.Models.Property>(key, propertyCollection[i])); propertyCollectionKeyValuePairs.Add(new KeyValuePair<string, Shared.Models.Property>(key, propertyCollection[i]));
resizeKeyValuePairsCollections.Add(new KeyValuePair<string, Dictionary<string, int[]>>(key, resizeKeyValuePairs[i])); resizeKeyValuePairsCollections.Add(new KeyValuePair<string, Dictionary<string, int[]>>(key, resizeKeyValuePairs[i]));
imageFaceCollectionsKeyValuePairs.Add(new KeyValuePair<string, List<Shared.Models.Face>?>(key, imageFaceCollections[i]));
metadataCollectionKeyValuePairs.Add(new KeyValuePair<string, List<KeyValuePair<string, string>>>(key, metadataCollection[i])); metadataCollectionKeyValuePairs.Add(new KeyValuePair<string, List<KeyValuePair<string, string>>>(key, metadataCollection[i]));
} }
if (propertyLogic.AngleBracketCollection.Any()) if (propertyLogic.AngleBracketCollection.Any())
@ -664,10 +631,7 @@ public partial class DlibDotNet
} }
} }
private (string, string, string, string, string, string) GetResultsFullGroupDirectories( private (string, string, string, string) GetResultsFullGroupDirectories(Model? model, PredictorModel? predictorModel, string outputResolution)
Model? model,
PredictorModel? predictorModel,
string outputResolution)
{ {
string aResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory( string aResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
_Configuration.PropertyConfiguration, _Configuration.PropertyConfiguration,
@ -705,25 +669,7 @@ public partial class DlibDotNet
includeResizeGroup: true, includeResizeGroup: true,
includeModel: true, includeModel: true,
includePredictorModel: true); includePredictorModel: true);
string d2ResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory( return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory);
_Configuration.PropertyConfiguration,
model,
predictorModel,
nameof(D2_FaceParts),
outputResolution,
includeResizeGroup: true,
includeModel: true,
includePredictorModel: true);
string eResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
_Configuration.PropertyConfiguration,
model,
predictorModel,
nameof(E_Distance),
outputResolution,
includeResizeGroup: true,
includeModel: true,
includePredictorModel: true);
return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory);
} }
private void SetAngleBracketCollections( private void SetAngleBracketCollections(
@ -733,8 +679,7 @@ public partial class DlibDotNet
string aResultsFullGroupDirectory, string aResultsFullGroupDirectory,
string bResultsFullGroupDirectory, string bResultsFullGroupDirectory,
string cResultsFullGroupDirectory, string cResultsFullGroupDirectory,
string dResultsFullGroupDirectory, string dResultsFullGroupDirectory)
string d2ResultsFullGroupDirectory)
{ {
_Faces.AngleBracketCollection.Clear(); _Faces.AngleBracketCollection.Clear();
_Resize.AngleBracketCollection.Clear(); _Resize.AngleBracketCollection.Clear();
@ -773,15 +718,6 @@ public partial class DlibDotNet
singletonDescription: string.Empty, singletonDescription: string.Empty,
collectionDescription: "For each image a json file with all faces found", collectionDescription: "For each image a json file with all faces found",
converted: true)); converted: true));
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_ = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(
_Configuration.PropertyConfiguration,
container.SourceDirectory,
d2ResultsFullGroupDirectory,
contentDescription: "n x 2 gif file(s) for each face found",
singletonDescription: string.Empty,
collectionDescription: string.Empty,
converted: false);
} }
private Item[] GetFilterItems(Container container) private Item[] GetFilterItems(Container container)
@ -798,15 +734,7 @@ public partial class DlibDotNet
return results.ToArray(); return results.ToArray();
} }
private void FullDoWork( private void FullDoWork(string argZero, Model? model, PredictorModel? predictorModel, string propertyRoot, long ticks, A_Property propertyLogic, int t, Container[] containers, string eDistanceContentDirectory, string[] mappedFaceFiles)
string argZero,
Model? model,
PredictorModel? predictorModel,
string propertyRoot,
long ticks,
A_Property propertyLogic,
int t,
Container[] containers)
{ {
if (_Log is null) if (_Log is null)
throw new NullReferenceException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
@ -820,33 +748,23 @@ public partial class DlibDotNet
string bResultsFullGroupDirectory; string bResultsFullGroupDirectory;
string cResultsFullGroupDirectory; string cResultsFullGroupDirectory;
string dResultsFullGroupDirectory; string dResultsFullGroupDirectory;
string eResultsFullGroupDirectory;
string d2ResultsFullGroupDirectory;
int containersLength = containers.Length; int containersLength = containers.Length;
Shared.Models.Property[] propertyCollection; Shared.Models.Property[] propertyCollection;
List<List<Shared.Models.Face>?> imageFaceCollections = new();
List<FileHolder?> propertyFileHolderCollection = new(); List<FileHolder?> propertyFileHolderCollection = new();
List<string[]> duplicateMappedFaceFilesCollection = new();
List<Dictionary<string, int[]>> resizeKeyValuePairs = new(); List<Dictionary<string, int[]>> resizeKeyValuePairs = new();
List<Tuple<string, DateTime>> sourceDirectoryChanges = new(); List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
List<List<Shared.Models.Face>?> imageFaceCollections = new();
List<Shared.Models.Property?> nullablePropertyCollection = new(); List<Shared.Models.Property?> nullablePropertyCollection = new();
int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism; int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism;
List<List<KeyValuePair<string, string>>> metadataCollection = new(); List<List<KeyValuePair<string, string>>> metadataCollection = new();
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), "{}");
foreach (string outputResolution in _Configuration.OutputResolutions) foreach (string outputResolution in _Configuration.OutputResolutions)
{ {
total = 0; total = 0;
_FileKeyValuePairs.Clear(); _FileKeyValuePairs.Clear();
duplicateMappedFaceFilesCollection.Clear();
_FilePropertiesKeyValuePairs.Clear(); _FilePropertiesKeyValuePairs.Clear();
(aResultsFullGroupDirectory, (aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution);
bResultsFullGroupDirectory,
cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(
model,
predictorModel,
outputResolution);
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "()"));
for (int i = 0; i < containers.Length; i++) for (int i = 0; i < containers.Length; i++)
{ {
container = containers[i]; container = containers[i];
@ -865,21 +783,23 @@ public partial class DlibDotNet
propertyFileHolderCollection.Clear(); propertyFileHolderCollection.Clear();
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $"{i + 1:000}.{container.G} [{filteredItems.Length:000} files] / {containersLength:000} - {total} / {t} total files - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}"; message = $"{i + 1:000}.{container.G} [{filteredItems.Length:000} files] / {containersLength:000} - {total} / {t} total files - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}";
SetAngleBracketCollections(propertyLogic, outputResolution, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory); SetAngleBracketCollections(propertyLogic, outputResolution, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory);
exceptionCount = FullParallelWork( exceptionCount = FullParallelWork(
maxDegreeOfParallelism, maxDegreeOfParallelism,
propertyLogic, propertyLogic,
mappedFaceFiles,
outputResolution, outputResolution,
bResultsFullGroupDirectory, bResultsFullGroupDirectory,
cResultsFullGroupDirectory, cResultsFullGroupDirectory,
dResultsFullGroupDirectory, dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory, eDistanceContentDirectory,
sourceDirectoryChanges, sourceDirectoryChanges,
propertyFileHolderCollection, propertyFileHolderCollection,
nullablePropertyCollection, nullablePropertyCollection,
metadataCollection, metadataCollection,
resizeKeyValuePairs, resizeKeyValuePairs,
imageFaceCollections, imageFaceCollections,
duplicateMappedFaceFilesCollection,
container, container,
filteredItems, filteredItems,
message); message);
@ -916,6 +836,11 @@ public partial class DlibDotNet
// break; // break;
total += container.Items.Count; total += container.Items.Count;
} }
foreach (string[] duplicateMappedFaceFiles in duplicateMappedFaceFilesCollection)
{
foreach (string duplicateMappedFaceFile in duplicateMappedFaceFiles)
_Log.Information(duplicateMappedFaceFile);
}
} }
} }
@ -926,9 +851,10 @@ public partial class DlibDotNet
bool? isWrongYear; bool? isWrongYear;
Item[] filteredItems; Item[] filteredItems;
DateTime minimumDateTime; DateTime minimumDateTime;
int normalizedPixelPercentage;
string deterministicHashCodeKey;
MappingFromItem mappingFromItem; MappingFromItem mappingFromItem;
MappingFromPerson mappingFromPerson; MappingFromPerson mappingFromPerson;
string deterministicHashCodeKeyDisplay;
MappingFromLocation mappingFromLocation; MappingFromLocation mappingFromLocation;
foreach (Container container in containers) foreach (Container container in containers)
{ {
@ -949,14 +875,15 @@ public partial class DlibDotNet
{ {
if (face.RelativePath != item.RelativePath) if (face.RelativePath != item.RelativePath)
break; break;
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null) if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
continue; continue;
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property); minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime); (isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
mappingFromItem = new(item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.ResizedFileHolder); mappingFromItem = new(item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.ResizedFileHolder);
mappingFromPerson = new(approximateYears: null, by: null, displayDirectoryName: string.Empty, personBirthday: null, segmentB: string.Empty); mappingFromPerson = new(approximateYears: null, by: null, displayDirectoryName: string.Empty, personBirthday: null, segmentB: string.Empty);
deterministicHashCodeKeyDisplay = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value); normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
mappingFromLocation = new(face.Location.Confidence, deterministicHashCodeKeyDisplay, face.Location.NormalizedPixelPercentage.Value); deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
mappingFromLocation = new(face.Location.Confidence, deterministicHashCodeKey, normalizedPixelPercentage);
mapping = new(mappingFromItem, mappingFromLocation, mappingFromPerson); mapping = new(mappingFromItem, mappingFromLocation, mappingFromPerson);
face.SetMapping(mapping); face.SetMapping(mapping);
results.Add(face); results.Add(face);
@ -972,21 +899,15 @@ public partial class DlibDotNet
PersonContainer[] personContainers, PersonContainer[] personContainers,
Container[] containers, Container[] containers,
string dResultsFullGroupDirectory, string dResultsFullGroupDirectory,
string eResultsFullGroupDirectory,
string d2ResultsFullGroupDirectory,
string outputResolution) string outputResolution)
{ {
E_Distance distance = new(); string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
if (string.IsNullOrEmpty(eResultsFullGroupDirectory))
throw new NullReferenceException(nameof(eResultsFullGroupDirectory));
string eDistanceContentDirectory = Path.Combine(eResultsFullGroupDirectory, "()");
List<Shared.Models.Face> distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers); List<Shared.Models.Face> distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers);
List<Shared.Models.Face> selectedFilteredFaces = E_Distance.GetSelectedFilteredFaces(distinctFilteredFaces); Shared.Models.Face[] selectedFilteredFaces = E_Distance.GetSelectedFilteredFaces(distinctFilteredFaces);
E_Distance.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, selectedFilteredFaces); E_Distance.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, selectedFilteredFaces);
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory( string eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), "()");
_Configuration.PropertyConfiguration, string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "{}");
nameof(A2_People), string d2FacePartsContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(D2_FaceParts), "()");
"{}");
MapLogic mapLogic = new( MapLogic mapLogic = new(
_AppSettings.MaxDegreeOfParallelism, _AppSettings.MaxDegreeOfParallelism,
_Configuration.PropertyConfiguration, _Configuration.PropertyConfiguration,
@ -996,33 +917,32 @@ public partial class DlibDotNet
_FaceParts.FileNameExtension, _FaceParts.FileNameExtension,
ticks, ticks,
personContainers, personContainers,
eDistanceContentDirectory,
a2PeopleSingletonDirectory, a2PeopleSingletonDirectory,
eDistanceContentDirectory,
distinctFilteredFaces, distinctFilteredFaces,
distance); _Distance);
SortingContainer[] sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortingContainers( SortingContainer[] sortingContainers = _Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(
_AppSettings.MaxDegreeOfParallelism, _AppSettings.MaxDegreeOfParallelism,
_MapConfiguration,
ticks, ticks,
mapLogic, mapLogic,
selectedFilteredFaces); selectedFilteredFaces);
E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, eResultsFullGroupDirectory, sortingContainers); E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers);
int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces); int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces);
if (totalNotMapped > 0) if (totalNotMapped > 0)
mapLogic.ForceSingleImageThenSaveMapping( mapLogic.ForceSingleImageThenSaveMapping(
dResultsFullGroupDirectory, dFacesContentDirectory,
d2ResultsFullGroupDirectory, d2FacePartsContentDirectory,
distinctFilteredFaces, distinctFilteredFaces,
sortingContainers, sortingContainers,
totalNotMapped); totalNotMapped);
mapLogic.CopyManualFiles(dResultsFullGroupDirectory, distinctFilteredFaces); mapLogic.CopyManualFiles(dFacesContentDirectory, distinctFilteredFaces);
if (_MapConfiguration.MappingSaveNotMapped) if (_MapConfiguration.MappingSaveNotMapped)
mapLogic.SaveNotMappedTicks(); mapLogic.SaveNotMappedTicks();
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
mapLogic.SaveShortcuts(_Configuration.JuliePhares, distinctFilteredFaces); mapLogic.SaveShortcuts(_Configuration.JuliePhares, distinctFilteredFaces);
} }
private static Container? AreAllSameStartsWith(string argZero, Container[] containers) private static Container? AreAllSameEndsWith(string argZero, Container[] containers)
{ {
Container? result = null; Container? result = null;
string[] directoryNames = Shared.Models.Stateless.Methods.IPath.GetDirectoryNames(argZero); string[] directoryNames = Shared.Models.Stateless.Methods.IPath.GetDirectoryNames(argZero);
@ -1037,7 +957,7 @@ public partial class DlibDotNet
if (container.SourceDirectory == argZero) if (container.SourceDirectory == argZero)
result = container; result = container;
directoryName = Path.GetFileName(container.SourceDirectory); directoryName = Path.GetFileName(container.SourceDirectory);
if (!directoryName.StartsWith(rootDirectoryName)) if (!directoryName.EndsWith(rootDirectoryName))
{ {
result = null; result = null;
break; break;
@ -1088,13 +1008,7 @@ public partial class DlibDotNet
return result; return result;
} }
private void Search( private void Search(long ticks, Model? model, PredictorModel? predictorModel, string argZero, string propertyRoot, PersonContainer[] personContainers)
long ticks,
Model? model,
PredictorModel? predictorModel,
string argZero,
string propertyRoot,
PersonContainer[] personContainers)
{ {
int j; int j;
int f; int f;
@ -1104,8 +1018,13 @@ public partial class DlibDotNet
string bResultsFullGroupDirectory; string bResultsFullGroupDirectory;
string cResultsFullGroupDirectory; string cResultsFullGroupDirectory;
string dResultsFullGroupDirectory; string dResultsFullGroupDirectory;
string eResultsFullGroupDirectory; string eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), "()");
string d2ResultsFullGroupDirectory; string[] mappedFaceFiles = Map.Models.Stateless.Methods.IMapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(
_MapConfiguration,
_Faces.FileNameExtension,
ticks,
eDistanceContentDirectory,
personContainers);
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Container(s) - {totalSeconds} total second(s)"; string message = $") Building Container(s) - {totalSeconds} total second(s)";
A_Property propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, model, predictorModel); A_Property propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, model, predictorModel);
@ -1115,7 +1034,7 @@ public partial class DlibDotNet
progressBar.Tick(); progressBar.Tick();
(j, f, t, containers) = Property.Models.Stateless.Container.GetContainers(_Configuration.PropertyConfiguration, _FirstRun, propertyLogic); (j, f, t, containers) = Property.Models.Stateless.Container.GetContainers(_Configuration.PropertyConfiguration, _FirstRun, propertyLogic);
} }
Container? container = AreAllSameStartsWith(argZero, containers); Container? container = AreAllSameEndsWith(argZero, containers);
if (_ArgZeroIsConfigurationRootDirectory && container is not null) if (_ArgZeroIsConfigurationRootDirectory && container is not null)
{ {
string? newRootDirectory = SaveUrlAndGetNewRootDirectory(container); string? newRootDirectory = SaveUrlAndGetNewRootDirectory(container);
@ -1138,20 +1057,12 @@ public partial class DlibDotNet
model, model,
predictorModel); predictorModel);
} }
FullDoWork(argZero, model, predictorModel, propertyRoot, ticks, propertyLogic, t, containers); FullDoWork(argZero, model, predictorModel, propertyRoot, ticks, propertyLogic, t, containers, eDistanceContentDirectory, mappedFaceFiles);
foreach (string outputResolution in _Configuration.OutputResolutions) foreach (string outputResolution in _Configuration.OutputResolutions)
{ {
if (_FirstRun || container is not null) if (_FirstRun || container is not null)
break; break;
(aResultsFullGroupDirectory, (aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution);
bResultsFullGroupDirectory,
cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(
model,
predictorModel,
outputResolution);
if (_ArgZeroIsConfigurationRootDirectory if (_ArgZeroIsConfigurationRootDirectory
&& _Configuration.SaveResizedSubfiles && _Configuration.SaveResizedSubfiles
&& outputResolution == _Configuration.OutputResolutions[0] && outputResolution == _Configuration.OutputResolutions[0]
@ -1160,15 +1071,7 @@ public partial class DlibDotNet
{ {
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any()) if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
break; break;
DistanceThenMapLogic( DistanceThenMapLogic(argZero, ticks, personContainers, containers, dResultsFullGroupDirectory, outputResolution);
argZero,
ticks,
personContainers,
containers,
dResultsFullGroupDirectory,
eResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
outputResolution);
if (_IsEnvironment.Development) if (_IsEnvironment.Development)
continue; continue;
if (_FileKeyValuePairs.Any()) if (_FileKeyValuePairs.Any())
@ -1194,10 +1097,6 @@ public partial class DlibDotNet
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, "{}")); _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, "{}"));
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution)) if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(dResultsFullGroupDirectory, "[]")); _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(dResultsFullGroupDirectory, "[]"));
if (_Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution))
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]"));
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(d2ResultsFullGroupDirectory, "[]"));
} }
} }
} }

View File

@ -14,6 +14,8 @@ public class Configuration
[Display(Name = "Check Json For Distance Results"), Required] public bool? CheckJsonForDistanceResults { get; set; } [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 = "CrossDirectory Max Items In Distance Collection"), Required] public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; }
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; } [Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
[Display(Name = "Distance Move Unable to Match by 1 Tick"), Required] public bool? DistanceMoveUnableToMatch { get; set; }
[Display(Name = "Distance Pixel Distance Tolerance"), Required] public int? DistancePixelDistanceTolerance { get; set; }
[Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; } [Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; }
[Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; } [Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; }
[Display(Name = "Face Distance Permyriad"), Required] public int? FaceDistancePermyriad { get; set; } [Display(Name = "Face Distance Permyriad"), Required] public int? FaceDistancePermyriad { get; set; }
@ -33,7 +35,6 @@ public class Configuration
[Display(Name = "Map Logic Sigma"), Required] public int? MapLogicSigma { get; set; } [Display(Name = "Map Logic Sigma"), Required] public int? MapLogicSigma { get; set; }
[Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; } [Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; }
[Display(Name = "Mapping Default Name"), Required] public string MappingDefaultName { get; set; } [Display(Name = "Mapping Default Name"), Required] public string MappingDefaultName { get; set; }
[Display(Name = "Mapping Move Unable to Match by 1 Tick"), Required] public bool? MappingMoveUnableToMatch { get; set; }
[Display(Name = "Mapping Save Mapped"), Required] public bool? MappingSaveMapped { get; set; } [Display(Name = "Mapping Save Mapped"), Required] public bool? MappingSaveMapped { get; set; }
[Display(Name = "Mapping Save Not Mapped"), Required] public bool? MappingSaveNotMapped { get; set; } [Display(Name = "Mapping Save Not Mapped"), Required] public bool? MappingSaveNotMapped { get; set; }
[Display(Name = "Mapping Use Deterministic Hash Code Unknown Face Key Value Pairs for Add to Mapping"), Required] public bool? MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { get; set; } [Display(Name = "Mapping Use Deterministic Hash Code Unknown Face Key Value Pairs for Add to Mapping"), Required] public bool? MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { get; set; }
@ -61,6 +62,7 @@ public class Configuration
[Display(Name = "Properties Changed For Metadata"), Required] public bool? PropertiesChangedForMetadata { 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 = "Properties Changed For Resize"), Required] public bool? PropertiesChangedForResize { get; set; }
[Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; }
[Display(Name = "Retry Images Without a Face"), Required] public bool? RetryImagesWithoutAFace { get; set; }
[Display(Name = "Reverse"), Required] public bool? Reverse { 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 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 Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; }
@ -93,6 +95,10 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection)); throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
if (configuration.DistanceFactor is null) if (configuration.DistanceFactor is null)
throw new NullReferenceException(nameof(configuration.DistanceFactor)); throw new NullReferenceException(nameof(configuration.DistanceFactor));
if (configuration.DistanceMoveUnableToMatch is null)
throw new NullReferenceException(nameof(configuration.DistanceMoveUnableToMatch));
if (configuration.DistancePixelDistanceTolerance is null)
throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance));
if (configuration.FaceDistanceHiddenImageFactor is null) if (configuration.FaceDistanceHiddenImageFactor is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor)); throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor));
if (configuration.FaceDistanceMinimumConfidence is null) if (configuration.FaceDistanceMinimumConfidence is null)
@ -127,8 +133,6 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.MapLogicSigma)); throw new NullReferenceException(nameof(configuration.MapLogicSigma));
if (configuration.MappingDefaultName is null) if (configuration.MappingDefaultName is null)
throw new NullReferenceException(nameof(configuration.MappingDefaultName)); throw new NullReferenceException(nameof(configuration.MappingDefaultName));
if (configuration.MappingMoveUnableToMatch is null)
throw new NullReferenceException(nameof(configuration.MappingMoveUnableToMatch));
if (configuration.MappingSaveNotMapped is null) if (configuration.MappingSaveNotMapped is null)
throw new NullReferenceException(nameof(configuration.MappingSaveNotMapped)); throw new NullReferenceException(nameof(configuration.MappingSaveNotMapped));
if (configuration.MappingSaveMapped is null) if (configuration.MappingSaveMapped is null)
@ -173,6 +177,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForResize is null) if (configuration.PropertiesChangedForResize is null)
throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize));
if (configuration.RetryImagesWithoutAFace is null)
throw new NullReferenceException(nameof(configuration.RetryImagesWithoutAFace));
if (configuration.Reverse is null) if (configuration.Reverse is null)
throw new NullReferenceException(nameof(configuration.Reverse)); throw new NullReferenceException(nameof(configuration.Reverse));
if (configuration.SaveFaceLandmarkForOutputResolutions is null) if (configuration.SaveFaceLandmarkForOutputResolutions is null)
@ -212,6 +218,8 @@ public class Configuration
configuration.CheckJsonForDistanceResults.Value, configuration.CheckJsonForDistanceResults.Value,
configuration.CrossDirectoryMaxItemsInDistanceCollection.Value, configuration.CrossDirectoryMaxItemsInDistanceCollection.Value,
configuration.DistanceFactor.Value, configuration.DistanceFactor.Value,
configuration.DistanceMoveUnableToMatch.Value,
configuration.DistancePixelDistanceTolerance.Value,
configuration.FaceDistanceHiddenImageFactor.Value, configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value, configuration.FaceDistanceMinimumConfidence.Value,
configuration.FaceDistancePermyriad.Value, configuration.FaceDistancePermyriad.Value,
@ -231,7 +239,6 @@ public class Configuration
configuration.MapLogicSigma.Value, configuration.MapLogicSigma.Value,
configuration.MappedMaxIndex, configuration.MappedMaxIndex,
configuration.MappingDefaultName, configuration.MappingDefaultName,
configuration.MappingMoveUnableToMatch.Value,
configuration.MappingSaveNotMapped.Value, configuration.MappingSaveNotMapped.Value,
configuration.MappingSaveMapped.Value, configuration.MappingSaveMapped.Value,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping.Value, configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping.Value,
@ -258,6 +265,7 @@ public class Configuration
configuration.PropertiesChangedForIndex.Value, configuration.PropertiesChangedForIndex.Value,
configuration.PropertiesChangedForMetadata.Value, configuration.PropertiesChangedForMetadata.Value,
configuration.PropertiesChangedForResize.Value, configuration.PropertiesChangedForResize.Value,
configuration.RetryImagesWithoutAFace.Value,
configuration.Reverse.Value, configuration.Reverse.Value,
configuration.SaveFaceLandmarkForOutputResolutions, configuration.SaveFaceLandmarkForOutputResolutions,
configuration.SaveFullYearOfRandomFiles.Value, configuration.SaveFullYearOfRandomFiles.Value,

View File

@ -13,6 +13,8 @@ public class Configuration
public bool CheckJsonForDistanceResults { init; get; } public bool CheckJsonForDistanceResults { init; get; }
public int CrossDirectoryMaxItemsInDistanceCollection { init; get; } public int CrossDirectoryMaxItemsInDistanceCollection { init; get; }
public int DistanceFactor { init; get; } public int DistanceFactor { init; get; }
public bool DistanceMoveUnableToMatch { init; get; }
public int DistancePixelDistanceTolerance { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; } public int FaceDistanceHiddenImageFactor { init; get; }
public double FaceDistanceMinimumConfidence { init; get; } public double FaceDistanceMinimumConfidence { init; get; }
public int FaceDistancePermyriad { init; get; } public int FaceDistancePermyriad { init; get; }
@ -32,7 +34,6 @@ public class Configuration
public int MapLogicSigma { init; get; } public int MapLogicSigma { init; get; }
public int? MappedMaxIndex { init; get; } public int? MappedMaxIndex { init; get; }
public string MappingDefaultName { init; get; } public string MappingDefaultName { init; get; }
public bool MappingMoveUnableToMatch { init; get; }
public bool MappingSaveNotMapped { init; get; } public bool MappingSaveNotMapped { init; get; }
public bool MappingSaveMapped { init; get; } public bool MappingSaveMapped { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { init; get; } public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { init; get; }
@ -59,6 +60,7 @@ public class Configuration
public bool PropertiesChangedForIndex { init; get; } public bool PropertiesChangedForIndex { init; get; }
public bool PropertiesChangedForMetadata { init; get; } public bool PropertiesChangedForMetadata { init; get; }
public bool PropertiesChangedForResize { init; get; } public bool PropertiesChangedForResize { init; get; }
public bool RetryImagesWithoutAFace { init; get; }
public bool Reverse { init; get; } public bool Reverse { init; get; }
public string[] SaveFaceLandmarkForOutputResolutions { init; get; } public string[] SaveFaceLandmarkForOutputResolutions { init; get; }
public bool SaveFullYearOfRandomFiles { init; get; } public bool SaveFullYearOfRandomFiles { init; get; }
@ -78,6 +80,8 @@ public class Configuration
bool checkJsonForDistanceResults, bool checkJsonForDistanceResults,
int crossDirectoryMaxItemsInDistanceCollection, int crossDirectoryMaxItemsInDistanceCollection,
int distanceFactor, int distanceFactor,
bool distanceMoveUnableToMatch,
int distancePixelDistanceTolerance,
int faceDistanceHiddenImageFactor, int faceDistanceHiddenImageFactor,
double faceDistanceMinimumConfidence, double faceDistanceMinimumConfidence,
int faceDistancePermyriad, int faceDistancePermyriad,
@ -97,7 +101,6 @@ public class Configuration
int mapLogicSigma, int mapLogicSigma,
int? mappedMaxIndex, int? mappedMaxIndex,
string mappingDefaultName, string mappingDefaultName,
bool mappingMoveUnableToMatch,
bool mappingSaveNotMapped, bool mappingSaveNotMapped,
bool mappingSaveMapped, bool mappingSaveMapped,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping, bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
@ -124,6 +127,7 @@ public class Configuration
bool propertiesChangedForIndex, bool propertiesChangedForIndex,
bool propertiesChangedForMetadata, bool propertiesChangedForMetadata,
bool propertiesChangedForResize, bool propertiesChangedForResize,
bool retryImagesWithoutAFace,
bool reverse, bool reverse,
string[] saveFaceLandmarkForOutputResolutions, string[] saveFaceLandmarkForOutputResolutions,
bool saveFullYearOfRandomFiles, bool saveFullYearOfRandomFiles,
@ -142,6 +146,8 @@ public class Configuration
CheckJsonForDistanceResults = checkJsonForDistanceResults; CheckJsonForDistanceResults = checkJsonForDistanceResults;
CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection; CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
DistanceFactor = distanceFactor; DistanceFactor = distanceFactor;
DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
DistancePixelDistanceTolerance = distancePixelDistanceTolerance;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor; FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence; FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
FaceDistancePermyriad = faceDistancePermyriad; FaceDistancePermyriad = faceDistancePermyriad;
@ -161,7 +167,6 @@ public class Configuration
MapLogicSigma = mapLogicSigma; MapLogicSigma = mapLogicSigma;
MappedMaxIndex = mappedMaxIndex; MappedMaxIndex = mappedMaxIndex;
MappingDefaultName = mappingDefaultName; MappingDefaultName = mappingDefaultName;
MappingMoveUnableToMatch = mappingMoveUnableToMatch;
MappingSaveNotMapped = mappingSaveNotMapped; MappingSaveNotMapped = mappingSaveNotMapped;
MappingSaveMapped = mappingSaveMapped; MappingSaveMapped = mappingSaveMapped;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping; MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping;
@ -188,6 +193,7 @@ public class Configuration
PropertiesChangedForIndex = propertiesChangedForIndex; PropertiesChangedForIndex = propertiesChangedForIndex;
PropertiesChangedForMetadata = propertiesChangedForMetadata; PropertiesChangedForMetadata = propertiesChangedForMetadata;
PropertiesChangedForResize = propertiesChangedForResize; PropertiesChangedForResize = propertiesChangedForResize;
RetryImagesWithoutAFace = retryImagesWithoutAFace;
Reverse = reverse; Reverse = reverse;
SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions; SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions;
SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles; SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles;

View File

@ -55,6 +55,8 @@
"CrossDirectoryMaxItemsInDistanceCollection": 7, "CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-09-22", "DateGroup": "2022-09-22",
"DistanceFactor": 8, "DistanceFactor": 8,
"DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1,
"FaceDistanceHiddenImageFactor": 2, "FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8, "FaceDistanceMinimumConfidence": 0.8,
"FaceDistancePermyriad": 10000, "FaceDistancePermyriad": 10000,
@ -71,7 +73,6 @@
"MapLogicSigma": 3, "MapLogicSigma": 3,
"MappedMaxIndex": 1034720, "MappedMaxIndex": 1034720,
"MappingDefaultName": "John Doe~25", "MappingDefaultName": "John Doe~25",
"MappingMoveUnableToMatch": false,
"MappingSaveFaceEncoding": false, "MappingSaveFaceEncoding": false,
"MappingSaveMapped": false, "MappingSaveMapped": false,
"MappingSaveNotMapped": false, "MappingSaveNotMapped": false,
@ -106,9 +107,11 @@
"ResultCollection": "[]", "ResultCollection": "[]",
"ResultContent": "()", "ResultContent": "()",
"ResultSingleton": "{}", "ResultSingleton": "{}",
"RetryImagesWithoutAFace": false,
"Reverse": false, "Reverse": false,
"xRootDirectory": "C:/Tmp/phares/Pictures", "xRootDirectory": "C:/Tmp/phares/Pictures",
"RootDirectory": "F:/Tmp/Phares/Compare/Images 2022-09-22 - fb1c68e - III", "RootDirectory": "F:/Tmp/Phares/Compare/Images 2022-09-22 - fb1c68e - III",
"xxRootDirectory": "F:/Tmp/Phares/Compare/Images 2022-09-22 - fb1c68e - III/Facebook/=2022.3 Facebook",
"SaveFullYearOfRandomFiles": true, "SaveFullYearOfRandomFiles": true,
"SaveResizedSubFiles": true, "SaveResizedSubFiles": true,
"SkipSearch": false, "SkipSearch": false,

View File

@ -55,6 +55,8 @@
"CrossDirectoryMaxItemsInDistanceCollection": 7, "CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-09-22", "DateGroup": "2022-09-22",
"DistanceFactor": 8, "DistanceFactor": 8,
"DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1,
"FaceDistanceHiddenImageFactor": 2, "FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8, "FaceDistanceMinimumConfidence": 0.8,
"FaceDistancePermyriad": 10000, "FaceDistancePermyriad": 10000,
@ -71,7 +73,6 @@
"MapLogicSigma": 3, "MapLogicSigma": 3,
"MappedMaxIndex": 1034720, "MappedMaxIndex": 1034720,
"MappingDefaultName": "John Doe~25", "MappingDefaultName": "John Doe~25",
"MappingMoveUnableToMatch": false,
"MappingSaveFaceEncoding": false, "MappingSaveFaceEncoding": false,
"MappingSaveMapped": false, "MappingSaveMapped": false,
"MappingSaveNotMapped": false, "MappingSaveNotMapped": false,
@ -106,6 +107,7 @@
"ResultCollection": "[]", "ResultCollection": "[]",
"ResultContent": "()", "ResultContent": "()",
"ResultSingleton": "{}", "ResultSingleton": "{}",
"RetryImagesWithoutAFace": false,
"Reverse": false, "Reverse": false,
"RootDirectory": "E:/Images", "RootDirectory": "E:/Images",
"SaveFullYearOfRandomFiles": true, "SaveFullYearOfRandomFiles": true,

View File

@ -55,6 +55,8 @@
"CrossDirectoryMaxItemsInDistanceCollection": 7, "CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-09-22", "DateGroup": "2022-09-22",
"DistanceFactor": 8, "DistanceFactor": 8,
"DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1,
"FaceDistanceHiddenImageFactor": 2, "FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8, "FaceDistanceMinimumConfidence": 0.8,
"FaceDistancePermyriad": 10000, "FaceDistancePermyriad": 10000,
@ -71,7 +73,6 @@
"MapLogicSigma": 3, "MapLogicSigma": 3,
"MappedMaxIndex": 1034720, "MappedMaxIndex": 1034720,
"MappingDefaultName": "John Doe~25", "MappingDefaultName": "John Doe~25",
"MappingMoveUnableToMatch": false,
"MappingSaveFaceEncoding": false, "MappingSaveFaceEncoding": false,
"MappingSaveMapped": false, "MappingSaveMapped": false,
"MappingSaveNotMapped": false, "MappingSaveNotMapped": false,
@ -106,6 +107,7 @@
"ResultCollection": "[]", "ResultCollection": "[]",
"ResultContent": "()", "ResultContent": "()",
"ResultSingleton": "{}", "ResultSingleton": "{}",
"RetryImagesWithoutAFace": false,
"Reverse": false, "Reverse": false,
"RootDirectory": "D:/Images", "RootDirectory": "D:/Images",
"SaveFullYearOfRandomFiles": true, "SaveFullYearOfRandomFiles": true,

View File

@ -10,11 +10,9 @@ public class Configuration
public int FaceDistancePermyriad { init; get; } public int FaceDistancePermyriad { init; get; }
public double FaceDistanceMinimumConfidence { init; get; } public double FaceDistanceMinimumConfidence { init; get; }
public double FaceDistanceTolerance { init; get; } public double FaceDistanceTolerance { init; get; }
public int LocationDigits { init; get; }
public int LocationFactor { init; get; }
public int MapLogicSigma { init; get; } public int MapLogicSigma { init; get; }
public string MappingDefaultName { init; get; } public string MappingDefaultName { init; get; }
public bool MappingMoveUnableToMatch { init; get; } public bool DistanceMoveUnableToMatch { init; get; }
public bool MappingSaveNotMapped { init; get; } public bool MappingSaveNotMapped { init; get; }
public bool MappingSaveMapped { init; get; } public bool MappingSaveMapped { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { init; get; } public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { init; get; }
@ -32,11 +30,9 @@ public class Configuration
int faceDistancePermyriad, int faceDistancePermyriad,
double faceDistanceMinimumConfidence, double faceDistanceMinimumConfidence,
double faceDistanceTolerance, double faceDistanceTolerance,
int locationDigits,
int locationFactor,
int mapLogicSigma, int mapLogicSigma,
string mappingDefaultName, string mappingDefaultName,
bool mappingMoveUnableToMatch, bool distanceMoveUnableToMatch,
bool mappingSaveNotMapped, bool mappingSaveNotMapped,
bool mappingSaveMapped, bool mappingSaveMapped,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping, bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
@ -53,11 +49,9 @@ public class Configuration
FaceDistancePermyriad = faceDistancePermyriad; FaceDistancePermyriad = faceDistancePermyriad;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence; FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
FaceDistanceTolerance = faceDistanceTolerance; FaceDistanceTolerance = faceDistanceTolerance;
LocationDigits = locationDigits;
LocationFactor = locationFactor;
MapLogicSigma = mapLogicSigma; MapLogicSigma = mapLogicSigma;
MappingDefaultName = mappingDefaultName; MappingDefaultName = mappingDefaultName;
MappingMoveUnableToMatch = mappingMoveUnableToMatch; DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
MappingSaveNotMapped = mappingSaveNotMapped; MappingSaveNotMapped = mappingSaveNotMapped;
MappingSaveMapped = mappingSaveMapped; MappingSaveMapped = mappingSaveMapped;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping; MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping;

View File

@ -464,7 +464,7 @@ public class MapLogic
} }
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday); personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
directory = Path.Combine(_EDistanceContentTicksDirectory, "Shortcuts", personKeyFormatted, subDirectoryName); directory = Path.Combine(_EDistanceContentTicksDirectory, "Shortcuts", personKeyFormatted, subDirectoryName);
if (face.FaceEncoding is not null && face.Location?.NormalizedPixelPercentage is not null) if (face.FaceEncoding is not null)
copyDirectory = Path.Combine(_EDistanceContentTicksDirectory, "Images", personKeyFormatted, subDirectoryName); copyDirectory = Path.Combine(_EDistanceContentTicksDirectory, "Images", personKeyFormatted, subDirectoryName);
else else
copyDirectory = Path.Combine(_EDistanceContentTicksDirectory, "ImagesBut", personKeyFormatted, subDirectoryName); copyDirectory = Path.Combine(_EDistanceContentTicksDirectory, "ImagesBut", personKeyFormatted, subDirectoryName);
@ -578,7 +578,7 @@ public class MapLogic
} }
} }
private List<SaveContainer> GetMappingSaveContainers(string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List<Face> filteredFaces) private List<SaveContainer> GetMappingSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, List<Face> filteredFaces)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -597,8 +597,6 @@ public class MapLogic
FileHolder facePartsFileHolder; FileHolder facePartsFileHolder;
FileHolder hiddenFaceFileHolder; FileHolder hiddenFaceFileHolder;
Dictionary<string, int> keyValuePairs = new(); Dictionary<string, int> keyValuePairs = new();
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, "()");
string forceSingleImageHumanized = nameof(Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title); string forceSingleImageHumanized = nameof(Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
foreach (Face face in filteredFaces) foreach (Face face in filteredFaces)
{ {
@ -652,20 +650,20 @@ public class MapLogic
return results; return results;
} }
public void ForceSingleImageThenSaveMapping(string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List<Face> distinctFilteredFaces, SortingContainer[] sortingContainers, int totalNotMapped) public void ForceSingleImageThenSaveMapping(string dFacesContentDirectory, string d2FacePartsContentDirectory, List<Face> distinctFilteredFaces, SortingContainer[] sortingContainers, int totalNotMapped)
{ {
List<SaveContainer> saveContainers; List<SaveContainer> saveContainers;
if (!sortingContainers.Any()) if (!sortingContainers.Any())
{ {
ForceSingleImage(distinctFilteredFaces); ForceSingleImage(distinctFilteredFaces);
saveContainers = GetMappingSaveContainers(dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces); saveContainers = GetMappingSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces);
} }
else else
{ {
int updated = UpdateFromSortingContainers(sortingContainers); int updated = UpdateFromSortingContainers(sortingContainers);
if (totalNotMapped - updated > 0) if (totalNotMapped - updated > 0)
ForceSingleImage(distinctFilteredFaces); ForceSingleImage(distinctFilteredFaces);
saveContainers = GetMappingSaveContainers(dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces); saveContainers = GetMappingSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, distinctFilteredFaces);
} }
SaveContainers(saveContainers); SaveContainers(saveContainers);
} }
@ -688,7 +686,7 @@ public class MapLogic
return results; return results;
} }
public void CopyManualFiles(string dResultsFullGroupDirectory, List<Face> distinctFilteredFaces) public void CopyManualFiles(string dFacesContentDirectory, List<Face> distinctFilteredFaces)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -714,7 +712,6 @@ public class MapLogic
Dictionary<int, PersonContainer[]>? keyValuePairs; Dictionary<int, PersonContainer[]>? keyValuePairs;
string by = nameof(Stateless.IMapLogic.ManualCopy); string by = nameof(Stateless.IMapLogic.ManualCopy);
Dictionary<int, Face>? normalizedPixelPercentageToFace; Dictionary<int, Face>? normalizedPixelPercentageToFace;
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
string successfull = $"_ {nameof(Stateless.IMapLogic.ManualCopy).Humanize(LetterCasing.Title)} Successfull"; string successfull = $"_ {nameof(Stateless.IMapLogic.ManualCopy).Humanize(LetterCasing.Title)} Successfull";
Dictionary<int, Dictionary<int, Face>> idToNormalizedPixelPercentageToFace = GetKeyValuePairs(distinctFilteredFaces); Dictionary<int, Dictionary<int, Face>> idToNormalizedPixelPercentageToFace = GetKeyValuePairs(distinctFilteredFaces);
foreach (KeyValuePair<long, PersonContainer> keyValuePair in _PersonKeyToPersonContainer) foreach (KeyValuePair<long, PersonContainer> keyValuePair in _PersonKeyToPersonContainer)
@ -726,7 +723,7 @@ public class MapLogic
{ {
if (!personDisplayDirectoryAllFile.EndsWith(_FacesFileNameExtension)) if (!personDisplayDirectoryAllFile.EndsWith(_FacesFileNameExtension))
continue; continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(_Configuration.LocationDigits, _FacesFileNameExtension, personDisplayDirectoryAllFile); (id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(Shared.Models.Stateless.ILocation.Digits, _FacesFileNameExtension, personDisplayDirectoryAllFile);
if (id is null || normalizedPixelPercentage is null) if (id is null || normalizedPixelPercentage is null)
continue; continue;
if (_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(id.Value, out keyValuePairs)) if (_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(id.Value, out keyValuePairs))

View File

@ -46,7 +46,7 @@ internal abstract class MapLogic
{ {
if (!personDisplayDirectoryAllFile.EndsWith(facesFileNameExtension)) if (!personDisplayDirectoryAllFile.EndsWith(facesFileNameExtension))
continue; continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(configuration.LocationDigits, facesFileNameExtension, personDisplayDirectoryAllFile); (id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(Shared.Models.Stateless.ILocation.Digits, facesFileNameExtension, personDisplayDirectoryAllFile);
if (id is null || normalizedPixelPercentage is null) if (id is null || normalizedPixelPercentage is null)
continue; continue;
if (!skipCollection.ContainsKey(id.Value)) if (!skipCollection.ContainsKey(id.Value))
@ -73,7 +73,7 @@ internal abstract class MapLogic
} }
} }
internal static List<(string, string[], string)> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, string facesFileNameExtension, long ticks, string eDistanceContentDirectory, List<string> personKeyFormattedCollection) internal static List<(string, string[], string)> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, string facesFileNameExtension, List<string> personKeyFormattedCollection, string[] ticksDirectories, string message)
{ {
List<(string, string[], string)> results = new(); List<(string, string[], string)> results = new();
int? id; int? id;
@ -91,10 +91,7 @@ internal abstract class MapLogic
string? personFirstInitialDirectory; string? personFirstInitialDirectory;
string[] personDisplayDirectoryNames; string[] personDisplayDirectoryNames;
string manualCopyHumanized = nameof(IMapLogic.ManualCopy).Humanize(LetterCasing.Title); string manualCopyHumanized = nameof(IMapLogic.ManualCopy).Humanize(LetterCasing.Title);
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string forceSingleImageHumanized = nameof(IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title); string forceSingleImageHumanized = nameof(IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly);
string message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - A - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(ticksDirectories.Length, message, options); using ProgressBar progressBar = new(ticksDirectories.Length, message, options);
foreach (string ticksDirectory in ticksDirectories) foreach (string ticksDirectory in ticksDirectories)
@ -151,7 +148,7 @@ internal abstract class MapLogic
{ {
if (file.EndsWith(".lnk") || file.EndsWith(".json")) if (file.EndsWith(".lnk") || file.EndsWith(".json"))
continue; continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(configuration.LocationDigits, facesFileNameExtension, file); (id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(Shared.Models.Stateless.ILocation.Digits, facesFileNameExtension, file);
if (id is null || normalizedPixelPercentage is null) if (id is null || normalizedPixelPercentage is null)
continue; continue;
results.Add(new(personKeyFormatted, personDisplayDirectoryNames, file)); results.Add(new(personKeyFormatted, personDisplayDirectoryNames, file));
@ -180,6 +177,35 @@ internal abstract class MapLogic
return results; return results;
} }
internal static string[] DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, string facesFileNameExtension, long ticks, string eDistanceContentDirectory, PersonContainer[] personContainers)
{
string[] results;
string personKeyFormatted;
List<string> personKeyFormattedCollection = new();
_ = GetDistinctCollection(configuration, personContainers.ToList(), new());
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly);
string message = $") {ticksDirectories.Length:000} collect from and clean ticks Director(ies) - A - {totalSeconds} total second(s)";
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
foreach (PersonBirthday personBirthday in personContainer.Birthdays)
{
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personBirthday);
personKeyFormattedCollection.Add(personKeyFormatted);
}
}
List<(string PersonKeyFormatted, string[] PersonDisplayDirectoryNames, string File)> collection = DeleteEmptyDirectoriesAndGetCollection(
configuration,
facesFileNameExtension,
personKeyFormattedCollection,
ticksDirectories,
message);
results = (from l in collection select l.File).ToArray();
return results;
}
private static PersonContainer[] GetDistinctPersonContainers(List<PersonContainer> personContainers) private static PersonContainer[] GetDistinctPersonContainers(List<PersonContainer> personContainers)
{ {
List<PersonContainer> results = new(); List<PersonContainer> results = new();
@ -195,32 +221,14 @@ internal abstract class MapLogic
private static void SetKeyValuePairs(Configuration configuration, long ticks, List<PersonContainer> personContainers, List<Face> distinctFilteredFaces, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedPixelPercentageToPersonContainers, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges) private static void SetKeyValuePairs(Configuration configuration, long ticks, List<PersonContainer> personContainers, List<Face> distinctFilteredFaces, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedPixelPercentageToPersonContainers, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges)
{ {
const int zero = 0;
PersonBirthday? personBirthday; PersonBirthday? personBirthday;
string newestPersonKeyFormatted;
PersonContainer[] distinctPersonContainers; PersonContainer[] distinctPersonContainers;
Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer = new(); Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer = new();
Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection = new();
Dictionary<int, Dictionary<int, List<PersonContainer>>> idThenNormalizedPixelPercentageToPersonContainerCollection = new(); Dictionary<int, Dictionary<int, List<PersonContainer>>> idThenNormalizedPixelPercentageToPersonContainerCollection = new();
Dictionary<int, Dictionary<int, List<PersonContainer>>> incorrectIdThenNormalizedPixelPercentageToPersonContainerCollection = new(); Dictionary<int, Dictionary<int, List<PersonContainer>>> incorrectIdThenNormalizedPixelPercentageToPersonContainerCollection = new();
foreach (PersonContainer personContainer in personContainers) List<(long, PersonContainer)> collection = GetDistinctCollection(configuration, personContainers, personKeyFormattedToPersonContainer);
{ foreach ((long personKey, PersonContainer personContainer) in collection)
if (personContainer.Key is null) personKeyToPersonContainer.Add(personKey, personContainer);
continue;
if (!personKeyToPersonContainerCollection.ContainsKey(personContainer.Key.Value))
personKeyToPersonContainerCollection.Add(personContainer.Key.Value, new());
personKeyToPersonContainerCollection[personContainer.Key.Value].Add(personContainer);
newestPersonKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personContainer.Key.Value);
if (!personKeyFormattedToPersonContainer.ContainsKey(newestPersonKeyFormatted))
personKeyFormattedToPersonContainer.Add(newestPersonKeyFormatted, personContainer);
}
foreach (KeyValuePair<long, List<PersonContainer>> keyValuePair in personKeyToPersonContainerCollection)
{
if (keyValuePair.Value.Count != 1 && (from l in keyValuePair.Value select l.DisplayDirectoryName).Distinct().Count() != 1)
throw new NotImplementedException();
personKeyToPersonContainer.Add(keyValuePair.Key, keyValuePair.Value[zero]);
}
if (personKeyFormattedIdThenNormalizedPixelPercentageCollection.Any()) if (personKeyFormattedIdThenNormalizedPixelPercentageCollection.Any())
{ {
string personDisplayDirectory; string personDisplayDirectory;
@ -291,104 +299,60 @@ internal abstract class MapLogic
} }
} }
private static string? GetCheckFile(Configuration configuration, string facesFileNameExtension, string file, int id, int normalizedPixelPercentage) private static List<(long, PersonContainer)> GetDistinctCollection(Configuration configuration, List<PersonContainer> personContainers, Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer)
{ {
string? result; List<(long, PersonContainer)> results = new();
string fileName = Path.GetFileName(file); const int zero = 0;
string? directoryName = Path.GetDirectoryName(file); string newestPersonKeyFormatted;
(string? Id, string? NormalizedPixelPercentage, string? ExtensionLowered, bool? Check) segments = IMapping.GetSegments(configuration.LocationDigits, facesFileNameExtension, fileName); Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection = new();
if (string.IsNullOrEmpty(directoryName) || string.IsNullOrEmpty(segments.Id) || string.IsNullOrEmpty(segments.NormalizedPixelPercentage) || string.IsNullOrEmpty(segments.ExtensionLowered)) foreach (PersonContainer personContainer in personContainers)
result = null;
else
result = Path.Combine(directoryName, $"{IMapping.GetDeterministicHashCodeKey(id, normalizedPixelPercentage)}{segments.ExtensionLowered}.json");
return result;
}
private static void MoveUnableToMatch(Configuration configuration, string eDistanceContentDirectory, string file, string jsonFile)
{
bool result;
string? fileName = Path.GetFileName(file);
string? jsonFileName = Path.GetFileName(jsonFile);
if (fileName is null || jsonFileName is null)
result = false;
else
{ {
string? directoryName = Path.GetDirectoryName(jsonFile); if (personContainer.Key is null)
string? jsonDirectoryName = Path.GetDirectoryName(jsonFile); continue;
if (string.IsNullOrEmpty(directoryName) || string.IsNullOrEmpty(directoryName) || directoryName != jsonDirectoryName || !directoryName.Contains(eDistanceContentDirectory)) if (!personKeyToPersonContainerCollection.ContainsKey(personContainer.Key.Value))
result = false; personKeyToPersonContainerCollection.Add(personContainer.Key.Value, new());
else personKeyToPersonContainerCollection[personContainer.Key.Value].Add(personContainer);
{ newestPersonKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personContainer.Key.Value);
List<string> directoryNames = new(); if (!personKeyFormattedToPersonContainer.ContainsKey(newestPersonKeyFormatted))
string? checkDirectoryName = directoryName; personKeyFormattedToPersonContainer.Add(newestPersonKeyFormatted, personContainer);
for (int i = 0; i < int.MaxValue; i++)
{
if (string.IsNullOrEmpty(checkDirectoryName))
continue;
directoryNames.Add(Path.GetFileName(checkDirectoryName));
checkDirectoryName = Path.GetDirectoryName(checkDirectoryName);
if (string.IsNullOrEmpty(checkDirectoryName))
continue;
if (checkDirectoryName == eDistanceContentDirectory)
break;
}
if (string.IsNullOrEmpty(checkDirectoryName) || !directoryNames.Any() || !long.TryParse(directoryNames[^1][1..^1], out long directoryTicks))
{
result = false;
File.Delete(jsonFile);
File.Delete(file);
}
else
{
bool jsonFileExists = File.Exists(jsonFile);
if (!jsonFileExists)
checkDirectoryName = Path.Combine(checkDirectoryName, $"({directoryTicks}.00)");
else
checkDirectoryName = Path.Combine(checkDirectoryName, $"({directoryTicks}{configuration.FaceDistanceTolerance.ToString()[1..]})");
for (int i = directoryNames.Count - 1 - 1; i > -1; i--)
checkDirectoryName = Path.Combine(checkDirectoryName, directoryNames[i]);
if (!Directory.Exists(checkDirectoryName))
_ = Directory.CreateDirectory(checkDirectoryName);
File.Move(file, Path.Combine(checkDirectoryName, fileName));
if (jsonFileExists)
File.Move(jsonFile, Path.Combine(checkDirectoryName, jsonFileName));
result = true;
}
}
} }
if (result) foreach (KeyValuePair<long, List<PersonContainer>> keyValuePair in personKeyToPersonContainerCollection)
{ } {
if (keyValuePair.Value.Count != 1 && (from l in keyValuePair.Value select l.DisplayDirectoryName).Distinct().Count() != 1)
throw new NotSupportedException(keyValuePair.Value[zero].DisplayDirectoryName);
results.Add(new(keyValuePair.Key, keyValuePair.Value[zero]));
}
return results;
} }
private static int SetCollectionsAndGetUnableToMatchCount(Configuration configuration, string facesFileNameExtension, long ticks, string eDistanceContentDirectory, Shared.Models.Methods.IFaceDistance? distance, Dictionary<int, List<Face>> idToFaces, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, string[], string)> collection) private static (int, int) SetCollectionsAndGetUnableToMatchCount(string facesFileNameExtension, long ticks, Dictionary<int, List<Face>> idToFaces, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, string[], string)> collection)
{ {
int? id;
int result = 0; int result = 0;
int? id;
bool debugCheck; bool debugCheck;
string? checkFile;
List<Face>? faces; List<Face>? faces;
List<int> debugChecks = new(); List<int> debugChecks = new();
List<Face> checkFaces = new(); List<Face> checkFaces = new();
int? normalizedPixelPercentage; int? normalizedPixelPercentage;
string newestPersonKeyFormatted; string newestPersonKeyFormatted;
List<string> duplicates = new();
string personDisplayDirectoryName; string personDisplayDirectoryName;
bool idToFacesAny = idToFaces.Any(); bool idToFacesAny = idToFaces.Any();
List<int> normalizedPixelPercentages; List<int> normalizedPixelPercentages;
List<string> duplicateMappedFaceFiles = new();
Dictionary<int, List<int>> idToNormalizedPixelPercentages = new(); Dictionary<int, List<int>> idToNormalizedPixelPercentages = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") {collection.Count:000} join from ticks Director(ies) - B - {totalSeconds} total second(s)"; string message = $") {collection.Count:000} join from ticks Director(ies) - C - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(collection.Count, message, options); using ProgressBar progressBar = new(collection.Count, message, options);
foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, string file) in collection) foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, string mappedFaceFile) in collection)
{ {
progressBar.Tick(); progressBar.Tick();
(id, normalizedPixelPercentage, faces) = IMapping.GetReversedDeterministicHashCodeKey( (id, normalizedPixelPercentage, faces) = IMapping.GetReversedDeterministicHashCodeKey(
configuration.LocationDigits, Shared.Models.Stateless.ILocation.Digits,
facesFileNameExtension, facesFileNameExtension,
idToFacesAny, idToFacesAny,
idToFaces, idToFaces,
file); mappedFaceFile);
if (id is null || normalizedPixelPercentage is null) if (id is null || normalizedPixelPercentage is null)
{ {
result++; result++;
@ -397,9 +361,6 @@ internal abstract class MapLogic
if (!idToNormalizedPixelPercentages.ContainsKey(id.Value)) if (!idToNormalizedPixelPercentages.ContainsKey(id.Value))
idToNormalizedPixelPercentages.Add(id.Value, new()); idToNormalizedPixelPercentages.Add(id.Value, new());
normalizedPixelPercentages = idToNormalizedPixelPercentages[id.Value]; normalizedPixelPercentages = idToNormalizedPixelPercentages[id.Value];
checkFile = GetCheckFile(configuration, facesFileNameExtension, file, id.Value, normalizedPixelPercentage.Value);
if (string.IsNullOrEmpty(checkFile))
throw new NotSupportedException();
if (faces is null) if (faces is null)
{ {
result++; result++;
@ -417,35 +378,25 @@ internal abstract class MapLogic
continue; continue;
if (normalizedPixelPercentages.Contains(face.Mapping.MappingFromLocation.NormalizedPixelPercentage)) if (normalizedPixelPercentages.Contains(face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
{ {
duplicates.Add(string.Concat(id.Value, '.', normalizedPixelPercentage.Value, ".jpg", facesFileNameExtension)); duplicateMappedFaceFiles.Add(mappedFaceFile);
continue; continue;
} }
debugCheck = true; debugCheck = true;
checkFaces.Add(face); checkFaces.Add(face);
if (!debugCheck) if (!debugCheck)
debugChecks.Add(normalizedPixelPercentage.Value); debugChecks.Add(face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
} }
if (checkFaces.Count != 1 && distance is not null && File.Exists(checkFile))
{
checkFaces.Clear();
checkFaces.AddRange(distance.GetMatchingFaces(configuration.FaceDistanceTolerance, checkFile, faces));
}
if (!checkFaces.Any() && faces.Count == 1)
checkFaces.AddRange(faces);
if (!checkFaces.Any()) if (!checkFaces.Any())
{ {
result++; result++;
if (configuration.MappingMoveUnableToMatch)
MoveUnableToMatch(configuration, eDistanceContentDirectory, file, checkFile);
continue; continue;
} }
if (checkFaces.Count != 1) if (checkFaces.Count != 1)
{ {
result++; result++;
if (configuration.MappingMoveUnableToMatch)
MoveUnableToMatch(configuration, eDistanceContentDirectory, file, checkFile);
continue; continue;
} }
normalizedPixelPercentages.Add(normalizedPixelPercentage.Value);
idToNormalizedPixelPercentages[id.Value].Add(normalizedPixelPercentage.Value); idToNormalizedPixelPercentages[id.Value].Add(normalizedPixelPercentage.Value);
if (!personKeyFormattedToNewestPersonKeyFormatted.ContainsKey(personKeyFormatted)) if (!personKeyFormattedToNewestPersonKeyFormatted.ContainsKey(personKeyFormatted))
newestPersonKeyFormatted = personKeyFormatted; newestPersonKeyFormatted = personKeyFormatted;
@ -457,13 +408,13 @@ internal abstract class MapLogic
else else
personKeyFormattedIdThenNormalizedPixelPercentageCollection.Add(new(newestPersonKeyFormatted, personDisplayDirectoryNames, id.Value, normalizedPixelPercentage.Value)); personKeyFormattedIdThenNormalizedPixelPercentageCollection.Add(new(newestPersonKeyFormatted, personDisplayDirectoryNames, id.Value, normalizedPixelPercentage.Value));
} }
if (duplicates.Any()) if (duplicateMappedFaceFiles.Any())
{ {
duplicates.Sort(); duplicateMappedFaceFiles.Sort();
if (duplicates.Any()) if (duplicateMappedFaceFiles.Any())
{ } { }
} }
return result; return new(result, duplicateMappedFaceFiles.Count);
} }
private static double GetStandardDeviation(IEnumerable<long> values, double average) private static double GetStandardDeviation(IEnumerable<long> values, double average)
@ -616,6 +567,8 @@ internal abstract class MapLogic
{ {
if (configuration is null) if (configuration is null)
throw new NullReferenceException(nameof(configuration)); throw new NullReferenceException(nameof(configuration));
string message;
int totalSeconds;
List<long> personKeys = new(); List<long> personKeys = new();
List<long?> nullablePersonKeyCollection = new(); List<long?> nullablePersonKeyCollection = new();
List<string> personKeyFormattedCollection = new(); List<string> personKeyFormattedCollection = new();
@ -636,7 +589,7 @@ internal abstract class MapLogic
personContainers.AddRange(AddToPersonKeysThenGetNonSpecificPeopleCollection(configuration, personKeys)); personContainers.AddRange(AddToPersonKeysThenGetNonSpecificPeopleCollection(configuration, personKeys));
foreach (Face face in distinctFilteredFaces) foreach (Face face in distinctFilteredFaces)
{ {
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null) if (face.FaceEncoding is null || face.Location is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (face.Mapping is null) if (face.Mapping is null)
throw new NotSupportedException(); throw new NotSupportedException();
@ -644,17 +597,18 @@ internal abstract class MapLogic
keyValuePairs.Add(face.Mapping.MappingFromItem.Id, new()); keyValuePairs.Add(face.Mapping.MappingFromItem.Id, new());
keyValuePairs[face.Mapping.MappingFromItem.Id].Add(face); keyValuePairs[face.Mapping.MappingFromItem.Id].Add(face);
} }
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
facesFileNameExtension, string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly);
ticks, message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)";
eDistanceContentDirectory, List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(
personKeyFormattedCollection);
int unableToMatchCount = SetCollectionsAndGetUnableToMatchCount(
configuration, configuration,
facesFileNameExtension,
personKeyFormattedCollection,
ticksDirectories,
message);
(int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToMatchCount(
facesFileNameExtension, facesFileNameExtension,
ticks, ticks,
eDistanceContentDirectory,
faceDistance,
keyValuePairs, keyValuePairs,
personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedToNewestPersonKeyFormatted,
personKeyFormattedIdThenNormalizedPixelPercentageCollection, personKeyFormattedIdThenNormalizedPixelPercentageCollection,
@ -672,8 +626,8 @@ internal abstract class MapLogic
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer,
incorrectIdThenNormalizedPixelPercentageToPersonContainers, incorrectIdThenNormalizedPixelPercentageToPersonContainers,
personKeyToRanges); personKeyToRanges);
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") {collection.Count:000} message from ticks Director(ies) - C - {unableToMatchCount} Unable To Match Count / {collection.Count} Collection - {totalSeconds} total second(s)"; message = $") {collection.Count:000} message from ticks Director(ies) - D - {duplicateCount} Duplicate Count {unableToMatchCount} Unable To Match Count / {collection.Count} Collection - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using (ProgressBar progressBar = new(collection.Count, message, options)) using (ProgressBar progressBar = new(collection.Count, message, options))
{ {

View File

@ -3,4 +3,9 @@ namespace View_by_Distance.Map.Models.Stateless.Methods;
public interface IMapLogic public interface IMapLogic
{ // ... { // ...
string[] TestStatic_DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, string facesFileNameExtension, long ticks, string eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) =>
DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, facesFileNameExtension, ticks, eDistanceContentDirectory, personContainers);
static string[] DeleteEmptyDirectoriesAndGetMappedFaceFiles(Configuration configuration, string facesFileNameExtension, long ticks, string eDistanceContentDirectory, Shared.Models.PersonContainer[] personContainers) =>
MapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(configuration, facesFileNameExtension, ticks, eDistanceContentDirectory, personContainers);
} }

View File

@ -12,7 +12,6 @@ public class Face : Properties.IFace
protected Dictionary<Stateless.FacePart, FacePoint[]>? _FaceParts; protected Dictionary<Stateless.FacePart, FacePoint[]>? _FaceParts;
protected readonly OutputResolution? _OutputResolution; protected readonly OutputResolution? _OutputResolution;
protected Location? _Location; protected Location? _Location;
protected readonly int? _LocationIndex;
protected Mapping? _Mapping; protected Mapping? _Mapping;
protected readonly string _RelativePath; protected readonly string _RelativePath;
public DateTime DateTime => _DateTime; public DateTime DateTime => _DateTime;
@ -20,34 +19,32 @@ public class Face : Properties.IFace
public FaceEncoding? FaceEncoding => _FaceEncoding; public FaceEncoding? FaceEncoding => _FaceEncoding;
public Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts => _FaceParts; public Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts => _FaceParts;
public Location? Location => _Location; public Location? Location => _Location;
public int? LocationIndex => _LocationIndex;
public Mapping? Mapping => _Mapping; public Mapping? Mapping => _Mapping;
public OutputResolution? OutputResolution => _OutputResolution; public OutputResolution? OutputResolution => _OutputResolution;
public string RelativePath => _RelativePath; public string RelativePath => _RelativePath;
[JsonConstructor] [JsonConstructor]
public Face(DateTime dateTime, FaceDistance? faceDistance, FaceEncoding? faceEncoding, Dictionary<Stateless.FacePart, FacePoint[]>? faceParts, Location? location, int? locationIndex, Mapping? mapping, OutputResolution? outputResolution, string relativePath) public Face(DateTime dateTime, FaceDistance? faceDistance, FaceEncoding? faceEncoding, Dictionary<Stateless.FacePart, FacePoint[]>? faceParts, Location? location, Mapping? mapping, OutputResolution? outputResolution, string relativePath)
{ {
_DateTime = dateTime; _DateTime = dateTime;
_FaceDistance = faceDistance; _FaceDistance = faceDistance;
_FaceEncoding = faceEncoding; _FaceEncoding = faceEncoding;
_FaceParts = faceParts; _FaceParts = faceParts;
_Location = location; _Location = location;
_LocationIndex = locationIndex;
_Mapping = mapping; _Mapping = mapping;
_OutputResolution = outputResolution; _OutputResolution = outputResolution;
_RelativePath = relativePath; _RelativePath = relativePath;
} }
public Face(int locationDigits, int locationFactor, int facesCount, Face face) : public Face(int locationDigits, int locationFactor, int facesCount, Face face) :
this(face.DateTime, null, face.FaceEncoding, face.FaceParts, face.Location, face.LocationIndex, null, face.OutputResolution, face.RelativePath) this(face.DateTime, null, face.FaceEncoding, face.FaceParts, face.Location, null, face.OutputResolution, face.RelativePath)
{ {
if (face.Location?.Confidence is not null && face.OutputResolution is not null) if (face.Location?.Confidence is not null && face.OutputResolution is not null)
_Location = new(face.Location.Confidence, face.OutputResolution.Height, face.Location, locationDigits, locationFactor, face.OutputResolution.Width, facesCount); _Location = new(face.Location.Confidence, face.OutputResolution.Height, face.Location, locationDigits, locationFactor, face.OutputResolution.Width, facesCount);
} }
public Face(Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string relativePath, int? i, Location? location) : public Face(Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string relativePath, Location? location) :
this(DateTime.MinValue, null, null, null, location, i, null, null, relativePath) this(DateTime.MinValue, null, null, null, location, null, null, relativePath)
{ {
DateTime?[] dateTimes; DateTime?[] dateTimes;
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth); _OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
@ -56,7 +53,7 @@ public class Face : Properties.IFace
} }
public Face(Face face, int height, Location location, int locationDigits, int locationFactor, int width, int zCount) : public Face(Face face, int height, Location location, int locationDigits, int locationFactor, int width, int zCount) :
this(face.DateTime, face.FaceDistance, face.FaceEncoding, face.FaceParts, new(height, location, locationDigits, locationFactor, width, zCount), face.LocationIndex, face.Mapping, face.OutputResolution, face.RelativePath) this(face.DateTime, face.FaceDistance, face.FaceEncoding, face.FaceParts, new(height, location, locationDigits, locationFactor, width, zCount), face.Mapping, face.OutputResolution, face.RelativePath)
{ } { }
public override string ToString() public override string ToString()
@ -73,6 +70,8 @@ public class Face : Properties.IFace
public void SetMapping(Mapping mapping) => _Mapping = mapping; public void SetMapping(Mapping mapping) => _Mapping = mapping;
public void FaceDistanceAdd(FaceDistance faceDistance) => _FaceDistance = faceDistance; public void SetFaceDistance(FaceDistance? faceDistance) => _FaceDistance = faceDistance;
public void ClearFaceDistance() => _FaceDistance = null;
} }

View File

@ -122,16 +122,8 @@ public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem
string locationDisplayIndex; string locationDisplayIndex;
int locationIndex; int locationIndex;
long sourceSize; long sourceSize;
if (face.LocationIndex is null) locationIndex = 0;
{ locationDisplayIndex = "01";
locationIndex = 0;
locationDisplayIndex = "01";
}
else
{
locationIndex = face.LocationIndex.Value;
locationDisplayIndex = (face.LocationIndex.Value + 1).ToString("00");
}
if (face.Location is null) if (face.Location is null)
{ {
faceTop = null; faceTop = null;
@ -161,7 +153,7 @@ public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem
string faceRelativePath = string.Concat(requestPath, new Uri(faceFullFileName).AbsoluteUri[rootResultsDirectoryAbsoluteUriLength..]); string faceRelativePath = string.Concat(requestPath, new Uri(faceFullFileName).AbsoluteUri[rootResultsDirectoryAbsoluteUriLength..]);
string sourceRelativePath = string.Concat(requestPath, new Uri(sourceFullFileName).AbsoluteUri[rootResultsDirectoryAbsoluteUriLength..]); string sourceRelativePath = string.Concat(requestPath, new Uri(sourceFullFileName).AbsoluteUri[rootResultsDirectoryAbsoluteUriLength..]);
FileInfo fileInfo = new(sourceFullFileName); FileInfo fileInfo = new(sourceFullFileName);
if (face.FaceEncoding is not null && face.Location?.NormalizedPixelPercentage is not null && !File.Exists(faceFullFileName)) if (face.FaceEncoding is not null && face.Location is not null && face.OutputResolution is not null && !File.Exists(faceFullFileName))
Stateless.Methods.IFaceFileSystem.SearchForMissingFile(faceFullFileName, fileInfo: new FileInfo(string.Empty), dataFullFileName); Stateless.Methods.IFaceFileSystem.SearchForMissingFile(faceFullFileName, fileInfo: new FileInfo(string.Empty), dataFullFileName);
if (fileInfo.Exists) if (fileInfo.Exists)
FileExists(face, faceBottom, faceRight, out imageHeight, out imageWidth, out sourceSize, fileInfo); FileExists(face, faceBottom, faceRight, out imageHeight, out imageWidth, out sourceSize, fileInfo);
@ -180,8 +172,8 @@ public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem
_LastModified = face.DateTime; _LastModified = face.DateTime;
_FaceLeft = faceLeft; _FaceLeft = faceLeft;
_LocationDisplayIndex = locationDisplayIndex; _LocationDisplayIndex = locationDisplayIndex;
_LocationIndex = face.LocationIndex; _LocationIndex = null;
_Populated = face.FaceEncoding is not null && face.Location?.NormalizedPixelPercentage is not null; _Populated = face.FaceEncoding is not null && face.Location is not null && face.OutputResolution is not null;
_RelativePath = string.Empty; _RelativePath = string.Empty;
_FaceRight = faceRight; _FaceRight = faceRight;
_SourceFullFileName = sourceFullFileName; _SourceFullFileName = sourceFullFileName;

View File

@ -9,20 +9,18 @@ public class Location : Properties.ILocation, IEquatable<Location>
public int Bottom { init; get; } public int Bottom { init; get; }
public double Confidence { init; get; } public double Confidence { init; get; }
public int Left { init; get; } public int Left { init; get; }
public int? NormalizedPixelPercentage { init; get; }
public int Right { init; get; } public int Right { init; get; }
public int Top { init; get; } public int Top { init; get; }
[JsonConstructor] [JsonConstructor]
public Location(int bottom, double confidence, int left, int? normalizedPixelPercentage, int right, int top) public Location(int bottom, double confidence, int left, int right, int top)
{ {
Confidence = confidence; Confidence = confidence;
Bottom = bottom; Bottom = bottom;
Left = left; Left = left;
NormalizedPixelPercentage = normalizedPixelPercentage;
Right = right; Right = right;
Top = top; Top = top;
Stateless.Methods.Location.Check(bottom, left, normalizedPixelPercentage, right, top, zCount: 1); Stateless.Methods.Location.Check(bottom, left, right, top, zCount: 1);
} }
public Location(double confidence, int height, Location location, int locationDigits, int locationFactor, int width, int zCount) : public Location(double confidence, int height, Location location, int locationDigits, int locationFactor, int width, int zCount) :
@ -30,30 +28,27 @@ public class Location : Properties.ILocation, IEquatable<Location>
location.Bottom, location.Bottom,
confidence, confidence,
location.Left, location.Left,
Stateless.Methods.Location.GetNormalizedPixelPercentage(location.Bottom, height, location.Left, locationDigits, locationFactor, location.Right, location.Top, width, zCount),
location.Right, location.Right,
location.Top) => location.Top) =>
Stateless.Methods.Location.Check(Bottom, Left, NormalizedPixelPercentage, Right, Top, zCount); Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount);
public Location(int bottom, double confidence, int height, int left, int locationDigits, int locationFactor, int right, int top, int width, int zCount) : public Location(int bottom, double confidence, int height, int left, int locationDigits, int locationFactor, int right, int top, int width, int zCount) :
this( this(
bottom, bottom,
confidence, confidence,
left, left,
Stateless.Methods.Location.GetNormalizedPixelPercentage(bottom, height, left, locationDigits, locationFactor, right, top, width, zCount),
right, right,
top) => top) =>
Stateless.Methods.Location.Check(Bottom, height, Left, NormalizedPixelPercentage, Right, Top, width, zCount); Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount);
public Location(int height, Location location, int locationDigits, int locationFactor, int width, int zCount) : public Location(int height, Location location, int locationDigits, int locationFactor, int width, int zCount) :
this( this(
location.Bottom, location.Bottom,
location.Confidence, location.Confidence,
location.Left, location.Left,
Stateless.Methods.Location.GetNormalizedPixelPercentage(location.Bottom, height, location.Left, locationDigits, locationFactor, location.Right, location.Top, width, zCount),
location.Right, location.Right,
location.Top) => location.Top) =>
Stateless.Methods.Location.Check(Bottom, Left, NormalizedPixelPercentage, Right, Top, zCount); Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount);
public Location(double confidence, int factor, int height, Location location, int locationDigits, int locationFactor, int width, int zCount) public Location(double confidence, int factor, int height, Location location, int locationDigits, int locationFactor, int width, int zCount)
{ {
@ -63,14 +58,10 @@ public class Location : Properties.ILocation, IEquatable<Location>
int left = Math.Max(location.Left - x, 0); int left = Math.Max(location.Left - x, 0);
int right = Math.Min(location.Right + x, width); int right = Math.Min(location.Right + x, width);
int top = Math.Max(location.Top - y, 0); int top = Math.Max(location.Top - y, 0);
int normalizedPixelPercentage = Stateless.Methods.Location.GetNormalizedPixelPercentage(location.Bottom, height, location.Left, locationDigits, locationFactor, location.Right, location.Top, width, zCount); Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount);
if (location.NormalizedPixelPercentage is null || normalizedPixelPercentage != location.NormalizedPixelPercentage.Value)
throw new Exception();
Stateless.Methods.Location.Check(bottom, left, NormalizedPixelPercentage, right, top, zCount);
Confidence = confidence; Confidence = confidence;
Bottom = bottom; Bottom = bottom;
Left = left; Left = left;
NormalizedPixelPercentage = normalizedPixelPercentage;
Right = right; Right = right;
Top = top; Top = top;
} }

View File

@ -38,10 +38,10 @@ public class MappingFromLocation : Properties.IMappingFromLocation
public int NormalizedPixelPercentage { init; get; } public int NormalizedPixelPercentage { init; get; }
[JsonConstructor] [JsonConstructor]
public MappingFromLocation(double confidence, string deterministicHashCodeKeyDisplay, int normalizedPixelPercentage) public MappingFromLocation(double confidence, string deterministicHashCodeKey, int normalizedPixelPercentage)
{ {
Confidence = confidence; Confidence = confidence;
DeterministicHashCodeKey = deterministicHashCodeKeyDisplay; DeterministicHashCodeKey = deterministicHashCodeKey;
NormalizedPixelPercentage = normalizedPixelPercentage; NormalizedPixelPercentage = normalizedPixelPercentage;
} }

View File

@ -3,7 +3,6 @@ namespace View_by_Distance.Shared.Models.Methods;
public interface IFaceDistance public interface IFaceDistance
{ {
List<Face> GetMatchingFaces(double faceDistanceTolerance, string checkFile, List<Face> faces);
void SavePossiblyNewPersonContainers(Properties.IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, string facesFileNameExtension, string a2PeopleContentDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); void SavePossiblyNewPersonContainers(Properties.IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, string facesFileNameExtension, string a2PeopleContentDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
} }

View File

@ -7,8 +7,6 @@ public interface IFace
public FaceDistance? FaceDistance { get; } public FaceDistance? FaceDistance { get; }
public FaceEncoding? FaceEncoding { get; } public FaceEncoding? FaceEncoding { get; }
public Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts { get; } public Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts { get; }
public Location? Location { get; }
public int? LocationIndex { get; }
public Mapping? Mapping { get; } public Mapping? Mapping { get; }
public OutputResolution? OutputResolution { get; } public OutputResolution? OutputResolution { get; }
public string RelativePath { get; } public string RelativePath { get; }

View File

@ -6,7 +6,6 @@ public interface ILocation
public int Bottom { init; get; } public int Bottom { init; get; }
public double Confidence { init; get; } public double Confidence { init; get; }
public int Left { init; get; } public int Left { init; get; }
public int? NormalizedPixelPercentage { init; get; }
public int Right { init; get; } public int Right { init; get; }
public int Top { init; get; } public int Top { init; get; }

View File

@ -58,11 +58,7 @@ internal abstract class FaceFileSystem
{ {
if (face[i] is null) if (face[i] is null)
continue; continue;
locationIndex = face[i].LocationIndex; locationIndex = 0;
if (locationIndex is null)
locationIndex = 0;
else
locationIndex = locationIndex.Value;
directoryName = Path.GetDirectoryName(face[i].RelativePath); directoryName = Path.GetDirectoryName(face[i].RelativePath);
if (directoryName is null) if (directoryName is null)
continue; continue;

View File

@ -28,9 +28,4 @@ public interface IFace
static double? Getα(Dictionary<FacePart, Models.FacePoint[]> faceParts) => static double? Getα(Dictionary<FacePart, Models.FacePoint[]> faceParts) =>
Face.Getα(faceParts); Face.Getα(faceParts);
int?[] TestStatic_GetInts(List<Models.Face> faces) =>
GetInts(faces);
static int?[] GetInts(List<Models.Face> faces) =>
(from l in faces where l.FaceEncoding is not null && l.Location?.NormalizedPixelPercentage is not null select l.Location?.NormalizedPixelPercentage).ToArray();
} }

View File

@ -6,13 +6,18 @@ public interface ILocation
string TestStatic_GetLeftPadded(int locationDigits, string value) => string TestStatic_GetLeftPadded(int locationDigits, string value) =>
GetLeftPadded(locationDigits, value); GetLeftPadded(locationDigits, value);
static string GetLeftPadded(int locationDigits, string value) => static string GetLeftPadded(int locationDigits, string value) =>
value.Length == locationDigits ? value : value.Length > locationDigits ? value[..locationDigits] : value.PadLeft(locationDigits, '0'); Location.GetLeftPadded(locationDigits, value);
string TestStatic_GetLeftPadded(int locationDigits, int value) => string TestStatic_GetLeftPadded(int locationDigits, int value) =>
GetLeftPadded(locationDigits, value); GetLeftPadded(locationDigits, value);
static string GetLeftPadded(int locationDigits, int value) => static string GetLeftPadded(int locationDigits, int value) =>
GetLeftPadded(locationDigits, value.ToString()); GetLeftPadded(locationDigits, value.ToString());
(int?, int?) TestStatic_GetXY(int locationDigits, int locationFactor, int width, int height, string normalizedPixelPercentage) =>
GetXY(locationDigits, locationFactor, width, height, normalizedPixelPercentage);
static (int?, int?) GetXY(int locationDigits, int locationFactor, int width, int height, string normalizedPixelPercentage) =>
Location.GetXY(locationDigits, locationFactor, width, height, normalizedPixelPercentage);
Models.Location? TestStatic_GetLocation(Models.Location? location, int locationDigits, int locationFactor, int height, int width, int zCount) => Models.Location? TestStatic_GetLocation(Models.Location? location, int locationDigits, int locationFactor, int height, int width, int zCount) =>
GetLocation(location, locationDigits, locationFactor, height, width, zCount); GetLocation(location, locationDigits, locationFactor, height, width, zCount);
static Models.Location? GetLocation(Models.Location? location, int locationDigits, int locationFactor, int height, int width, int zCount) => static Models.Location? GetLocation(Models.Location? location, int locationDigits, int locationFactor, int height, int width, int zCount) =>
@ -23,11 +28,6 @@ public interface ILocation
static Models.Location? GetLocation(int factor, Models.Location? location, int locationDigits, int locationFactor, int height, int width, int zCount) => static Models.Location? GetLocation(int factor, Models.Location? location, int locationDigits, int locationFactor, int height, int width, int zCount) =>
location is null ? null : new(location.Confidence, factor, height, location, locationDigits, locationFactor, width, zCount); location is null ? null : new(location.Confidence, factor, height, location, locationDigits, locationFactor, width, zCount);
int?[] TestStatic_GetInts(List<Models.Location> locations) =>
GetInts(locations);
static int?[] GetInts(List<Models.Location> locations) =>
(from l in locations where l.NormalizedPixelPercentage is not null select l.NormalizedPixelPercentage).ToArray();
int TestStatic_GetNormalizedPixelPercentage(Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution) => int TestStatic_GetNormalizedPixelPercentage(Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution) =>
GetNormalizedPixelPercentage(location, locationDigits, locationFactor, outputResolution); GetNormalizedPixelPercentage(location, locationDigits, locationFactor, outputResolution);
static int GetNormalizedPixelPercentage(Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution) => static int GetNormalizedPixelPercentage(Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution) =>

View File

@ -3,14 +3,16 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IMapping public interface IMapping
{ // ... { // ...
static string GetDeterministicHashCodeKey(int id, int pixel)
=> $"{id}.{pixel}";
(string?, string?, string?, bool?) TestStatic_GetSegments(int locationDigits, string facesFileNameExtension, string fileName) (string?, string?, string?, bool?) TestStatic_GetSegments(int locationDigits, string facesFileNameExtension, string fileName)
=> GetSegments(locationDigits, facesFileNameExtension, fileName); => GetSegments(locationDigits, facesFileNameExtension, fileName);
static (string?, string?, string?, bool?) GetSegments(int locationDigits, string facesFileNameExtension, string fileName) static (string?, string?, string?, bool?) GetSegments(int locationDigits, string facesFileNameExtension, string fileName)
=> Mapping.GetSegments(locationDigits, facesFileNameExtension, fileName); => Mapping.GetSegments(locationDigits, facesFileNameExtension, fileName);
string TestStatic_GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution)
=> GetDeterministicHashCodeKey(id, location, locationDigits, locationFactor, outputResolution);
static string GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution)
=> $"{id}.{ILocation.GetNormalizedPixelPercentage(location, locationDigits, locationFactor, outputResolution)}";
(int?, int?, List<Models.Face>?) TestStatic_GetReversedDeterministicHashCodeKey(int locationDigits, string facesFileNameExtension, string file) => (int?, int?, List<Models.Face>?) TestStatic_GetReversedDeterministicHashCodeKey(int locationDigits, string facesFileNameExtension, string file) =>
GetReversedDeterministicHashCodeKey(locationDigits, facesFileNameExtension, file); GetReversedDeterministicHashCodeKey(locationDigits, facesFileNameExtension, file);
static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(int locationDigits, string facesFileNameExtension, string file) => static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(int locationDigits, string facesFileNameExtension, string file) =>

View File

@ -33,26 +33,25 @@ internal abstract class Location
throw new Exception(); throw new Exception();
if (zCount < 0) if (zCount < 0)
throw new Exception(); throw new Exception();
Check(bottom, left, right, top, zCount);
} }
internal static void Check(int bottom, int left, int? normalizedPixelPercentage, int right, int top, int zCount) internal static string GetLeftPadded(int locationDigits, string value)
{ {
Check(bottom, left, right, top, zCount); string result;
if (normalizedPixelPercentage.HasValue && normalizedPixelPercentage.Value < 0) if (value.Length == locationDigits)
throw new Exception(); result = value;
} else if (value.Length > locationDigits)
result = value[..locationDigits];
internal static void Check(int bottom, int height, int left, int? normalizedPixelPercentage, int right, int top, int width, int zCount) else
{ result = value.PadLeft(locationDigits, '0');
Check(bottom, left, right, top, zCount); return result;
Check(bottom, height, left, right, top, width, zCount);
if (normalizedPixelPercentage.HasValue && normalizedPixelPercentage.Value < 0)
throw new Exception();
} }
internal static int GetNormalizedPixelPercentage(int bottom, int height, int left, int locationDigits, int locationFactor, int right, int top, int width, int zCount) internal static int GetNormalizedPixelPercentage(int bottom, int height, int left, int locationDigits, int locationFactor, int right, int top, int width, int zCount)
{ {
int result; int result;
Check(bottom, height, left, right, top, width, zCount);
int checksum; int checksum;
decimal center = 2m; decimal center = 2m;
string xCenterPadded; string xCenterPadded;
@ -60,10 +59,12 @@ internal abstract class Location
decimal factor = locationFactor; decimal factor = locationFactor;
// int.MaxPercentage = 21 4748 3647; // int.MaxPercentage = 21 4748 3647;
int length = (locationDigits - 1) / 2; int length = (locationDigits - 1) / 2;
Check(bottom, left, right, top, zCount); decimal xCenterValue = (left + right) / center;
Check(bottom, height, left, right, top, width, zCount); decimal yCenterValue = (top + bottom) / center;
decimal xCenterValue = left + ((right - left) / center); if (xCenterValue < left || xCenterValue > right)
decimal yCenterValue = top + ((bottom - top) / center); throw new Exception();
if (yCenterValue < top || yCenterValue > bottom)
throw new Exception();
if (xCenterValue > yCenterValue) if (xCenterValue > yCenterValue)
checksum = 1; checksum = 1;
else else
@ -87,4 +88,28 @@ internal abstract class Location
return result; return result;
} }
internal static (int?, int?) GetXY(int locationDigits, int locationFactor, int width, int height, string normalizedPixelPercentage)
{
int? x;
int? y;
int center = 2;
decimal factor = locationFactor;
int each = (locationDigits - 1) / center;
string segmentA = normalizedPixelPercentage[..each];
string segmentB = normalizedPixelPercentage[each..^1];
if (!int.TryParse(segmentA, out int xNormalized) || !int.TryParse(segmentB, out int yNormalized))
{
x = null;
y = null;
}
else
{
decimal xValue = xNormalized / factor * width;
decimal yValue = yNormalized / factor * height;
x = (int)Math.Round(xValue, 0);
y = (int)Math.Round(yValue, 0);
}
return new(x, y);
}
} }

View File

@ -112,6 +112,7 @@ internal abstract class PersonBirthday
internal static List<Models.PersonBirthday> GetPersonBirthdays(string personBirthdayFormat, string[] personKeyDirectories, string personDisplayDirectory) internal static List<Models.PersonBirthday> GetPersonBirthdays(string personBirthdayFormat, string[] personKeyDirectories, string personDisplayDirectory)
{ {
List<Models.PersonBirthday> results = new(); List<Models.PersonBirthday> results = new();
string[] files;
string personKeyFormatted; string personKeyFormatted;
Models.PersonBirthday? personBirthday; Models.PersonBirthday? personBirthday;
foreach (string personKeyDirectory in personKeyDirectories) foreach (string personKeyDirectory in personKeyDirectories)
@ -124,6 +125,10 @@ internal abstract class PersonBirthday
if (personBirthday is null) if (personBirthday is null)
continue; continue;
results.Add(personBirthday); results.Add(personBirthday);
files = Directory.GetFiles(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
if (files.Any())
continue;
File.WriteAllText(Path.Combine(personKeyDirectory, $"{personKeyFormatted}.txt"), string.Empty);
} }
return results; return results;
} }

View File

@ -98,7 +98,7 @@ public class Configuration
string[] validResolutions) string[] validResolutions)
{ {
_PropertyConfiguration = propertyConfiguration; _PropertyConfiguration = propertyConfiguration;
CheckDFaceAndUpWriteDates = CheckDFaceAndUpWriteDates; CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
CheckJsonForDistanceResults = checkJsonForDistanceResults; CheckJsonForDistanceResults = checkJsonForDistanceResults;
CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection; CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
DistanceFactor = distanceFactor; DistanceFactor = distanceFactor;

View File

@ -113,38 +113,38 @@ public class UnitTestCalculations
[TestMethod] [TestMethod]
public void TestMethodDamn() public void TestMethodDamn()
{ {
string name; // string name;
string[] directories; // string[] directories;
string? directoryName; // string? directoryName;
string checkDirectory; // string checkDirectory;
string sourceDirectory = @"F:\Tmp\Phares\Compare\Images 2022-09-15 - 7390c13 - III - Results\E) Distance\2022-09-15\7680 x 4320\7680x4320 - Hog - Large\()"; // string sourceDirectory = @"F:\Tmp\Phares\Compare\Images 2022-09-15 - 7390c13 - III - Results\E) Distance\2022-09-15\7680 x 4320\7680x4320 - Hog - Large\()";
directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly); // directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories) // foreach (string directory in directories)
{ // {
directoryName = Path.GetDirectoryName(directory); // directoryName = Path.GetDirectoryName(directory);
if (directoryName is null) // if (directoryName is null)
continue; // continue;
name = Path.GetFileName(directory); // name = Path.GetFileName(directory);
if (name.Length is 1 or 20) // if (name.Length is 1 or 20)
continue; // continue;
checkDirectory = Path.Combine(directoryName, "b", name); // checkDirectory = Path.Combine(directoryName, "b", name);
Directory.Move(directory, checkDirectory); // Directory.Move(directory, checkDirectory);
} // }
directories = Directory.GetDirectories(Path.Combine(sourceDirectory, "b"), "*", SearchOption.TopDirectoryOnly); // directories = Directory.GetDirectories(Path.Combine(sourceDirectory, "b"), "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories) // foreach (string directory in directories)
{ // {
directoryName = Path.GetDirectoryName(directory); // directoryName = Path.GetDirectoryName(directory);
if (directoryName is null) // if (directoryName is null)
continue; // continue;
name = Path.GetFileName(directory); // name = Path.GetFileName(directory);
if (name.Length is 1 or 20) // if (name.Length is 1 or 20)
continue; // continue;
checkDirectory = Path.Combine(directoryName, $"{name[..^4]})"); // checkDirectory = Path.Combine(directoryName, $"{name[..^4]})");
if (Directory.Exists(checkDirectory)) // if (Directory.Exists(checkDirectory))
continue; // continue;
Directory.Move(directory, checkDirectory); // Directory.Move(directory, checkDirectory);
} // }
Assert.IsTrue(true); // Assert.IsTrue(true);
} }
[TestMethod] [TestMethod]
@ -164,8 +164,8 @@ public class UnitTestCalculations
Assert.IsTrue(names.Length == 3); Assert.IsTrue(names.Length == 3);
names = IPath.GetDirectoryNames(@"C:\Tmp\phares\"); names = IPath.GetDirectoryNames(@"C:\Tmp\phares\");
Assert.IsTrue(names.Length == 3); Assert.IsTrue(names.Length == 3);
names = IPath.GetDirectoryNames(@"C:\Tmp\phares\Pictures - Results\E) Distance\2022-09-15\7680 x 4320\7680x4320 - Hog - Large\()\(637991752537712052)\1976-03-08_00\#2019\K\-735727008.520765.jpg"); // names = IPath.GetDirectoryNames(@"C:\Tmp\phares\Pictures - Results\E) Distance\2022-09-15\7680 x 4320\7680x4320 - Hog - Large\()\(637991752537712052)\1976-03-08_00\#2019\K\-735727008.520765.jpg");
Assert.IsTrue(names.Length == 13); // Assert.IsTrue(names.Length == 13);
// Length = 13 // Length = 13
// [0] [string]: // [0] [string]:
// "C:\\" // "C:\\"
@ -193,112 +193,193 @@ public class UnitTestCalculations
double confidence = 0.1D; double confidence = 0.1D;
int left, top, right, bottom, width, height; int left, top, right, bottom, width, height;
left = 20; left = 20;
top = 40;
right = 60; right = 60;
top = 40;
bottom = 80; bottom = 80;
width = 100; width = 100;
height = 100; height = 100;
Location location = new(bottom, confidence, left, null, right, top); Location location = new(bottom, confidence, left, right, top);
_ = new Location(confidence, height, location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, 1); _ = new Location(confidence, height, location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, 1);
_ = new Location(bottom, confidence, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width, 1); _ = new Location(bottom, confidence, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width, 1);
} }
[TestMethod] [TestMethod]
public void TestGetPixelPercentage() public void TestGetPixelPercentageA()
{
int normalizedPixelPercentage;
int bottom, height, left, right, top, width;
left = 1;
top = 1;
right = 10;
bottom = 10;
width = 100;
height = 100;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 055005502);
left = 50;
top = 50;
right = 60;
bottom = 60;
width = 100;
height = 100;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 550055002);
}
[TestMethod]
public void TestGetPixelPercentageB()
{
int normalizedPixelPercentage;
int bottom, height, left, right, top, width;
left = 240;
top = 240;
right = 260;
bottom = 260;
width = 500;
height = 500;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 500050002);
left = 490;
top = 490;
right = 510;
bottom = 510;
width = 1000;
height = 1000;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 500050002);
left++;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 500550001);
left++;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 501050001);
}
[TestMethod]
public void TestGetPixelPercentageC()
{
int normalizedPixelPercentage;
int bottom, height, left, right, top, width;
left = 20;
top = 40;
right = 60;
bottom = 80;
width = 100;
height = 100;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 400060002);
left = 20;
top = 40;
right = 60;
bottom = 80;
width = 100;
height = 100;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 400060002);
}
[TestMethod]
public void TestGetPixelPercentageD()
{ {
int? x, y;
int normalizedPixelPercentage; int normalizedPixelPercentage;
int bottom, height, left, right, top, width; int bottom, height, left, right, top, width;
string normalizedPixelPercentagePadded;
left = 7678; left = 7678;
top = 4318;
right = 7680; right = 7680;
top = 4318;
bottom = 4320; bottom = 4320;
width = 7680; width = 7680;
height = 4320; height = 4320;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width); normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 999999981); Assert.IsTrue(normalizedPixelPercentage == 999999981);
normalizedPixelPercentagePadded = ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
Assert.IsTrue(x.HasValue && x.Value == 7679);
Assert.IsTrue(y.HasValue && y.Value == 4319);
left = 7680; left = 7680;
top = 4320;
right = 7680; right = 7680;
top = 4320;
bottom = 4320; bottom = 4320;
width = 7680; width = 7680;
height = 4320; height = 4320;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width); normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 999999991); Assert.IsTrue(normalizedPixelPercentage == 999999991);
normalizedPixelPercentagePadded = ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
Assert.IsTrue(x.HasValue && x.Value == 7679);
Assert.IsTrue(y.HasValue && y.Value == 4320);
}
[TestMethod]
public void TestGetPixelPercentageB()
{
int? x, y;
int normalizedPixelPercentage;
int bottom, height, left, right, top, width;
string normalizedPixelPercentagePadded;
left = 20;
right = 60;
top = 40;
bottom = 80;
width = 100;
height = 100;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 400060002);
normalizedPixelPercentagePadded = ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
Assert.IsTrue(x.HasValue && x.Value == 40);
Assert.IsTrue(y.HasValue && y.Value == 60);
left = 45;
right = 55;
top = 45;
bottom = 55;
width = 100;
height = 100;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 500050002);
normalizedPixelPercentagePadded = ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
Assert.IsTrue(x.HasValue && x.Value == 50);
Assert.IsTrue(y.HasValue && y.Value == 50);
}
[TestMethod]
public void TestGetPixelPercentageC()
{
int? x, y;
int normalizedPixelPercentage;
string normalizedPixelPercentagePadded;
int bottom, height, left, right, top, width;
left = 1;
right = 3;
top = 1;
bottom = 3;
width = 100;
height = 100;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 20002002);
normalizedPixelPercentagePadded = ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
Assert.IsTrue(x.HasValue && x.Value == 2);
Assert.IsTrue(y.HasValue && y.Value == 2);
left = 50;
right = 60;
top = 50;
bottom = 60;
width = 100;
height = 100;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 550055002);
normalizedPixelPercentagePadded = ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
Assert.IsTrue(x.HasValue && x.Value == 55);
Assert.IsTrue(y.HasValue && y.Value == 55);
}
[TestMethod]
public void TestGetPixelPercentageD()
{
int? x, y;
int normalizedPixelPercentage;
int bottom, height, left, right, top, width;
string normalizedPixelPercentagePadded;
left = 240;
right = 260;
top = 240;
bottom = 260;
width = 500;
height = 500;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 500050002);
normalizedPixelPercentagePadded = ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
Assert.IsTrue(x.HasValue && x.Value == 250);
Assert.IsTrue(y.HasValue && y.Value == 250);
left = 490;
right = 510;
top = 490;
bottom = 510;
width = 1000;
height = 1000;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 500050002);
normalizedPixelPercentagePadded = ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
Assert.IsTrue(x.HasValue && x.Value == 500);
Assert.IsTrue(y.HasValue && y.Value == 500);
left++;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 500550001);
normalizedPixelPercentagePadded = ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
Assert.IsTrue(x.HasValue && x.Value == 500);
Assert.IsTrue(y.HasValue && y.Value == 500);
left++;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 501050001);
normalizedPixelPercentagePadded = ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
Assert.IsTrue(x.HasValue && x.Value == 501);
Assert.IsTrue(y.HasValue && y.Value == 500);
}
[TestMethod]
public void TestGetPixelPercentageE()
{
int? x, y;
int normalizedPixelPercentage;
int bottom, height, left, right, top, width;
string normalizedPixelPercentagePadded;
left = 1477;
right = 1477;
top = 641;
bottom = 641;
width = 2408;
height = 2077;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
Assert.IsTrue(normalizedPixelPercentage == 613430861);
normalizedPixelPercentagePadded = ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
Assert.IsTrue(x.HasValue && x.Value == 1477);
Assert.IsTrue(y.HasValue && y.Value == 641);
}
[TestMethod]
public void TestGetDistance()
{
double x1, x2, y1, y2;
x1 = 12f;
x2 = 13f;
y1 = 11f;
y2 = 10f;
double distance = Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2));
Assert.IsTrue(distance == 1.4142135623730951);
} }
} }

View File

@ -14,6 +14,8 @@ public class Configuration
[Display(Name = "Check Json For Distance Results"), Required] public bool? CheckJsonForDistanceResults { get; set; } [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 = "CrossDirectory Max Items In Distance Collection"), Required] public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; }
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; } [Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
[Display(Name = "Distance Move Unable to Match by 1 Tick"), Required] public bool? DistanceMoveUnableToMatch { get; set; }
[Display(Name = "Distance Pixel Distance Tolerance"), Required] public int? DistancePixelDistanceTolerance { get; set; }
[Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; } [Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; }
[Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; } [Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; }
[Display(Name = "Face Distance Permyriad"), Required] public int? FaceDistancePermyriad { get; set; } [Display(Name = "Face Distance Permyriad"), Required] public int? FaceDistancePermyriad { get; set; }
@ -33,7 +35,6 @@ public class Configuration
[Display(Name = "Map Logic Sigma"), Required] public int? MapLogicSigma { get; set; } [Display(Name = "Map Logic Sigma"), Required] public int? MapLogicSigma { get; set; }
[Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; } [Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; }
[Display(Name = "Mapping Default Name"), Required] public string MappingDefaultName { get; set; } [Display(Name = "Mapping Default Name"), Required] public string MappingDefaultName { get; set; }
[Display(Name = "Mapping Move Unable to Match by 1 Tick"), Required] public bool? MappingMoveUnableToMatch { get; set; }
[Display(Name = "Mapping Save Mapped"), Required] public bool? MappingSaveMapped { get; set; } [Display(Name = "Mapping Save Mapped"), Required] public bool? MappingSaveMapped { get; set; }
[Display(Name = "Mapping Save Not Mapped"), Required] public bool? MappingSaveNotMapped { get; set; } [Display(Name = "Mapping Save Not Mapped"), Required] public bool? MappingSaveNotMapped { get; set; }
[Display(Name = "Mapping Use Deterministic Hash Code Unknown Face Key Value Pairs for Add to Mapping"), Required] public bool? MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { get; set; } [Display(Name = "Mapping Use Deterministic Hash Code Unknown Face Key Value Pairs for Add to Mapping"), Required] public bool? MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { get; set; }
@ -61,6 +62,7 @@ public class Configuration
[Display(Name = "Properties Changed For Metadata"), Required] public bool? PropertiesChangedForMetadata { 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 = "Properties Changed For Resize"), Required] public bool? PropertiesChangedForResize { get; set; }
[Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; }
[Display(Name = "Retry Images Without a Face"), Required] public bool? RetryImagesWithoutAFace { get; set; }
[Display(Name = "Reverse"), Required] public bool? Reverse { 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 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 Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; }
@ -93,6 +95,10 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection)); throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
if (configuration.DistanceFactor is null) if (configuration.DistanceFactor is null)
throw new NullReferenceException(nameof(configuration.DistanceFactor)); throw new NullReferenceException(nameof(configuration.DistanceFactor));
if (configuration.DistanceMoveUnableToMatch is null)
throw new NullReferenceException(nameof(configuration.DistanceMoveUnableToMatch));
if (configuration.DistancePixelDistanceTolerance is null)
throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance));
if (configuration.FaceDistanceHiddenImageFactor is null) if (configuration.FaceDistanceHiddenImageFactor is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor)); throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor));
if (configuration.FaceDistanceMinimumConfidence is null) if (configuration.FaceDistanceMinimumConfidence is null)
@ -127,8 +133,6 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.MapLogicSigma)); throw new NullReferenceException(nameof(configuration.MapLogicSigma));
if (configuration.MappingDefaultName is null) if (configuration.MappingDefaultName is null)
throw new NullReferenceException(nameof(configuration.MappingDefaultName)); throw new NullReferenceException(nameof(configuration.MappingDefaultName));
if (configuration.MappingMoveUnableToMatch is null)
throw new NullReferenceException(nameof(configuration.MappingMoveUnableToMatch));
if (configuration.MappingSaveNotMapped is null) if (configuration.MappingSaveNotMapped is null)
throw new NullReferenceException(nameof(configuration.MappingSaveNotMapped)); throw new NullReferenceException(nameof(configuration.MappingSaveNotMapped));
if (configuration.MappingSaveMapped is null) if (configuration.MappingSaveMapped is null)
@ -173,6 +177,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForResize is null) if (configuration.PropertiesChangedForResize is null)
throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize)); throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize));
if (configuration.RetryImagesWithoutAFace is null)
throw new NullReferenceException(nameof(configuration.RetryImagesWithoutAFace));
if (configuration.Reverse is null) if (configuration.Reverse is null)
throw new NullReferenceException(nameof(configuration.Reverse)); throw new NullReferenceException(nameof(configuration.Reverse));
if (configuration.SaveFaceLandmarkForOutputResolutions is null) if (configuration.SaveFaceLandmarkForOutputResolutions is null)
@ -212,6 +218,8 @@ public class Configuration
configuration.CheckJsonForDistanceResults.Value, configuration.CheckJsonForDistanceResults.Value,
configuration.CrossDirectoryMaxItemsInDistanceCollection.Value, configuration.CrossDirectoryMaxItemsInDistanceCollection.Value,
configuration.DistanceFactor.Value, configuration.DistanceFactor.Value,
configuration.DistanceMoveUnableToMatch.Value,
configuration.DistancePixelDistanceTolerance.Value,
configuration.FaceDistanceHiddenImageFactor.Value, configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value, configuration.FaceDistanceMinimumConfidence.Value,
configuration.FaceDistancePermyriad.Value, configuration.FaceDistancePermyriad.Value,
@ -231,7 +239,6 @@ public class Configuration
configuration.MapLogicSigma.Value, configuration.MapLogicSigma.Value,
configuration.MappedMaxIndex, configuration.MappedMaxIndex,
configuration.MappingDefaultName, configuration.MappingDefaultName,
configuration.MappingMoveUnableToMatch.Value,
configuration.MappingSaveNotMapped.Value, configuration.MappingSaveNotMapped.Value,
configuration.MappingSaveMapped.Value, configuration.MappingSaveMapped.Value,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping.Value, configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping.Value,
@ -258,6 +265,7 @@ public class Configuration
configuration.PropertiesChangedForIndex.Value, configuration.PropertiesChangedForIndex.Value,
configuration.PropertiesChangedForMetadata.Value, configuration.PropertiesChangedForMetadata.Value,
configuration.PropertiesChangedForResize.Value, configuration.PropertiesChangedForResize.Value,
configuration.RetryImagesWithoutAFace.Value,
configuration.Reverse.Value, configuration.Reverse.Value,
configuration.SaveFaceLandmarkForOutputResolutions, configuration.SaveFaceLandmarkForOutputResolutions,
configuration.SaveFullYearOfRandomFiles.Value, configuration.SaveFullYearOfRandomFiles.Value,

View File

@ -13,6 +13,8 @@ public class Configuration
public bool CheckJsonForDistanceResults { init; get; } public bool CheckJsonForDistanceResults { init; get; }
public int CrossDirectoryMaxItemsInDistanceCollection { init; get; } public int CrossDirectoryMaxItemsInDistanceCollection { init; get; }
public int DistanceFactor { init; get; } public int DistanceFactor { init; get; }
public bool DistanceMoveUnableToMatch { init; get; }
public int DistancePixelDistanceTolerance { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; } public int FaceDistanceHiddenImageFactor { init; get; }
public double FaceDistanceMinimumConfidence { init; get; } public double FaceDistanceMinimumConfidence { init; get; }
public int FaceDistancePermyriad { init; get; } public int FaceDistancePermyriad { init; get; }
@ -32,7 +34,6 @@ public class Configuration
public int MapLogicSigma { init; get; } public int MapLogicSigma { init; get; }
public int? MappedMaxIndex { init; get; } public int? MappedMaxIndex { init; get; }
public string MappingDefaultName { init; get; } public string MappingDefaultName { init; get; }
public bool MappingMoveUnableToMatch { init; get; }
public bool MappingSaveNotMapped { init; get; } public bool MappingSaveNotMapped { init; get; }
public bool MappingSaveMapped { init; get; } public bool MappingSaveMapped { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { init; get; } public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { init; get; }
@ -59,6 +60,7 @@ public class Configuration
public bool PropertiesChangedForIndex { init; get; } public bool PropertiesChangedForIndex { init; get; }
public bool PropertiesChangedForMetadata { init; get; } public bool PropertiesChangedForMetadata { init; get; }
public bool PropertiesChangedForResize { init; get; } public bool PropertiesChangedForResize { init; get; }
public bool RetryImagesWithoutAFace { init; get; }
public bool Reverse { init; get; } public bool Reverse { init; get; }
public string[] SaveFaceLandmarkForOutputResolutions { init; get; } public string[] SaveFaceLandmarkForOutputResolutions { init; get; }
public bool SaveFullYearOfRandomFiles { init; get; } public bool SaveFullYearOfRandomFiles { init; get; }
@ -78,6 +80,8 @@ public class Configuration
bool checkJsonForDistanceResults, bool checkJsonForDistanceResults,
int crossDirectoryMaxItemsInDistanceCollection, int crossDirectoryMaxItemsInDistanceCollection,
int distanceFactor, int distanceFactor,
bool distanceMoveUnableToMatch,
int distancePixelDistanceTolerance,
int faceDistanceHiddenImageFactor, int faceDistanceHiddenImageFactor,
double faceDistanceMinimumConfidence, double faceDistanceMinimumConfidence,
int faceDistancePermyriad, int faceDistancePermyriad,
@ -97,7 +101,6 @@ public class Configuration
int mapLogicSigma, int mapLogicSigma,
int? mappedMaxIndex, int? mappedMaxIndex,
string mappingDefaultName, string mappingDefaultName,
bool mappingMoveUnableToMatch,
bool mappingSaveNotMapped, bool mappingSaveNotMapped,
bool mappingSaveMapped, bool mappingSaveMapped,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping, bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
@ -124,6 +127,7 @@ public class Configuration
bool propertiesChangedForIndex, bool propertiesChangedForIndex,
bool propertiesChangedForMetadata, bool propertiesChangedForMetadata,
bool propertiesChangedForResize, bool propertiesChangedForResize,
bool retryImagesWithoutAFace,
bool reverse, bool reverse,
string[] saveFaceLandmarkForOutputResolutions, string[] saveFaceLandmarkForOutputResolutions,
bool saveFullYearOfRandomFiles, bool saveFullYearOfRandomFiles,
@ -142,6 +146,8 @@ public class Configuration
CheckJsonForDistanceResults = checkJsonForDistanceResults; CheckJsonForDistanceResults = checkJsonForDistanceResults;
CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection; CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
DistanceFactor = distanceFactor; DistanceFactor = distanceFactor;
DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
DistancePixelDistanceTolerance = distancePixelDistanceTolerance;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor; FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence; FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
FaceDistancePermyriad = faceDistancePermyriad; FaceDistancePermyriad = faceDistancePermyriad;
@ -161,7 +167,6 @@ public class Configuration
MapLogicSigma = mapLogicSigma; MapLogicSigma = mapLogicSigma;
MappedMaxIndex = mappedMaxIndex; MappedMaxIndex = mappedMaxIndex;
MappingDefaultName = mappingDefaultName; MappingDefaultName = mappingDefaultName;
MappingMoveUnableToMatch = mappingMoveUnableToMatch;
MappingSaveNotMapped = mappingSaveNotMapped; MappingSaveNotMapped = mappingSaveNotMapped;
MappingSaveMapped = mappingSaveMapped; MappingSaveMapped = mappingSaveMapped;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping; MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping;
@ -188,6 +193,7 @@ public class Configuration
PropertiesChangedForIndex = propertiesChangedForIndex; PropertiesChangedForIndex = propertiesChangedForIndex;
PropertiesChangedForMetadata = propertiesChangedForMetadata; PropertiesChangedForMetadata = propertiesChangedForMetadata;
PropertiesChangedForResize = propertiesChangedForResize; PropertiesChangedForResize = propertiesChangedForResize;
RetryImagesWithoutAFace = retryImagesWithoutAFace;
Reverse = reverse; Reverse = reverse;
SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions; SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions;
SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles; SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles;

View File

@ -241,8 +241,8 @@ public class UnitTestFace
Image image = FaceRecognition.LoadImageFile(item.ResizedFileHolder.FullName); Image image = FaceRecognition.LoadImageFile(item.ResizedFileHolder.FullName);
Assert.IsNotNull(image); Assert.IsNotNull(image);
FaceRecognition faceRecognition = new(_Configuration.NumberOfTimesToUpsample, _Configuration.NumberOfJitters, predictorModel, model, modelParameter); FaceRecognition faceRecognition = new(_Configuration.NumberOfTimesToUpsample, _Configuration.NumberOfJitters, predictorModel, model, modelParameter);
List<(int, Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection; List<(Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection;
collection = faceRecognition.GetCollection(image, includeFaceEncoding: true, includeFaceParts: true, sortByNormalizedPixelPercentage: true); collection = faceRecognition.GetCollection(image, includeFaceEncoding: true, includeFaceParts: true);
Assert.IsTrue(collection.Count == 2); Assert.IsTrue(collection.Count == 2);
List<FaceDistance> faceDistanceEncodings = (from l in collection where l.FaceEncoding is not null select new FaceDistance(l.FaceEncoding)).ToList(); List<FaceDistance> faceDistanceEncodings = (from l in collection where l.FaceEncoding is not null select new FaceDistance(l.FaceEncoding)).ToList();
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncodings[0]); List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncodings[0]);