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 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))
_ = Directory.CreateDirectory(eDistanceContentCollectionDirectory);
#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();
#pragma warning restore
string eDistanceContentFileName = Path.Combine(eDistanceContentCollectionDirectory, $"{propertyConfiguration.ResultAllInOne}.tvs");
string eDistanceContentFileName = Path.Combine(eDistanceContentCollectionDirectory, $"{configuration.ResultAllInOne}.tvs");
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<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
if (faceDistanceLengths.Count != faceDistanceContainersLength)
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);
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();
SortingContainer sortingContainer;
@ -42,11 +65,11 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
{
if (face.Mapping is null || faceDistanceEncoding.NormalizedPixelPercentage is null)
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;
sortingContainer = new(face, sorting);
results.Add(sortingContainer);
if (results.Count >= configuration.SortingMaximumPerFaceShouldBeHigh)
if (results.Count >= _SortingMaximumPerFaceShouldBeHigh)
break;
}
return results;
@ -64,7 +87,16 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
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;
FaceDistance faceDistance;
@ -80,23 +112,22 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
faceDistanceContainer = new(face, faceDistance);
collection.Add(faceDistanceContainer);
}
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!");
results = GetOrderedFaceDistanceContainers(collection);
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;
List<SortingContainer> collection = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
FaceDistanceContainer[] faceDistanceContainers = GetFaceDistanceContainers(selectedFilteredFaces);
FaceDistanceContainer[] faceDistanceContainers = GetOrderedFaceDistanceContainers(selectedFilteredFaces);
List<FaceDistance> faceDistanceEncodings = GetFaceDistanceEncodings(faceDistanceContainers);
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 };
selectedFilteredFaces.Clear();
foreach (Face face in selectedFilteredFaces)
face.ClearFaceDistance();
using ProgressBar progressBar = new(faceDistanceContainers.Length, message, options);
_ = 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)
throw new NotSupportedException();
FaceDistance faceDistanceEncoding = faceDistanceContainers[i].FaceDistance;
List<Sorting> sortingCollection = GetSortingCollection(configuration, mapLogic, faceDistanceEncodings, faceDistanceContainers.Length, i, faceDistanceEncoding);
List<SortingContainer> sortingContainers = GetSortingContainers(configuration, face, faceDistanceEncoding, sortingCollection);
List<Sorting> sortingCollection = GetSortingCollection(mapLogic, faceDistanceEncodings, faceDistanceContainers.Length, i, faceDistanceEncoding);
List<SortingContainer> sortingContainers = GetSortingContainers(face, faceDistanceEncoding, sortingCollection);
lock (collection)
collection.AddRange(sortingContainers);
lock (face)
@ -116,49 +147,73 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
return results;
}
public static List<Face> GetSelectedFilteredFaces(List<Face> distinctFilteredFaces)
public static Face[] GetSelectedFilteredFaces(List<Face> distinctFilteredFaces)
{
List<Face> results;
Face[] orderedFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromItem.MinimumDateTime descending select l).ToArray();
results = orderedFilteredFaces.ToList();
Face[] results = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromItem.MinimumDateTime descending select l).ToArray();
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);
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 };
using ProgressBar progressBar = new(selectedFilteredFaces.Count, message, options);
_ = Parallel.For(0, selectedFilteredFaces.Count, parallelOptions, (i, state) =>
using ProgressBar progressBar = new(selectedFilteredFaces.Length, message, options);
_ = Parallel.For(0, selectedFilteredFaces.Length, parallelOptions, (i, state) =>
{
progressBar.Tick();
FaceDistance faceDistance;
Face face = selectedFilteredFaces[i];
FaceRecognitionDotNet.FaceEncoding faceEncoding;
if (face.FaceEncoding is null || face.Mapping is null)
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);
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)
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;
FaceDistance faceDistanceLength;
string json = File.ReadAllText(checkFile);
List<(Face Face, double Length)> collection = new();
Shared.Models.FaceEncoding? modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
if (modelsFaceEncoding is null)
throw new NotSupportedException();
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
FaceDistance faceDistanceEncoding = new(faceRecognitionDotNetFaceEncoding);
FaceDistanceContainer[] faceDistanceContainers = GetFaceDistanceContainers(faces);
FaceDistanceContainer[] faceDistanceContainers = GetOrderedFaceDistanceContainers(mappingFromItem, faces);
int faceDistanceContainersLength = faceDistanceContainers.Length;
if (faceDistanceContainersLength != faces.Count)
throw new NotSupportedException();
@ -172,12 +227,19 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
{
face = faces[i];
faceDistanceLength = faceDistanceLengths[i];
if (face.Mapping is null || faceDistanceLength.Length is null)
if (faceDistanceLength.Length is null)
throw new NotSupportedException();
if (faceDistanceLength.Length.Value > faceDistanceTolerance)
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())
{
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 string _ArgZero;
private readonly int _NumberOfJitters;
private readonly Serilog.ILogger? _Log;
private readonly bool _OverrideForFaceImages;
private readonly bool _RetryImagesWithoutAFace;
private readonly Configuration _Configuration;
private readonly int _NumberOfTimesToUpsample;
private readonly ImageCodecInfo _ImageCodecInfo;
private readonly ModelParameter _ModelParameter;
private readonly PredictorModel _PredictorModel;
private readonly bool _CheckDFaceAndUpWriteDates;
private readonly bool _PropertiesChangedForFaces;
private readonly ConstructorInfo _ConstructorInfo;
private readonly int _FaceDistanceHiddenImageFactor;
private readonly EncoderParameters _EncoderParameters;
private readonly ImageCodecInfo _HiddenImageCodecInfo;
private readonly bool _ForceFaceLastWriteTimeToCreationTime;
private readonly EncoderParameters _HiddenEncoderParameters;
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(
string argZero,
bool checkDFaceAndUpWriteDates,
@ -61,13 +59,12 @@ public class D_Face
string hiddenFileNameExtension,
ImageCodecInfo hiddenImageCodecInfo,
ImageCodecInfo imageCodecInfo,
int locationDigits,
int locationFactor,
Model model,
ModelParameter modelParameter,
int numberOfJitters,
int numberOfTimesToUpsample,
bool overrideForFaceImages,
bool retryImagesWithoutAFace,
PredictorModel predictorModel,
bool propertiesChangedForFaces)
{
@ -75,8 +72,6 @@ public class D_Face
_ArgZero = argZero;
_Configuration = configuration;
_ImageCodecInfo = imageCodecInfo;
_LocationDigits = locationDigits;
_LocationFactor = locationFactor;
_ModelParameter = modelParameter;
_PredictorModel = predictorModel;
_NumberOfJitters = numberOfJitters;
@ -86,6 +81,7 @@ public class D_Face
AngleBracketCollection = new List<string>();
_HiddenImageCodecInfo = hiddenImageCodecInfo;
_OverrideForFaceImages = overrideForFaceImages;
_RetryImagesWithoutAFace = retryImagesWithoutAFace;
_HiddenEncoderParameters = hiddenEncoderParameters;
_HiddenFileNameExtension = hiddenFileNameExtension;
_NumberOfTimesToUpsample = numberOfTimesToUpsample;
@ -145,15 +141,15 @@ public class D_Face
{
if (fileInfo is null)
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;
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)
continue;
width = location.Right - location.Left;
height = location.Bottom - location.Top;
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);
using (bitmap = new(width, height))
{
@ -165,7 +161,7 @@ public class D_Face
}
if (File.Exists(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)
continue;
width = location.Right - location.Left;
@ -199,22 +195,22 @@ public class D_Face
{ unknownImage = 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
{
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);
collection = faceRecognition.GetCollection(unknownImage, includeFaceEncoding: true, includeFaceParts: true, sortByNormalizedPixelPercentage: true);
collection = faceRecognition.GetCollection(unknownImage, includeFaceEncoding: true, includeFaceParts: true);
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
{
double[] rawEncoding;
Shared.Models.Face face;
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)
{
rawEncoding = faceEncoding.GetRawEncoding();
@ -246,8 +242,6 @@ public class D_Face
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
throw new NullReferenceException(nameof(dResultsFullGroupDirectory));
string json;
int?[] normalizedPixelPercentageCollection;
int normalizedPixelPercentageDistinctCount;
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();
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);
if (results is null)
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));
}
catch (Exception)
@ -311,22 +298,22 @@ public class 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);
json = JsonSerializer.Serialize(results, _WriteIndentedAndWhenWritingNull);
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
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 (wasNull || (!wasNull && results.Any(l => l.FaceEncoding is not null)))
{
json = JsonSerializer.Serialize(results, _WriteIndentedAndWhenWritingNull);
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
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)
{
results = (from l in results select new Shared.Models.Face(_LocationDigits, _LocationFactor, 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}>");
results = (from l in results select new Shared.Models.Face(ILocation.Digits, ILocation.Factor, results.Count, l)).ToList();
json = JsonSerializer.Serialize(results, _WriteIndentedAndWhenWritingNull);
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
@ -340,7 +327,7 @@ public class D_Face
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)
throw new NullReferenceException(nameof(item.ImageFileHolder));
@ -349,22 +336,22 @@ public class D_Face
FileInfo fileInfo;
bool check = false;
string parentCheck;
string deterministicHashCodeKeyDisplay;
string deterministicHashCodeKey;
List<(Shared.Models.Face, FileInfo?, string)> collection = new();
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
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();
if (!Directory.Exists(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));
continue;
}
deterministicHashCodeKeyDisplay = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value);
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKeyDisplay}{item.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
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, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
if (!fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
@ -373,7 +360,7 @@ public class D_Face
if (File.Exists(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)
check = true;
else if (!fileInfo.Exists)

View File

@ -144,7 +144,7 @@ public class D2_FaceParts
Bitmap rotated;
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;
try
{
@ -215,8 +215,8 @@ public class D2_FaceParts
FileInfo rotatedFileInfo;
DateTime? dateTime = null;
long ticks = DateTime.Now.Ticks;
string deterministicHashCodeKey;
bool updateDateWhenMatches = false;
string deterministicHashCodeKeyDisplay;
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) };
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);
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));
continue;
}
deterministicHashCodeKeyDisplay = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value);
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKeyDisplay}{item.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
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, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
if (!fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
@ -241,7 +241,7 @@ public class D2_FaceParts
}
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
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));
if (check)
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)
throw new NullReferenceException(nameof(image));
@ -150,14 +150,6 @@ public class FaceRecognition : DisposableObject
mModRect.Dispose();
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;
}
@ -187,7 +179,7 @@ public class FaceRecognition : DisposableObject
return results;
}
private List<Location> GetLocations(Image image, bool sortByNormalizedPixelPercentage)
private List<Location> GetLocations(Image image)
{
List<Location> results = new();
MModRect[] mModRects = GetMModRects(image);
@ -203,33 +195,25 @@ public class FaceRecognition : DisposableObject
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;
}
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)
throw new NullReferenceException(nameof(image));
image.ThrowIfDisposed();
ThrowIfDisposed();
if (_PredictorModel == PredictorModel.Custom)
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);
if (fullObjectDetections.Count != locations.Count)
throw new Exception();
List<(int LocationIndex, Location Location, List<FaceEncoding?> FaceEncodings, List<List<(FacePart, FacePoint[])>> FaceParts)> collection = new();
for (int i = 0; i < locations.Count; i++)
collection.Add(new(i, locations[i], new(), new()));
List<(Location Location, List<FaceEncoding?> FaceEncodings, List<List<(FacePart, FacePoint[])>> FaceParts)> collection = new();
foreach (Location location in locations)
collection.Add(new(location, new(), new()));
if (locations.Count != collection.Count)
throw new Exception();
if (!includeFaceEncoding)
@ -266,18 +250,18 @@ public class FaceRecognition : DisposableObject
fullObjectDetection.Dispose();
const int indexZero = 0;
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)
continue;
if (!faceParts[indexZero].Any())
results.Add(new(locationIndex, location, faceEncodings[indexZero], null));
results.Add(new(location, faceEncodings[indexZero], null));
else
{
keyValuePairs = new();
foreach ((FacePart facePart, FacePoint[] facePoints) in faceParts[indexZero])
keyValuePairs.Add(facePart, facePoints);
results.Add(new(locationIndex, location, faceEncodings[indexZero], keyValuePairs));
results.Add(new(location, faceEncodings[indexZero], keyValuePairs));
}
}
return results;

