Face Distance Area Permille Tolerance

This commit is contained in:
Mike Phares 2022-09-27 15:50:52 -07:00
parent abe6c80d82
commit 152612bacb
17 changed files with 115 additions and 10 deletions

View File

@ -22,6 +22,7 @@
"Niépce", "Niépce",
"nosj", "nosj",
"paramref", "paramref",
"permille",
"permyriad", "permyriad",
"Phares", "Phares",
"Phgtv", "Phgtv",

View File

@ -18,9 +18,10 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
private readonly bool _DistanceMoveUnableToMatch; private readonly bool _DistanceMoveUnableToMatch;
private readonly int _DistancePixelDistanceTolerance; private readonly int _DistancePixelDistanceTolerance;
private readonly double _FaceDistanceMinimumConfidence; private readonly double _FaceDistanceMinimumConfidence;
private readonly int _FaceDistanceAreaPermilleTolerance;
private readonly int _SortingMaximumPerFaceShouldBeHigh; private readonly int _SortingMaximumPerFaceShouldBeHigh;
public E_Distance(bool distanceMoveUnableToMatch, int distancePixelDistanceTolerance, double faceDistanceMinimumConfidence, int faceDistancePermyriad, double faceDistanceTolerance, string resultAllInOne, int sortingDaysDeltaTolerance, int sortingMaximumPerFaceShouldBeHigh) public E_Distance(bool distanceMoveUnableToMatch, int distancePixelDistanceTolerance, int faceDistanceAreaPermilleTolerance, double faceDistanceMinimumConfidence, int faceDistancePermyriad, double faceDistanceTolerance, string resultAllInOne, int sortingDaysDeltaTolerance, int sortingMaximumPerFaceShouldBeHigh)
{ {
_ResultAllInOne = resultAllInOne; _ResultAllInOne = resultAllInOne;
_Log = Serilog.Log.ForContext<E_Distance>(); _Log = Serilog.Log.ForContext<E_Distance>();
@ -30,6 +31,7 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
_SortingDaysDeltaTolerance = sortingDaysDeltaTolerance; _SortingDaysDeltaTolerance = sortingDaysDeltaTolerance;
_FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence; _FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
_DistancePixelDistanceTolerance = distancePixelDistanceTolerance; _DistancePixelDistanceTolerance = distancePixelDistanceTolerance;
_FaceDistanceAreaPermilleTolerance = faceDistanceAreaPermilleTolerance;
_SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh; _SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
} }
@ -63,77 +65,89 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
double faceDistancePermyriad; double faceDistancePermyriad;
double sortingDaysDeltaTolerance; double sortingDaysDeltaTolerance;
double faceDistanceMinimumConfidence; double faceDistanceMinimumConfidence;
double faceDistanceAreaPermilleTolerance;
if (useFiltersCounter is null) if (useFiltersCounter is null)
{ {
sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance; sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance;
faceDistancePermyriad = _FaceDistancePermyriad; faceDistancePermyriad = _FaceDistancePermyriad;
faceDistanceAreaPermilleTolerance = _FaceDistanceAreaPermilleTolerance;
faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence; faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence;
} }
else if (useFiltersCounter.Value == 1) else if (useFiltersCounter.Value == 1)
{ {
sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 1.5; sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 1.5;
faceDistancePermyriad = _FaceDistancePermyriad; faceDistancePermyriad = _FaceDistancePermyriad;
faceDistanceAreaPermilleTolerance = _FaceDistanceAreaPermilleTolerance;
faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence; faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence;
} }
else if (useFiltersCounter.Value == 2) else if (useFiltersCounter.Value == 2)
{ {
sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance; sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance;
faceDistancePermyriad = _FaceDistancePermyriad * 1.5; faceDistancePermyriad = _FaceDistancePermyriad * 1.5;
faceDistanceAreaPermilleTolerance = _FaceDistanceAreaPermilleTolerance;
faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence; faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence;
} }
else if (useFiltersCounter.Value == 3) else if (useFiltersCounter.Value == 3)
{ {
sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance; sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance;
faceDistancePermyriad = _FaceDistancePermyriad; faceDistancePermyriad = _FaceDistancePermyriad;
faceDistanceAreaPermilleTolerance = _FaceDistanceAreaPermilleTolerance;
faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .5; faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .5;
} }
else if (useFiltersCounter.Value == 4) else if (useFiltersCounter.Value == 4)
{ {
sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 2; sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 2;
faceDistancePermyriad = _FaceDistancePermyriad * 1.5; faceDistancePermyriad = _FaceDistancePermyriad * 1.5;
faceDistanceAreaPermilleTolerance = _FaceDistanceAreaPermilleTolerance;
faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .5; faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .5;
} }
else if (useFiltersCounter.Value == 5) else if (useFiltersCounter.Value == 5)
{ {
sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 1.5; sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 1.5;
faceDistancePermyriad = _FaceDistancePermyriad * 2; faceDistancePermyriad = _FaceDistancePermyriad * 2;
faceDistanceAreaPermilleTolerance = _FaceDistanceAreaPermilleTolerance;
faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .5; faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .5;
} }
else if (useFiltersCounter.Value == 6) else if (useFiltersCounter.Value == 6)
{ {
sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 1.5; sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 1.5;
faceDistancePermyriad = _FaceDistancePermyriad * 1.5; faceDistancePermyriad = _FaceDistancePermyriad * 1.5;
faceDistanceAreaPermilleTolerance = _FaceDistanceAreaPermilleTolerance;
faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .25; faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .25;
} }
else if (useFiltersCounter.Value == 7) else if (useFiltersCounter.Value == 7)
{ {
sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 2.5; sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 2.5;
faceDistancePermyriad = _FaceDistancePermyriad * 2; faceDistancePermyriad = _FaceDistancePermyriad * 2;
faceDistanceAreaPermilleTolerance = _FaceDistanceAreaPermilleTolerance;
faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .25; faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .25;
} }
else if (useFiltersCounter.Value == 8) else if (useFiltersCounter.Value == 8)
{ {
sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 2; sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 2;
faceDistancePermyriad = _FaceDistancePermyriad * 2.5; faceDistancePermyriad = _FaceDistancePermyriad * 2.5;
faceDistanceAreaPermilleTolerance = _FaceDistanceAreaPermilleTolerance;
faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .25; faceDistanceMinimumConfidence = _FaceDistanceMinimumConfidence * .25;
} }
else if (useFiltersCounter.Value == 9) else if (useFiltersCounter.Value == 9)
{ {
sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 2; sortingDaysDeltaTolerance = _SortingDaysDeltaTolerance * 2;
faceDistancePermyriad = _FaceDistancePermyriad * 2; faceDistancePermyriad = _FaceDistancePermyriad * 2;
faceDistanceAreaPermilleTolerance = _FaceDistanceAreaPermilleTolerance;
faceDistanceMinimumConfidence = 0; faceDistanceMinimumConfidence = 0;
} }
else else
{ {
sortingDaysDeltaTolerance = int.MaxValue; sortingDaysDeltaTolerance = int.MaxValue;
faceDistancePermyriad = int.MaxValue; faceDistancePermyriad = int.MaxValue;
faceDistanceAreaPermilleTolerance = 0;
faceDistanceMinimumConfidence = 0; faceDistanceMinimumConfidence = 0;
} }
foreach (Sorting sorting in collection) foreach (Sorting sorting in collection)
{ {
if (face.Mapping is null || faceDistanceEncoding.NormalizedPixelPercentage is null) if (face.Mapping is null || faceDistanceEncoding.NormalizedPixelPercentage is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (sorting.DaysDelta > sortingDaysDeltaTolerance || sorting.DistancePermyriad > faceDistancePermyriad || face.Mapping.MappingFromLocation.Confidence < faceDistanceMinimumConfidence) if (sorting.DaysDelta > sortingDaysDeltaTolerance || sorting.DistancePermyriad > faceDistancePermyriad || face.Mapping.MappingFromLocation.Confidence < faceDistanceMinimumConfidence || face.Mapping.MappingFromLocation.AreaPermille < faceDistanceAreaPermilleTolerance)
continue; continue;
sortingContainer = new(face, sorting); sortingContainer = new(face, sorting);
results.Add(sortingContainer); results.Add(sortingContainer);
@ -433,7 +447,7 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
return results; return results;
} }
private static List<(Face Face, double Length)> GetValues(double faceDistanceTolerance, MappingFromItem mappingFromItem, List<Face> faces, string json) private List<(Face Face, double Length)> GetValues(MappingFromItem mappingFromItem, List<Face> faces, string json)
{ {
List<(Face Face, double Length)> results = new(); List<(Face Face, double Length)> results = new();
Face face; Face face;
@ -459,17 +473,17 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
faceDistanceLength = faceDistanceLengths[i]; faceDistanceLength = faceDistanceLengths[i];
if (faceDistanceLength.Length is null) if (faceDistanceLength.Length is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (faceDistanceLength.Length.Value > faceDistanceTolerance) if (faceDistanceLength.Length.Value > _FaceDistanceTolerance)
continue; continue;
results.Add(new(face, faceDistanceLength.Length.Value)); results.Add(new(face, faceDistanceLength.Length.Value));
} }
return results; return results;
} }
private static Face[] GetMatchingFaces(double faceDistanceTolerance, MappingFromItem mappingFromItem, List<Face> faces, string json) private Face[] GetMatchingFaces(MappingFromItem mappingFromItem, List<Face> faces, string json)
{ {
Face[] results; Face[] results;
List<(Face Face, double Length)> collection = GetValues(faceDistanceTolerance, mappingFromItem, faces, json); List<(Face Face, double Length)> collection = GetValues(mappingFromItem, faces, json);
if (!collection.Any()) if (!collection.Any())
results = Array.Empty<Face>(); results = Array.Empty<Face>();
else else
@ -623,7 +637,7 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
checkFaces.Clear(); checkFaces.Clear();
if (json is null) if (json is null)
throw new NotSupportedException(); throw new NotSupportedException();
checkFaces.AddRange(GetMatchingFaces(_FaceDistanceTolerance, mappingFromItem, faces, json)); checkFaces.AddRange(GetMatchingFaces(mappingFromItem, faces, json));
} }
if (checkFaces.Count != 1 && _DistancePixelDistanceTolerance > 0) if (checkFaces.Count != 1 && _DistancePixelDistanceTolerance > 0)
{ {

View File

@ -34,6 +34,7 @@ public class D_Face
private readonly bool _RetryImagesWithoutAFace; private readonly bool _RetryImagesWithoutAFace;
private readonly Configuration _Configuration; private readonly Configuration _Configuration;
private readonly int _NumberOfTimesToUpsample; private readonly int _NumberOfTimesToUpsample;
private readonly int _FaceDistanceAreaPermilleTolerance;
private readonly ImageCodecInfo _ImageCodecInfo; private readonly ImageCodecInfo _ImageCodecInfo;
private readonly ModelParameter _ModelParameter; private readonly ModelParameter _ModelParameter;
private readonly PredictorModel _PredictorModel; private readonly PredictorModel _PredictorModel;
@ -52,6 +53,7 @@ public class D_Face
bool checkDFaceAndUpWriteDates, bool checkDFaceAndUpWriteDates,
Configuration configuration, Configuration configuration,
EncoderParameters encoderParameters, EncoderParameters encoderParameters,
int faceDistanceAreaPermilleTolerance,
int faceDistanceHiddenImageFactor, int faceDistanceHiddenImageFactor,
string filenameExtension, string filenameExtension,
bool forceFaceLastWriteTimeToCreationTime, bool forceFaceLastWriteTimeToCreationTime,
@ -87,6 +89,7 @@ public class D_Face
_NumberOfTimesToUpsample = numberOfTimesToUpsample; _NumberOfTimesToUpsample = numberOfTimesToUpsample;
_CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates; _CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
_PropertiesChangedForFaces = propertiesChangedForFaces; _PropertiesChangedForFaces = propertiesChangedForFaces;
_FaceDistanceAreaPermilleTolerance = faceDistanceAreaPermilleTolerance;
_FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor; _FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
_ForceFaceLastWriteTimeToCreationTime = forceFaceLastWriteTimeToCreationTime; _ForceFaceLastWriteTimeToCreationTime = forceFaceLastWriteTimeToCreationTime;
ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null); ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null);

