2023-02-11
This commit is contained in:
@ -1,9 +1,7 @@
|
||||
using ShellProgressBar;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.FaceRecognitionDotNet;
|
||||
using View_by_Distance.Map.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
namespace View_by_Distance.Distance.Models;
|
||||
|
||||
@ -15,19 +13,38 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
private int _Distance;
|
||||
private int _Confidence;
|
||||
|
||||
private readonly int _FaceConfidencePercent;
|
||||
private readonly int _FaceDistancePermyriad;
|
||||
private readonly int[] _RangeDaysDeltaTolerance;
|
||||
private readonly int[] _RangeFaceAreaPermilleTolerance;
|
||||
private readonly double _FaceAreaPermille;
|
||||
private readonly double _RangeDaysDeltaTolerance;
|
||||
private readonly double _FaceConfidencePercent;
|
||||
private readonly double _FaceDistancePermyriad;
|
||||
private readonly int _SortingMaximumPerFaceShouldBeHigh;
|
||||
private readonly bool _RangeDaysDeltaTargetLessThenUpper;
|
||||
|
||||
public MapLogicSupport(int faceConfidencePercent, int faceDistancePermyriad, int[] rangeDaysDeltaTolerance, int[] rangeFaceAreaPermilleTolerance, int sortingMaximumPerFaceShouldBeHigh)
|
||||
public MapLogicSupport(int faceConfidencePercent,
|
||||
int faceDistancePermyriad,
|
||||
int[] rangeDaysDeltaTolerance,
|
||||
double[] rangeDistanceTolerance,
|
||||
int[] rangeFaceAreaPermilleTolerance,
|
||||
double[] rangeFaceConfidence,
|
||||
int sortingMaximumPerFaceShouldBeHigh,
|
||||
int? useFiltersCounter = null)
|
||||
{
|
||||
_FaceConfidencePercent = faceConfidencePercent;
|
||||
_FaceDistancePermyriad = faceDistancePermyriad;
|
||||
_RangeDaysDeltaTolerance = rangeDaysDeltaTolerance;
|
||||
_RangeFaceAreaPermilleTolerance = rangeFaceAreaPermilleTolerance;
|
||||
_SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
|
||||
_RangeDaysDeltaTargetLessThenUpper = rangeDaysDeltaTolerance[1] > rangeDaysDeltaTolerance[2];
|
||||
if (useFiltersCounter is null)
|
||||
{
|
||||
_FaceAreaPermille = rangeFaceAreaPermilleTolerance[1];
|
||||
_RangeDaysDeltaTolerance = rangeDaysDeltaTolerance[1];
|
||||
_FaceConfidencePercent = faceConfidencePercent * rangeFaceConfidence[1];
|
||||
_FaceDistancePermyriad = faceDistancePermyriad * rangeDistanceTolerance[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
_RangeDaysDeltaTolerance = ((rangeDaysDeltaTolerance[2] - rangeDaysDeltaTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDaysDeltaTolerance[1];
|
||||
_FaceConfidencePercent = faceConfidencePercent * ((rangeFaceConfidence[2] - rangeFaceConfidence[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceConfidence[1];
|
||||
_FaceAreaPermille = ((rangeFaceAreaPermilleTolerance[2] - rangeFaceAreaPermilleTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceAreaPermilleTolerance[1];
|
||||
_FaceDistancePermyriad = faceDistancePermyriad * ((rangeDistanceTolerance[2] - rangeDistanceTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDistanceTolerance[1];
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveFaceDistances(Property.Models.Configuration configuration, SortingContainer[] sortingContainers)
|
||||
@ -42,118 +59,33 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
File.WriteAllLines(eDistanceContentFileName, results);
|
||||
}
|
||||
|
||||
private List<SortingContainer> GetSortingContainers(Configuration mapConfiguration, Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection, int? useFiltersCounter)
|
||||
private List<SortingContainer> GetSortingContainers(Configuration mapConfiguration, Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection)
|
||||
{
|
||||
List<SortingContainer> results = new();
|
||||
SortingContainer sortingContainer;
|
||||
Sorting[] collection = Shared.Models.Stateless.Methods.ISorting.Sort(sortingCollection);
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double faceAreaPermille;
|
||||
double faceConfidencePercent;
|
||||
double faceDistancePermyriad;
|
||||
double rangeDaysDeltaTolerance;
|
||||
if (useFiltersCounter is null)
|
||||
{
|
||||
a = 1f;
|
||||
b = 1f;
|
||||
c = 1f;
|
||||
d = 1f;
|
||||
}
|
||||
else if (useFiltersCounter.Value < 5)
|
||||
{
|
||||
a = 1.25f;
|
||||
b = 0.8f;
|
||||
c = a;
|
||||
d = b;
|
||||
}
|
||||
else if (useFiltersCounter.Value < 9)
|
||||
{
|
||||
a = 1.5f;
|
||||
b = 0.667f;
|
||||
c = a;
|
||||
d = b;
|
||||
}
|
||||
else if (useFiltersCounter.Value < 13)
|
||||
{
|
||||
a = 1.75f;
|
||||
b = 0.571f;
|
||||
c = a;
|
||||
d = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = 2f;
|
||||
b = 0.5f;
|
||||
c = a;
|
||||
d = b;
|
||||
}
|
||||
if (useFiltersCounter is null)
|
||||
{
|
||||
rangeDaysDeltaTolerance = _RangeDaysDeltaTolerance[1];
|
||||
faceDistancePermyriad = _FaceDistancePermyriad;
|
||||
faceConfidencePercent = _FaceConfidencePercent;
|
||||
faceAreaPermille = _RangeFaceAreaPermilleTolerance[1];
|
||||
}
|
||||
else if (useFiltersCounter.Value is 1 or 5 or 9 or 13)
|
||||
{
|
||||
rangeDaysDeltaTolerance = _RangeDaysDeltaTolerance[1] * a;
|
||||
faceDistancePermyriad = _FaceDistancePermyriad * c;
|
||||
faceConfidencePercent = _FaceConfidencePercent * d;
|
||||
faceAreaPermille = _RangeFaceAreaPermilleTolerance[1] * d;
|
||||
}
|
||||
else if (useFiltersCounter.Value is 2 or 6 or 10 or 14)
|
||||
{
|
||||
rangeDaysDeltaTolerance = _RangeDaysDeltaTolerance[1] * c;
|
||||
faceDistancePermyriad = _FaceDistancePermyriad * a;
|
||||
faceConfidencePercent = _FaceConfidencePercent * d;
|
||||
faceAreaPermille = _RangeFaceAreaPermilleTolerance[1] * d;
|
||||
}
|
||||
else if (useFiltersCounter.Value is 3 or 7 or 11 or 15)
|
||||
{
|
||||
rangeDaysDeltaTolerance = _RangeDaysDeltaTolerance[1] * c;
|
||||
faceDistancePermyriad = _FaceDistancePermyriad * c;
|
||||
faceConfidencePercent = _FaceConfidencePercent * b;
|
||||
faceAreaPermille = _RangeFaceAreaPermilleTolerance[1] * d;
|
||||
}
|
||||
else if (useFiltersCounter.Value is 4 or 8 or 12 or 16)
|
||||
{
|
||||
rangeDaysDeltaTolerance = _RangeDaysDeltaTolerance[1] * c;
|
||||
faceDistancePermyriad = _FaceDistancePermyriad * c;
|
||||
faceConfidencePercent = _FaceConfidencePercent * d;
|
||||
faceAreaPermille = _RangeFaceAreaPermilleTolerance[1] * b;
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeDaysDeltaTolerance = int.MaxValue;
|
||||
faceDistancePermyriad = int.MaxValue;
|
||||
faceAreaPermille = 0;
|
||||
faceConfidencePercent = 0;
|
||||
}
|
||||
foreach (Sorting sorting in collection)
|
||||
{
|
||||
if (face.Mapping is null || faceDistanceEncoding.NormalizedRectangle is null)
|
||||
if (face.Mapping?.MappingFromLocation is null || faceDistanceEncoding.NormalizedRectangle is null)
|
||||
throw new NotSupportedException();
|
||||
if (!mapConfiguration.SaveSortingWithoutPerson && face.Mapping.MappingFromPerson is null)
|
||||
continue;
|
||||
if (sorting.DaysDelta > rangeDaysDeltaTolerance)
|
||||
if (sorting.DaysDelta > _RangeDaysDeltaTolerance)
|
||||
{
|
||||
_Days += 1;
|
||||
continue;
|
||||
}
|
||||
if (sorting.DistancePermyriad > faceDistancePermyriad)
|
||||
if (sorting.DistancePermyriad > _FaceDistancePermyriad)
|
||||
{
|
||||
_Distance += 1;
|
||||
continue;
|
||||
}
|
||||
if (face.Mapping.MappingFromLocation.ConfidencePercent < faceConfidencePercent)
|
||||
if (face.Mapping.MappingFromLocation.ConfidencePercent < _FaceConfidencePercent)
|
||||
{
|
||||
_Confidence += 1;
|
||||
continue;
|
||||
}
|
||||
if (face.Mapping.MappingFromLocation.AreaPermille < faceAreaPermille)
|
||||
if (face.Mapping.MappingFromLocation.AreaPermille < _FaceAreaPermille)
|
||||
{
|
||||
_Area += 1;
|
||||
continue;
|
||||
@ -182,7 +114,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
List<FaceDistanceContainer> collection = new();
|
||||
foreach (Face face in distinctFilteredFaces)
|
||||
{
|
||||
if (face.Mapping is null)
|
||||
if (face.Mapping?.MappingFromLocation is null)
|
||||
throw new NotSupportedException();
|
||||
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
||||
continue;
|
||||
@ -212,7 +144,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
return faceDistanceEncodings;
|
||||
}
|
||||
|
||||
public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, Configuration mapConfiguration, long ticks, MapLogic mapLogic, List<Face> distinctFilteredFaces, List<FaceDistanceContainer> missingFaceDistanceContainers, int? useFiltersCounter)
|
||||
public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, Configuration mapConfiguration, long ticks, MapLogic mapLogic, List<Face> distinctFilteredFaces, List<FaceDistanceContainer> missingFaceDistanceContainers)
|
||||
{
|
||||
SortingContainer[] results;
|
||||
List<SortingContainer> collection = new();
|
||||
@ -235,7 +167,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
List<Sorting> sortingCollection = GetSortingCollection(mapLogic, faceDistanceEncodings, i, faceDistanceEncoding);
|
||||
if (!sortingCollection.Any())
|
||||
return;
|
||||
List<SortingContainer> sortingContainers = GetSortingContainers(mapConfiguration, face, faceDistanceEncoding, sortingCollection, useFiltersCounter);
|
||||
List<SortingContainer> sortingContainers = GetSortingContainers(mapConfiguration, face, faceDistanceEncoding, sortingCollection);
|
||||
if (sortingContainers.Any())
|
||||
{
|
||||
lock (collection)
|
||||
@ -246,7 +178,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
results = Array.Empty<SortingContainer>();
|
||||
else
|
||||
{
|
||||
if (_RangeDaysDeltaTolerance[1] > _RangeDaysDeltaTolerance[2])
|
||||
if (_RangeDaysDeltaTargetLessThenUpper)
|
||||
results = Shared.Models.Stateless.Methods.ISortingContainer.Sort(collection);
|
||||
else
|
||||
results = Shared.Models.Stateless.Methods.ISortingContainer.SortUsingDaysDelta(collection);
|
||||
@ -272,7 +204,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
_ = Parallel.For(0, distinctFilteredFaces.Count, parallelOptions, (i, state) =>
|
||||
{
|
||||
Face face = distinctFilteredFaces[i];
|
||||
if (face.FaceEncoding is null || face.Mapping is null)
|
||||
if (face.FaceEncoding is null || face.Mapping?.MappingFromLocation is null)
|
||||
throw new NotSupportedException();
|
||||
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
||||
return;
|
||||
@ -284,62 +216,14 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
});
|
||||
}
|
||||
|
||||
void Shared.Models.Methods.IMapLogicSupport.SavePossiblyNewPersonContainers(IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension, string? a2PeopleSingletonDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||
{
|
||||
string json;
|
||||
string[] files;
|
||||
string checkFile;
|
||||
string[] segments;
|
||||
const int zero = 0;
|
||||
char personCharacter;
|
||||
string personKeyFormatted;
|
||||
string personDisplayDirectory;
|
||||
PersonBirthday personBirthday;
|
||||
string personDisplayDirectoryName;
|
||||
string checkPersonDisplayDirectory;
|
||||
string checkPersonKeyFormattedDirectory;
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
|
||||
foreach ((string[] personDisplayDirectoryNames, PersonContainer personContainer) in possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||
{
|
||||
if (a2PeopleSingletonDirectory is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
|
||||
continue;
|
||||
personBirthday = personContainer.Birthdays[zero];
|
||||
personDisplayDirectoryName = personDisplayDirectoryNames[^1];
|
||||
personDisplayDirectory = Path.Combine(personDisplayDirectoryNames);
|
||||
personKeyFormatted = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthdayFormat, personBirthday);
|
||||
segments = personDisplayDirectoryName.Split(personCharacters);
|
||||
if (segments.Length != 2)
|
||||
personCharacter = '_';
|
||||
else
|
||||
personCharacter = personDisplayDirectoryName[segments[zero].Length];
|
||||
checkPersonDisplayDirectory = Path.Combine(a2PeopleSingletonDirectory, personCharacter.ToString(), personDisplayDirectoryName);
|
||||
checkPersonKeyFormattedDirectory = Path.Combine(checkPersonDisplayDirectory, personKeyFormatted);
|
||||
if (Directory.Exists(checkPersonKeyFormattedDirectory))
|
||||
continue;
|
||||
_ = Directory.CreateDirectory(checkPersonKeyFormattedDirectory);
|
||||
checkFile = Path.Combine(checkPersonKeyFormattedDirectory, $"{personKeyFormatted}.json");
|
||||
json = JsonSerializer.Serialize(personContainer.Person, jsonSerializerOptions);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||
if (!Directory.Exists(personDisplayDirectory))
|
||||
continue;
|
||||
files = Directory.GetFiles(personDisplayDirectory, $"*{facesFileNameExtension}", SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
checkFile = Path.Combine(checkPersonDisplayDirectory, Path.GetFileName(file));
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
File.Copy(files[0], checkFile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<int, Dictionary<int, Mapping>> GetIdToNormalizedRectangleToFace(Mapping[] mappingCollection)
|
||||
{
|
||||
Dictionary<int, Dictionary<int, Mapping>> results = new();
|
||||
Dictionary<int, Mapping>? keyValuePairs;
|
||||
foreach (Mapping mapping in mappingCollection)
|
||||
{
|
||||
if (mapping.MappingFromLocation is null)
|
||||
continue;
|
||||
if (!results.TryGetValue(mapping.MappingFromItem.Id, out keyValuePairs))
|
||||
{
|
||||
results.Add(mapping.MappingFromItem.Id, new());
|
||||
|
Reference in New Issue
Block a user