SegmentB, personKey,
personKeyFormatted and Sorting
This commit is contained in:
@ -118,7 +118,7 @@ internal class D2_FaceParts
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
internal void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, string sourceDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Face> faceCollection, bool saveRotated)
|
||||
internal void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, Container container, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Face> faceCollection, bool saveRotated)
|
||||
{
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
@ -137,7 +137,7 @@ internal class D2_FaceParts
|
||||
List<(Face, string, string)> collection = new();
|
||||
angleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(
|
||||
_Configuration.PropertyConfiguration,
|
||||
sourceDirectory,
|
||||
container.SourceDirectory,
|
||||
d2ResultsFullGroupDirectory,
|
||||
contentDescription: "n x 2 gif file(s) for each face found",
|
||||
singletonDescription: string.Empty,
|
||||
|
@ -11,6 +11,8 @@ namespace View_by_Distance.Instance.Models;
|
||||
internal class E_Distance
|
||||
{
|
||||
|
||||
internal List<string> AngleBracketCollection { get; }
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||
@ -18,6 +20,7 @@ internal class E_Distance
|
||||
internal E_Distance(Configuration configuration)
|
||||
{
|
||||
_Configuration = configuration;
|
||||
AngleBracketCollection = new List<string>();
|
||||
_Log = Serilog.Log.ForContext<E_Distance>();
|
||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
||||
}
|
||||
@ -411,6 +414,76 @@ internal class E_Distance
|
||||
}
|
||||
}
|
||||
|
||||
internal void SaveFaceNumbers(string eResultsFullGroupDirectory, Item item, Face face, List<int[]> faceDistances)
|
||||
{
|
||||
if (item.Property?.Id is null)
|
||||
throw new NullReferenceException(nameof(item.Property.Id));
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
if (face.Location?.NormalizedPixelPercentage is null)
|
||||
throw new NullReferenceException(nameof(face.Location.NormalizedPixelPercentage));
|
||||
if (string.IsNullOrEmpty(eResultsFullGroupDirectory))
|
||||
throw new NullReferenceException(nameof(eResultsFullGroupDirectory));
|
||||
string json;
|
||||
List<(Face, string, string)> collection = new();
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
|
||||
string eSingletonFile = Path.Combine(eResultsFullGroupDirectory, "{}", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}.{face.Location.NormalizedPixelPercentage.Value}{item.ImageFileHolder.ExtensionLowered}.json");
|
||||
FileInfo fileInfo = new(eSingletonFile);
|
||||
json = JsonSerializer.Serialize(faceDistances, _WriteIndentedJsonSerializerOptions);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
||||
}
|
||||
|
||||
internal void GetFaceDistances(string eResultsFullGroupDirectory, List<bool> faceEncodingRequired, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Face> faceCollection)
|
||||
{
|
||||
List<int[]>? results;
|
||||
if (item.Property?.Id is null)
|
||||
throw new NullReferenceException(nameof(item.Property.Id));
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
if (string.IsNullOrEmpty(eResultsFullGroupDirectory))
|
||||
throw new NullReferenceException(nameof(eResultsFullGroupDirectory));
|
||||
string json;
|
||||
FileInfo fileInfo;
|
||||
string eSingletonFile;
|
||||
List<(Face, string, string)> collection = new();
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
|
||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
foreach (Face face in faceCollection)
|
||||
{
|
||||
results = null;
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
continue;
|
||||
eSingletonFile = Path.Combine(eResultsFullGroupDirectory, "{}", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}.{face.Location.NormalizedPixelPercentage.Value}{item.ImageFileHolder.ExtensionLowered}.json");
|
||||
fileInfo = new(eSingletonFile);
|
||||
if (_Configuration.PropertiesChangedForDistance)
|
||||
results = null;
|
||||
else if (!fileInfo.Exists)
|
||||
results = null;
|
||||
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
results = null;
|
||||
else
|
||||
{
|
||||
json = File.ReadAllText(fileInfo.FullName);
|
||||
try
|
||||
{
|
||||
results = JsonSerializer.Deserialize<List<int[]>>(json);
|
||||
if (results is null)
|
||||
throw new NullReferenceException(nameof(results));
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), fileInfo.LastWriteTime));
|
||||
lock (face)
|
||||
face.SetFaceNumbers(results);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
results = null;
|
||||
parseExceptions.Add(nameof(E_Distance));
|
||||
}
|
||||
}
|
||||
if (results is null && !faceEncodingRequired.Any())
|
||||
faceEncodingRequired.Add(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static double GetStandardDeviation(IEnumerable<double> values, double average)
|
||||
{
|
||||
double result = 0;
|
||||
@ -661,55 +734,40 @@ internal class E_Distance
|
||||
return results;
|
||||
}
|
||||
|
||||
internal Dictionary<string, List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)>> ParallelWork(int maxDegreeOfParallelism, string[] ignoreRelativePaths, string argZero, long ticks, Map.Models.MapLogic mapLogic, Container[] containers, int totalNotMapped)
|
||||
internal Dictionary<string, List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)>> ParallelWork(int maxDegreeOfParallelism, long ticks, Map.Models.MapLogic mapLogic, Item[] items, int totalNotMapped)
|
||||
{
|
||||
Dictionary<string, List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)>> results;
|
||||
Random random = new((int)ticks);
|
||||
mapLogic.ForceSingleImage(ignoreRelativePaths, argZero, containers, totalNotMapped, random);
|
||||
Dictionary<string, List<MappingContainer>> keyValuePairs = Map.Models.Stateless.IMapLogic.GetKeyValuePairs(ignoreRelativePaths, argZero, containers);
|
||||
mapLogic.ForceSingleImage(ticks, items, totalNotMapped, random);
|
||||
Dictionary<string, List<MappingContainer>> keyValuePairs = Map.Models.Stateless.IMapLogic.GetKeyValuePairs(items);
|
||||
results = GetThreeSigmaFaceEncodings(maxDegreeOfParallelism, ticks, random, keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
public void AddToFaceDistance(int maxDegreeOfParallelism, string argZero, long ticks, Map.Models.MapLogic mapLogic, Container[] containers, string outputResolution, List<(string, int, Mapping, DateTime, bool?, List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)>)> collection)
|
||||
public static void AddToFaceDistance(int maxDegreeOfParallelism, Map.Models.MapLogic mapLogic, Item[] items, List<(string, int, Mapping, DateTime, bool?, List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)>)> collection)
|
||||
{
|
||||
if (_Log is null)
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
Face face;
|
||||
string message;
|
||||
int totalSeconds;
|
||||
double deterministicHashCodeKey;
|
||||
DateTime dateTime = DateTime.Now;
|
||||
List<FaceDistance> faceDistances;
|
||||
int containersCount = containers.Length;
|
||||
foreach (Container container in containers)
|
||||
foreach (Item item in items)
|
||||
{
|
||||
if (!container.Items.Any())
|
||||
if (item.Property?.Id is null || item.ImageFileHolder is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
if (!container.SourceDirectory.StartsWith(argZero))
|
||||
continue;
|
||||
foreach (Item item in container.Items)
|
||||
for (int i = 0; i < item.Faces.Count; i++)
|
||||
{
|
||||
if (item.ImageFileHolder is null || item.Property?.Id is null)
|
||||
face = item.Faces[i];
|
||||
face.FaceDistances.Clear();
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
continue;
|
||||
for (int i = 0; i < item.Faces.Count; i++)
|
||||
{
|
||||
face = item.Faces[i];
|
||||
face.FaceDistances.Clear();
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
continue;
|
||||
if ((from l in item.Mapping where l.NormalizedPixelPercentage.HasValue && l.NormalizedPixelPercentage.Value == face.Location.NormalizedPixelPercentage.Value select true).Any())
|
||||
continue;
|
||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
|
||||
if (mapLogic.Skip(deterministicHashCodeKey))
|
||||
continue;
|
||||
faceDistances = GetFaceDistanceCollection(maxDegreeOfParallelism, collection, face);
|
||||
face.FaceDistances.AddRange(faceDistances);
|
||||
}
|
||||
if ((from l in item.Mapping where l.NormalizedPixelPercentage.HasValue && l.NormalizedPixelPercentage.Value == face.Location.NormalizedPixelPercentage.Value select true).Any())
|
||||
continue;
|
||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
|
||||
if (mapLogic.Skip(deterministicHashCodeKey))
|
||||
continue;
|
||||
faceDistances = GetFaceDistanceCollection(maxDegreeOfParallelism, collection, face);
|
||||
face.FaceDistances.AddRange(faceDistances);
|
||||
}
|
||||
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||
message = $"{container.R:000}.{container.G} / {containersCount:000}) {container.Items.Count:000} file(s) - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}";
|
||||
_Log.Information(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user