View File

@ -75,6 +75,7 @@ public partial class DlibDotNet
_Distance = new( _Distance = new(
configuration.DistanceMoveUnableToMatch, configuration.DistanceMoveUnableToMatch,
configuration.DistancePixelDistanceTolerance, configuration.DistancePixelDistanceTolerance,
configuration.FaceDistanceAreaPermilleTolerance,
configuration.FaceDistanceMinimumConfidence, configuration.FaceDistanceMinimumConfidence,
configuration.FaceDistancePermyriad, configuration.FaceDistancePermyriad,
configuration.FaceDistanceTolerance, configuration.FaceDistanceTolerance,
@ -98,6 +99,7 @@ public partial class DlibDotNet
configuration.CheckDFaceAndUpWriteDates, configuration.CheckDFaceAndUpWriteDates,
configuration.PropertyConfiguration, configuration.PropertyConfiguration,
encoderParameters, encoderParameters,
configuration.FaceDistanceAreaPermilleTolerance,
configuration.FaceDistanceHiddenImageFactor, configuration.FaceDistanceHiddenImageFactor,
filenameExtension, filenameExtension,
configuration.ForceFaceLastWriteTimeToCreationTime, configuration.ForceFaceLastWriteTimeToCreationTime,
@ -324,6 +326,7 @@ public partial class DlibDotNet
private static Map.Models.Configuration Get(Models.Configuration configuration) private static Map.Models.Configuration Get(Models.Configuration configuration)
{ {
Map.Models.Configuration result = new( Map.Models.Configuration result = new(
configuration.FaceDistanceAreaPermilleTolerance,
configuration.FaceDistanceHiddenImageFactor, configuration.FaceDistanceHiddenImageFactor,
configuration.FaceDistancePermyriad, configuration.FaceDistancePermyriad,
configuration.FaceDistanceMinimumConfidence, configuration.FaceDistanceMinimumConfidence,
@ -843,6 +846,7 @@ public partial class DlibDotNet
{ {
List<Shared.Models.Face> results = new(); List<Shared.Models.Face> results = new();
Mapping mapping; Mapping mapping;
int areaPermille;
bool? isWrongYear; bool? isWrongYear;
Item[] filteredItems; Item[] filteredItems;
DateTime minimumDateTime; DateTime minimumDateTime;
@ -875,10 +879,11 @@ public partial class DlibDotNet
break; break;
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
continue; continue;
areaPermille = Shared.Models.Stateless.Methods.IMapping.GetAreaPermille(face.Location, face.OutputResolution);
mappingFromPerson = new(approximateYears: null, by: null, displayDirectoryName: string.Empty, personBirthday: null, segmentB: string.Empty); mappingFromPerson = new(approximateYears: null, by: null, displayDirectoryName: string.Empty, personBirthday: null, segmentB: string.Empty);
normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution); 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); 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); mappingFromLocation = new(areaPermille, face.Location.Confidence, deterministicHashCodeKey, normalizedPixelPercentage);
mapping = new(mappingFromItem, mappingFromLocation, mappingFromPerson); mapping = new(mappingFromItem, mappingFromLocation, mappingFromPerson);
face.SetMapping(mapping); face.SetMapping(mapping);
results.Add(face); results.Add(face);

View File

@ -16,6 +16,7 @@ public class Configuration
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; } [Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
[Display(Name = "Distance Move Unable to Match by 1 Tick"), Required] public bool? DistanceMoveUnableToMatch { get; set; } [Display(Name = "Distance 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 = "Distance Pixel Distance Tolerance"), Required] public int? DistancePixelDistanceTolerance { get; set; }
[Display(Name = "Face Area Permille Tolerance"), Required] public int? FaceDistanceAreaPermilleTolerance { get; set; }
[Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; } [Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; }
[Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; } [Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; }
[Display(Name = "Face Distance Permyriad"), Required] public int? FaceDistancePermyriad { get; set; } [Display(Name = "Face Distance Permyriad"), Required] public int? FaceDistancePermyriad { get; set; }
@ -99,6 +100,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.DistanceMoveUnableToMatch)); throw new NullReferenceException(nameof(configuration.DistanceMoveUnableToMatch));
if (configuration.DistancePixelDistanceTolerance is null) if (configuration.DistancePixelDistanceTolerance is null)
throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance)); throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance));
if (configuration.FaceDistanceAreaPermilleTolerance is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceAreaPermilleTolerance));
if (configuration.FaceDistanceHiddenImageFactor is null) if (configuration.FaceDistanceHiddenImageFactor is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor)); throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor));
if (configuration.FaceDistanceMinimumConfidence is null) if (configuration.FaceDistanceMinimumConfidence is null)
@ -220,6 +223,7 @@ public class Configuration
configuration.DistanceFactor.Value, configuration.DistanceFactor.Value,
configuration.DistanceMoveUnableToMatch.Value, configuration.DistanceMoveUnableToMatch.Value,
configuration.DistancePixelDistanceTolerance.Value, configuration.DistancePixelDistanceTolerance.Value,
configuration.FaceDistanceAreaPermilleTolerance.Value,
configuration.FaceDistanceHiddenImageFactor.Value, configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value, configuration.FaceDistanceMinimumConfidence.Value,
configuration.FaceDistancePermyriad.Value, configuration.FaceDistancePermyriad.Value,