View File

@ -28,6 +28,7 @@ public partial class DlibDotNet
private readonly F_Random _Random;
private readonly E3_Rename _Rename;
private readonly IConsole _Console;
private readonly E_Distance _Distance;
private readonly B_Metadata _Metadata;
private readonly Serilog.ILogger? _Log;
private readonly D2_FaceParts _FaceParts;
@ -67,10 +68,19 @@ public partial class DlibDotNet
Verify(configuration);
VerifyExtra(args, propertyConfiguration, configuration);
_Configuration = configuration;
_Index = new G_Index(configuration);
_Random = new F_Random(configuration);
_Index = new(configuration);
_Random = new(configuration);
_Rename = new(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)
throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
string propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(propertyConfiguration, nameof(A_Property), create: false);
@ -95,13 +105,12 @@ public partial class DlibDotNet
hiddenFileNameExtension,
hiddenImageCodecInfo,
imageCodecInfo,
configuration.LocationDigits,
configuration.LocationFactor,
model,
modelParameter,
configuration.NumberOfJitters,
configuration.NumberOfTimesToUpsample,
configuration.OverrideForFaceImages,
configuration.RetryImagesWithoutAFace,
predictorModel,
configuration.PropertiesChangedForFaces);
}
@ -323,11 +332,9 @@ public partial class DlibDotNet
configuration.FaceDistancePermyriad,
configuration.FaceDistanceMinimumConfidence,
configuration.FaceDistanceTolerance,
configuration.LocationDigits,
configuration.LocationFactor,
configuration.MapLogicSigma,
configuration.MappingDefaultName,
configuration.MappingMoveUnableToMatch,
configuration.DistanceMoveUnableToMatch,
configuration.MappingSaveNotMapped,
configuration.MappingSaveMapped,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
@ -342,22 +349,7 @@ public partial class DlibDotNet
return result;
}
private void FullParallelForWork(
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)
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)
{
if (item.ImageFileHolder is null)
throw new NullReferenceException(nameof(item.ImageFileHolder));
@ -366,8 +358,8 @@ public partial class DlibDotNet
Shared.Models.Property property;
long ticks = DateTime.Now.Ticks;
DateTime dateTime = DateTime.Now;
List<Shared.Models.Face>? faces;
List<string> parseExceptions = new();
List<Shared.Models.Face>? faceCollection;
Dictionary<string, int[]> imageResizeKeyValuePairs;
List<Tuple<string, DateTime>> subFileTuples = new();
List<KeyValuePair<string, string>> metadataCollection;
@ -420,46 +412,35 @@ public partial class DlibDotNet
File.WriteAllBytes(path, bytes);
}
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
faceCollection = null;
faces = null;
else
{
int[] outputResolutionCollection = imageResizeKeyValuePairs[outputResolution];
int outputResolutionWidth = outputResolutionCollection[0];
int outputResolutionHeight = outputResolutionCollection[1];
int outputResolutionOrientation = outputResolutionCollection[2];
faceCollection = _Faces.GetFaces(
dResultsFullGroupDirectory,
subFileTuples,
parseExceptions,
item,
property,
outputResolutionWidth,
outputResolutionHeight,
outputResolutionOrientation);
faces = _Faces.GetFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation);
if (_AppSettings.MaxDegreeOfParallelism < 2)
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)
ticks = LogDelta(ticks, nameof(D_Face.SaveFaces));
int?[] normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(faceCollection);
int normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length || _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_ = _Distance.GetUnableToMatchCountAndRenameMatches(_Faces.FileNameExtension, eDistanceContentDirectory, duplicateMappedFaceFilesCollection, item, faces, mappedFaceFiles);
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
{
bool saveRotated = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution);
string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(
_Configuration.PropertyConfiguration,
container.SourceDirectory);
string facesDirectory = Path.GetFullPath(Path.Combine($"{Path.Combine(d2ResultsFullGroupDirectory, "()")}{sourceDirectorySegment}", item.ImageFileHolder.NameWithoutExtension));
_FaceParts.SaveFaceLandmarkImages(facesDirectory, subFileTuples, parseExceptions, item, faceCollection, saveRotated);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D2_FaceParts.SaveFaceLandmarkImages));
throw new NotImplementedException();
// bool saveRotated = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution);
// string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory);
// string facesDirectory = Path.GetFullPath(Path.Combine($"{Path.Combine(d2FacePartsContentDirectory, "()")}{sourceDirectorySegment}", item.ImageFileHolder.NameWithoutExtension));
// _FaceParts.SaveFaceLandmarkImages(facesDirectory, subFileTuples, parseExceptions, item, faceCollection, saveRotated);
// if (_AppSettings.MaxDegreeOfParallelism < 2)
// ticks = LogDelta(ticks, nameof(D2_FaceParts.SaveFaceLandmarkImages));
}
}
lock (sourceDirectoryChanges)
{
imageFaceCollections[index] = faces;
propertyCollection[index] = property;
imageFaceCollections[index] = faceCollection;
metadataCollections[index] = metadataCollection;
resizeKeyValuePairs[index] = imageResizeKeyValuePairs;
propertyFileHolderCollection[index] = item.ImageFileHolder;
@ -467,23 +448,7 @@ public partial class DlibDotNet
}
}
private int FullParallelWork(
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)
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)
{
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
@ -511,17 +476,19 @@ public partial class DlibDotNet
{
FullParallelForWork(
propertyLogic,
mappedFaceFiles,
outputResolution,
bResultsFullGroupDirectory,
cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
eDistanceContentDirectory,
sourceDirectoryChanges,
propertyFileHolderCollection,
propertyCollection,
metadataCollection,
resizeKeyValuePairs,
imageFaceCollections,
duplicateMappedFaceFilesCollection,
container,
index: i,
filteredItems[i]);
@ -595,9 +562,9 @@ public partial class DlibDotNet
if (!(from l in propertyCollection where l?.Width is null select true).Any())
{
string checkDirectory;
List<KeyValuePair<string, List<Shared.Models.Face>?>> imageFaceCollectionsKeyValuePairs = new();
List<KeyValuePair<string, Shared.Models.Property>> propertyCollectionKeyValuePairs = 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();
(int level, List<string> directories) = Shared.Models.Stateless.Methods.IPath.Get(
_Configuration.PropertyConfiguration.RootDirectory,
@ -616,9 +583,9 @@ public partial class DlibDotNet
_FileKeyValuePairs.Add(new KeyValuePair<string, string>(container.SourceDirectory, key));
_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]));
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]));
}
if (propertyLogic.AngleBracketCollection.Any())
@ -664,10 +631,7 @@ public partial class DlibDotNet
}
}
private (string, string, string, string, string, string) GetResultsFullGroupDirectories(
Model? model,
PredictorModel? predictorModel,
string outputResolution)
private (string, string, string, string) GetResultsFullGroupDirectories(Model? model, PredictorModel? predictorModel, string outputResolution)
{
string aResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
_Configuration.PropertyConfiguration,
@ -705,25 +669,7 @@ public partial class DlibDotNet
includeResizeGroup: true,
includeModel: true,
includePredictorModel: true);
string d2ResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
_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);
return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory);
}
private void SetAngleBracketCollections(
@ -733,8 +679,7 @@ public partial class DlibDotNet
string aResultsFullGroupDirectory,
string bResultsFullGroupDirectory,
string cResultsFullGroupDirectory,
string dResultsFullGroupDirectory,
string d2ResultsFullGroupDirectory)
string dResultsFullGroupDirectory)
{
_Faces.AngleBracketCollection.Clear();
_Resize.AngleBracketCollection.Clear();
@ -773,15 +718,6 @@ public partial class DlibDotNet
singletonDescription: string.Empty,
collectionDescription: "For each image a json file with all faces found",
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)
@ -798,15 +734,7 @@ public partial class DlibDotNet
return results.ToArray();
}
private void FullDoWork(
string argZero,
Model? model,
PredictorModel? predictorModel,
string propertyRoot,
long ticks,
A_Property propertyLogic,
int t,
Container[] containers)
private void FullDoWork(string argZero, Model? model, PredictorModel? predictorModel, string propertyRoot, long ticks, A_Property propertyLogic, int t, Container[] containers, string eDistanceContentDirectory, string[] mappedFaceFiles)
{
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
@ -820,33 +748,23 @@ public partial class DlibDotNet
string bResultsFullGroupDirectory;
string cResultsFullGroupDirectory;
string dResultsFullGroupDirectory;
string eResultsFullGroupDirectory;
string d2ResultsFullGroupDirectory;
int containersLength = containers.Length;
Shared.Models.Property[] propertyCollection;
List<List<Shared.Models.Face>?> imageFaceCollections = new();
List<FileHolder?> propertyFileHolderCollection = new();
List<string[]> duplicateMappedFaceFilesCollection = new();
List<Dictionary<string, int[]>> resizeKeyValuePairs = new();
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
List<List<Shared.Models.Face>?> imageFaceCollections = new();
List<Shared.Models.Property?> nullablePropertyCollection = new();
int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism;
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)
{
total = 0;
_FileKeyValuePairs.Clear();
duplicateMappedFaceFilesCollection.Clear();
_FilePropertiesKeyValuePairs.Clear();
(aResultsFullGroupDirectory,
bResultsFullGroupDirectory,
cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(
model,
predictorModel,
outputResolution);
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "()"));
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution);
for (int i = 0; i < containers.Length; i++)
{
container = containers[i];
@ -865,21 +783,23 @@ public partial class DlibDotNet
propertyFileHolderCollection.Clear();
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}";
SetAngleBracketCollections(propertyLogic, outputResolution, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory);
SetAngleBracketCollections(propertyLogic, outputResolution, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory);
exceptionCount = FullParallelWork(
maxDegreeOfParallelism,
propertyLogic,
mappedFaceFiles,
outputResolution,
bResultsFullGroupDirectory,
cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
eDistanceContentDirectory,
sourceDirectoryChanges,
propertyFileHolderCollection,
nullablePropertyCollection,
metadataCollection,
resizeKeyValuePairs,
imageFaceCollections,
duplicateMappedFaceFilesCollection,
container,
filteredItems,
message);
@ -916,6 +836,11 @@ public partial class DlibDotNet
// break;
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;
Item[] filteredItems;
DateTime minimumDateTime;
int normalizedPixelPercentage;
string deterministicHashCodeKey;
MappingFromItem mappingFromItem;
MappingFromPerson mappingFromPerson;
string deterministicHashCodeKeyDisplay;
MappingFromLocation mappingFromLocation;
foreach (Container container in containers)
{
@ -949,14 +875,15 @@ public partial class DlibDotNet
{
if (face.RelativePath != item.RelativePath)
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;
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);
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);
mappingFromLocation = new(face.Location.Confidence, deterministicHashCodeKeyDisplay, 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);
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);
face.SetMapping(mapping);
results.Add(face);
@ -972,21 +899,15 @@ public partial class DlibDotNet
PersonContainer[] personContainers,
Container[] containers,
string dResultsFullGroupDirectory,
string eResultsFullGroupDirectory,
string d2ResultsFullGroupDirectory,
string outputResolution)
{
E_Distance distance = new();
if (string.IsNullOrEmpty(eResultsFullGroupDirectory))
throw new NullReferenceException(nameof(eResultsFullGroupDirectory));
string eDistanceContentDirectory = Path.Combine(eResultsFullGroupDirectory, "()");
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
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);
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(
_Configuration.PropertyConfiguration,
nameof(A2_People),
"{}");
string eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), "()");
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "{}");
string d2FacePartsContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(D2_FaceParts), "()");
MapLogic mapLogic = new(
_AppSettings.MaxDegreeOfParallelism,
_Configuration.PropertyConfiguration,
@ -996,33 +917,32 @@ public partial class DlibDotNet
_FaceParts.FileNameExtension,
ticks,
personContainers,
eDistanceContentDirectory,
a2PeopleSingletonDirectory,
eDistanceContentDirectory,
distinctFilteredFaces,
distance);
SortingContainer[] sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(
_Distance);
SortingContainer[] sortingContainers = _Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(
_AppSettings.MaxDegreeOfParallelism,
_MapConfiguration,
ticks,
mapLogic,
selectedFilteredFaces);
E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, eResultsFullGroupDirectory, sortingContainers);
E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers);
int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces);
if (totalNotMapped > 0)
mapLogic.ForceSingleImageThenSaveMapping(
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
dFacesContentDirectory,
d2FacePartsContentDirectory,
distinctFilteredFaces,
sortingContainers,
totalNotMapped);
mapLogic.CopyManualFiles(dResultsFullGroupDirectory, distinctFilteredFaces);
mapLogic.CopyManualFiles(dFacesContentDirectory, distinctFilteredFaces);
if (_MapConfiguration.MappingSaveNotMapped)
mapLogic.SaveNotMappedTicks();
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
mapLogic.SaveShortcuts(_Configuration.JuliePhares, distinctFilteredFaces);
}
private static Container? AreAllSameStartsWith(string argZero, Container[] containers)
private static Container? AreAllSameEndsWith(string argZero, Container[] containers)
{
Container? result = null;
string[] directoryNames = Shared.Models.Stateless.Methods.IPath.GetDirectoryNames(argZero);
@ -1037,7 +957,7 @@ public partial class DlibDotNet
if (container.SourceDirectory == argZero)
result = container;
directoryName = Path.GetFileName(container.SourceDirectory);
if (!directoryName.StartsWith(rootDirectoryName))
if (!directoryName.EndsWith(rootDirectoryName))
{
result = null;
break;
@ -1088,13 +1008,7 @@ public partial class DlibDotNet
return result;
}
private void Search(
long ticks,
Model? model,
PredictorModel? predictorModel,
string argZero,
string propertyRoot,
PersonContainer[] personContainers)
private void Search(long ticks, Model? model, PredictorModel? predictorModel, string argZero, string propertyRoot, PersonContainer[] personContainers)
{
int j;
int f;
@ -1104,8 +1018,13 @@ public partial class DlibDotNet
string bResultsFullGroupDirectory;
string cResultsFullGroupDirectory;
string dResultsFullGroupDirectory;
string eResultsFullGroupDirectory;
string d2ResultsFullGroupDirectory;
string eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), "()");
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);
string message = $") Building Container(s) - {totalSeconds} total second(s)";
A_Property propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, model, predictorModel);
@ -1115,7 +1034,7 @@ public partial class DlibDotNet
progressBar.Tick();
(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)
{
string? newRootDirectory = SaveUrlAndGetNewRootDirectory(container);
@ -1138,20 +1057,12 @@ public partial class DlibDotNet
model,
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)
{
if (_FirstRun || container is not null)
break;
(aResultsFullGroupDirectory,
bResultsFullGroupDirectory,
cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(
model,
predictorModel,
outputResolution);
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution);
if (_ArgZeroIsConfigurationRootDirectory
&& _Configuration.SaveResizedSubfiles
&& outputResolution == _Configuration.OutputResolutions[0]
@ -1160,15 +1071,7 @@ public partial class DlibDotNet
{
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
break;
DistanceThenMapLogic(
argZero,
ticks,
personContainers,
containers,
dResultsFullGroupDirectory,
eResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
outputResolution);
DistanceThenMapLogic(argZero, ticks, personContainers, containers, dResultsFullGroupDirectory, outputResolution);
if (_IsEnvironment.Development)
continue;
if (_FileKeyValuePairs.Any())
@ -1194,10 +1097,6 @@ public partial class DlibDotNet
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, "{}"));
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
_ = 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 = "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 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 = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { 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 = "Mapped Max Index"), Required] public int? MappedMaxIndex { 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 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; }
@ -61,6 +62,7 @@ public class Configuration
[Display(Name = "Properties Changed For Metadata"), Required] public bool? PropertiesChangedForMetadata { get; set; }
[Display(Name = "Properties Changed For Resize"), Required] public bool? PropertiesChangedForResize { get; set; }
[Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; }
[Display(Name = "Retry Images Without a Face"), Required] public bool? RetryImagesWithoutAFace { get; set; }
[Display(Name = "Reverse"), Required] public bool? Reverse { get; set; }
[Display(Name = "Save Face Landmark For Output Resolutions"), Required] public string[] SaveFaceLandmarkForOutputResolutions { get; set; }
[Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; }
@ -93,6 +95,10 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
if (configuration.DistanceFactor is null)
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)
throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor));
if (configuration.FaceDistanceMinimumConfidence is null)
@ -127,8 +133,6 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.MapLogicSigma));
if (configuration.MappingDefaultName is null)
throw new NullReferenceException(nameof(configuration.MappingDefaultName));
if (configuration.MappingMoveUnableToMatch is null)
throw new NullReferenceException(nameof(configuration.MappingMoveUnableToMatch));
if (configuration.MappingSaveNotMapped is null)
throw new NullReferenceException(nameof(configuration.MappingSaveNotMapped));
if (configuration.MappingSaveMapped is null)
@ -173,6 +177,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForResize is null)
throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize));
if (configuration.RetryImagesWithoutAFace is null)
throw new NullReferenceException(nameof(configuration.RetryImagesWithoutAFace));
if (configuration.Reverse is null)
throw new NullReferenceException(nameof(configuration.Reverse));
if (configuration.SaveFaceLandmarkForOutputResolutions is null)
@ -212,6 +218,8 @@ public class Configuration
configuration.CheckJsonForDistanceResults.Value,
configuration.CrossDirectoryMaxItemsInDistanceCollection.Value,
configuration.DistanceFactor.Value,
configuration.DistanceMoveUnableToMatch.Value,
configuration.DistancePixelDistanceTolerance.Value,
configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value,
configuration.FaceDistancePermyriad.Value,
@ -231,7 +239,6 @@ public class Configuration
configuration.MapLogicSigma.Value,
configuration.MappedMaxIndex,
configuration.MappingDefaultName,
configuration.MappingMoveUnableToMatch.Value,
configuration.MappingSaveNotMapped.Value,
configuration.MappingSaveMapped.Value,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping.Value,
@ -258,6 +265,7 @@ public class Configuration
configuration.PropertiesChangedForIndex.Value,
configuration.PropertiesChangedForMetadata.Value,
configuration.PropertiesChangedForResize.Value,
configuration.RetryImagesWithoutAFace.Value,
configuration.Reverse.Value,
configuration.SaveFaceLandmarkForOutputResolutions,
configuration.SaveFullYearOfRandomFiles.Value,

