AppSettings and Configuration changes,

major changes to E_Distance and minor for D_Face
This commit is contained in:
2022-08-19 21:37:36 -07:00
parent 004017b9dd
commit be7a6abbf4
60 changed files with 1269 additions and 1344 deletions

View File

@ -1,19 +1,15 @@
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using View_by_Distance.FaceRecognitionDotNet;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Property.Models;
using View_by_Distance.Resize.Models;
using View_by_Distance.Shared.Models.Properties;
using View_by_Distance.Shared.Models.Stateless;
using WindowsShortcutFactory;
namespace View_by_Distance.Instance.Models;
/// <summary>
// List<D_Faces>
/// </summary>
internal class E_Distance
{
@ -34,183 +30,177 @@ internal class E_Distance
return result;
}
private static void LoadFaceEncodingCollections(Item[] filteredItems, List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<FaceEncoding> faceEncodingCollection, List<List<FaceEncoding>> faceEncodingCollections)
private static List<DistanceHolder> GetDistanceHolder(Item[] items, List<(string JSONDirectory, string TSVDirectory)> directories)
{
List<D_Face> faceCollection;
FaceEncoding faceEncoding;
for (int i = 0; i < filteredItems.Length; i++)
List<DistanceHolder> results = new();
Item item;
const int zero = 0;
string tsvDirectory;
string jsonDirectory;
FaceEncoding? faceEncoding;
if (items.Length != directories.Count)
throw new Exception();
for (int i = 0; i < items.Length; i++)
{
faceCollection = faceCollections[i];
if (!faceCollection.Any())
throw new Exception();
faceEncodingCollections.Add(new List<FaceEncoding>());
for (int j = 0; j < faceCollection.Count; j++)
faceEncoding = null;
item = items[i];
if (item.ImageFileHolder is null || item.Property?.Id is null || !item.Faces.Any())
continue;
tsvDirectory = directories[i].TSVDirectory;
jsonDirectory = directories[i].JSONDirectory;
foreach (IFace face in item.Faces)
{
if (!faceCollection[j].Populated)
if (!face.Populated)
continue;
faceEncoding = FaceRecognition.LoadFaceEncoding(faceCollection[j].FaceEncoding.RawEncoding);
faceEncodingCollection.Add(faceEncoding);
faceEncodingCollections[i].Add(faceEncoding);
locationIndicesCollection.Add(new int[] { i, j });
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
results.Add(new(face, faceEncoding, item.ImageFileHolder, item.Property.Id.Value, jsonDirectory, item.Faces[zero].Location, tsvDirectory));
}
if (faceEncoding is null)
results.Add(new(item.Faces[zero], null, item.ImageFileHolder, item.Property.Id.Value, jsonDirectory, item.Faces[zero].Location, tsvDirectory));
}
return results;
}
private List<Tuple<Shared.Models.Properties.IFace, string>> GetOrderedNoFaceCollection(List<List<D_Face>> faceCollections, int i, D_Face face)
private List<Tuple<IFace, string>> GetOrderedNoFaceCollection(List<List<IFace>> faceCollections, int i, IFace face)
{
List<Tuple<Shared.Models.Properties.IFace, string>> results = new() { new(face, string.Empty) };
if (_Configuration.MaxItemsInDistanceCollection is null)
throw new NullReferenceException(nameof(_Configuration.MaxItemsInDistanceCollection));
List<Tuple<IFace, string>> results = new() { new(face, string.Empty) };
for (int n = 0; n < faceCollections.Count; n++)
{
if (i == n)
continue;
for (int j = 0; j < faceCollections[n].Count; j++)
{
if (!faceCollections[n][j].Populated)
continue;
results.Add(new(faceCollections[n][j], string.Empty));
}
}
for (int r = results.Count - 1; r > _Configuration.MaxItemsInDistanceCollection.Value; r--)
for (int r = results.Count - 1; r > _Configuration.MaxItemsInDistanceCollection; r--)
results.RemoveAt(r);
return results;
}
private List<double[]> GetValues(List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<double> faceDistances)
private void WriteNoFaceCollection(bool updateDateWhenMatches, DateTime? updateToWhenMatches, List<Tuple<string, DateTime>> subFileTuples, List<DistanceHolder> distanceHolders)
{
List<double[]> results = new();
if (_Configuration.LocationConfidenceFactor is null)
throw new NullReferenceException(nameof(_Configuration.LocationConfidenceFactor));
if (_Configuration.DistanceFactor is null)
throw new NullReferenceException(nameof(_Configuration.DistanceFactor));
D_Face face;
int[] locationIndices;
for (int d = 0; d < faceDistances.Count; d++)
{
locationIndices = locationIndicesCollection[d];
face = faceCollections[locationIndices[0]][locationIndices[1]];
if (face.Populated && face.LocationIndex is not null && locationIndices[1] != face.LocationIndex)
throw new Exception();
results.Add(new double[] { d, faceDistances[d], (faceDistances[d] * _Configuration.DistanceFactor.Value) + face.Location.Confidence * _Configuration.LocationConfidenceFactor.Value / 10 });
}
results = (from l in results orderby l[2] select l).ToList();
return results;
}
private List<Tuple<Shared.Models.Properties.IFace, string>> GetOrderedFaceCollection(List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<double[]> indicesAndValues)
{
List<Tuple<Shared.Models.Properties.IFace, string>> results = new();
if (_Configuration.MaxItemsInDistanceCollection is null)
throw new NullReferenceException(nameof(_Configuration.MaxItemsInDistanceCollection));
int[] locationIndices;
for (int t = 0; t < indicesAndValues.Count; t++)
{
locationIndices = locationIndicesCollection[(int)indicesAndValues[t][0]];
results.Add(new(faceCollections[locationIndices[0]][locationIndices[1]], string.Join('|', (from l in indicesAndValues[t] select l.ToString("0.000")).ToArray(), 1, indicesAndValues[t].Length - 1)));
}
for (int r = results.Count - 1; r > _Configuration.MaxItemsInDistanceCollection.Value; r--)
results.RemoveAt(r);
return results;
}
private static string GetText(string fileNameWithoutExtension, List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<double[]> indicesAndValues)
{
string result;
D_Face face;
int[] locationIndices;
StringBuilder tvs = new();
_ = tvs.Append("FileNameWithoutExtension").Append('\t').Append("LocationIndex").Append('\t').Append("FaceConfidence").Append('\t').Append("FaceDistance").Append('\t').Append("FactoredValue").AppendLine();
for (int t = 0; t < indicesAndValues.Count; t++)
{
locationIndices = locationIndicesCollection[(int)indicesAndValues[t][0]];
face = faceCollections[locationIndices[0]][locationIndices[1]];
if (face.Populated && face.LocationIndex is not null && locationIndices[1] != face.LocationIndex)
throw new Exception();
_ = tvs.Append(fileNameWithoutExtension).Append('\t').Append(face.LocationIndex).Append('\t').Append(face.Location.Confidence).Append('\t').Append(indicesAndValues[t][1]).Append('\t').Append(indicesAndValues[t][2]).AppendLine();
}
result = tvs.ToString();
return result;
}
private void LoadOrCreateThenSaveDistanceResultsForOutputResolutionsLoop(List<List<D_Face>> faceCollections, int subFilesCount, int i, List<D_Face> faceCollection, List<int[]> locationIndicesCollection, List<Tuple<string, DateTime>> subFileTuples, List<FaceEncoding> faceEncodingCollection, List<FaceEncoding> faceEncodingCollections, string fileNameWithoutExtension, string jsonDirectory, string tvsDirectory, bool updateDateWhenMatches, DateTime? updateToWhenMatches)
{
string text;
string json;
string check;
string jsonFile;
List<Tuple<Shared.Models.Properties.IFace, string>> orderedFaceCollection;
if (!Directory.Exists(jsonDirectory))
_ = Directory.CreateDirectory(jsonDirectory);
if (!Directory.Exists(tvsDirectory))
_ = Directory.CreateDirectory(tvsDirectory);
if (!faceEncodingCollections.Any())
const int zero = 0;
DistanceHolder distanceHolder;
List<Tuple<IFace, string>> tupleCollection;
for (int i = 0; i < distanceHolders.Count; i++)
{
int j = 0;
orderedFaceCollection = GetOrderedNoFaceCollection(faceCollections, i, faceCollection[j]);
json = JsonSerializer.Serialize(orderedFaceCollection, _WriteIndentedJsonSerializerOptions);
jsonFile = Path.Combine(jsonDirectory, $"{j} - {fileNameWithoutExtension}.json");
distanceHolder = distanceHolders[i];
if (distanceHolder.Face.Location.NormalizedPixelPercentage is null)
continue;
check = Path.Combine(distanceHolder.JSONDirectory, $"{zero} - {distanceHolder.FileHolder.NameWithoutExtension}.json");
jsonFile = Path.Combine(distanceHolder.JSONDirectory, $"{distanceHolder.Id}.{zero}{distanceHolder.FileHolder.ExtensionLowered}.json");
if (File.Exists(check))
File.Move(check, jsonFile);
tupleCollection = new() { new(distanceHolders[i].Face, string.Empty) };
for (int j = 0; j < distanceHolders.Count; j++)
{
if (j == i)
continue;
distanceHolder = distanceHolders[j];
tupleCollection.Add(new(distanceHolder.Face, string.Empty));
if (tupleCollection.Count > _Configuration.MaxItemsInDistanceCollection)
break;
}
json = JsonSerializer.Serialize(tupleCollection, _WriteIndentedJsonSerializerOptions);
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: updateToWhenMatches))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
}
else
{
string tvsFile;
List<double> faceDistances;
List<double[]> indicesAndValues;
for (int j = 0; j < faceEncodingCollections.Count; j++)
{
if (!faceCollection[j].Populated)
continue;
tvsFile = Path.Combine(tvsDirectory, $"{j} - {fileNameWithoutExtension}.tvs");
jsonFile = Path.Combine(jsonDirectory, $"{j} - {fileNameWithoutExtension}.json");
faceDistances = FaceRecognition.FaceDistances(faceEncodingCollection, faceEncodingCollections[j]);
indicesAndValues = GetValues(faceCollections, locationIndicesCollection, faceDistances);
orderedFaceCollection = GetOrderedFaceCollection(faceCollections, locationIndicesCollection, indicesAndValues);
text = GetText(fileNameWithoutExtension, faceCollections, locationIndicesCollection, indicesAndValues);
if (Property.Models.Stateless.IPath.WriteAllText(tvsFile, text, updateDateWhenMatches, compareBeforeWrite: true))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
json = JsonSerializer.Serialize(orderedFaceCollection, _WriteIndentedJsonSerializerOptions);
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
}
}
}
private void LoadOrCreateThenSaveDistanceResultsForOutputResolutions(Item[] filteredItems, List<List<D_Face>> faceCollections, List<string[]> directories, bool updateDateWhenMatches, DateTime? updateToWhenMatches)
private static List<FaceEncoding> GetFaceEncodings(List<DistanceHolder> distanceHolders)
{
FileHolder? fileHolder;
List<int[]> locationIndicesCollection = new();
List<Tuple<string, DateTime>> subFileTuples = new();
List<FaceEncoding> faceEncodingCollection = new();
List<List<FaceEncoding>> faceEncodingCollections = new();
LoadFaceEncodingCollections(filteredItems, faceCollections, locationIndicesCollection, faceEncodingCollection, faceEncodingCollections);
if (faceEncodingCollections.Count != faceCollections.Count)
throw new Exception();
if (locationIndicesCollection.Count != faceEncodingCollection.Count)
throw new Exception();
for (int i = 0; i < filteredItems.Length; i++)
List<FaceEncoding> results = new();
foreach (DistanceHolder distanceHolder in distanceHolders)
{
fileHolder = filteredItems[i].ImageFileHolder;
if (fileHolder is null)
if (!distanceHolder.Face.Populated || distanceHolder.FaceEncoding is null)
continue;
LoadOrCreateThenSaveDistanceResultsForOutputResolutionsLoop(faceCollections, filteredItems.Length, i, faceCollections[i], locationIndicesCollection, subFileTuples, faceEncodingCollection, faceEncodingCollections[i], fileHolder.NameWithoutExtension, directories[i][0], directories[i][1], updateDateWhenMatches, updateToWhenMatches);
results.Add(distanceHolder.FaceEncoding);
}
return results;
}
private void SaveDistanceResults(bool updateDateWhenMatches, DateTime? updateToWhenMatches, List<Tuple<string, DateTime>> subFileTuples, List<DistanceHolder> distanceHolders)
{
string json;
string check;
string jsonFile;
int locationIndex;
List<double> faceDistances;
DistanceHolder distanceHolder;
int normalizedPixelPercentage;
DistanceHolder[] sortedDistanceHolders;
List<Tuple<IFace, string>> tupleCollection;
List<(int Index, double Distance)> collection;
distanceHolders = distanceHolders.OrderByDescending(l => l.Face.Populated).ToList();
List<FaceEncoding> faceEncodings = GetFaceEncodings(distanceHolders);
for (int i = 0; i < distanceHolders.Count; i++)
{
distanceHolder = distanceHolders[i];
collection = new();
tupleCollection = new();
distanceHolder.Sort = 0d;
if (distanceHolder.Face.LocationIndex is null)
locationIndex = 0;
else
locationIndex = distanceHolder.Face.LocationIndex.Value;
if (!distanceHolder.Face.Populated || distanceHolder.Face.Location.NormalizedPixelPercentage is null)
normalizedPixelPercentage = 0;
else
normalizedPixelPercentage = distanceHolder.Face.Location.NormalizedPixelPercentage.Value;
check = Path.Combine(distanceHolder.JSONDirectory, $"{locationIndex} - {distanceHolder.FileHolder.NameWithoutExtension}.json");
jsonFile = Path.Combine(distanceHolder.JSONDirectory, $"{distanceHolder.Id}.{normalizedPixelPercentage}{distanceHolder.FileHolder.ExtensionLowered}.json");
if (!Directory.Exists(distanceHolder.JSONDirectory))
_ = Directory.CreateDirectory(distanceHolder.JSONDirectory);
if (File.Exists(check))
File.Move(check, jsonFile);
if (faceEncodings.Count == 1)
faceDistances = new() { 0d };
else if (distanceHolder.FaceEncoding is null)
faceDistances = Enumerable.Repeat(9d, faceEncodings.Count).ToList();
else
faceDistances = FaceRecognition.FaceDistances(faceEncodings, distanceHolder.FaceEncoding);
if (distanceHolder.Face.Populated && distanceHolder.FaceEncoding is not null && faceDistances[i] != 0d)
faceDistances[i] = 0d;
for (int d = 0; d < faceDistances.Count; d++)
collection.Add(new(d, faceDistances[d]));
collection = collection.OrderBy(l => l.Distance).ToList();
foreach ((int index, double distance) in collection)
distanceHolders[index].Sort = ((distance * _Configuration.DistanceFactor) + (distanceHolders[index].Location.Confidence * _Configuration.LocationConfidenceFactor)) / 10;
sortedDistanceHolders = distanceHolders.OrderBy(l => l.Sort).ToArray();
for (int j = 0; j < sortedDistanceHolders.Length; j++)
{
distanceHolder = sortedDistanceHolders[j];
tupleCollection.Add(new(distanceHolders[j].Face, string.Empty));
if (tupleCollection.Count > _Configuration.MaxItemsInDistanceCollection)
break;
}
json = JsonSerializer.Serialize(tupleCollection, _WriteIndentedJsonSerializerOptions);
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: updateToWhenMatches))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
}
}
internal void LoadOrCreateThenSaveDistanceResultsForOutputResolutions(Property.Models.Configuration configuration, string eResultsFullGroupDirectory, string sourceDirectory, string outputResolution, List<Tuple<string, DateTime>> sourceDirectoryChanges, Item[] filteredItems, List<List<D_Face>> faceCollections)
internal void LoadOrCreateThenSaveDistanceResults(Property.Models.Configuration configuration, string eResultsFullGroupDirectory, string sourceDirectory, string outputResolution, List<Tuple<string, DateTime>> sourceDirectoryChanges, Item[] filteredItems)
{
if (_Configuration.CheckJsonForDistanceResults is null)
throw new NullReferenceException(nameof(_Configuration.CheckJsonForDistanceResults));
if (_Configuration.PropertiesChangedForDistance is null)
throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForDistance));
Item item;
string json;
bool check = false;
string parentCheck;
bool hasPopulatedFace;
string usingRelativePath;
DateTime? dateTime = null;
string dCollectionDirectory;
FileInfo[] fileInfoCollection;
bool updateDateWhenMatches = false;
List<string[]> directories = new();
System.IO.DirectoryInfo directoryInfo;
System.IO.DirectoryInfo tvsDirectoryInfo;
IEnumerator<FileInfo> fileInfoCollection;
List<(string, string)> directories = new();
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
List<DateTime> dateTimes = (from l in sourceDirectoryChanges where changesFrom.Contains(l.Item1) select l.Item2).ToList();
List<string> directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(
@ -226,6 +216,7 @@ internal class E_Distance
item = filteredItems[i];
if (item.ImageFileHolder is null || item.Property?.Id is null)
continue;
hasPopulatedFace = (from l in item.Faces where l.Populated select true).Any();
usingRelativePath = Path.Combine(directoryInfoCollection[0].Replace("<>", "[]"), item.ImageFileHolder.NameWithoutExtension);
dCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, "[]", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}");
directoryInfo = new System.IO.DirectoryInfo(dCollectionDirectory);
@ -250,24 +241,32 @@ internal class E_Distance
}
}
tvsDirectoryInfo = new System.IO.DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension));
directories.Add(new string[] { directoryInfo.FullName, tvsDirectoryInfo.FullName });
if (_Configuration.CheckJsonForDistanceResults.Value && directoryInfo.Exists)
directories.Add(new(directoryInfo.FullName, tvsDirectoryInfo.FullName));
if (_Configuration.CheckJsonForDistanceResults && directoryInfo.Exists)
{
fileInfoCollection = directoryInfo.GetFiles("*.json", SearchOption.AllDirectories);
for (int j = 0; j < fileInfoCollection.Length; j++)
json = string.Empty;
fileInfoCollection = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
for (int j = 0; j < int.MaxValue; j++)
{
json = Shared.Models.Stateless.Methods.IIndex.GetJson(fileInfoCollection[j].FullName, fileInfoCollection[j]);
if (!_Configuration.PropertiesChangedForDistance.Value && Shared.Models.Stateless.Methods.IFace.GetFace(fileInfoCollection[j].FullName) is null)
if (!fileInfoCollection.MoveNext())
break;
json = Shared.Models.Stateless.Methods.IIndex.GetJson(fileInfoCollection.Current.FullName, fileInfoCollection.Current);
if (!_Configuration.PropertiesChangedForDistance && Shared.Models.Stateless.Methods.IFace.GetFace(fileInfoCollection.Current.FullName) is null)
{
check = true;
break;
}
}
if (!check && string.IsNullOrEmpty(json))
check = true;
}
if (check)
continue;
if (_Configuration.PropertiesChangedForDistance.Value)
if (_Configuration.PropertiesChangedForDistance)
check = true;
else if (!directoryInfo.Exists)
else if (hasPopulatedFace && !directoryInfo.Exists)
check = true;
else if (!tvsDirectoryInfo.Exists)
else if (hasPopulatedFace && !tvsDirectoryInfo.Exists)
check = true;
else if (dateTimes.Any() && dateTimes.Max() > directoryInfo.LastWriteTime)
check = true;
@ -278,7 +277,12 @@ internal class E_Distance
}
}
if (check)
LoadOrCreateThenSaveDistanceResultsForOutputResolutions(filteredItems, faceCollections, directories, updateDateWhenMatches, updateToWhenMatches: dateTime);
{
DateTime? updateToWhenMatches = dateTime;
List<Tuple<string, DateTime>> subFileTuples = new();
List<DistanceHolder> distanceHolders = GetDistanceHolder(filteredItems, directories);
SaveDistanceResults(updateDateWhenMatches, updateToWhenMatches, subFileTuples, distanceHolders);
}
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(directoryInfoCollection[0].Replace("<>", "()"));
}
@ -377,8 +381,6 @@ internal class E_Distance
int filesCount = files.Count;
for (int i = 0; i < filesCount; i++)
{
if (_Configuration.CrossDirectoryMaxItemsInDistanceCollection is null)
continue;
_Log.Debug(string.Concat("LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions - ", nameof(outputResolution), ' ', outputResolution, " - ", i, " of ", filesCount));
for (int j = 0; j < files[i].Item2.Count; j++)
{
@ -405,7 +407,7 @@ internal class E_Distance
});
if (faceAndFaceDistanceCollection.Any())
{
faceAndFaceDistanceCollection = (from l in faceAndFaceDistanceCollection orderby l.Item2 select l).Take(_Configuration.CrossDirectoryMaxItemsInDistanceCollection.Value).ToList();
faceAndFaceDistanceCollection = (from l in faceAndFaceDistanceCollection orderby l.Item2 select l).Take(_Configuration.CrossDirectoryMaxItemsInDistanceCollection).ToList();
Save(configuration, model, predictorModel, outputResolution, eDistanceCollectionDirectory, k, relativePath, face, faceAndFaceDistanceCollection);
}
}
@ -423,7 +425,7 @@ internal class E_Distance
return result;
}
private static FaceEncoding? GetFaceEncoding(Shared.Models.Properties.IFace face)
private static FaceEncoding? GetFaceEncoding(IFace face)
{
FaceEncoding? result;
if (!face.Populated)
@ -439,14 +441,14 @@ internal class E_Distance
return new(i, faceDistances.Sum());
}
private static List<FaceEncoding> GetFaceEncodings(int maxDegreeOfParallelism, List<(DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, Shared.Models.Properties.IFace Face)> collection)
private static List<FaceEncoding> GetFaceEncodings(int maxDegreeOfParallelism, List<(DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, IFace Face)> collection)
{
List<FaceEncoding> results;
if (maxDegreeOfParallelism == 1)
{
results = new();
FaceEncoding faceEncoding;
foreach ((DateTime _, bool? _, Shared.Models.PersonBirthday _, Shared.Models.Properties.IFace face) in collection)
foreach ((DateTime _, bool? _, Shared.Models.PersonBirthday _, IFace face) in collection)
{
if (!face.Populated)
continue;
@ -518,12 +520,12 @@ internal class E_Distance
return results;
}
private static List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> GetThreeSigmaFaceEncodings(int maxDegreeOfParallelism, Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, Shared.Models.Properties.IFace)>> keyValuePairs)
private static List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> GetThreeSigmaFaceEncodings(int maxDegreeOfParallelism, Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, IFace)>> keyValuePairs)
{
List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> results = new();
const int zero = 0;
List<FaceEncoding> faceEncodings;
foreach (KeyValuePair<string, List<(DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, Shared.Models.Properties.IFace _)>> keyValuePair in keyValuePairs)
foreach (KeyValuePair<string, List<(DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, IFace _)>> keyValuePair in keyValuePairs)
{
faceEncodings = GetFaceEncodings(maxDegreeOfParallelism, keyValuePair.Value);
results.Add(new(keyValuePair.Value[zero].MinimumDateTime, keyValuePair.Value[zero].IsWrongYear, keyValuePair.Value[zero].PersonBirthday, faceEncodings.ToArray()));
@ -531,7 +533,7 @@ internal class E_Distance
return results;
}
private static Closest? GetClosestParallelFor(DateTime minimumDateTime, bool? isWrongYear, Shared.Models.Properties.IFace face, FaceEncoding faceEncoding, (DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, FaceEncoding[] FaceEncodings) tuple)
private static Closest? GetClosestParallelFor(DateTime minimumDateTime, bool? isWrongYear, IFace face, FaceEncoding faceEncoding, (DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, FaceEncoding[] FaceEncodings) tuple)
{
Closest? result;
if (isWrongYear.HasValue && !isWrongYear.Value && minimumDateTime < tuple.PersonBirthday.Value)
@ -546,7 +548,7 @@ internal class E_Distance
return result;
}
private static Closest[] GetClosestCollection(int maxDegreeOfParallelism, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, DateTime itemMinimumDateTime, bool? itemIsWrongYear, Shared.Models.Properties.IFace face)
private static Closest[] GetClosestCollection(int maxDegreeOfParallelism, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, DateTime itemMinimumDateTime, bool? itemIsWrongYear, IFace face)
{
Closest[] results;
List<Closest> closestCollection;
@ -585,14 +587,16 @@ internal class E_Distance
return results;
}
private static void AddClosest(int maxDegreeOfParallelism, string argZero, List<Container> containers, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection)
private static void AddClosest(int maxDegreeOfParallelism, string argZero, PropertyLogic propertyLogic, List<Container> containers, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection)
{
string key;
IFace face;
Closest closest;
string personKey;
bool? itemIsWrongYear;
Closest[] closestCollection;
DateTime? itemMinimumDateTime;
Shared.Models.Properties.IFace face;
float deterministicHashCodeKey;
Dictionary<string, int> results = new();
foreach (Container container in containers)
{
@ -618,12 +622,16 @@ internal class E_Distance
item.Closest.Add(closest);
if (!face.Populated)
continue;
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face);
closestCollection = GetClosestCollection(maxDegreeOfParallelism, collection, itemMinimumDateTime.Value, itemIsWrongYear, face);
for (int j = 0; j < closestCollection.Length; j++)
{
closest = closestCollection[j];
if (closest.PersonBirthday is null)
continue;
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(closest.PersonBirthday);
if (propertyLogic.IncorrectDeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey) && propertyLogic.IncorrectDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey].Contains(personKey))
continue;
key = Item.GetKey(closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday);
if (!results.ContainsKey(key))
results.Add(key, 0);
@ -638,12 +646,12 @@ internal class E_Distance
}
}
internal static List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> ParallelWork(int maxDegreeOfParallelism, string argZero, List<Container> containers)
internal static List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> ParallelWork(int maxDegreeOfParallelism, string argZero, PropertyLogic propertyLogic, List<Container> containers)
{
List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> results;
Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, Shared.Models.Properties.IFace)>> keyValuePairs = Item.GetKeyValuePairs(argZero, containers);
Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, IFace)>> keyValuePairs = Item.GetKeyValuePairs(argZero, containers);
results = GetThreeSigmaFaceEncodings(maxDegreeOfParallelism, keyValuePairs);
AddClosest(maxDegreeOfParallelism, argZero, containers, results);
AddClosest(maxDegreeOfParallelism, argZero, propertyLogic, containers, results);
return results;
}
@ -707,7 +715,7 @@ internal class E_Distance
}
}
internal static List<(FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> GetClosest(string argZero, List<Container> containers, Dictionary<string, List<Shared.Models.Person>> peopleCollection, PropertyLogic propertyLogic, string eDistanceContentDirectory, string dFacesContentDirectory)
internal static List<(FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> GetClosest(string argZero, List<Container> containers, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string eDistanceContentDirectory, string dFacesContentDirectory)
{
List<(FileHolder?, string, FileInfo?, string, string)> results = new();
string checkFile;
@ -720,8 +728,8 @@ internal class E_Distance
string facesDirectory;
string personDirectory;
Shared.Models.Person person;
float deterministicHashCodeKey;
const string facePopulatedKey = "Closest";
string deterministicHashCodeIdAndFaceLocationIndex;
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
foreach (Container container in containers)
{
@ -740,14 +748,10 @@ internal class E_Distance
throw new Exception();
foreach (Closest closest in item.Closest)
{
if (closest.Average is null || closest.FaceLocationIndex is null || closest.PersonBirthday is null)
continue;
deterministicHashCodeIdAndFaceLocationIndex = $"{closest.FaceLocationIndex.Value} - {item.Property.Id.Value}";
if (propertyLogic.NamedDeterministicHashCodeIdAndFaceLocationIndex.Contains(deterministicHashCodeIdAndFaceLocationIndex))
if (closest.Average is null || closest.NormalizedPixelPercentage is null || closest.PersonBirthday is null)
continue;
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(closest.PersonBirthday);
directory = Item.GetDirectory(eDistanceContentDirectory, facePopulatedKey, closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday, personKey);
// checkFile = Path.Combine(directory, item.ImageFileHolder.Name);
if (!peopleCollection.ContainsKey(personKey))
personDirectory = string.Empty;
else
@ -758,12 +762,13 @@ internal class E_Distance
results.Add(new(null, personDirectory, null, string.Empty, string.Empty));
}
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
faceFileInfo = new(Path.Combine(facesDirectory, $"{closest.FaceLocationIndex.Value} - {item.ImageFileHolder.NameWithoutExtension}.png"));
checkFile = Path.Combine(directory, $"{deterministicHashCodeIdAndFaceLocationIndex}{item.ImageFileHolder.ExtensionLowered}");
faceFileInfo = new(Path.Combine(facesDirectory, $"{closest.NormalizedPixelPercentage.Value} - {item.ImageFileHolder.NameWithoutExtension}.png"));
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, closest);
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
if (string.IsNullOrEmpty(personDirectory))
shortcutFile = string.Empty;
else
shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeIdAndFaceLocationIndex}{item.ImageFileHolder.ExtensionLowered}.lnk");
shortcutFile = Path.Combine(personDirectory, $"{item.ImageFileHolder.ExtensionLowered}.lnk");
results.Add(new(item.ResizedFileHolder, directory, faceFileInfo, checkFile, shortcutFile));
}
}
@ -771,10 +776,10 @@ internal class E_Distance
return results;
}
internal static void SaveClosest(string argZero, List<Container> containers, Dictionary<string, List<Shared.Models.Person>> peopleCollection, PropertyLogic propertyLogic, string eDistanceContentDirectory, string dFacesContentDirectory)
internal static void SaveClosest(string argZero, List<Container> containers, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string eDistanceContentDirectory, string dFacesContentDirectory)
{
WindowsShortcut windowsShortcut;
List<(FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> collection = GetClosest(argZero, containers, peopleCollection, propertyLogic, eDistanceContentDirectory, dFacesContentDirectory);
List<(FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> collection = GetClosest(argZero, containers, peopleCollection, eDistanceContentDirectory, dFacesContentDirectory);
string[] directories = (from l in collection select l.directory).Distinct().ToArray();
foreach (string directory in directories)
{