View File

@ -15,6 +15,7 @@ public class Configuration
public int DistanceFactor { init; get; } public int DistanceFactor { init; get; }
public bool DistanceMoveUnableToMatch { init; get; } public bool DistanceMoveUnableToMatch { init; get; }
public int DistancePixelDistanceTolerance { init; get; } public int DistancePixelDistanceTolerance { init; get; }
public int FaceDistanceAreaPermilleTolerance { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; } public int FaceDistanceHiddenImageFactor { init; get; }
public double FaceDistanceMinimumConfidence { init; get; } public double FaceDistanceMinimumConfidence { init; get; }
public int FaceDistancePermyriad { init; get; } public int FaceDistancePermyriad { init; get; }
@ -82,6 +83,7 @@ public class Configuration
int distanceFactor, int distanceFactor,
bool distanceMoveUnableToMatch, bool distanceMoveUnableToMatch,
int distancePixelDistanceTolerance, int distancePixelDistanceTolerance,
int faceDistanceAreaPermilleTolerance,
int faceDistanceHiddenImageFactor, int faceDistanceHiddenImageFactor,
double faceDistanceMinimumConfidence, double faceDistanceMinimumConfidence,
int faceDistancePermyriad, int faceDistancePermyriad,
@ -148,6 +150,7 @@ public class Configuration
DistanceFactor = distanceFactor; DistanceFactor = distanceFactor;
DistanceMoveUnableToMatch = distanceMoveUnableToMatch; DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
DistancePixelDistanceTolerance = distancePixelDistanceTolerance; DistancePixelDistanceTolerance = distancePixelDistanceTolerance;
FaceDistanceAreaPermilleTolerance = faceDistanceAreaPermilleTolerance;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor; FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence; FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
FaceDistancePermyriad = faceDistancePermyriad; FaceDistancePermyriad = faceDistancePermyriad;