View File

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

View File

@ -55,6 +55,8 @@
"CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-09-22",
"DistanceFactor": 8,
"DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1,
"FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8,
"FaceDistancePermyriad": 10000,
@ -71,7 +73,6 @@
"MapLogicSigma": 3,
"MappedMaxIndex": 1034720,
"MappingDefaultName": "John Doe~25",
"MappingMoveUnableToMatch": false,
"MappingSaveFaceEncoding": false,
"MappingSaveMapped": false,
"MappingSaveNotMapped": false,
@ -106,9 +107,11 @@
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"RetryImagesWithoutAFace": false,
"Reverse": false,
"xRootDirectory": "C:/Tmp/phares/Pictures",
"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,
"SaveResizedSubFiles": true,
"SkipSearch": false,

View File

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

View File

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

View File

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

View File

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

View File

@ -46,7 +46,7 @@ internal abstract class MapLogic
{
if (!personDisplayDirectoryAllFile.EndsWith(facesFileNameExtension))
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)
continue;
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();
int? id;
@ -91,10 +91,7 @@ internal abstract class MapLogic
string? personFirstInitialDirectory;
string[] personDisplayDirectoryNames;
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[] 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 };
using ProgressBar progressBar = new(ticksDirectories.Length, message, options);
foreach (string ticksDirectory in ticksDirectories)
@ -151,7 +148,7 @@ internal abstract class MapLogic
{
if (file.EndsWith(".lnk") || file.EndsWith(".json"))
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)
continue;
results.Add(new(personKeyFormatted, personDisplayDirectoryNames, file));
@ -180,6 +177,35 @@ internal abstract class MapLogic
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)
{
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)
{
const int zero = 0;
PersonBirthday? personBirthday;
string newestPersonKeyFormatted;
PersonContainer[] distinctPersonContainers;
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>>> incorrectIdThenNormalizedPixelPercentageToPersonContainerCollection = new();
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null)
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]);
}
List<(long, PersonContainer)> collection = GetDistinctCollection(configuration, personContainers, personKeyFormattedToPersonContainer);
foreach ((long personKey, PersonContainer personContainer) in collection)
personKeyToPersonContainer.Add(personKey, personContainer);
if (personKeyFormattedIdThenNormalizedPixelPercentageCollection.Any())
{
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;
string fileName = Path.GetFileName(file);
string? directoryName = Path.GetDirectoryName(file);
(string? Id, string? NormalizedPixelPercentage, string? ExtensionLowered, bool? Check) segments = IMapping.GetSegments(configuration.LocationDigits, facesFileNameExtension, fileName);
if (string.IsNullOrEmpty(directoryName) || string.IsNullOrEmpty(segments.Id) || string.IsNullOrEmpty(segments.NormalizedPixelPercentage) || string.IsNullOrEmpty(segments.ExtensionLowered))
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
List<(long, PersonContainer)> results = new();
const int zero = 0;
string newestPersonKeyFormatted;
Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection = new();
foreach (PersonContainer personContainer in personContainers)
{
string? directoryName = Path.GetDirectoryName(jsonFile);
string? jsonDirectoryName = Path.GetDirectoryName(jsonFile);
if (string.IsNullOrEmpty(directoryName) || string.IsNullOrEmpty(directoryName) || directoryName != jsonDirectoryName || !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(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 (personContainer.Key is null)
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);
}
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? id;
bool debugCheck;
string? checkFile;
List<Face>? faces;
List<int> debugChecks = new();
List<Face> checkFaces = new();
int? normalizedPixelPercentage;
string newestPersonKeyFormatted;
List<string> duplicates = new();
string personDisplayDirectoryName;
bool idToFacesAny = idToFaces.Any();
List<int> normalizedPixelPercentages;
List<string> duplicateMappedFaceFiles = new();
Dictionary<int, List<int>> idToNormalizedPixelPercentages = new();
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 };
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();
(id, normalizedPixelPercentage, faces) = IMapping.GetReversedDeterministicHashCodeKey(
configuration.LocationDigits,
Shared.Models.Stateless.ILocation.Digits,
facesFileNameExtension,
idToFacesAny,
idToFaces,
file);
mappedFaceFile);
if (id is null || normalizedPixelPercentage is null)
{
result++;
@ -397,9 +361,6 @@ internal abstract class MapLogic
if (!idToNormalizedPixelPercentages.ContainsKey(id.Value))
idToNormalizedPixelPercentages.Add(id.Value, new());
normalizedPixelPercentages = idToNormalizedPixelPercentages[id.Value];
checkFile = GetCheckFile(configuration, facesFileNameExtension, file, id.Value, normalizedPixelPercentage.Value);
if (string.IsNullOrEmpty(checkFile))
throw new NotSupportedException();
if (faces is null)
{
result++;
@ -417,35 +378,25 @@ internal abstract class MapLogic
continue;
if (normalizedPixelPercentages.Contains(face.Mapping.MappingFromLocation.NormalizedPixelPercentage))
{
duplicates.Add(string.Concat(id.Value, '.', normalizedPixelPercentage.Value, ".jpg", facesFileNameExtension));
duplicateMappedFaceFiles.Add(mappedFaceFile);
continue;
}
debugCheck = true;
checkFaces.Add(face);
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())
{
result++;
if (configuration.MappingMoveUnableToMatch)
MoveUnableToMatch(configuration, eDistanceContentDirectory, file, checkFile);
continue;
}
if (checkFaces.Count != 1)
{
result++;
if (configuration.MappingMoveUnableToMatch)
MoveUnableToMatch(configuration, eDistanceContentDirectory, file, checkFile);
continue;
}
normalizedPixelPercentages.Add(normalizedPixelPercentage.Value);
idToNormalizedPixelPercentages[id.Value].Add(normalizedPixelPercentage.Value);
if (!personKeyFormattedToNewestPersonKeyFormatted.ContainsKey(personKeyFormatted))
newestPersonKeyFormatted = personKeyFormatted;
@ -457,13 +408,13 @@ internal abstract class MapLogic
else
personKeyFormattedIdThenNormalizedPixelPercentageCollection.Add(new(newestPersonKeyFormatted, personDisplayDirectoryNames, id.Value, normalizedPixelPercentage.Value));
}
if (duplicates.Any())
if (duplicateMappedFaceFiles.Any())
{
duplicates.Sort();
if (duplicates.Any())
duplicateMappedFaceFiles.Sort();
if (duplicateMappedFaceFiles.Any())
{ }
}
return result;
return new(result, duplicateMappedFaceFiles.Count);
}
private static double GetStandardDeviation(IEnumerable<long> values, double average)
@ -616,6 +567,8 @@ internal abstract class MapLogic
{
if (configuration is null)
throw new NullReferenceException(nameof(configuration));
string message;
int totalSeconds;
List<long> personKeys = new();
List<long?> nullablePersonKeyCollection = new();
List<string> personKeyFormattedCollection = new();
@ -636,7 +589,7 @@ internal abstract class MapLogic
personContainers.AddRange(AddToPersonKeysThenGetNonSpecificPeopleCollection(configuration, personKeys));
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();
if (face.Mapping is null)
throw new NotSupportedException();
@ -644,17 +597,18 @@ internal abstract class MapLogic
keyValuePairs.Add(face.Mapping.MappingFromItem.Id, new());
keyValuePairs[face.Mapping.MappingFromItem.Id].Add(face);
}
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration,
facesFileNameExtension,
ticks,
eDistanceContentDirectory,
personKeyFormattedCollection);
int unableToMatchCount = SetCollectionsAndGetUnableToMatchCount(
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly);
message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)";
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(
configuration,
facesFileNameExtension,
personKeyFormattedCollection,
ticksDirectories,
message);
(int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToMatchCount(
facesFileNameExtension,
ticks,
eDistanceContentDirectory,
faceDistance,
keyValuePairs,
personKeyFormattedToNewestPersonKeyFormatted,
personKeyFormattedIdThenNormalizedPixelPercentageCollection,
@ -672,8 +626,8 @@ internal abstract class MapLogic
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer,
incorrectIdThenNormalizedPixelPercentageToPersonContainers,
personKeyToRanges);
int 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)";
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
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 };
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
{ // ...
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 readonly OutputResolution? _OutputResolution;
protected Location? _Location;
protected readonly int? _LocationIndex;
protected Mapping? _Mapping;
protected readonly string _RelativePath;
public DateTime DateTime => _DateTime;
@ -20,34 +19,32 @@ public class Face : Properties.IFace
public FaceEncoding? FaceEncoding => _FaceEncoding;
public Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts => _FaceParts;
public Location? Location => _Location;
public int? LocationIndex => _LocationIndex;
public Mapping? Mapping => _Mapping;
public OutputResolution? OutputResolution => _OutputResolution;
public string RelativePath => _RelativePath;
[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;
_FaceDistance = faceDistance;
_FaceEncoding = faceEncoding;
_FaceParts = faceParts;
_Location = location;
_LocationIndex = locationIndex;
_Mapping = mapping;
_OutputResolution = outputResolution;
_RelativePath = relativePath;
}
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)
_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) :
this(DateTime.MinValue, null, null, null, location, i, null, null, relativePath)
public Face(Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string relativePath, Location? location) :
this(DateTime.MinValue, null, null, null, location, null, null, relativePath)
{
DateTime?[] dateTimes;
_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) :
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()
@ -73,6 +70,8 @@ public class Face : Properties.IFace
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;
int locationIndex;
long sourceSize;
if (face.LocationIndex is null)
{
locationIndex = 0;
locationDisplayIndex = "01";
}
else
{
locationIndex = face.LocationIndex.Value;
locationDisplayIndex = (face.LocationIndex.Value + 1).ToString("00");
}
locationIndex = 0;
locationDisplayIndex = "01";
if (face.Location is null)
{
faceTop = null;
@ -161,7 +153,7 @@ public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem
string faceRelativePath = string.Concat(requestPath, new Uri(faceFullFileName).AbsoluteUri[rootResultsDirectoryAbsoluteUriLength..]);
string sourceRelativePath = string.Concat(requestPath, new Uri(sourceFullFileName).AbsoluteUri[rootResultsDirectoryAbsoluteUriLength..]);
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);
if (fileInfo.Exists)
FileExists(face, faceBottom, faceRight, out imageHeight, out imageWidth, out sourceSize, fileInfo);
@ -180,8 +172,8 @@ public class FaceFileSystem : FileSystem, Properties.IFaceFileSystem
_LastModified = face.DateTime;
_FaceLeft = faceLeft;
_LocationDisplayIndex = locationDisplayIndex;
_LocationIndex = face.LocationIndex;
_Populated = face.FaceEncoding is not null && face.Location?.NormalizedPixelPercentage is not null;
_LocationIndex = null;
_Populated = face.FaceEncoding is not null && face.Location is not null && face.OutputResolution is not null;
_RelativePath = string.Empty;
_FaceRight = faceRight;
_SourceFullFileName = sourceFullFileName;