View File

@ -57,6 +57,7 @@
"DistanceFactor": 8, "DistanceFactor": 8,
"DistanceMoveUnableToMatch": false, "DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1, "DistancePixelDistanceTolerance": 1,
"FaceDistanceAreaPermilleTolerance": 250,
"FaceDistanceHiddenImageFactor": 2, "FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8, "FaceDistanceMinimumConfidence": 0.8,
"FaceDistancePermyriad": 10000, "FaceDistancePermyriad": 10000,

View File

@ -57,6 +57,7 @@
"DistanceFactor": 8, "DistanceFactor": 8,
"DistanceMoveUnableToMatch": false, "DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1, "DistancePixelDistanceTolerance": 1,
"FaceDistanceAreaPermilleTolerance": 250,
"FaceDistanceHiddenImageFactor": 2, "FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8, "FaceDistanceMinimumConfidence": 0.8,
"FaceDistancePermyriad": 10000, "FaceDistancePermyriad": 10000,

View File

@ -57,6 +57,7 @@
"DistanceFactor": 8, "DistanceFactor": 8,
"DistanceMoveUnableToMatch": false, "DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1, "DistancePixelDistanceTolerance": 1,
"FaceDistanceAreaPermilleTolerance": 250,
"FaceDistanceHiddenImageFactor": 2, "FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8, "FaceDistanceMinimumConfidence": 0.8,
"FaceDistancePermyriad": 10000, "FaceDistancePermyriad": 10000,

View File

@ -6,6 +6,7 @@ namespace View_by_Distance.Map.Models;
public class Configuration public class Configuration
{ {
public int FaceDistanceAreaPermilleTolerance { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; } public int FaceDistanceHiddenImageFactor { init; get; }
public int FaceDistancePermyriad { init; get; } public int FaceDistancePermyriad { init; get; }
public double FaceDistanceMinimumConfidence { init; get; } public double FaceDistanceMinimumConfidence { init; get; }
@ -26,7 +27,8 @@ public class Configuration
public int SortingSigma { init; get; } public int SortingSigma { init; get; }
[JsonConstructor] [JsonConstructor]
public Configuration(int faceDistanceHiddenImageFactor, public Configuration(int faceDistanceAreaPermilleTolerance,
int faceDistanceHiddenImageFactor,
int faceDistancePermyriad, int faceDistancePermyriad,
double faceDistanceMinimumConfidence, double faceDistanceMinimumConfidence,
double faceDistanceTolerance, double faceDistanceTolerance,
@ -45,6 +47,7 @@ public class Configuration
int sortingMaximumPerKey, int sortingMaximumPerKey,
int sortingSigma) int sortingSigma)
{ {
FaceDistanceAreaPermilleTolerance = faceDistanceAreaPermilleTolerance;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor; FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistancePermyriad = faceDistancePermyriad; FaceDistancePermyriad = faceDistancePermyriad;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence; FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;

View File

@ -35,13 +35,15 @@ public class MappingFromItem : Properties.IMappingFromItem
public class MappingFromLocation : Properties.IMappingFromLocation public class MappingFromLocation : Properties.IMappingFromLocation
{ {
public double AreaPermille { init; get; }
public double Confidence { init; get; } public double Confidence { init; get; }
public string DeterministicHashCodeKey { init; get; } public string DeterministicHashCodeKey { init; get; }
public int NormalizedPixelPercentage { init; get; } public int NormalizedPixelPercentage { init; get; }
[JsonConstructor] [JsonConstructor]
public MappingFromLocation(double confidence, string deterministicHashCodeKey, int normalizedPixelPercentage) public MappingFromLocation(int areaPermille, double confidence, string deterministicHashCodeKey, int normalizedPixelPercentage)
{ {
AreaPermille = areaPermille;
Confidence = confidence; Confidence = confidence;
DeterministicHashCodeKey = deterministicHashCodeKey; DeterministicHashCodeKey = deterministicHashCodeKey;
NormalizedPixelPercentage = normalizedPixelPercentage; NormalizedPixelPercentage = normalizedPixelPercentage;

View File

@ -15,6 +15,7 @@ public interface IMappingFromItem
public interface IMappingFromLocation public interface IMappingFromLocation
{ {
public double AreaPermille { init; get; }
public double Confidence { init; get; } public double Confidence { init; get; }
public string DeterministicHashCodeKey { init; get; } public string DeterministicHashCodeKey { init; get; }
public int NormalizedPixelPercentage { init; get; } public int NormalizedPixelPercentage { init; get; }

View File

@ -8,6 +8,21 @@ public interface IMapping
static (string?, string?, string?, bool?) GetSegments(string facesFileNameExtension, string fileName) static (string?, string?, string?, bool?) GetSegments(string facesFileNameExtension, string fileName)
=> Mapping.GetSegments(facesFileNameExtension, fileName); => Mapping.GetSegments(facesFileNameExtension, fileName);
int TestStatic_GetAreaPermille(int height, Models.Location location, int width)
=> GetAreaPermille(height, location, width);
static int GetAreaPermille(int height, Models.Location location, int width)
=> Mapping.GetAreaPermille(location.Bottom, height, location.Left, location.Right, location.Top, width);
int TestStatic_GetAreaPermille(int bottom, int height, int left, int right, int top, int width)
=> GetAreaPermille(bottom, height, left, right, top, width);
static int GetAreaPermille(int bottom, int height, int left, int right, int top, int width)
=> Mapping.GetAreaPermille(bottom, height, left, right, top, width);
int TestStatic_GetAreaPermille(Models.Location location, OutputResolution outputResolution)
=> GetAreaPermille(location, outputResolution);
static int GetAreaPermille(Models.Location location, OutputResolution outputResolution)
=> Mapping.GetAreaPermille(location.Bottom, outputResolution.Height, location.Left, location.Right, location.Top, outputResolution.Width);
string TestStatic_GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution) string TestStatic_GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution)
=> GetDeterministicHashCodeKey(id, location, locationDigits, locationFactor, outputResolution); => GetDeterministicHashCodeKey(id, location, locationDigits, locationFactor, outputResolution);
static string GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution) static string GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution)

View File

@ -78,4 +78,13 @@ internal abstract class Mapping
return new(id, normalizedPixelPercentage, faces); return new(id, normalizedPixelPercentage, faces);
} }
internal static int GetAreaPermille(int bottom, int height, int left, int right, int top, int width)
{
int result;
double area = width * height;
double locationArea = (right - left) * (bottom - top);
result = (int)Math.Round(locationArea / area * 1000, 0);
return result;
}
} }

View File

@ -203,6 +203,41 @@ public class UnitTestCalculations
_ = new Location(bottom, confidence, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width, 1); _ = new Location(bottom, confidence, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width, 1);
} }
[TestMethod]
public void TestAreaPermille()
{
Location location;
double confidence = 0.1D;
int areaPermille, left, top, right, bottom, width, height;
left = 0;
right = 100;
top = 0;
bottom = 100;
width = 100;
height = 100;
areaPermille = IMapping.GetAreaPermille(bottom, height, left, right, top, width);
Assert.IsTrue(areaPermille == 1000);
left = 0;
right = 50;
top = 0;
bottom = 50;
width = 100;
height = 100;
location = new(bottom, confidence, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width, 1);
areaPermille = IMapping.GetAreaPermille(height, location, width);
Assert.IsTrue(areaPermille == 250);
left = 0;
right = 25;
top = 0;
bottom = 25;
width = 100;
height = 100;
location = new(bottom, confidence, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width, 1);
OutputResolution outputResolution = new(height, 0, width);
areaPermille = IMapping.GetAreaPermille(location, outputResolution);
Assert.IsTrue(areaPermille == 62);
}
[TestMethod] [TestMethod]
public void TestGetPixelPercentageA() public void TestGetPixelPercentageA()
{ {

View File

@ -16,6 +16,7 @@ public class Configuration
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; } [Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
[Display(Name = "Distance Move Unable to Match by 1 Tick"), Required] public bool? DistanceMoveUnableToMatch { get; set; } [Display(Name = "Distance 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 = "Distance Pixel Distance Tolerance"), Required] public int? DistancePixelDistanceTolerance { get; set; }
[Display(Name = "Face Area Permille Tolerance"), Required] public int? FaceDistanceAreaPermilleTolerance { get; set; }
[Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; } [Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; }
[Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; } [Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; }
[Display(Name = "Face Distance Permyriad"), Required] public int? FaceDistancePermyriad { get; set; } [Display(Name = "Face Distance Permyriad"), Required] public int? FaceDistancePermyriad { get; set; }
@ -99,6 +100,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.DistanceMoveUnableToMatch)); throw new NullReferenceException(nameof(configuration.DistanceMoveUnableToMatch));
if (configuration.DistancePixelDistanceTolerance is null) if (configuration.DistancePixelDistanceTolerance is null)
throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance)); throw new NullReferenceException(nameof(configuration.DistancePixelDistanceTolerance));
if (configuration.FaceDistanceAreaPermilleTolerance is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceAreaPermilleTolerance));
if (configuration.FaceDistanceHiddenImageFactor is null) if (configuration.FaceDistanceHiddenImageFactor is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor)); throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor));
if (configuration.FaceDistanceMinimumConfidence is null) if (configuration.FaceDistanceMinimumConfidence is null)
@ -220,6 +223,7 @@ public class Configuration
configuration.DistanceFactor.Value, configuration.DistanceFactor.Value,
configuration.DistanceMoveUnableToMatch.Value, configuration.DistanceMoveUnableToMatch.Value,
configuration.DistancePixelDistanceTolerance.Value, configuration.DistancePixelDistanceTolerance.Value,
configuration.FaceDistanceAreaPermilleTolerance.Value,
configuration.FaceDistanceHiddenImageFactor.Value, configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value, configuration.FaceDistanceMinimumConfidence.Value,
configuration.FaceDistancePermyriad.Value, configuration.FaceDistancePermyriad.Value,