View File

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

View File

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

View File

@ -3,7 +3,6 @@ namespace View_by_Distance.Shared.Models.Methods;
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);
}

View File

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

View File

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

View File

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

View File

@ -28,9 +28,4 @@ public interface IFace
static double? Getα(Dictionary<FacePart, Models.FacePoint[]> 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) =>
GetLeftPadded(locationDigits, 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) =>
GetLeftPadded(locationDigits, value);
static string GetLeftPadded(int locationDigits, int value) =>
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) =>
GetLocation(location, locationDigits, locationFactor, height, width, 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) =>
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) =>
GetNormalizedPixelPercentage(location, locationDigits, locationFactor, 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
{ // ...
static string GetDeterministicHashCodeKey(int id, int pixel)
=> $"{id}.{pixel}";
(string?, string?, string?, bool?) TestStatic_GetSegments(int locationDigits, string facesFileNameExtension, string fileName)
=> GetSegments(locationDigits, facesFileNameExtension, fileName);
static (string?, string?, string?, bool?) GetSegments(int locationDigits, string facesFileNameExtension, string 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) =>
GetReversedDeterministicHashCodeKey(locationDigits, facesFileNameExtension, 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();
if (zCount < 0)
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);
if (normalizedPixelPercentage.HasValue && normalizedPixelPercentage.Value < 0)
throw new Exception();
}
internal static void Check(int bottom, int height, int left, int? normalizedPixelPercentage, int right, int top, int width, int zCount)
{
Check(bottom, left, right, top, zCount);
Check(bottom, height, left, right, top, width, zCount);
if (normalizedPixelPercentage.HasValue && normalizedPixelPercentage.Value < 0)
throw new Exception();
string result;
if (value.Length == locationDigits)
result = value;
else if (value.Length > locationDigits)
result = value[..locationDigits];
else
result = value.PadLeft(locationDigits, '0');
return result;
}
internal static int GetNormalizedPixelPercentage(int bottom, int height, int left, int locationDigits, int locationFactor, int right, int top, int width, int zCount)
{
int result;
Check(bottom, height, left, right, top, width, zCount);
int checksum;
decimal center = 2m;
string xCenterPadded;
@ -60,10 +59,12 @@ internal abstract class Location
decimal factor = locationFactor;
// int.MaxPercentage = 21 4748 3647;
int length = (locationDigits - 1) / 2;
Check(bottom, left, right, top, zCount);
Check(bottom, height, left, right, top, width, zCount);
decimal xCenterValue = left + ((right - left) / center);
decimal yCenterValue = top + ((bottom - top) / center);
decimal xCenterValue = (left + right) / center;
decimal yCenterValue = (top + bottom) / center;
if (xCenterValue < left || xCenterValue > right)
throw new Exception();
if (yCenterValue < top || yCenterValue > bottom)
throw new Exception();
if (xCenterValue > yCenterValue)
checksum = 1;
else
@ -87,4 +88,28 @@ internal abstract class Location
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)
{
List<Models.PersonBirthday> results = new();
string[] files;
string personKeyFormatted;
Models.PersonBirthday? personBirthday;
foreach (string personKeyDirectory in personKeyDirectories)
@ -124,6 +125,10 @@ internal abstract class PersonBirthday
if (personBirthday is null)
continue;
results.Add(personBirthday);
files = Directory.GetFiles(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
if (files.Any())
continue;
File.WriteAllText(Path.Combine(personKeyDirectory, $"{personKeyFormatted}.txt"), string.Empty);
}
return results;
}

View File

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

View File

@ -113,38 +113,38 @@ public class UnitTestCalculations
[TestMethod]
public void TestMethodDamn()
{
string name;
string[] directories;
string? directoryName;
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\()";
directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetDirectoryName(directory);
if (directoryName is null)
continue;
name = Path.GetFileName(directory);
if (name.Length is 1 or 20)
continue;
checkDirectory = Path.Combine(directoryName, "b", name);
Directory.Move(directory, checkDirectory);
}
directories = Directory.GetDirectories(Path.Combine(sourceDirectory, "b"), "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetDirectoryName(directory);
if (directoryName is null)
continue;
name = Path.GetFileName(directory);
if (name.Length is 1 or 20)
continue;
checkDirectory = Path.Combine(directoryName, $"{name[..^4]})");
if (Directory.Exists(checkDirectory))
continue;
Directory.Move(directory, checkDirectory);
}
Assert.IsTrue(true);
// string name;
// string[] directories;
// string? directoryName;
// 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\()";
// directories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
// foreach (string directory in directories)
// {
// directoryName = Path.GetDirectoryName(directory);
// if (directoryName is null)
// continue;
// name = Path.GetFileName(directory);
// if (name.Length is 1 or 20)
// continue;
// checkDirectory = Path.Combine(directoryName, "b", name);
// Directory.Move(directory, checkDirectory);
// }
// directories = Directory.GetDirectories(Path.Combine(sourceDirectory, "b"), "*", SearchOption.TopDirectoryOnly);
// foreach (string directory in directories)
// {
// directoryName = Path.GetDirectoryName(directory);
// if (directoryName is null)
// continue;
// name = Path.GetFileName(directory);
// if (name.Length is 1 or 20)
// continue;
// checkDirectory = Path.Combine(directoryName, $"{name[..^4]})");
// if (Directory.Exists(checkDirectory))
// continue;
// Directory.Move(directory, checkDirectory);
// }
// Assert.IsTrue(true);
}
[TestMethod]
@ -164,8 +164,8 @@ public class UnitTestCalculations
Assert.IsTrue(names.Length == 3);
names = IPath.GetDirectoryNames(@"C:\Tmp\phares\");
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");
Assert.IsTrue(names.Length == 13);
// 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);
// Length = 13
// [0] [string]:
// "C:\\"
@ -193,112 +193,193 @@ public class UnitTestCalculations
double confidence = 0.1D;
int left, top, right, bottom, width, height;
left = 20;
top = 40;
right = 60;
top = 40;
bottom = 80;
width = 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(bottom, confidence, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width, 1);
}
[TestMethod]
public void TestGetPixelPercentage()
{
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()
public void TestGetPixelPercentageA()
{
int? x, y;
int normalizedPixelPercentage;
int bottom, height, left, right, top, width;
string normalizedPixelPercentagePadded;
left = 7678;
top = 4318;
right = 7680;
top = 4318;
bottom = 4320;
width = 7680;
height = 4320;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
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;
top = 4320;
right = 7680;
top = 4320;
bottom = 4320;
width = 7680;
height = 4320;
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
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 = "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 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 = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { 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 = "Mapped Max Index"), Required] public int? MappedMaxIndex { 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 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; }
@ -61,6 +62,7 @@ public class Configuration
[Display(Name = "Properties Changed For Metadata"), Required] public bool? PropertiesChangedForMetadata { get; set; }
[Display(Name = "Properties Changed For Resize"), Required] public bool? PropertiesChangedForResize { get; set; }
[Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; }
[Display(Name = "Retry Images Without a Face"), Required] public bool? RetryImagesWithoutAFace { get; set; }
[Display(Name = "Reverse"), Required] public bool? Reverse { get; set; }
[Display(Name = "Save Face Landmark For Output Resolutions"), Required] public string[] SaveFaceLandmarkForOutputResolutions { get; set; }
[Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; }
@ -93,6 +95,10 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
if (configuration.DistanceFactor is null)
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)
throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor));
if (configuration.FaceDistanceMinimumConfidence is null)
@ -127,8 +133,6 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.MapLogicSigma));
if (configuration.MappingDefaultName is null)
throw new NullReferenceException(nameof(configuration.MappingDefaultName));
if (configuration.MappingMoveUnableToMatch is null)
throw new NullReferenceException(nameof(configuration.MappingMoveUnableToMatch));
if (configuration.MappingSaveNotMapped is null)
throw new NullReferenceException(nameof(configuration.MappingSaveNotMapped));
if (configuration.MappingSaveMapped is null)
@ -173,6 +177,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata));
if (configuration.PropertiesChangedForResize is null)
throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize));
if (configuration.RetryImagesWithoutAFace is null)
throw new NullReferenceException(nameof(configuration.RetryImagesWithoutAFace));
if (configuration.Reverse is null)
throw new NullReferenceException(nameof(configuration.Reverse));
if (configuration.SaveFaceLandmarkForOutputResolutions is null)
@ -212,6 +218,8 @@ public class Configuration
configuration.CheckJsonForDistanceResults.Value,
configuration.CrossDirectoryMaxItemsInDistanceCollection.Value,
configuration.DistanceFactor.Value,
configuration.DistanceMoveUnableToMatch.Value,
configuration.DistancePixelDistanceTolerance.Value,
configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value,
configuration.FaceDistancePermyriad.Value,
@ -231,7 +239,6 @@ public class Configuration
configuration.MapLogicSigma.Value,
configuration.MappedMaxIndex,
configuration.MappingDefaultName,
configuration.MappingMoveUnableToMatch.Value,
configuration.MappingSaveNotMapped.Value,
configuration.MappingSaveMapped.Value,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping.Value,
@ -258,6 +265,7 @@ public class Configuration
configuration.PropertiesChangedForIndex.Value,
configuration.PropertiesChangedForMetadata.Value,
configuration.PropertiesChangedForResize.Value,
configuration.RetryImagesWithoutAFace.Value,
configuration.Reverse.Value,
configuration.SaveFaceLandmarkForOutputResolutions,
configuration.SaveFullYearOfRandomFiles.Value,

View File

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

View File

@ -241,8 +241,8 @@ public class UnitTestFace
Image image = FaceRecognition.LoadImageFile(item.ResizedFileHolder.FullName);
Assert.IsNotNull(image);
FaceRecognition faceRecognition = new(_Configuration.NumberOfTimesToUpsample, _Configuration.NumberOfJitters, predictorModel, model, modelParameter);
List<(int, Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection;
collection = faceRecognition.GetCollection(image, includeFaceEncoding: true, includeFaceParts: true, sortByNormalizedPixelPercentage: true);
List<(Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection;
collection = faceRecognition.GetCollection(image, includeFaceEncoding: true, includeFaceParts: true);
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> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncodings[0]);