View File

@ -15,6 +15,7 @@ public class Configuration
public int DistanceFactor { init; get; } public int DistanceFactor { init; get; }
public bool DistanceMoveUnableToMatch { init; get; } public bool DistanceMoveUnableToMatch { init; get; }
public int DistancePixelDistanceTolerance { init; get; } public int DistancePixelDistanceTolerance { init; get; }
public int FaceDistanceAreaPermilleTolerance { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; } public int FaceDistanceHiddenImageFactor { init; get; }
public double FaceDistanceMinimumConfidence { init; get; } public double FaceDistanceMinimumConfidence { init; get; }
public int FaceDistancePermyriad { init; get; } public int FaceDistancePermyriad { init; get; }
@ -82,6 +83,7 @@ public class Configuration
int distanceFactor, int distanceFactor,
bool distanceMoveUnableToMatch, bool distanceMoveUnableToMatch,
int distancePixelDistanceTolerance, int distancePixelDistanceTolerance,
int faceDistanceAreaPermilleTolerance,
int faceDistanceHiddenImageFactor, int faceDistanceHiddenImageFactor,
double faceDistanceMinimumConfidence, double faceDistanceMinimumConfidence,
int faceDistancePermyriad, int faceDistancePermyriad,
@ -148,6 +150,7 @@ public class Configuration
DistanceFactor = distanceFactor; DistanceFactor = distanceFactor;
DistanceMoveUnableToMatch = distanceMoveUnableToMatch; DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
DistancePixelDistanceTolerance = distancePixelDistanceTolerance; DistancePixelDistanceTolerance = distancePixelDistanceTolerance;
FaceDistanceAreaPermilleTolerance = faceDistanceAreaPermilleTolerance;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor; FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence; FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
FaceDistancePermyriad = faceDistancePermyriad; FaceDistancePermyriad = faceDistancePermyriad;