Change to support 7680 x 4320 and

Configuration additions
This commit is contained in:
Mike Phares 2022-09-16 21:05:34 -07:00
parent deff6f484c
commit c86ad38455
40 changed files with 1153 additions and 454 deletions

16
.vscode/launch.json vendored
View File

@ -42,18 +42,4 @@
// Get id in normal fashion
// If id is in collection update collection to new path/name
// If not save and add to collection
// Nicéphore Niépce in 1826 or 182
// Stateless.ILocation.Digits
// locationDigits
// Stateless.ILocation.Factor
// locationFactor
// Stateless.IFaceDistance.Tolerance
// faceDistanceTolerance
// Stateless.IFaceDistance.Permyriad
// faceDistancePermyriad
// Stateless.IPersonBirthday.FirstYear
// personBirthdayFirstYear
// Stateless.IPersonBirthday.Format
// personBirthdayFormat
// Stateless.IPerson.KeyFormat
// personKeyFormat
// Nicéphore Niépce in 1826 or 182

View File

@ -76,20 +76,6 @@ public class FaceRecognition : DisposableObject
return results.ToArray();
}
private static Location TrimBound(double detectionConfidence, DlibDotNet.Rectangle rectangle, int width, int height, int facesCount) =>
new(
Math.Min(rectangle.Bottom, height),
detectionConfidence,
height,
Math.Max(rectangle.Left, 0),
ILocation.Digits,
ILocation.Factor,
Math.Min(rectangle.Right, width),
Math.Max(rectangle.Top, 0),
width,
facesCount
);
private List<(FacePart, FacePoint[])> GetFaceParts(FullObjectDetection fullObjectDetection)
{
List<(FacePart, FacePoint[])> results = new();
@ -155,11 +141,13 @@ public class FaceRecognition : DisposableObject
image.ThrowIfDisposed();
ThrowIfDisposed();
List<Location> results = new();
IEnumerable<MModRect> faces = GetMModRects(image);
foreach (MModRect? face in faces)
System.Drawing.Rectangle rectangle;
IEnumerable<MModRect> mModRects = GetMModRects(image);
foreach (MModRect? mModRect in mModRects)
{
Location location = TrimBound(face.DetectionConfidence, face.Rect, image.Width, image.Height, faces.Count());
face.Dispose();
rectangle = new(mModRect.Rect.Left, mModRect.Rect.Top, (int)mModRect.Rect.Width, (int)mModRect.Rect.Height);
Location location = Shared.Models.Stateless.Methods.ILocation.TrimBound(mModRect.DetectionConfidence, rectangle, image.Width, image.Height, mModRects.Count());
mModRect.Dispose();
results.Add(location);
}
if (sortByNormalizedPixelPercentage)
@ -206,9 +194,11 @@ public class FaceRecognition : DisposableObject
if (mModRects.Any())
{
Location location;
System.Drawing.Rectangle rectangle;
foreach (MModRect? mModRect in mModRects)
{
location = TrimBound(mModRect.DetectionConfidence, mModRect.Rect, image.Width, image.Height, mModRects.Length);
rectangle = new(mModRect.Rect.Left, mModRect.Rect.Top, (int)mModRect.Rect.Width, (int)mModRect.Rect.Height);
location = Shared.Models.Stateless.Methods.ILocation.TrimBound(mModRect.DetectionConfidence, rectangle, image.Width, image.Height, mModRects.Length);
mModRect.Dispose();
results.Add(location);
}

View File

@ -93,7 +93,7 @@ public partial class DlibDotNet
_Resize = new C_Resize(configuration.ForceResizeLastWriteTimeToCreationTime, configuration.OverrideForResizeImages, configuration.PropertiesChangedForResize, configuration.ValidResolutions, imageCodecInfo, encoderParameters, filenameExtension);
}
if (!configuration.SkipSearch)
Search(propertyConfiguration, model, predictorModel, argZero, propertyRoot, people);
Search(model, predictorModel, argZero, propertyRoot, people);
if (!_FirstRun && _Exceptions.Count == 0 && _ArgZeroIsConfigurationRootDirectory)
{
long ticks = DateTime.Now.Ticks;
@ -248,6 +248,10 @@ public partial class DlibDotNet
string[] resizeMatch = (from l in sourceDirectoryNames where configuration.ValidResolutions.Contains(l) select l).ToArray();
if (resizeMatch.Any())
throw new Exception("Input directory should be the source and not a resized directory!");
if (configuration.LocationDigits != Shared.Models.Stateless.ILocation.Digits)
throw new Exception("Configuration has to match interface!");
if (configuration.LocationFactor != Shared.Models.Stateless.ILocation.Factor)
throw new Exception("Configuration has to match interface!");
}
private void FullParallelForWork(A_Property propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Face>?> imageFaceCollections, Container container, int index, Item item)
@ -280,10 +284,10 @@ public partial class DlibDotNet
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), (from l in subFileTuples select l.Item2).Max()));
}
}
(int metadataGroups, metadataCollection) = _Metadata.GetMetadataCollection(bResultsFullGroupDirectory, subFileTuples, parseExceptions, item);
(int metadataGroups, metadataCollection) = _Metadata.GetMetadataCollection(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, subFileTuples, parseExceptions, item);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection));
imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs));
if (_Configuration.SaveResizedSubfiles)
@ -338,12 +342,12 @@ public partial class DlibDotNet
}
}
private int FullParallelWork(A_Property propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Face>?> imageFaceCollections, Container container, Item[] filteredItems, string message)
private int FullParallelWork(int maxDegreeOfParallelism, A_Property propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Face>?> imageFaceCollections, Container container, Item[] filteredItems, string message)
{
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
int result = 0;
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism };
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
if (imageFaceCollections.Count != filteredItems.Length || metadataCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || propertyCollection.Count != filteredItems.Length)
{
@ -411,7 +415,7 @@ public partial class DlibDotNet
}
}
private void WriteGroup(Property.Models.Configuration configuration, A_Property propertyLogic, Shared.Models.Property[] propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Face>?> imageFaceCollections, string outputResolution, Container container, Item[] filteredItems)
private void WriteGroup(A_Property propertyLogic, Shared.Models.Property[] propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Face>?> imageFaceCollections, string outputResolution, Container container, Item[] filteredItems)
{
Item item;
string key;
@ -428,8 +432,8 @@ public partial class DlibDotNet
List<KeyValuePair<string, Shared.Models.Property>> propertyCollectionKeyValuePairs = new();
List<KeyValuePair<string, Dictionary<string, int[]>>> resizeKeyValuePairsCollections = new();
List<KeyValuePair<string, List<KeyValuePair<string, string>>>> metadataCollectionKeyValuePairs = new();
(int level, List<string> directories) = Shared.Models.Stateless.Methods.IPath.Get(configuration.RootDirectory, container.SourceDirectory);
string fileName = string.Concat(string.Join(configuration.FileNameDirectorySeparator, directories), ".json");
(int level, List<string> directories) = Shared.Models.Stateless.Methods.IPath.Get(_Configuration.PropertyConfiguration.RootDirectory, container.SourceDirectory);
string fileName = string.Concat(string.Join(_Configuration.PropertyConfiguration.FileNameDirectorySeparator, directories), ".json");
for (int i = 0; i < filteredItems.Length; i++)
{
item = filteredItems[i];
@ -491,44 +495,44 @@ public partial class DlibDotNet
}
}
private (string, string, string, string, string, string) GetResultsFullGroupDirectories(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution)
private (string, string, string, string, string, string) GetResultsFullGroupDirectories(Model? model, PredictorModel? predictorModel, string outputResolution)
{
string aResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
configuration, model, predictorModel, nameof(A_Property), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false);
_Configuration.PropertyConfiguration, model, predictorModel, nameof(A_Property), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false);
string bResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
configuration, model, predictorModel, nameof(B_Metadata), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false);
_Configuration.PropertyConfiguration, model, predictorModel, nameof(B_Metadata), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false);
string cResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
configuration, model, predictorModel, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false);
_Configuration.PropertyConfiguration, model, predictorModel, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false);
string dResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
_Configuration.PropertyConfiguration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
string d2ResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
configuration, model, predictorModel, nameof(D2_FaceParts), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
_Configuration.PropertyConfiguration, model, predictorModel, nameof(D2_FaceParts), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
string eResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
_Configuration.PropertyConfiguration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory);
}
private void SetAngleBracketCollections(Property.Models.Configuration configuration, A_Property propertyLogic, string outputResolution, Container container, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string eResultsFullGroupDirectory)
private void SetAngleBracketCollections(A_Property propertyLogic, string outputResolution, Container container, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string eResultsFullGroupDirectory)
{
_Faces.AngleBracketCollection.Clear();
_Resize.AngleBracketCollection.Clear();
_Metadata.AngleBracketCollection.Clear();
propertyLogic.AngleBracketCollection.Clear();
propertyLogic.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
propertyLogic.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(_Configuration.PropertyConfiguration,
container.SourceDirectory,
aResultsFullGroupDirectory,
contentDescription: string.Empty,
singletonDescription: "Properties for each image",
collectionDescription: string.Empty,
converted: false));
_Metadata.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
_Metadata.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(_Configuration.PropertyConfiguration,
container.SourceDirectory,
bResultsFullGroupDirectory,
contentDescription: string.Empty,
singletonDescription: "Metadata as key value pairs",
collectionDescription: string.Empty,
converted: true));
_Resize.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
_Resize.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(_Configuration.PropertyConfiguration,
container.SourceDirectory,
cResultsFullGroupDirectory,
contentDescription: "Resized image",
@ -536,7 +540,7 @@ public partial class DlibDotNet
collectionDescription: string.Empty,
converted: true));
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
_Faces.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
_Faces.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(_Configuration.PropertyConfiguration,
container.SourceDirectory,
dResultsFullGroupDirectory,
contentDescription: "n png file(s) for each face found",
@ -553,7 +557,7 @@ public partial class DlibDotNet
collectionDescription: string.Empty,
converted: false);
if (_Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution))
_ = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
_ = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(_Configuration.PropertyConfiguration,
container.SourceDirectory,
eResultsFullGroupDirectory,
contentDescription: string.Empty,
@ -585,6 +589,7 @@ public partial class DlibDotNet
List<Dictionary<string, int[]>> resizeKeyValuePairs = new();
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
List<Shared.Models.Property?> nullablePropertyCollection = new();
int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism;
List<List<KeyValuePair<string, string>>> metadataCollection = new();
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), "{}");
foreach (string outputResolution in _Configuration.OutputResolutions)
@ -592,7 +597,7 @@ public partial class DlibDotNet
total = 0;
_FileKeyValuePairs.Clear();
_FilePropertiesKeyValuePairs.Clear();
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(_Configuration.PropertyConfiguration, model, predictorModel, outputResolution);
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution);
for (int i = 0; i < containers.Length; i++)
{
container = containers[i];
@ -610,9 +615,9 @@ public partial class DlibDotNet
nullablePropertyCollection.Clear();
propertyFileHolderCollection.Clear();
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $"{i:000}.{container.G} / {containersLength:000}) {filteredItems.Length:000} file(s) - {total} / {t} total file(s) - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}";
SetAngleBracketCollections(_Configuration.PropertyConfiguration, propertyLogic, outputResolution, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory);
exceptionCount = FullParallelWork(propertyLogic, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, sourceDirectoryChanges, propertyFileHolderCollection, nullablePropertyCollection, metadataCollection, resizeKeyValuePairs, imageFaceCollections, container, filteredItems, message);
message = $"{i + 1:000}.{container.G} [{filteredItems.Length:000} files] / {containersLength:000} - {total} / {t} total files - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}";
SetAngleBracketCollections(propertyLogic, outputResolution, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory);
exceptionCount = FullParallelWork(maxDegreeOfParallelism, propertyLogic, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, sourceDirectoryChanges, propertyFileHolderCollection, nullablePropertyCollection, metadataCollection, resizeKeyValuePairs, imageFaceCollections, container, filteredItems, message);
if (metadataCollection.Count != filteredItems.Length || nullablePropertyCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || imageFaceCollections.Count != filteredItems.Length)
throw new Exception("Counts don't match!");
if (exceptionCount != 0)
@ -621,7 +626,7 @@ public partial class DlibDotNet
filteredItems[f].Faces.AddRange(from l in imageFaceCollections[f] select l);
propertyCollection = (from l in nullablePropertyCollection where l is not null select l).ToArray();
if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0)
WriteGroup(_Configuration.PropertyConfiguration, propertyLogic, propertyCollection, metadataCollection, resizeKeyValuePairs, imageFaceCollections, outputResolution, container, filteredItems);
WriteGroup(propertyLogic, propertyCollection, metadataCollection, resizeKeyValuePairs, imageFaceCollections, outputResolution, container, filteredItems);
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
{
for (int y = 0; y < int.MaxValue; y++)
@ -649,12 +654,12 @@ public partial class DlibDotNet
}
}
private string GetMapLogicResultsFullGroupDirectory(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel)
private string GetMapLogicResultsFullGroupDirectory(Model? model, PredictorModel? predictorModel)
{
const int zero = 0;
string outputResolution = _Configuration.OutputResolutions[zero];
string zResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
configuration, model, predictorModel, $"Z_{nameof(Item)}", outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false);
_Configuration.PropertyConfiguration, model, predictorModel, $"Z_{nameof(Item)}", outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false);
return zResultsFullGroupDirectory;
}
@ -695,7 +700,7 @@ public partial class DlibDotNet
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
mappingFromItem = new(item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.ResizedFileHolder);
mappingFromPerson = new(approximateYears: null, by: null, displayDirectoryName: string.Empty, personBirthday: null, segmentB: string.Empty);
deterministicHashCodeKeyDisplay = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKeyDisplay(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value);
deterministicHashCodeKeyDisplay = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value);
mappingFromLocation = new(face.Location.Confidence, deterministicHashCodeKeyDisplay, face.Location.NormalizedPixelPercentage.Value);
mapping = new(mappingFromItem, mappingFromLocation, mappingFromPerson);
face.SetMapping(mapping);
@ -722,7 +727,55 @@ public partial class DlibDotNet
return results;
}
private void Search(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string argZero, string propertyRoot, Person[] people)
private void DistanceThenMapLogic(string argZero, long ticks, Person[] people, Container[] containers, MapLogic? mapLogic, string dResultsFullGroupDirectory, string eResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string zResultsFullGroupDirectory, string peopleDateGroupDirectory, string outputResolution)
{
E_Distance distance = new();
if (string.IsNullOrEmpty(eResultsFullGroupDirectory))
throw new NullReferenceException(nameof(eResultsFullGroupDirectory));
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
string eDistanceContentDirectory = Path.Combine(eResultsFullGroupDirectory, "([])");
if (!Directory.Exists(eDistanceContentDirectory))
_ = Directory.CreateDirectory(eDistanceContentDirectory);
Map.Models.Configuration configuration = new(_Configuration.FaceDistanceHiddenImageFactor,
_Configuration.FaceDistancePermyriad,
_Configuration.FaceDistanceMinimumConfidence,
_Configuration.FaceDistanceTolerance,
_Configuration.LocationDigits,
_Configuration.LocationFactor,
_Configuration.MapLogicSigma,
_Configuration.MappingSaveFaceEncoding,
_Configuration.MappingSaveMapped,
_Configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
_Configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping,
_Configuration.PersonBirthdayFirstYear,
_Configuration.PersonBirthdayFormat,
_Configuration.PersonKeyFormat,
_Configuration.SortingDaysDeltaTolerance,
_Configuration.SortingFacesToSkipAfterSortBeforeLoad,
_Configuration.SortingFacesToTakeAfterSortBeforeLoad,
_Configuration.SortingMaximumPerFaceShouldBeHigh,
_Configuration.SortingMaximumPerKey,
_Configuration.SortingSigma);
if (mapLogic is not null)
mapLogic.Update(configuration);
string eDistanceContentFileName = Path.Combine(eDistanceContentDirectory, $"{_Configuration.PropertyConfiguration.ResultAllInOne}.tvs");
List<Face> distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers);
List<Face> selectedFilteredFaces = E_Distance.GetSelectedFilteredFaces(configuration, distinctFilteredFaces);
E_Distance.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, selectedFilteredFaces);
if (mapLogic is null)
mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FilenameExtension, _Faces.FilenameExtension, _Faces.HiddenFilenameExtension, _FaceParts.FilenameExtension, ticks, people, peopleDateGroupDirectory, zResultsFullGroupDirectory, configuration, distinctFilteredFaces, distance);
mapLogic.SetPersonTicks(distinctFilteredFaces);
SortingContainer[] sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, configuration, ticks, mapLogic, selectedFilteredFaces);
E_Distance.SaveFaceDistances(eDistanceContentFileName, sortingContainers);
int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces);
if (totalNotMapped > 0)
mapLogic.ForceSingleImageThenSaveMapping(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, dFacesContentDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces, sortingContainers, totalNotMapped);
mapLogic.SaveNotMappedTicks(_Configuration.PropertyConfiguration);
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
mapLogic.SaveShortcuts(_Configuration.JuliePhares, distinctFilteredFaces);
}
private void Search(Model? model, PredictorModel? predictorModel, string argZero, string propertyRoot, Person[] people)
{
int j;
int f;
@ -737,8 +790,8 @@ public partial class DlibDotNet
string dResultsFullGroupDirectory;
string eResultsFullGroupDirectory;
string d2ResultsFullGroupDirectory;
string zResultsFullGroupDirectory = GetMapLogicResultsFullGroupDirectory(configuration, model, predictorModel);
string peopleDateGroupDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People));
string zResultsFullGroupDirectory = GetMapLogicResultsFullGroupDirectory(model, predictorModel);
string peopleDateGroupDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People));
if (!_FirstRun)
{
mapLogic = null;
@ -754,45 +807,33 @@ public partial class DlibDotNet
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using (ProgressBar progressBar = new(1, message, options))
{
if (string.IsNullOrEmpty(configuration.RootDirectory))
(j, f, t, containers) = A_Property.Get(configuration, propertyLogic);
progressBar.Tick();
if (string.IsNullOrEmpty(_Configuration.PropertyConfiguration.RootDirectory))
(j, f, t, containers) = A_Property.Get(_Configuration.PropertyConfiguration, propertyLogic);
else
(j, f, t, containers) = Property.Models.Stateless.Container.GetContainers(configuration, _FirstRun, propertyLogic);
(j, f, t, containers) = Property.Models.Stateless.Container.GetContainers(_Configuration.PropertyConfiguration, _FirstRun, propertyLogic);
}
FullDoWork(argZero, model, predictorModel, propertyRoot, ticks, propertyLogic, t, containers);
foreach (string outputResolution in _Configuration.OutputResolutions)
{
if (_FirstRun)
break;
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(configuration, model, predictorModel, outputResolution);
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution);
if (_ArgZeroIsConfigurationRootDirectory && _Configuration.SaveResizedSubfiles && outputResolution == _Configuration.OutputResolutions[0] && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) && _Exceptions.Count == 0)
{
if (string.IsNullOrEmpty(eResultsFullGroupDirectory))
throw new NullReferenceException(nameof(eResultsFullGroupDirectory));
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
string eDistanceContentDirectory = Path.Combine(eResultsFullGroupDirectory, "([])");
if (!Directory.Exists(eDistanceContentDirectory))
_ = Directory.CreateDirectory(eDistanceContentDirectory);
string eDistanceContentFileName = Path.Combine(eDistanceContentDirectory, $"{Property.Models.Stateless.IResult.AllInOne}.tvs");
List<Face> distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers);
if (mapLogic is null)
mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FilenameExtension, _Faces.FilenameExtension, _Faces.HiddenFilenameExtension, _FaceParts.FilenameExtension, ticks, people, peopleDateGroupDirectory, zResultsFullGroupDirectory);
SortingContainer[] sortingContainers = E_Distance.SetPersonTicksAndSetFaceDistancesAndSetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, ticks, mapLogic, outputResolution, eDistanceContentFileName, distinctFilteredFaces);
mapLogic.CommonWork(_AppSettings.MaxDegreeOfParallelism, dFacesContentDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces, sortingContainers);
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
mapLogic.SaveShortcuts(_Configuration.JuliePhares, distinctFilteredFaces);
DistanceThenMapLogic(argZero, ticks, people, containers, mapLogic, dResultsFullGroupDirectory, eResultsFullGroupDirectory, d2ResultsFullGroupDirectory, zResultsFullGroupDirectory, peopleDateGroupDirectory, outputResolution);
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
break;
if (_FileKeyValuePairs.Any())
_Random.Random(configuration, _Configuration.OutputResolutions[0], _FileKeyValuePairs);
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], _FileKeyValuePairs);
if (_IsEnvironment.Development)
continue;
G2_Identify identify = new(_Configuration);
List<G2_Identify> identifiedCollection = identify.GetIdentifiedCollection(configuration, _IsEnvironment, _People);
_People.WriteAllText(configuration, _Configuration.OutputResolutions[0], identifiedCollection);
identify.WriteAllText(configuration, _Configuration.OutputResolutions[0], identifiedCollection);
List<G2_Identify> identifiedCollection = identify.GetIdentifiedCollection(_Configuration.PropertyConfiguration, _IsEnvironment, _People);
_People.WriteAllText(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], identifiedCollection);
identify.WriteAllText(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], identifiedCollection);
if (_Configuration.LoadOrCreateThenSaveIndex && _FilePropertiesKeyValuePairs.Any())
_Index.SetIndex(configuration, model, predictorModel, _Configuration.OutputResolutions[0], _FilePropertiesKeyValuePairs);
_Index.SetIndex(_Configuration.PropertyConfiguration, model, predictorModel, _Configuration.OutputResolutions[0], _FilePropertiesKeyValuePairs);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, "{}"));
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(bResultsFullGroupDirectory, "{}"));
@ -806,6 +847,6 @@ public partial class DlibDotNet
}
}
internal void RenameQueue(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel) => _Rename.RenameQueue(configuration, model, predictorModel);
internal void RenameQueue(Model? model, PredictorModel? predictorModel) => _Rename.RenameQueue(_Configuration.PropertyConfiguration, model, predictorModel);
}

View File

@ -13,6 +13,10 @@ public class Configuration
[Display(Name = "Check Json For Distance Results"), Required] public bool? CheckJsonForDistanceResults { get; set; }
[Display(Name = "CrossDirectory Max Items In Distance Collection"), Required] public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; }
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
[Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; }
[Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; }
[Display(Name = "Face Distance Permyriad"), Required] public int? FaceDistancePermyriad { get; set; }
[Display(Name = "Face Distance Tolerance"), Required] public double? FaceDistanceTolerance { get; set; }
[Display(Name = "Force Face Last Write Time to Creation Time"), Required] public bool? ForceFaceLastWriteTimeToCreationTime { get; set; }
[Display(Name = "Force Metadata Last Write Time to Creation Time"), Required] public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; }
[Display(Name = "Force Resize Last Write Time to Creation Time"), Required] public bool? ForceResizeLastWriteTimeToCreationTime { get; set; }
@ -23,7 +27,14 @@ public class Configuration
[Display(Name = "Load Or Create Then Save Image Faces Results"), Required] public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
[Display(Name = "Load Or Create Then Save Index"), Required] public bool? LoadOrCreateThenSaveIndex { get; set; }
[Display(Name = "Location Confidence Factor"), Required] public int? LocationConfidenceFactor { get; set; }
[Display(Name = "Location Digits"), Required] public int? LocationDigits { get; set; }
[Display(Name = "Location Factor"), Required] public int? LocationFactor { get; set; }
[Display(Name = "Map Logic Sigma"), Required] public int? MapLogicSigma { get; set; }
[Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; }
[Display(Name = "Mapping Save Face Encoding"), Required] public bool? MappingSaveFaceEncoding { get; set; }
[Display(Name = "MappingSaveMapped"), Required] public bool? MappingSaveMapped { get; set; }
[Display(Name = "Mapping Use Deterministic Hash Code Unknown Face Key Value Pairs for Add to Mapping"), Required] public bool? MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { get; set; }
[Display(Name = "Mapping Use Deterministic Hash Code Unknown Face Key Value Pairs for Save Mapping"), Required] public bool? MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping { get; set; }
[Display(Name = "Max Items In Distance Collection"), Required] public int? MaxItemsInDistanceCollection { get; set; }
[Display(Name = "Mixed Year Relative Paths"), Required] public string[] MixedYearRelativePaths { get; set; }
[Display(Name = "Model Directory"), Required] public string ModelDirectory { get; set; }
@ -37,6 +48,9 @@ public class Configuration
[Display(Name = "Override For Face Landmark Images"), Required] public bool? OverrideForFaceLandmarkImages { get; set; }
[Display(Name = "Override For Resize Images"), Required] public bool? OverrideForResizeImages { get; set; }
[Display(Name = "Padding Loops"), Required] public int? PaddingLoops { get; set; }
[Display(Name = "Person Birthday First Year"), Required] public int? PersonBirthdayFirstYear { get; set; }
[Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; }
[Display(Name = "PersonKey Format"), Required] public string PersonKeyFormat { get; set; }
[Display(Name = "Predictor Model Name"), Required] public string PredictorModelName { get; set; }
[Display(Name = "Properties Changed For Distance"), Required] public bool? PropertiesChangedForDistance { get; set; }
[Display(Name = "Properties Changed For Faces"), Required] public bool? PropertiesChangedForFaces { get; set; }
@ -50,6 +64,12 @@ public class Configuration
[Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; }
[Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; }
[Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; }
[Display(Name = "Sorting Days Delta Tolerance"), Required] public int? SortingDaysDeltaTolerance { get; set; }
[Display(Name = "Sorting Faces To Skip After Sort Before Load"), Required] public int? SortingFacesToSkipAfterSortBeforeLoad { get; set; }
[Display(Name = "Sorting Faces To Take After Sort Before Load"), Required] public int? SortingFacesToTakeAfterSortBeforeLoad { get; set; }
[Display(Name = "SortingMaximumPerFaceShould be High"), Required] public int? SortingMaximumPerFaceShouldBeHigh { get; set; }
[Display(Name = "Sorting Maximum Per Key"), Required] public int? SortingMaximumPerKey { get; set; }
[Display(Name = "Sorting Sigma"), Required] public int? SortingSigma { get; set; }
[Display(Name = "Test Distance Results"), Required] public bool? TestDistanceResults { get; set; }
[Display(Name = "Valid Resolutions"), Required] public string[] ValidResolutions { get; set; }
@ -70,6 +90,14 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
if (configuration.DistanceFactor is null)
throw new NullReferenceException(nameof(configuration.DistanceFactor));
if (configuration.FaceDistanceHiddenImageFactor is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor));
if (configuration.FaceDistanceMinimumConfidence is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceMinimumConfidence));
if (configuration.FaceDistancePermyriad is null)
throw new NullReferenceException(nameof(configuration.FaceDistancePermyriad));
if (configuration.FaceDistanceTolerance is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceTolerance));
if (configuration.ForceFaceLastWriteTimeToCreationTime is null)
throw new NullReferenceException(nameof(configuration.ForceFaceLastWriteTimeToCreationTime));
if (configuration.ForceMetadataLastWriteTimeToCreationTime is null)
@ -80,10 +108,28 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
if (configuration.IgnoreRelativePaths is null)
throw new NullReferenceException(nameof(configuration.IgnoreRelativePaths));
if (configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions is null)
configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions = Array.Empty<string>();
if (configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions is null)
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions = Array.Empty<string>();
if (configuration.LoadOrCreateThenSaveIndex is null)
throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveIndex));
if (configuration.LocationConfidenceFactor is null)
throw new NullReferenceException(nameof(configuration.LocationConfidenceFactor));
if (configuration.LocationDigits is null)
throw new NullReferenceException(nameof(configuration.LocationDigits));
if (configuration.LocationFactor is null)
throw new NullReferenceException(nameof(configuration.LocationFactor));
if (configuration.MapLogicSigma is null)
throw new NullReferenceException(nameof(configuration.MapLogicSigma));
if (configuration.MappingSaveFaceEncoding is null)
throw new NullReferenceException(nameof(configuration.MappingSaveFaceEncoding));
if (configuration.MappingSaveMapped is null)
throw new NullReferenceException(nameof(configuration.MappingSaveMapped));
if (configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping is null)
throw new NullReferenceException(nameof(configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping));
if (configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping is null)
throw new NullReferenceException(nameof(configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping));
if (configuration.MaxItemsInDistanceCollection is null)
throw new NullReferenceException(nameof(configuration.MaxItemsInDistanceCollection));
if (configuration.MixedYearRelativePaths is null)
@ -104,6 +150,12 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.OverrideForResizeImages));
if (configuration.PaddingLoops is null)
throw new NullReferenceException(nameof(configuration.PaddingLoops));
if (configuration.PersonBirthdayFirstYear is null)
throw new NullReferenceException(nameof(configuration.PersonBirthdayFirstYear));
if (configuration.PersonBirthdayFormat is null)
throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
if (configuration.PersonKeyFormat is null)
throw new NullReferenceException(nameof(configuration.PersonKeyFormat));
if (configuration.PropertiesChangedForDistance is null)
throw new NullReferenceException(nameof(configuration.PropertiesChangedForDistance));
if (configuration.PropertiesChangedForFaces is null)
@ -116,14 +168,30 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize));
if (configuration.Reverse is null)
throw new NullReferenceException(nameof(configuration.Reverse));
if (configuration.SaveFaceLandmarkForOutputResolutions is null)
configuration.SaveFaceLandmarkForOutputResolutions = Array.Empty<string>();
if (configuration.SaveFaceLandmarkForOutputResolutions is null)
throw new NullReferenceException(nameof(configuration.SaveFaceLandmarkForOutputResolutions));
if (configuration.SaveFullYearOfRandomFiles is null)
throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles));
if (configuration.SaveResizedSubfiles is null)
throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles));
if (configuration.SaveShortcutsForOutputResolutions is null)
configuration.SaveShortcutsForOutputResolutions = Array.Empty<string>();
if (configuration.SkipSearch is null)
throw new NullReferenceException(nameof(configuration.SkipSearch));
if (configuration.SortingDaysDeltaTolerance is null)
throw new NullReferenceException(nameof(configuration.SortingDaysDeltaTolerance));
if (configuration.SortingFacesToSkipAfterSortBeforeLoad is null)
throw new NullReferenceException(nameof(configuration.SortingFacesToSkipAfterSortBeforeLoad));
if (configuration.SortingFacesToTakeAfterSortBeforeLoad is null)
throw new NullReferenceException(nameof(configuration.SortingFacesToTakeAfterSortBeforeLoad));
if (configuration.SortingMaximumPerFaceShouldBeHigh is null)
throw new NullReferenceException(nameof(configuration.SortingMaximumPerFaceShouldBeHigh));
if (configuration.SortingMaximumPerKey is null)
throw new NullReferenceException(nameof(configuration.SortingMaximumPerKey));
if (configuration.SortingSigma is null)
throw new NullReferenceException(nameof(configuration.SortingSigma));
if (configuration.TestDistanceResults is null)
throw new NullReferenceException(nameof(configuration.TestDistanceResults));
if (configuration.ValidResolutions is null)
@ -140,6 +208,10 @@ public class Configuration
configuration.CheckJsonForDistanceResults.Value,
configuration.CrossDirectoryMaxItemsInDistanceCollection.Value,
configuration.DistanceFactor.Value,
configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value,
configuration.FaceDistancePermyriad.Value,
configuration.FaceDistanceTolerance.Value,
configuration.ForceFaceLastWriteTimeToCreationTime.Value,
configuration.ForceMetadataLastWriteTimeToCreationTime.Value,
configuration.ForceResizeLastWriteTimeToCreationTime.Value,
@ -150,7 +222,14 @@ public class Configuration
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions,
configuration.LoadOrCreateThenSaveIndex.Value,
configuration.LocationConfidenceFactor.Value,
configuration.LocationDigits.Value,
configuration.LocationFactor.Value,
configuration.MapLogicSigma.Value,
configuration.MappedMaxIndex,
configuration.MappingSaveFaceEncoding.Value,
configuration.MappingSaveMapped.Value,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping.Value,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping.Value,
configuration.MaxItemsInDistanceCollection.Value,
configuration.MixedYearRelativePaths,
configuration.ModelDirectory,
@ -164,6 +243,9 @@ public class Configuration
configuration.OverrideForFaceLandmarkImages.Value,
configuration.OverrideForResizeImages.Value,
configuration.PaddingLoops.Value,
configuration.PersonBirthdayFirstYear.Value,
configuration.PersonBirthdayFormat,
configuration.PersonKeyFormat,
configuration.PredictorModelName,
configuration.PropertiesChangedForDistance.Value,
configuration.PropertiesChangedForFaces.Value,
@ -176,6 +258,12 @@ public class Configuration
configuration.SaveResizedSubfiles.Value,
configuration.SaveShortcutsForOutputResolutions,
configuration.SkipSearch.Value,
configuration.SortingDaysDeltaTolerance.Value,
configuration.SortingFacesToSkipAfterSortBeforeLoad.Value,
configuration.SortingFacesToTakeAfterSortBeforeLoad.Value,
configuration.SortingMaximumPerFaceShouldBeHigh.Value,
configuration.SortingMaximumPerKey.Value,
configuration.SortingSigma.Value,
configuration.TestDistanceResults.Value,
configuration.ValidResolutions);
return result;

View File

@ -12,6 +12,10 @@ public class Configuration
public bool CheckJsonForDistanceResults { init; get; }
public int CrossDirectoryMaxItemsInDistanceCollection { init; get; }
public int DistanceFactor { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; }
public double FaceDistanceMinimumConfidence { init; get; }
public int FaceDistancePermyriad { init; get; }
public double FaceDistanceTolerance { init; get; }
public bool ForceFaceLastWriteTimeToCreationTime { init; get; }
public bool ForceMetadataLastWriteTimeToCreationTime { init; get; }
public bool ForceResizeLastWriteTimeToCreationTime { init; get; }
@ -22,7 +26,14 @@ public class Configuration
public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { init; get; }
public bool LoadOrCreateThenSaveIndex { init; get; }
public int LocationConfidenceFactor { init; get; }
public int LocationDigits { init; get; }
public int LocationFactor { init; get; }
public int MapLogicSigma { init; get; }
public int? MappedMaxIndex { init; get; }
public bool MappingSaveFaceEncoding { init; get; }
public bool MappingSaveMapped { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping { init; get; }
public int MaxItemsInDistanceCollection { init; get; }
public string[] MixedYearRelativePaths { init; get; }
public string ModelDirectory { init; get; }
@ -36,6 +47,9 @@ public class Configuration
public bool OverrideForFaceLandmarkImages { init; get; }
public bool OverrideForResizeImages { init; get; }
public int PaddingLoops { init; get; }
public int PersonBirthdayFirstYear { init; get; }
public string PersonBirthdayFormat { init; get; }
public string PersonKeyFormat { init; get; }
public string PredictorModelName { init; get; }
public bool PropertiesChangedForDistance { init; get; }
public bool PropertiesChangedForFaces { init; get; }
@ -48,16 +62,87 @@ public class Configuration
public bool SaveResizedSubfiles { init; get; }
public string[] SaveShortcutsForOutputResolutions { init; get; }
public bool SkipSearch { init; get; }
public int SortingDaysDeltaTolerance { init; get; }
public int SortingFacesToSkipAfterSortBeforeLoad { init; get; }
public int SortingFacesToTakeAfterSortBeforeLoad { init; get; }
public int SortingMaximumPerFaceShouldBeHigh { init; get; }
public int SortingMaximumPerKey { init; get; }
public int SortingSigma { init; get; }
public bool TestDistanceResults { init; get; }
public string[] ValidResolutions { init; get; }
[JsonConstructor]
public Configuration(Property.Models.Configuration propertyConfiguration, bool checkJsonForDistanceResults, int crossDirectoryMaxItemsInDistanceCollection, int distanceFactor, bool forceFaceLastWriteTimeToCreationTime, bool forceMetadataLastWriteTimeToCreationTime, bool forceResizeLastWriteTimeToCreationTime, string[] ignoreExtensions, string[] ignoreRelativePaths, string[] juliePhares, string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions, bool loadOrCreateThenSaveIndex, int locationConfidenceFactor, int? mappedMaxIndex, int maxItemsInDistanceCollection, string[] mixedYearRelativePaths, string modelDirectory, string modelName, int numberOfJitters, int numberOfTimesToUpsample, string outputExtension, int outputQuality, string[] outputResolutions, bool overrideForFaceImages, bool overrideForFaceLandmarkImages, bool overrideForResizeImages, int paddingLoops, string predictorModelName, bool propertiesChangedForDistance, bool propertiesChangedForFaces, bool propertiesChangedForIndex, bool propertiesChangedForMetadata, bool propertiesChangedForResize, bool reverse, string[] saveFaceLandmarkForOutputResolutions, bool saveFullYearOfRandomFiles, bool saveResizedSubfiles, string[] saveShortcutsForOutputResolutions, bool skipSearch, bool testDistanceResults, string[] validResolutions)
public Configuration(Property.Models.Configuration propertyConfiguration,
bool checkJsonForDistanceResults,
int crossDirectoryMaxItemsInDistanceCollection,
int distanceFactor,
int faceDistanceHiddenImageFactor,
double faceDistanceMinimumConfidence,
int faceDistancePermyriad,
double faceDistanceTolerance,
bool forceFaceLastWriteTimeToCreationTime,
bool forceMetadataLastWriteTimeToCreationTime,
bool forceResizeLastWriteTimeToCreationTime,
string[] ignoreExtensions,
string[] ignoreRelativePaths,
string[] juliePhares,
string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions,
string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions,
bool loadOrCreateThenSaveIndex,
int locationConfidenceFactor,
int locationDigits,
int locationFactor,
int mapLogicSigma,
int? mappedMaxIndex,
bool mappingSaveFaceEncoding,
bool mappingSaveMapped,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping,
int maxItemsInDistanceCollection,
string[] mixedYearRelativePaths,
string modelDirectory,
string modelName,
int numberOfJitters,
int numberOfTimesToUpsample,
string outputExtension,
int outputQuality,
string[] outputResolutions,
bool overrideForFaceImages,
bool overrideForFaceLandmarkImages,
bool overrideForResizeImages,
int paddingLoops,
int personBirthdayFirstYear,
string personBirthdayFormat,
string personKeyFormat,
string predictorModelName,
bool propertiesChangedForDistance,
bool propertiesChangedForFaces,
bool propertiesChangedForIndex,
bool propertiesChangedForMetadata,
bool propertiesChangedForResize,
bool reverse,
string[] saveFaceLandmarkForOutputResolutions,
bool saveFullYearOfRandomFiles,
bool saveResizedSubfiles,
string[] saveShortcutsForOutputResolutions,
bool skipSearch,
int sortingDaysDeltaTolerance,
int sortingFacesToSkipAfterSortBeforeLoad,
int sortingFacesToTakeAfterSortBeforeLoad,
int sortingMaximumPerFaceShouldBeHigh,
int sortingMaximumPerKey,
int sortingSigma,
bool testDistanceResults,
string[] validResolutions)
{
_PropertyConfiguration = propertyConfiguration;
CheckJsonForDistanceResults = checkJsonForDistanceResults;
CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
DistanceFactor = distanceFactor;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
FaceDistancePermyriad = faceDistancePermyriad;
FaceDistanceTolerance = faceDistanceTolerance;
ForceFaceLastWriteTimeToCreationTime = forceFaceLastWriteTimeToCreationTime;
ForceMetadataLastWriteTimeToCreationTime = forceMetadataLastWriteTimeToCreationTime;
ForceResizeLastWriteTimeToCreationTime = forceResizeLastWriteTimeToCreationTime;
@ -68,7 +153,14 @@ public class Configuration
LoadOrCreateThenSaveImageFacesResultsForOutputResolutions = loadOrCreateThenSaveImageFacesResultsForOutputResolutions;
LoadOrCreateThenSaveIndex = loadOrCreateThenSaveIndex;
LocationConfidenceFactor = locationConfidenceFactor;
LocationDigits = locationDigits;
LocationFactor = locationFactor;
MapLogicSigma = mapLogicSigma;
MappedMaxIndex = mappedMaxIndex;
MappingSaveFaceEncoding = mappingSaveFaceEncoding;
MappingSaveMapped = mappingSaveMapped;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping;
MaxItemsInDistanceCollection = maxItemsInDistanceCollection;
MixedYearRelativePaths = mixedYearRelativePaths;
ModelDirectory = modelDirectory;
@ -82,6 +174,9 @@ public class Configuration
OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages;
OverrideForResizeImages = overrideForResizeImages;
PaddingLoops = paddingLoops;
PersonBirthdayFirstYear = personBirthdayFirstYear;
PersonBirthdayFormat = personBirthdayFormat;
PersonKeyFormat = personKeyFormat;
PredictorModelName = predictorModelName;
PropertiesChangedForDistance = propertiesChangedForDistance;
PropertiesChangedForFaces = propertiesChangedForFaces;
@ -94,6 +189,12 @@ public class Configuration
SaveResizedSubfiles = saveResizedSubfiles;
SaveShortcutsForOutputResolutions = saveShortcutsForOutputResolutions;
SkipSearch = skipSearch;
SortingDaysDeltaTolerance = sortingDaysDeltaTolerance;
SortingFacesToSkipAfterSortBeforeLoad = sortingFacesToSkipAfterSortBeforeLoad;
SortingFacesToTakeAfterSortBeforeLoad = sortingFacesToTakeAfterSortBeforeLoad;
SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
SortingMaximumPerKey = sortingMaximumPerKey;
SortingSigma = sortingSigma;
TestDistanceResults = testDistanceResults;
ValidResolutions = validResolutions;
}

View File

@ -69,7 +69,7 @@ internal class A2_People
if (rootResultsDirectory is null)
throw new Exception();
Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory);
results = Shared.Models.Stateless.Methods.IPerson.GetPeople(storage, Shared.Models.Stateless.IPersonBirthday.FirstYear, Shared.Models.Stateless.IPersonBirthday.Format, Shared.Models.Stateless.IPerson.KeyFormat);
results = Shared.Models.Stateless.Methods.IPerson.GetPeople(storage, _Configuration.PersonBirthdayFirstYear, _Configuration.PersonBirthdayFormat, _Configuration.PersonKeyFormat);
return results.ToArray();
}

View File

@ -145,7 +145,7 @@ internal class D2_FaceParts
collection.Add(new(face, string.Empty, string.Empty));
continue;
}
deterministicHashCodeKeyDisplay = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKeyDisplay(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value);
deterministicHashCodeKeyDisplay = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value);
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKeyDisplay}{item.ImageFileHolder.ExtensionLowered}{_FilenameExtension}"));
if (!fileInfo.Exists)
{

View File

@ -159,7 +159,7 @@ public class D_Face
continue;
if (face.FaceEncoding is null || face?.Location is null)
continue;
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, ILocation.Digits, ILocation.Factor, source.Height, source.Width, collection.Count);
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, _Configuration.LocationDigits, _Configuration.LocationFactor, source.Height, source.Width, collection.Count);
if (location is null)
continue;
width = location.Right - location.Left;
@ -173,7 +173,7 @@ public class D_Face
}
if (File.Exists(fileName))
File.Delete(fileName);
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(IFaceDistance.HiddenImageFactor, face.Location, ILocation.Digits, ILocation.Factor, source.Height, source.Width, collection.Count);
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(_Configuration.FaceDistanceHiddenImageFactor, face.Location, _Configuration.LocationDigits, _Configuration.LocationFactor, source.Height, source.Width, collection.Count);
if (location is null)
continue;
width = location.Right - location.Left;
@ -259,7 +259,7 @@ public class D_Face
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{item.ImageFileHolder.NameWithoutExtension}.json");
string dCollectionFile = Path.Combine(dResultsFullGroupDirectory, "[]", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
string dCollectionFile = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.PropertyConfiguration.ResultAllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
FileInfo fileInfo = new(dCollectionFile);
if (!fileInfo.Exists)
{
@ -330,7 +330,7 @@ public class D_Face
}
if (_Configuration.ForceFaceLastWriteTimeToCreationTime)
{
results = (from l in results select new Face(ILocation.Digits, ILocation.Factor, results.Count, l)).ToList();
results = (from l in results select new Face(_Configuration.LocationDigits, _Configuration.LocationFactor, results.Count, l)).ToList();
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
@ -372,7 +372,7 @@ public class D_Face
collection.Add(new(face, null, string.Empty));
continue;
}
deterministicHashCodeKeyDisplay = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKeyDisplay(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value);
deterministicHashCodeKeyDisplay = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location.NormalizedPixelPercentage.Value);
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKeyDisplay}{item.ImageFileHolder.ExtensionLowered}{_FilenameExtension}"));
if (!fileInfo.Exists)
{

View File

@ -2,14 +2,13 @@ using ShellProgressBar;
using View_by_Distance.FaceRecognitionDotNet;
using View_by_Distance.Map.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless;
namespace View_by_Distance.Instance.Models;
internal class E_Distance
internal class E_Distance : Shared.Models.Methods.IFaceDistance
{
private static void SaveFaceDistances(string eDistanceContentFileName, SortingContainer[] sortingContainers)
internal static void SaveFaceDistances(string eDistanceContentFileName, SortingContainer[] sortingContainers)
{
#pragma warning disable
string[] results = (from l in sortingContainers select string.Concat(l.Sorting.WithinRange, '\t', l.Sorting.DistancePermyriad, '\t', l.Sorting.DaysDelta, '\t', l.Sorting.Id, '\t', l.Sorting.NormalizedPixelPercentage, '\t', l.Sorting.Older, '\t', l.Face.Mapping.MappingFromItem.Id, '\t', l.Face.Mapping.MappingFromLocation.NormalizedPixelPercentage)).ToArray();
@ -17,18 +16,18 @@ internal class E_Distance
File.WriteAllLines(eDistanceContentFileName, results);
}
private static List<Sorting> GetSortingCollection(MapLogic mapLogic, List<FaceDistance> faceDistanceEncodings, int faceDistanceContainersLength, int i, FaceDistance faceDistanceEncoding)
private static List<Sorting> GetSortingCollection(Map.Models.Configuration configuration, MapLogic mapLogic, List<FaceDistance> faceDistanceEncodings, int faceDistanceContainersLength, int i, FaceDistance faceDistanceEncoding)
{
List<Sorting> results;
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
if (faceDistanceLengths.Count != faceDistanceContainersLength)
throw new NotSupportedException();
bool anyLowerThanTolerance = (from l in faceDistanceLengths where l.Length is not null && l.Length.Value != 0 && l.Length.Value < IFaceDistance.Tolerance select true).Any();
bool anyLowerThanTolerance = (from l in faceDistanceLengths where l.Length is not null && l.Length.Value != 0 && l.Length.Value < configuration.FaceDistanceTolerance select true).Any();
results = mapLogic.GetSortingCollection(i, faceDistanceEncoding, faceDistanceLengths, anyLowerThanTolerance);
return results;
}
private static List<SortingContainer> GetSortingContainers(Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection)
private static List<SortingContainer> GetSortingContainers(Map.Models.Configuration configuration, Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection)
{
List<SortingContainer> results = new();
SortingContainer sortingContainer;
@ -37,31 +36,39 @@ internal class E_Distance
{
if (face.Mapping is null || faceDistanceEncoding.NormalizedPixelPercentage is null)
throw new NotSupportedException();
if (face.Mapping.MappingFromLocation.Confidence < IFaceDistance.MinimumConfidence || sorting.DistancePermyriad > IFaceDistance.Permyriad || sorting.DaysDelta > ISorting.DaysDeltaTolerance)
if (face.Mapping.MappingFromLocation.Confidence < configuration.FaceDistanceMinimumConfidence || sorting.DistancePermyriad > configuration.FaceDistancePermyriad || sorting.DaysDelta > configuration.SortingDaysDeltaTolerance)
continue;
sortingContainer = new(face, sorting);
results.Add(sortingContainer);
if (results.Count >= ISorting.MaximumPerFaceShouldBeHigh)
if (results.Count >= configuration.SortingMaximumPerFaceShouldBeHigh)
break;
}
return results;
}
private static SortingContainer[] GetSortingContainersThenSetFaceMappingSortingCollection(int maxDegreeOfParallelism, long ticks, MapLogic mapLogic, string outputResolution, FaceDistanceContainer[] faceDistanceContainers)
private static List<FaceDistance> GetFaceDistanceEncodings(FaceDistanceContainer[] faceDistanceContainers)
{
SortingContainer[] results;
List<SortingContainer> collection = new();
List<FaceDistance> faceDistanceEncodings = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
string message = $") {faceDistanceContainers.Length:000} faceDistanceContainer(s) - {totalSeconds} total second(s) - {outputResolution}";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
foreach (FaceDistanceContainer faceDistanceContainer in faceDistanceContainers)
{
if (faceDistanceContainer.FaceDistance.Encoding is null)
continue;
faceDistanceEncodings.Add(faceDistanceContainer.FaceDistance);
}
return faceDistanceEncodings;
}
internal static SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, Map.Models.Configuration configuration, long ticks, MapLogic mapLogic, List<Face> selectedFilteredFaces)
{
SortingContainer[] results;
List<SortingContainer> collection = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
FaceDistanceContainer[] faceDistanceContainers = GetFaceDistanceContainers(selectedFilteredFaces);
List<FaceDistance> faceDistanceEncodings = GetFaceDistanceEncodings(faceDistanceContainers);
string message = $") {faceDistanceContainers.Length:000} Get Sorting Containers Then Set Face Mapping Sorting Collection - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
selectedFilteredFaces.Clear();
using ProgressBar progressBar = new(faceDistanceContainers.Length, message, options);
_ = Parallel.For(0, faceDistanceContainers.Length, parallelOptions, (i, state) =>
{
@ -70,8 +77,8 @@ internal class E_Distance
if (face.Mapping is null)
throw new NotSupportedException();
FaceDistance faceDistanceEncoding = faceDistanceContainers[i].FaceDistance;
List<Sorting> sortingCollection = GetSortingCollection(mapLogic, faceDistanceEncodings, faceDistanceContainers.Length, i, faceDistanceEncoding);
List<SortingContainer> sortingContainers = GetSortingContainers(face, faceDistanceEncoding, sortingCollection);
List<Sorting> sortingCollection = GetSortingCollection(configuration, mapLogic, faceDistanceEncodings, faceDistanceContainers.Length, i, faceDistanceEncoding);
List<SortingContainer> sortingContainers = GetSortingContainers(configuration, face, faceDistanceEncoding, sortingCollection);
lock (collection)
collection.AddRange(sortingContainers);
lock (face)
@ -81,17 +88,15 @@ internal class E_Distance
return results;
}
private static FaceDistanceContainer[] GetFaceDistanceContainers(Face[] firstFilteredFaces)
private static FaceDistanceContainer[] GetFaceDistanceContainers(List<Face> selectedFilteredFaces)
{
FaceDistanceContainer[] results;
FaceDistance faceDistance;
FaceDistanceContainer faceDistanceContainer;
List<FaceDistanceContainer> collection = new();
foreach (Face face in firstFilteredFaces)
foreach (Face face in selectedFilteredFaces)
{
if (face.Mapping is null)
throw new NotSupportedException();
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding)
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding || face.Mapping is null)
throw new NotSupportedException();
faceDistance = new(face.Mapping.MappingFromLocation.Confidence, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
faceDistanceContainer = new(face, faceDistance);
@ -103,39 +108,73 @@ internal class E_Distance
return results;
}
private static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, string outputResolution, Face[] selectedFilteredFaces)
internal static List<Face> GetSelectedFilteredFaces(Map.Models.Configuration configuration, List<Face> distinctFilteredFaces)
{
List<Face> results;
Face[] orderedFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromItem.MinimumDateTime descending select l).ToArray();
results = orderedFilteredFaces.Skip(configuration.SortingFacesToSkipAfterSortBeforeLoad).Take(configuration.SortingFacesToTakeAfterSortBeforeLoad).ToList();
return results;
}
internal static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, List<Face> selectedFilteredFaces)
{
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
string message = $") {selectedFilteredFaces.Length:000} Load Face Encoding - {totalSeconds} total second(s) - {outputResolution}";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = false };
using ProgressBar progressBar = new(selectedFilteredFaces.Length, message, options);
_ = Parallel.For(0, selectedFilteredFaces.Length, parallelOptions, (i, state) =>
string message = $") {selectedFilteredFaces.Count:000} Load Face Encoding - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(selectedFilteredFaces.Count, message, options);
_ = Parallel.For(0, selectedFilteredFaces.Count, parallelOptions, (i, state) =>
{
progressBar.Tick();
FaceDistance faceDistance;
FaceRecognitionDotNet.FaceEncoding faceEncoding;
Face face = selectedFilteredFaces[i];
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
throw new NotSupportedException();
if (face.Mapping is null)
FaceRecognitionDotNet.FaceEncoding faceEncoding;
if (face.FaceEncoding is null || face.Mapping is null)
throw new NotSupportedException();
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
faceDistance = new(face.Location.Confidence, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Location.NormalizedPixelPercentage.Value);
faceDistance = new(face.Mapping.MappingFromLocation.Confidence, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
lock (face)
face.FaceDistanceAdd(faceDistance);
});
}
internal static SortingContainer[] SetPersonTicksAndSetFaceDistancesAndSetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, long ticks, MapLogic mapLogic, string outputResolution, string eDistanceContentFileName, List<Face> distinctFilteredFaces)
List<Face> Shared.Models.Methods.IFaceDistance.GetMatchingFaces(double faceDistanceTolerance, string checkFile, List<Face> faces)
{
SortingContainer[] results;
Face[] orderedFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromItem.MinimumDateTime descending select l).ToArray();
mapLogic.SetPersonTicks(outputResolution, orderedFilteredFaces);
Face[] selectedFilteredFaces = orderedFilteredFaces.Skip(ISorting.FacesToSkipAfterSortBeforeLoad).Take(ISorting.FacesToTakeAfterSortBeforeLoad).ToArray();
SetFaceDistances(maxDegreeOfParallelism, ticks, outputResolution, selectedFilteredFaces);
FaceDistanceContainer[] faceDistanceContainers = GetFaceDistanceContainers(selectedFilteredFaces);
results = GetSortingContainersThenSetFaceMappingSortingCollection(maxDegreeOfParallelism, ticks, mapLogic, outputResolution, faceDistanceContainers);
SaveFaceDistances(eDistanceContentFileName, results);
List<Face> results = new();
Face face;
FaceDistance faceDistanceLength;
string json = File.ReadAllText(checkFile);
List<(Face Face, double Length)> collection = new();
Shared.Models.FaceEncoding? modelsFaceEncoding = System.Text.Json.JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
if (modelsFaceEncoding is null)
throw new NotSupportedException();
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
FaceDistance faceDistanceEncoding = new(faceRecognitionDotNetFaceEncoding);
FaceDistanceContainer[] faceDistanceContainers = GetFaceDistanceContainers(faces);
int faceDistanceContainersLength = faceDistanceContainers.Length;
if (faceDistanceContainersLength != faces.Count)
throw new NotSupportedException();
List<FaceDistance> faceDistanceEncodings = GetFaceDistanceEncodings(faceDistanceContainers);
if (faceDistanceEncodings.Count != faces.Count)
throw new NotSupportedException();
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
if (faceDistanceLengths.Count != faceDistanceContainersLength)
throw new NotSupportedException();
for (int i = 0; i < faces.Count; i++)
{
face = faces[i];
faceDistanceLength = faceDistanceLengths[i];
if (face.Mapping is null || faceDistanceLength.Length is null)
throw new NotSupportedException();
if (faceDistanceLength.Length.Value > faceDistanceTolerance)
continue;
collection.Add(new(face, faceDistanceLength.Length.Value));
}
if (collection.Any())
{
collection = (from l in collection orderby l.Length select l).ToList();
results.Add(collection[0].Face);
}
return results;
}

View File

@ -89,7 +89,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
json = File.ReadAllText(named.FullName);
Person[] people = a2People.GetPeople(configuration);
Dictionary<string, string[]> resultKeyValuePairs = new();
string[] peopleBirthDates = (from l in people select Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(Shared.Models.Stateless.IPersonBirthday.Format, l.Birthday)).ToArray();
string[] peopleBirthDates = (from l in people select Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, l.Birthday)).ToArray();
Dictionary<string, string[]> sourceKeyValuePairs = JsonSerializer.Deserialize<Dictionary<string, string[]>>(json);
foreach (KeyValuePair<string, string[]> keyValuePair in sourceKeyValuePairs)
{

View File

@ -52,8 +52,12 @@
"Configuration": {
"CheckJsonForDistanceResults": false,
"CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-08-22",
"DateGroup": "2022-09-15",
"DistanceFactor": 8,
"FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8,
"FaceDistancePermyriad": 10000,
"FaceDistanceTolerance": 0.25,
"FileNameDirectorySeparator": ".Z.",
"ForceFaceLastWriteTimeToCreationTime": false,
"ForceMetadataLastWriteTimeToCreationTime": false,
@ -61,7 +65,14 @@
"ForceResizeLastWriteTimeToCreationTime": false,
"LoadOrCreateThenSaveIndex": false,
"LocationConfidenceFactor": 2,
"LocationDigits": 6,
"LocationFactor": 1000000,
"MapLogicSigma": 3,
"MappedMaxIndex": 1034720,
"MappingSaveFaceEncoding": false,
"MappingSaveMapped": false,
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping": false,
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping": false,
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
"MaxItemsInDistanceCollection": 50,
"ModelDirectory": "C:/GitHub/dlib-models",
@ -75,6 +86,9 @@
"OverrideForResizeImages": false,
"PaddingLoops": 5,
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PersonBirthdayFirstYear": 1500,
"PersonBirthdayFormat": "yyyy-MM-dd_HH",
"PersonKeyFormat": "yyyy-MM-dd_HH",
"PopulatePropertyId": true,
"PredictorModelName": "Large",
"PropertiesChangedForDistance": false,
@ -83,12 +97,22 @@
"PropertiesChangedForMetadata": false,
"PropertiesChangedForProperty": false,
"PropertiesChangedForResize": false,
"ResultAllInOne": "_ _ _",
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"Reverse": false,
"xRootDirectory": "C:/Tmp/phares/Pictures",
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-08-22 - bc2174b - III",
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-09-15 - 7390c13 - III",
"SaveFullYearOfRandomFiles": true,
"SaveResizedSubFiles": true,
"SkipSearch": false,
"SortingDaysDeltaTolerance": 700,
"SortingFacesToSkipAfterSortBeforeLoad": 0,
"SortingFacesToTakeAfterSortBeforeLoad": 55000,
"SortingMaximumPerFaceShouldBeHigh": 1000,
"SortingMaximumPerKey": 27,
"SortingSigma": 3,
"TestDistanceResults": true,
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
@ -154,20 +178,16 @@
"1982-05-02_00"
],
"LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions": [
"1920 x 1080"
"7680 x 4320"
],
"LoadOrCreateThenSaveDistanceResultsForOutputResolutions": [
"1920 x 1080"
"7680 x 4320"
],
"LoadOrCreateThenSaveImageFacesResultsForOutputResolutions": [
"1920 x 1080"
"7680 x 4320"
],
"OutputResolutions": [
"176 x 176",
"256 x 256",
"353 x 353",
"1024 x 768",
"1920 x 1080"
"7680 x 4320"
],
"PropertyContentCollectionFiles": [],
"SaveFaceLandmarkForOutputResolutions": [
@ -175,7 +195,6 @@
"256 x 256"
],
"SaveShortcutsForOutputResolutions": [
"1920 x 1080"
],
"ValidImageFormatExtensions": [
".bmp",

View File

@ -54,6 +54,10 @@
"CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-09-15",
"DistanceFactor": 8,
"FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8,
"FaceDistancePermyriad": 10000,
"FaceDistanceTolerance": 0.25,
"FileNameDirectorySeparator": ".Z.",
"ForceFaceLastWriteTimeToCreationTime": false,
"ForceMetadataLastWriteTimeToCreationTime": false,
@ -61,7 +65,14 @@
"ForceResizeLastWriteTimeToCreationTime": false,
"LoadOrCreateThenSaveIndex": false,
"LocationConfidenceFactor": 2,
"LocationDigits": 6,
"LocationFactor": 1000000,
"MapLogicSigma": 3,
"MappedMaxIndex": 1034720,
"MappingSaveFaceEncoding": false,
"MappingSaveMapped": false,
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping": false,
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping": false,
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
"MaxItemsInDistanceCollection": 50,
"ModelDirectory": "L:/GitHub/dlib-models",
@ -75,6 +86,9 @@
"OverrideForResizeImages": false,
"PaddingLoops": 5,
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PersonBirthdayFirstYear": 1500,
"PersonBirthdayFormat": "yyyy-MM-dd_HH",
"PersonKeyFormat": "yyyy-MM-dd_HH",
"PopulatePropertyId": true,
"PredictorModelName": "Large",
"PropertiesChangedForDistance": false,
@ -83,11 +97,21 @@
"PropertiesChangedForMetadata": false,
"PropertiesChangedForProperty": false,
"PropertiesChangedForResize": false,
"ResultAllInOne": "_ _ _",
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"Reverse": false,
"RootDirectory": "E:/Images",
"SaveFullYearOfRandomFiles": true,
"SaveResizedSubFiles": true,
"SkipSearch": false,
"SortingDaysDeltaTolerance": 700,
"SortingFacesToSkipAfterSortBeforeLoad": 0,
"SortingFacesToTakeAfterSortBeforeLoad": 55000,
"SortingMaximumPerFaceShouldBeHigh": 1000,
"SortingMaximumPerKey": 27,
"SortingSigma": 3,
"TestDistanceResults": true,
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [

View File

@ -54,6 +54,10 @@
"CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-09-15",
"DistanceFactor": 8,
"FaceDistanceHiddenImageFactor": 2,
"FaceDistanceMinimumConfidence": 0.8,
"FaceDistancePermyriad": 10000,
"FaceDistanceTolerance": 0.25,
"FileNameDirectorySeparator": ".Z.",
"ForceFaceLastWriteTimeToCreationTime": false,
"ForceMetadataLastWriteTimeToCreationTime": false,
@ -61,7 +65,14 @@
"ForceResizeLastWriteTimeToCreationTime": false,
"LoadOrCreateThenSaveIndex": false,
"LocationConfidenceFactor": 2,
"LocationDigits": 6,
"LocationFactor": 1000000,
"MapLogicSigma": 3,
"MappedMaxIndex": 1034720,
"MappingSaveFaceEncoding": false,
"MappingSaveMapped": false,
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping": false,
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping": false,
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
"MaxItemsInDistanceCollection": 50,
"ModelDirectory": "C:/GitHub/dlib-models",
@ -75,6 +86,9 @@
"OverrideForResizeImages": false,
"PaddingLoops": 5,
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PersonBirthdayFirstYear": 1500,
"PersonBirthdayFormat": "yyyy-MM-dd_HH",
"PersonKeyFormat": "yyyy-MM-dd_HH",
"PopulatePropertyId": true,
"PredictorModelName": "Large",
"PropertiesChangedForDistance": false,
@ -83,11 +97,21 @@
"PropertiesChangedForMetadata": false,
"PropertiesChangedForProperty": false,
"PropertiesChangedForResize": false,
"ResultAllInOne": "_ _ _",
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"Reverse": false,
"RootDirectory": "D:/Images",
"SaveFullYearOfRandomFiles": true,
"SaveResizedSubFiles": true,
"SkipSearch": false,
"SortingDaysDeltaTolerance": 700,
"SortingFacesToSkipAfterSortBeforeLoad": 0,
"SortingFacesToTakeAfterSortBeforeLoad": 55000,
"SortingMaximumPerFaceShouldBeHigh": 1000,
"SortingMaximumPerKey": 27,
"SortingSigma": 3,
"TestDistanceResults": true,
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [

View File

@ -0,0 +1,80 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Map.Models;
public class Configuration
{
public int FaceDistanceHiddenImageFactor { init; get; }
public int FaceDistancePermyriad { init; get; }
public double FaceDistanceMinimumConfidence { init; get; }
public double FaceDistanceTolerance { init; get; }
public int LocationDigits { init; get; }
public int LocationFactor { init; get; }
public int MapLogicSigma { init; get; }
public bool MappingSaveFaceEncoding { init; get; }
public bool MappingSaveMapped { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping { init; get; }
public int PersonBirthdayFirstYear { init; get; }
public string PersonBirthdayFormat { init; get; }
public string PersonKeyFormat { init; get; }
public int SortingDaysDeltaTolerance { init; get; }
public int SortingFacesToSkipAfterSortBeforeLoad { init; get; }
public int SortingFacesToTakeAfterSortBeforeLoad { init; get; }
public int SortingMaximumPerFaceShouldBeHigh { init; get; }
public int SortingMaximumPerKey { init; get; }
public int SortingSigma { init; get; }
[JsonConstructor]
public Configuration(int faceDistanceHiddenImageFactor,
int faceDistancePermyriad,
double faceDistanceMinimumConfidence,
double faceDistanceTolerance,
int locationDigits,
int locationFactor,
int mapLogicSigma,
bool mappingSaveFaceEncoding,
bool mappingSaveMapped,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping,
int personBirthdayFirstYear,
string personBirthdayFormat,
string personKeyFormat,
int sortingDaysDeltaTolerance,
int sortingFacesToSkipAfterSortBeforeLoad,
int sortingFacesToTakeAfterSortBeforeLoad,
int sortingMaximumPerFaceShouldBeHigh,
int sortingMaximumPerKey,
int sortingSigma)
{
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistancePermyriad = faceDistancePermyriad;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
FaceDistanceTolerance = faceDistanceTolerance;
LocationDigits = locationDigits;
LocationFactor = locationFactor;
MapLogicSigma = mapLogicSigma;
MappingSaveFaceEncoding = mappingSaveFaceEncoding;
MappingSaveMapped = mappingSaveMapped;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping;
PersonBirthdayFirstYear = personBirthdayFirstYear;
PersonBirthdayFormat = personBirthdayFormat;
PersonKeyFormat = personKeyFormat;
SortingDaysDeltaTolerance = sortingDaysDeltaTolerance;
SortingFacesToSkipAfterSortBeforeLoad = sortingFacesToSkipAfterSortBeforeLoad;
SortingFacesToTakeAfterSortBeforeLoad = sortingFacesToTakeAfterSortBeforeLoad;
SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
SortingMaximumPerKey = sortingMaximumPerKey;
SortingSigma = sortingSigma;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -1,6 +1,5 @@
using ShellProgressBar;
using System.Text.Json;
using View_by_Distance.Property.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods;
using WindowsShortcutFactory;
@ -23,8 +22,12 @@ public class MapLogic
public Dictionary<int, int[]> IndicesFromNew => _IndicesFromNew;
private readonly long _Ticks;
private const int _Mapping = 1;
private const int _Sorting = 2;
private Configuration? _Configuration;
private readonly Serilog.ILogger? _Log;
private readonly Configuration _Configuration;
private const int _ForceSingleImage = 3;
private readonly int _MaxDegreeOfParallelism;
private readonly string _FacesFilenameExtension;
private readonly string _ResizeFilenameExtension;
private readonly string _FacePartsFilenameExtension;
@ -32,18 +35,21 @@ public class MapLogic
private readonly string _ZPropertyHolderContentDirectory;
private readonly string _ZPropertyHolderContentTicksDirectory;
private readonly string _ZPropertyHolderSingletonTicksDirectory;
private readonly Property.Models.Configuration _PropertyConfiguration;
public MapLogic(int maxDegreeOfParallelism, Configuration configuration, string resizeFilenameExtension, string facesFilenameExtension, string facesHiddenFilenameExtension, string facePartsFilenameExtension, long ticks, Person[] people, string peopleDateGroupDirectory, string zResultsFullGroupDirectory)
public MapLogic(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, string resizeFilenameExtension, string facesFilenameExtension, string facesHiddenFilenameExtension, string facePartsFilenameExtension, long ticks, Person[] people, string peopleDateGroupDirectory, string zResultsFullGroupDirectory, Configuration? configuration, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance? distance)
{
_Ticks = ticks;
_PersonKeysRanges = new();
_Configuration = configuration;
_Log = Serilog.Log.ForContext<MapLogic>();
_PropertyConfiguration = propertyConfiguration;
_FacesFilenameExtension = facesFilenameExtension;
_MaxDegreeOfParallelism = maxDegreeOfParallelism;
_ResizeFilenameExtension = resizeFilenameExtension;
_FacePartsFilenameExtension = facePartsFilenameExtension;
_FacesHiddenFilenameExtension = facesHiddenFilenameExtension;
if (configuration.VerifyToSeason is null || !configuration.VerifyToSeason.Any())
if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any())
throw new Exception();
string json;
string[] files;
@ -54,7 +60,7 @@ public class MapLogic
Dictionary<int, int[]>? keyValuePairs;
List<KeyValuePair<int, int[]>>? collection;
Dictionary<int, int[]> indicesFromNew = new();
string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory);
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
Dictionary<long, (string, int?, PersonBirthday[], long)> peopleKeyValuePairs = new();
string zPropertyHolderContentDirectory = Path.Combine(zResultsFullGroupDirectory, "()");
string zPropertyHolderSingletonDirectory = Path.Combine(zResultsFullGroupDirectory, "{}");
@ -72,7 +78,7 @@ public class MapLogic
_ = Directory.CreateDirectory(zPropertyHolderContentDirectory);
if (!Directory.Exists(zPropertyHolderPeopleContentDirectory))
_ = Directory.CreateDirectory(zPropertyHolderPeopleContentDirectory);
Stateless.ByDeterministicHashCode.SetByRef(maxDegreeOfParallelism, ticks, _ResizeFilenameExtension, people, skipCollection, peopleKeyValuePairs, notMappedTicks, idThenNormalizedPixelPercentageKeyValuePairs, incorrectIdThenNormalizedPixelPercentageKeyValuePairs, zPropertyHolderContentDirectory, zPropertyHolderPeopleContentDirectory);
Stateless.ByRef.Set(propertyConfiguration, configuration, ticks, _ResizeFilenameExtension, people, zPropertyHolderContentDirectory, zPropertyHolderPeopleContentDirectory, distinctFilteredFaces, distance, skipCollection, peopleKeyValuePairs, notMappedTicks, idThenNormalizedPixelPercentageKeyValuePairs, incorrectIdThenNormalizedPixelPercentageKeyValuePairs);
if (!Directory.Exists(zPropertyHolderContentTicksDirectory))
_ = Directory.CreateDirectory(zPropertyHolderContentTicksDirectory);
files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs-6*.json", SearchOption.TopDirectoryOnly);
@ -85,10 +91,10 @@ public class MapLogic
if (keyValuePairs is null)
throw new NullReferenceException(nameof(keyValuePairs));
}
foreach (string propertyContentCollectionFile in configuration.PropertyContentCollectionFiles)
foreach (string propertyContentCollectionFile in propertyConfiguration.PropertyContentCollectionFiles)
{
fullPath = Path.GetFullPath(string.Concat(rootDirectoryParent, propertyContentCollectionFile));
if (fullPath.Contains(configuration.RootDirectory))
if (fullPath.Contains(propertyConfiguration.RootDirectory))
continue;
if (!File.Exists(fullPath))
continue;
@ -115,8 +121,12 @@ public class MapLogic
_IncorrectIdThenNormalizedPixelPercentageKeyValuePairs = incorrectIdThenNormalizedPixelPercentageKeyValuePairs;
}
public MapLogic(int maxDegreeOfParallelism, Configuration configuration, string outputExtension, long ticks, Person[] people, string peopleDateGroupDirectory, string zResultsFullGroupDirectory) :
this(maxDegreeOfParallelism, configuration, outputExtension, outputExtension, outputExtension, outputExtension, ticks, people, peopleDateGroupDirectory, zResultsFullGroupDirectory)
public MapLogic(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, string resizeFilenameExtension, string facesFilenameExtension, string facesHiddenFilenameExtension, string facePartsFilenameExtension, long ticks, Person[] people, string peopleDateGroupDirectory, string zResultsFullGroupDirectory) :
this(maxDegreeOfParallelism, propertyConfiguration, resizeFilenameExtension, facesFilenameExtension, facesHiddenFilenameExtension, facePartsFilenameExtension, ticks, people, peopleDateGroupDirectory, zResultsFullGroupDirectory, null, new(), null)
{ }
public MapLogic(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, string outputExtension, long ticks, Person[] people, string peopleDateGroupDirectory, string zResultsFullGroupDirectory) :
this(maxDegreeOfParallelism, propertyConfiguration, outputExtension, outputExtension, outputExtension, outputExtension, ticks, people, peopleDateGroupDirectory, zResultsFullGroupDirectory, null, new(), null)
{ }
public override string ToString()
@ -125,6 +135,8 @@ public class MapLogic
return result;
}
public void Update(Configuration configuration) => _Configuration = configuration;
public bool Skip(double deterministicHashCodeKey) => _SkipCollection.Contains(deterministicHashCodeKey);
private long LogDelta(long ticks, string? methodName)
@ -154,6 +166,8 @@ public class MapLogic
public List<Sorting> GetSortingCollection(int i, FaceDistance faceDistanceEncoding, List<FaceDistance> faceDistanceLengths, bool anyLowerThanTolerance)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<Sorting> results = new();
Sorting sorting;
FaceDistance faceDistanceLength;
@ -180,7 +194,7 @@ public class MapLogic
if (!keyValuePairs.ContainsKey(faceDistanceLength.NormalizedPixelPercentage.Value))
continue;
personKeysRangesCollection = GetPersonKeysRangesCollection(keyValuePairs[faceDistanceLength.NormalizedPixelPercentage.Value]);
sorting = ISorting.Get(Shared.Models.Stateless.IFaceDistance.Permyriad, Shared.Models.Stateless.IFaceDistance.Tolerance, faceDistanceEncoding, faceDistanceLength, anyLowerThanTolerance, personKeysRangesCollection);
sorting = ISorting.Get(_Configuration.FaceDistancePermyriad, _Configuration.FaceDistanceTolerance, faceDistanceEncoding, faceDistanceLength, anyLowerThanTolerance, personKeysRangesCollection);
if (sorting.DistancePermyriad == 0)
continue;
if (sorting.Id == faceDistanceEncoding.Id)
@ -196,6 +210,8 @@ public class MapLogic
public void SaveShortcuts(string[] juliePhares, List<Face> distinctFilteredFaces)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
string fileName;
string fullName;
string personKeyFormatted;
@ -210,7 +226,7 @@ public class MapLogic
if (face.Mapping is null)
throw new NotSupportedException();
personBirthday = IPersonBirthday.GetPersonBirthday(personKey.Value);
personKeyFormatted = IPersonBirthday.GetFormatted(Shared.Models.Stateless.IPersonBirthday.Format, personBirthday);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
if (juliePhares.Contains(personKeyFormatted) && !string.IsNullOrEmpty(copyDirectory))
{
if (!Directory.Exists(copyDirectory))
@ -241,25 +257,6 @@ public class MapLogic
}
}
private void UseKeyValuePairsSaveFaceEncoding(int maxDegreeOfParallelism, SortingContainer[] sortingContainers)
{
Dictionary<long, long> personKeyAliases = new();
Dictionary<int, List<Face>> keyValuePairs = new();
List<(PersonBirthday, int, int)> idThenNormalizedPixelPercentageCollection = new();
List<(PersonBirthday, int, int)> incorrectIdThenNormalizedPixelPercentageCollection = new();
foreach (SortingContainer sortingContainer in sortingContainers)
{
if (sortingContainer.Face.FaceEncoding is null || sortingContainer.Face.Location?.NormalizedPixelPercentage is null)
throw new NotSupportedException();
if (sortingContainer.Face.Mapping is null)
throw new NotSupportedException();
if (!keyValuePairs.ContainsKey(sortingContainer.Face.Mapping.MappingFromItem.Id))
keyValuePairs.Add(sortingContainer.Face.Mapping.MappingFromItem.Id, new());
keyValuePairs[sortingContainer.Face.Mapping.MappingFromItem.Id].Add(sortingContainer.Face);
}
Stateless.ByDeterministicHashCode.SetCollections(maxDegreeOfParallelism, _Ticks, _ZPropertyHolderContentDirectory, personKeyAliases, idThenNormalizedPixelPercentageCollection, incorrectIdThenNormalizedPixelPercentageCollection, keyValuePairs);
}
private static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, long minimumDateTimeTicks, bool? isWrongYear)
{
int years;
@ -298,8 +295,10 @@ public class MapLogic
return result;
}
private static Dictionary<int, PersonBirthday[]> GetKeyValuePairs(string json)
private Dictionary<int, PersonBirthday[]> GetKeyValuePairs(string json)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
Dictionary<int, PersonBirthday[]> results = new();
PersonBirthday? personBirthday;
List<PersonBirthday> personBirthdays;
@ -311,7 +310,7 @@ public class MapLogic
personBirthdays = new();
foreach (string personKey in keyValuePair.Value)
{
personBirthday = IPersonBirthday.GetPersonBirthday(Shared.Models.Stateless.IPersonBirthday.Format, personKey);
personBirthday = IPersonBirthday.GetPersonBirthday(_Configuration.PersonBirthdayFormat, personKey);
if (personBirthday is null)
continue;
}
@ -322,10 +321,13 @@ public class MapLogic
return results;
}
private int AddToMapping(List<Face> distinctFilteredFaces)
public int AddToMapping(List<Face> distinctFilteredFaces)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int result = 0;
long personKey;
int by = _Mapping;
const int zero = 0;
int? approximateYears;
string mappingSegmentB;
@ -334,7 +336,6 @@ public class MapLogic
PersonBirthday personBirthday;
List<PersonBirthday> personBirthdays = new();
Dictionary<int, PersonBirthday[]> keyValuePairs;
int by = Shared.Models.Stateless.ISorting.Mapping;
(string DisplayDirectoryName, int? ApproximateYears, PersonBirthday[] PersonBirthdays, long PersonKey) person;
foreach (Face face in distinctFilteredFaces)
{
@ -360,7 +361,7 @@ public class MapLogic
approximateYears = person.ApproximateYears;
personBirthday = person.PersonBirthdays[zero];
displayDirectoryName = person.DisplayDirectoryName;
personKeyFormatted = IPersonBirthday.GetFormatted(Shared.Models.Stateless.IPersonBirthday.Format, personBirthday);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, approximateYears, face.Mapping.MappingFromItem);
face.Mapping.UpdateMappingFromPerson(approximateYears, by, displayDirectoryName, personBirthday, mappingSegmentB);
}
@ -374,7 +375,7 @@ public class MapLogic
string[] directories = (from l in saveContainers select l.Directory).Distinct().ToArray();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
string message = $") {saveContainers.Count:000} save(s) - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = false };
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
foreach (string directory in directories)
{
if (string.IsNullOrEmpty(directory))
@ -424,19 +425,21 @@ public class MapLogic
}
}
private void SaveNotMappedTicks()
public void SaveNotMappedTicks(Property.Models.Configuration propertyConfiguration)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
string directory;
string personKeyFormatted;
SaveContainer saveContainer;
PersonBirthday personBirthday;
List<SaveContainer> saveContainers = new();
const string facePopulatedKey = nameof(Sorting);
const string facePopulatedKey = nameof(_Sorting);
foreach (long personKey in _NotMappedPersonKeys)
{
personBirthday = IPersonBirthday.GetPersonBirthday(personKey);
personKeyFormatted = IPersonBirthday.GetFormatted(Shared.Models.Stateless.IPersonBirthday.Format, personBirthday);
directory = Path.Combine(_ZPropertyHolderContentTicksDirectory, $"{facePopulatedKey}NotMapped", personKeyFormatted, Property.Models.Stateless.IResult.AllInOne);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
directory = Path.Combine(_ZPropertyHolderContentTicksDirectory, $"{facePopulatedKey}NotMapped", personKeyFormatted, propertyConfiguration.ResultAllInOne);
saveContainer = new(directory);
saveContainers.Add(saveContainer);
}
@ -445,6 +448,8 @@ public class MapLogic
public List<(Face, long?, (string, string, string, string))> GetCollection(List<Face> distinctFilteredFaces)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<(Face, long?, (string, string, string, string))> results = new();
int years;
long? personKey;
@ -504,7 +509,7 @@ public class MapLogic
subDirectoryName = $"^{years:000}";
}
}
personKeyFormatted = IPersonBirthday.GetFormatted(Shared.Models.Stateless.IPersonBirthday.Format, personBirthday);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
directory = Path.Combine(_ZPropertyHolderContentTicksDirectory, "Shortcuts", personKeyFormatted, subDirectoryName);
if (face.FaceEncoding is not null && face.Location?.NormalizedPixelPercentage is not null)
copyDirectory = Path.Combine(_ZPropertyHolderContentTicksDirectory, "Images", personKeyFormatted, subDirectoryName);
@ -550,6 +555,8 @@ public class MapLogic
private int UpdateFromSortingContainers(SortingContainer[] sortingContainers)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int result = 0;
Dictionary<int, HashSet<int>> results = new();
string key;
@ -557,22 +564,23 @@ public class MapLogic
const int zero = 0;
HashSet<int> hashSet;
string mappingSegmentB;
const int by = _Sorting;
string personKeyFormatted;
List<Mapping> checkCollection;
PersonBirthday personBirthday;
PersonBirthday[] personBirthdays;
Dictionary<int, PersonBirthday[]> keyValuePairs;
const int by = Shared.Models.Stateless.ISorting.Sorting;
Dictionary<string, List<Mapping>> checkKeyValuePairs = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
(string DisplayDirectoryName, int? ApproximateYears, PersonBirthday[] PersonBirthdays, long PersonKey) person;
string message = $") {sortingContainers.Length:000} Update From Sorting Container(s) - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = false };
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
foreach (KeyValuePair<int, Dictionary<int, PersonBirthday[]>> keyValuePair in _IdThenNormalizedPixelPercentageKeyValuePairs)
results.Add(keyValuePair.Key, (from l in keyValuePair.Value select l.Key).ToHashSet());
using ProgressBar progressBar = new(sortingContainers.Length, message, options);
foreach (SortingContainer sortingContainer in sortingContainers)
{
progressBar.Tick();
if (sortingContainer.Face.Mapping is null)
throw new NotSupportedException();
if (!_IdThenNormalizedPixelPercentageKeyValuePairs.ContainsKey(sortingContainer.Sorting.Id))
@ -586,7 +594,7 @@ public class MapLogic
if (!keyValuePairs.ContainsKey(sortingContainer.Sorting.NormalizedPixelPercentage))
throw new NotSupportedException();
personBirthdays = keyValuePairs[sortingContainer.Sorting.NormalizedPixelPercentage];
if (sortingContainer.Face.Mapping.MappingFromLocation.Confidence < Shared.Models.Stateless.IFaceDistance.MinimumConfidence || sortingContainer.Sorting.DistancePermyriad > Shared.Models.Stateless.IFaceDistance.Permyriad || sortingContainer.Sorting.DaysDelta > Shared.Models.Stateless.ISorting.DaysDeltaTolerance)
if (sortingContainer.Face.Mapping.MappingFromLocation.Confidence < _Configuration.FaceDistanceMinimumConfidence || sortingContainer.Sorting.DistancePermyriad > _Configuration.FaceDistancePermyriad || sortingContainer.Sorting.DaysDelta > _Configuration.SortingDaysDeltaTolerance)
continue;
for (int i = 0; i < personBirthdays.Length; i++)
{
@ -595,13 +603,13 @@ public class MapLogic
continue;
person = _PeopleKeyValuePairs[personKey];
personBirthday = person.PersonBirthdays[zero];
personKeyFormatted = IPersonBirthday.GetFormatted(Shared.Models.Stateless.IPersonBirthday.Format, personBirthday);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
mappingSegmentB = GetMappingSegmentB(_Ticks, personBirthday, person.ApproximateYears, sortingContainer.Face.Mapping.MappingFromItem);
key = string.Concat(personKeyFormatted, '\t', mappingSegmentB);
if (!checkKeyValuePairs.ContainsKey(key))
checkKeyValuePairs.Add(key, new());
checkCollection = checkKeyValuePairs[key];
if (checkCollection.Count > Shared.Models.Stateless.ISorting.MaximumPerKey)
if (checkCollection.Count > _Configuration.SortingMaximumPerKey)
continue;
_ = hashSet.Add(sortingContainer.Sorting.NormalizedPixelPercentage);
sortingContainer.Face.Mapping.UpdateMappingFromPerson(person.ApproximateYears, by, person.DisplayDirectoryName, personBirthday, mappingSegmentB);
@ -613,16 +621,16 @@ public class MapLogic
return result;
}
internal void ForceSingleImage(IEnumerable<Face> distinctFilteredFaces)
internal void ForceSingleImage(Property.Models.Configuration propertyConfiguration, IEnumerable<Face> distinctFilteredFaces)
{
long? personKey;
const int zero = 0;
string mappingSegmentB;
int by = _ForceSingleImage;
int? approximateYears = null;
PersonBirthday personBirthday;
int by = Shared.Models.Stateless.ISorting.ForceSingleImage;
string displayDirectoryName = propertyConfiguration.ResultAllInOne;
Face[] orderedDistinctFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromLocation.Confidence descending select l).ToArray();
const string displayDirectoryName = Property.Models.Stateless.IResult.AllInOne;
foreach (Face face in orderedDistinctFilteredFaces)
{
if (face.Mapping is null)
@ -639,6 +647,8 @@ public class MapLogic
private List<SaveContainer> GetMappingSaveContainers(string dFacesContentDirectory, string d2ResultsFullGroupDirectory, List<Face> filteredFaces)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<SaveContainer> results = new();
string by;
string json;
@ -654,6 +664,7 @@ public class MapLogic
SaveContainer saveContainer;
FileHolder facePartsFileHolder;
FileHolder hiddenFaceFileHolder;
Dictionary<string, int> keyValuePairs = new();
foreach (Face face in filteredFaces)
{
if (face.Mapping is null)
@ -665,24 +676,27 @@ public class MapLogic
continue;
if (string.IsNullOrEmpty(face.Mapping.MappingFromPerson.SegmentB))
throw new NotSupportedException();
personKeyFormatted = IPersonBirthday.GetFormatted(Shared.Models.Stateless.IPersonBirthday.Format, face.Mapping.MappingFromPerson.PersonBirthday);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, face.Mapping.MappingFromPerson.PersonBirthday);
if (face.Mapping.MappingFromPerson.By is null)
by = $"{nameof(Mapping)}Null";
by = $"{nameof(_Mapping)}Null";
else
{
if (face.Mapping.MappingFromPerson.By == Shared.Models.Stateless.ISorting.Mapping && !Shared.Models.Stateless.IMapping.SaveMapped)
if (face.Mapping.MappingFromPerson.By == _Mapping && !_Configuration.MappingSaveMapped)
continue;
by = face.Mapping.MappingFromPerson.By.Value switch
{
Shared.Models.Stateless.ISorting.Mapping => nameof(Mapping),
Shared.Models.Stateless.ISorting.Sorting => nameof(Sorting),
Shared.Models.Stateless.ISorting.ForceSingleImage => nameof(MapLogic.ForceSingleImage),
_Mapping => nameof(_Mapping),
_Sorting => nameof(_Sorting),
_ForceSingleImage => nameof(MapLogic.ForceSingleImage),
_ => throw new NotImplementedException()
};
}
directory = Path.Combine(_ZPropertyHolderContentTicksDirectory, by, personKeyFormatted, face.Mapping.MappingFromPerson.SegmentB);
if (!keyValuePairs.ContainsKey(directory))
keyValuePairs.Add(directory, 0);
keyValuePairs[directory]++;
saveContainer = new(Path.Combine(directory, "!"));
if (face.Mapping.MappingFromPerson.By.HasValue && face.Mapping.MappingFromPerson.By == Shared.Models.Stateless.ISorting.Sorting)
if (face.Mapping.MappingFromPerson.By.HasValue && face.Mapping.MappingFromPerson.By == _Sorting && keyValuePairs[directory] > 3)
results.Add(saveContainer);
if (face.Mapping.MappingFromPerson.By is not null)
personDirectory = Path.Combine(directory, face.Mapping.MappingFromPerson.DisplayDirectoryName, "lnk");
@ -692,19 +706,19 @@ public class MapLogic
results.Add(saveContainer);
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, face.Mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension));
facePartsDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, face.Mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension));
checkFile = Path.Combine(directory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKeyDisplay}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
faceFileHolder = new(Path.Combine(facesDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKeyDisplay}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_FacesFilenameExtension}"));
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKeyDisplay}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_FacesHiddenFilenameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKeyDisplay}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_FacePartsFilenameExtension}"));
checkFile = Path.Combine(directory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
faceFileHolder = new(Path.Combine(facesDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_FacesFilenameExtension}"));
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_FacesHiddenFilenameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_FacePartsFilenameExtension}"));
if (string.IsNullOrEmpty(personDirectory))
shortcutFile = string.Empty;
else
shortcutFile = Path.Combine(personDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKeyDisplay}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
shortcutFile = Path.Combine(personDirectory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, string.Empty, facePartsFileHolder, face.Mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
results.Add(saveContainer);
if (!string.IsNullOrEmpty(checkFile) && Shared.Models.Stateless.IMapping.SaveFaceEncoding)
if (!string.IsNullOrEmpty(checkFile) && _Configuration.MappingSaveFaceEncoding)
{
checkFile = Path.Combine(directory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKeyDisplay}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.json");
checkFile = Path.Combine(directory, $"{face.Mapping.MappingFromLocation.DeterministicHashCodeKey}{face.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.json");
json = JsonSerializer.Serialize(face.FaceEncoding);
saveContainer = new(checkFile, directory, json);
results.Add(saveContainer);
@ -714,28 +728,22 @@ public class MapLogic
return results;
}
public void CommonWork(int maxDegreeOfParallelism, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, List<Face> distinctFilteredFaces, SortingContainer[] sortingContainers)
public void ForceSingleImageThenSaveMapping(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, List<Face> distinctFilteredFaces, SortingContainer[] sortingContainers, int totalNotMapped)
{
List<SaveContainer> saveContainers;
if (!_IdThenNormalizedPixelPercentageKeyValuePairs.Any())
UseKeyValuePairsSaveFaceEncoding(maxDegreeOfParallelism, sortingContainers);
int totalNotMapped = AddToMapping(distinctFilteredFaces);
if (totalNotMapped == 0)
saveContainers = new();
else if (!sortingContainers.Any())
if (!sortingContainers.Any())
{
ForceSingleImage(distinctFilteredFaces);
ForceSingleImage(propertyConfiguration, distinctFilteredFaces);
saveContainers = GetMappingSaveContainers(dFacesContentDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces);
}
else
{
int updated = UpdateFromSortingContainers(sortingContainers);
if (totalNotMapped - updated > 0)
ForceSingleImage(distinctFilteredFaces);
ForceSingleImage(propertyConfiguration, distinctFilteredFaces);
saveContainers = GetMappingSaveContainers(dFacesContentDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces);
}
SaveContainers(saveContainers);
SaveNotMappedTicks();
}
private static double GetStandardDeviation(IEnumerable<long> values, double average)
@ -782,16 +790,16 @@ public class MapLogic
}
}
public void SetPersonTicks(string outputResolution, Face[] filteredFaces)
public void SetPersonTicks(List<Face> distinctFilteredFaces)
{
PersonBirthday[] personBirthdays;
Dictionary<int, PersonBirthday[]> keyValuePairs;
Dictionary<long, List<long>> personTicks = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
string message = $") {filteredFaces.Length:000} Set Person Ticks - {totalSeconds} total second(s) - {outputResolution}";
string message = $") {distinctFilteredFaces.Count:000} Set Person Ticks - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(filteredFaces.Length, message, options);
foreach (Face face in filteredFaces)
using ProgressBar progressBar = new(distinctFilteredFaces.Count, message, options);
foreach (Face face in distinctFilteredFaces)
{
progressBar.Tick();
if (face.Mapping is null)

View File

@ -5,10 +5,10 @@ using View_by_Distance.Shared.Models;
namespace View_by_Distance.Map.Models.Stateless;
public class ByDeterministicHashCode
public class ByRef
{
private static void SetOther(string resizeFilenameExtension, Person[] people, string deterministicHashCodePeopleDirectory, List<double> skipCollection, Dictionary<long, long> personKeyAliases, List<(string, int?, PersonBirthday[], long)> peopleCollection)
private static void SetOther(Property.Models.Configuration propertyConfiguration, Configuration configuration, string resizeFilenameExtension, Person[] people, string deterministicHashCodePeopleDirectory, List<double> skipCollection, Dictionary<long, long> personKeyAliases, List<(string, int?, PersonBirthday[], long)> peopleCollection)
{
long pK;
string json;
@ -32,7 +32,7 @@ public class ByDeterministicHashCode
Dictionary<string, Person> personKeyValuePairs = new();
foreach (Person person in people)
{
personKeyFormatted = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(Shared.Models.Stateless.IPersonBirthday.Format, person.Birthday);
personKeyFormatted = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, person.Birthday);
if (personKeyValuePairs.ContainsKey(personKeyFormatted))
break;
personKeyValuePairs.Add(personKeyFormatted, person);
@ -71,11 +71,11 @@ public class ByDeterministicHashCode
{
personKeyFormatted = Path.GetFileName(personKeyDirectory);
if (!DateTime.TryParseExact(personKeyFormatted, "MM.dd.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime birthday))
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(Shared.Models.Stateless.IPersonBirthday.Format, personKeyFormatted);
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormatted);
else
{
personBirthday = new PersonBirthday(birthday);
personKeyFormatted = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(Shared.Models.Stateless.IPersonBirthday.Format, personBirthday);
personKeyFormatted = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personBirthday);
convertedPersonKeyDirectory = Path.Combine(personDisplayDirectory, personKeyFormatted);
if (!Directory.Exists(convertedPersonKeyDirectory))
Directory.Move(personKeyDirectory, convertedPersonKeyDirectory);
@ -89,7 +89,7 @@ public class ByDeterministicHashCode
foreach (string personKeyDirectory in personKeyDirectories)
{
personKeyFormatted = Path.GetFileName(personKeyDirectory);
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(Shared.Models.Stateless.IPersonBirthday.Format, personKeyFormatted);
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormatted);
if (personBirthday is null)
continue;
if (personKeyValuePairs.ContainsKey(personKeyFormatted))
@ -123,25 +123,27 @@ public class ByDeterministicHashCode
}
}
approximateYears = null;
const string displayDirectoryName = Property.Models.Stateless.IResult.AllInOne;
DateTime incrementDate = new(Shared.Models.Stateless.IPersonBirthday.FirstYear, 1, 1);
string displayDirectoryName = propertyConfiguration.ResultAllInOne;
DateTime incrementDate = new(configuration.PersonBirthdayFirstYear, 1, 1);
for (int i = 0; i < 500; i++)
{
personKey = incrementDate.Ticks;
personBirthday = new(incrementDate);
incrementDate = incrementDate.AddDays(1);
personKeyFormatted = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(Shared.Models.Stateless.IPersonBirthday.Format, personBirthday);
personKeyFormatted = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personBirthday);
if (personKeys.Contains(personKey))
continue;
personKeys.Add(personKey);
peopleCollection.Add(new(displayDirectoryName, approximateYears, new PersonBirthday[] { personBirthday }, personKey));
}
}
internal static void SetCollections(int maxDegreeOfParallelism, long ticks, string zPropertyHolderContentDirectory, Dictionary<long, long> personKeyAliases, List<(PersonBirthday, int, int)> idThenNormalizedPixelPercentageCollection, List<(PersonBirthday, int, int)> incorrectIdThenNormalizedPixelPercentageCollection, Dictionary<int, List<Face>> keyValuePairs)
internal static List<(string, char, string, int?, int?, List<Face>?)> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, long ticks, string zPropertyHolderContentDirectory, Dictionary<int, List<Face>> keyValuePairs)
{
List<(string, char, string, int?, int?, List<Face>?)> results = new();
int? id;
string[] files;
long personKey;
List<Face>? faces;
const int zero = 0;
string[] yearDirectories;
string personKeyFormatted;
@ -150,14 +152,12 @@ public class ByDeterministicHashCode
string[] personKeyDirectories;
int? normalizedPixelPercentage;
string[] personNameDirectories;
PersonBirthday? personBirthday;
string[] personNameLinkDirectories;
string? personFirstInitialDirectory;
bool keyValuePairsAny = keyValuePairs.Any();
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string[] ticksDirectories = Directory.GetDirectories(zPropertyHolderContentDirectory, "*", SearchOption.TopDirectoryOnly);
string message = $") {ticksDirectories.Length:000} ticks Director(ies) - {totalSeconds} total second(s)";
string message = $") {ticksDirectories.Length:000} ticks Director(ies) - A - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(ticksDirectories.Length, message, options);
foreach (string ticksDirectory in ticksDirectories)
@ -170,20 +170,8 @@ public class ByDeterministicHashCode
foreach (string personKeyDirectory in personKeyDirectories)
{
personKeyFormatted = Path.GetFileName(personKeyDirectory);
if (personKeyFormatted.Length != Shared.Models.Stateless.IPersonBirthday.Format.Length)
personBirthday = null;
else
{
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(Shared.Models.Stateless.IPersonBirthday.Format, personKeyFormatted);
if (personBirthday is null)
continue;
personKey = personBirthday.Value.Ticks;
if (personKeyAliases.ContainsKey(personKey))
{
personKey = personKeyAliases[personKey];
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
}
}
if (personKeyFormatted.Length != configuration.PersonBirthdayFormat.Length)
continue;
yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string yearDirectory in yearDirectories)
{
@ -196,27 +184,24 @@ public class ByDeterministicHashCode
personFirstInitial = Path.GetFileName(personNameDirectory)[..1];
if (personFirstInitial is null)
continue;
personFirstInitialDirectory = Path.Combine(yearDirectory, personFirstInitial);
files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
personFirstInitialDirectory = Path.Combine(yearDirectory, personFirstInitial.ToString());
if (personNameDirectory != personFirstInitialDirectory)
Directory.Move(personNameDirectory, personFirstInitialDirectory);
files = Directory.GetFiles(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
if (personKeyFormatted == nameof(Models.MapLogic.ForceSingleImage) && files.Any())
throw new Exception($"Move personKey directories up one from {nameof(Models.MapLogic.ForceSingleImage)} and delete {nameof(Models.MapLogic.ForceSingleImage)} directory!");
if (personKeyFormatted == nameof(Sorting) && files.Any())
throw new Exception($"Move personKey directories up one from {nameof(Sorting)} and delete {nameof(Sorting)} directory!");
if (personBirthday is null)
continue;
foreach (string file in files)
{
if (file.EndsWith(".lnk") || file.EndsWith(".json"))
continue;
(id, normalizedPixelPercentage) = Shared.Models.Stateless.Methods.IMapping.GetReversedDeterministicHashCodeKey(Shared.Models.Stateless.ILocation.Digits, keyValuePairsAny, keyValuePairs, file);
(id, normalizedPixelPercentage, faces) = Shared.Models.Stateless.Methods.IMapping.GetReversedDeterministicHashCodeKey(configuration.LocationDigits, keyValuePairsAny, keyValuePairs, file);
if (id is null || normalizedPixelPercentage is null)
continue;
if (personFirstInitial != "!")
idThenNormalizedPixelPercentageCollection.Add(new(personBirthday, id.Value, normalizedPixelPercentage.Value));
else
incorrectIdThenNormalizedPixelPercentageCollection.Add(new(personBirthday, id.Value, normalizedPixelPercentage.Value));
results.Add(new(personKeyFormatted, personFirstInitial[0], file, id, normalizedPixelPercentage, faces));
}
personNameLinkDirectories = Directory.GetDirectories(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
personNameLinkDirectories = Directory.GetDirectories(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personNameLinkDirectory in personNameLinkDirectories)
{
files = Directory.GetFiles(personNameLinkDirectory, "*", SearchOption.TopDirectoryOnly);
@ -228,10 +213,7 @@ public class ByDeterministicHashCode
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personNameLinkDirectory);
}
if (personNameDirectory == personFirstInitialDirectory)
continue;
Directory.Move(personNameDirectory, personFirstInitialDirectory);
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personNameDirectory);
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personFirstInitialDirectory);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(yearDirectory);
}
@ -240,9 +222,10 @@ public class ByDeterministicHashCode
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(ticksDirectory);
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(ticksDirectory);
}
return results;
}
private static void SetKeyValuePairs(List<(PersonBirthday, int, int)> idThenNormalizedPixelPercentageCollection, List<(PersonBirthday, int, int)> incorrectIdThenNormalizedPixelPercentageCollection, Dictionary<int, Dictionary<int, PersonBirthday[]>> idThenNormalizedPixelPercentageKeyValuePairs, Dictionary<int, Dictionary<int, PersonBirthday[]>> incorrectIdThenNormalizedPixelPercentageKeyValuePairs)
private static void SetKeyValuePairs(Configuration configuration, List<(PersonBirthday, int, int)> idThenNormalizedPixelPercentageCollection, List<(PersonBirthday, int, int)> incorrectIdThenNormalizedPixelPercentageCollection, Dictionary<int, Dictionary<int, PersonBirthday[]>> idThenNormalizedPixelPercentageKeyValuePairs, Dictionary<int, Dictionary<int, PersonBirthday[]>> incorrectIdThenNormalizedPixelPercentageKeyValuePairs)
{
string check;
int normalizedPixelPercentageInDecimalForm;
@ -252,7 +235,7 @@ public class ByDeterministicHashCode
if (!idThenNormalizedPixelPercentageScope.ContainsKey(id))
idThenNormalizedPixelPercentageScope.Add(id, new());
check = normalizedPixelPercentage.ToString();
if (check.Length == Shared.Models.Stateless.ILocation.Digits)
if (check.Length == configuration.LocationDigits)
{
if (!idThenNormalizedPixelPercentageScope[id].ContainsKey(normalizedPixelPercentage))
idThenNormalizedPixelPercentageScope[id].Add(normalizedPixelPercentage, new());
@ -260,7 +243,7 @@ public class ByDeterministicHashCode
}
else
{
normalizedPixelPercentageInDecimalForm = int.Parse(check.PadRight(Shared.Models.Stateless.ILocation.Digits, '0'));
normalizedPixelPercentageInDecimalForm = int.Parse(check.PadRight(configuration.LocationDigits, '0'));
if (!idThenNormalizedPixelPercentageScope[id].ContainsKey(normalizedPixelPercentageInDecimalForm))
idThenNormalizedPixelPercentageScope[id].Add(normalizedPixelPercentageInDecimalForm, new());
idThenNormalizedPixelPercentageScope[id][normalizedPixelPercentageInDecimalForm].Add(personBirthday);
@ -278,7 +261,7 @@ public class ByDeterministicHashCode
if (!incorrectIdThenNormalizedPixelPercentageScope.ContainsKey(id))
incorrectIdThenNormalizedPixelPercentageScope.Add(id, new());
check = normalizedPixelPercentage.ToString();
if (check.Length == Shared.Models.Stateless.ILocation.Digits)
if (check.Length == configuration.LocationDigits)
{
if (!incorrectIdThenNormalizedPixelPercentageScope[id].ContainsKey(normalizedPixelPercentage))
incorrectIdThenNormalizedPixelPercentageScope[id].Add(normalizedPixelPercentage, new());
@ -286,7 +269,7 @@ public class ByDeterministicHashCode
}
else
{
normalizedPixelPercentageInDecimalForm = int.Parse(check.PadRight(Shared.Models.Stateless.ILocation.Digits, '0'));
normalizedPixelPercentageInDecimalForm = int.Parse(check.PadRight(configuration.LocationDigits, '0'));
if (!incorrectIdThenNormalizedPixelPercentageScope[id].ContainsKey(normalizedPixelPercentageInDecimalForm))
incorrectIdThenNormalizedPixelPercentageScope[id].Add(normalizedPixelPercentageInDecimalForm, new());
incorrectIdThenNormalizedPixelPercentageScope[id][normalizedPixelPercentageInDecimalForm].Add(personBirthday);
@ -300,19 +283,151 @@ public class ByDeterministicHashCode
}
}
internal static void SetByRef(int maxDegreeOfParallelism, long ticks, string resizeFilenameExtension, Person[] people, List<double> skipCollection, Dictionary<long, (string DisplayDirectoryName, int? ApproximateYears, PersonBirthday[] PersonBirthdays, long PersonKey)> peopleKeyValuePairs, List<long> notMappedPersonKeys, Dictionary<int, Dictionary<int, PersonBirthday[]>> idThenNormalizedPixelPercentageKeyValuePairs, Dictionary<int, Dictionary<int, PersonBirthday[]>> incorrectIdThenNormalizedPixelPercentageKeyValuePairs, string zPropertyHolderContentDirectory, string zPropertyHolderPeopleContentDirectory)
private static string? GetCheckFile(string file, int id, int normalizedPixelPercentage)
{
string? result;
string? fileName = Path.GetFileName(file);
if (fileName is null)
result = null;
else
{
string[] segments = fileName.Split('.');
if (segments.Length != 3)
result = null;
else
{
string extensionLowered = $".{segments[2]}";
string? directoryName = Path.GetDirectoryName(file);
if (string.IsNullOrEmpty(directoryName))
result = null;
else
result = Path.Combine(directoryName, $"{Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(id, normalizedPixelPercentage)}{extensionLowered}.json");
}
}
return result;
}
private static bool Valid(string checkFile, List<Face> faces)
{
bool result = false;
string json;
foreach (Face face in faces)
{
if (face.FaceEncoding is null)
throw new NotSupportedException();
if (faces.Count != 1)
break;
result = true;
if (File.Exists(checkFile))
continue;
json = JsonSerializer.Serialize(face.FaceEncoding);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
}
return result;
}
private static int SetCollectionsAndGet(Configuration configuration, long ticks, Shared.Models.Methods.IFaceDistance? distance, Dictionary<long, long> personKeyAliases, List<(PersonBirthday, int, int)> idThenNormalizedPixelPercentageCollection, List<(PersonBirthday, int, int)> incorrectIdThenNormalizedPixelPercentageCollection, List<(string, char, string, int?, int?, List<Face>?)> collection)
{
int result = 0;
long personKey;
string? checkFile;
List<Face> checkFaces = new();
PersonBirthday? personBirthday;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") {collection.Count:000} ticks Director(ies) - B - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(collection.Count, message, options);
foreach ((string personKeyFormatted, char personFirstInitial, string file, int? id, int? normalizedPixelPercentage, List<Face>? faces) in collection)
{
progressBar.Tick();
if (id is null || normalizedPixelPercentage is null)
continue;
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormatted);
if (personBirthday is null)
continue;
personKey = personBirthday.Value.Ticks;
if (personKeyAliases.ContainsKey(personKey))
{
personKey = personKeyAliases[personKey];
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
}
if (faces is not null)
{
checkFaces.Clear();
foreach (Face face in faces)
{
if (face.Mapping is null)
throw new NotSupportedException();
if (normalizedPixelPercentage.Value != face.Mapping.MappingFromLocation.NormalizedPixelPercentage)
continue;
checkFaces.Add(face);
}
checkFile = GetCheckFile(file, id.Value, normalizedPixelPercentage.Value);
if (string.IsNullOrEmpty(checkFile))
{
result++;
continue;
}
if (checkFaces.Count != 1 && distance is not null && File.Exists(checkFile))
{
checkFaces.Clear();
checkFaces.AddRange(distance.GetMatchingFaces(configuration.FaceDistanceTolerance, checkFile, faces));
}
if (!checkFaces.Any())
{
result++;
continue;
}
if (checkFaces.Count != 1)
{
result++;
continue;
}
if (!Valid(checkFile, checkFaces))
{
result++;
continue;
}
}
if (personFirstInitial != '!')
idThenNormalizedPixelPercentageCollection.Add(new(personBirthday, id.Value, normalizedPixelPercentage.Value));
else
incorrectIdThenNormalizedPixelPercentageCollection.Add(new(personBirthday, id.Value, normalizedPixelPercentage.Value));
}
return result;
}
internal static void Set(Property.Models.Configuration propertyConfiguration, Configuration? configuration, long ticks, string resizeFilenameExtension, Person[] people, string zPropertyHolderContentDirectory, string zPropertyHolderPeopleContentDirectory, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance? distance, List<double> skipCollection, Dictionary<long, (string DisplayDirectoryName, int? ApproximateYears, PersonBirthday[] PersonBirthdays, long PersonKey)> peopleKeyValuePairs, List<long> notMappedPersonKeys, Dictionary<int, Dictionary<int, PersonBirthday[]>> idThenNormalizedPixelPercentageKeyValuePairs, Dictionary<int, Dictionary<int, PersonBirthday[]>> incorrectIdThenNormalizedPixelPercentageKeyValuePairs)
{
if (configuration is null)
throw new NullReferenceException(nameof(configuration));
Dictionary<long, long> personKeyAliases = new();
Dictionary<int, List<Face>> keyValuePairs = new();
List<long> idThenNormalizedPixelPercentagePersonKeys = new();
List<(string, int?, PersonBirthday[], long)> peopleCollection = new();
List<(PersonBirthday, int, int)> idThenNormalizedPixelPercentageCollection = new();
List<(PersonBirthday, int, int)> incorrectIdThenNormalizedPixelPercentageCollection = new();
SetOther(resizeFilenameExtension, people, zPropertyHolderPeopleContentDirectory, skipCollection, personKeyAliases, peopleCollection);
SetCollections(maxDegreeOfParallelism, ticks, zPropertyHolderContentDirectory, personKeyAliases, idThenNormalizedPixelPercentageCollection, incorrectIdThenNormalizedPixelPercentageCollection, keyValuePairs);
SetKeyValuePairs(idThenNormalizedPixelPercentageCollection, incorrectIdThenNormalizedPixelPercentageCollection, idThenNormalizedPixelPercentageKeyValuePairs, incorrectIdThenNormalizedPixelPercentageKeyValuePairs);
SetOther(propertyConfiguration, configuration, resizeFilenameExtension, people, zPropertyHolderPeopleContentDirectory, skipCollection, personKeyAliases, peopleCollection);
foreach (Face face in distinctFilteredFaces)
{
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
throw new NotSupportedException();
if (face.Mapping is null)
throw new NotSupportedException();
if (!keyValuePairs.ContainsKey(face.Mapping.MappingFromItem.Id))
keyValuePairs.Add(face.Mapping.MappingFromItem.Id, new());
keyValuePairs[face.Mapping.MappingFromItem.Id].Add(face);
}
List<(string, char, string, int?, int?, List<Face>?)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, ticks, zPropertyHolderContentDirectory, keyValuePairs);
int unableToMatchCount = SetCollectionsAndGet(configuration, ticks, distance, personKeyAliases, idThenNormalizedPixelPercentageCollection, incorrectIdThenNormalizedPixelPercentageCollection, collection);
SetKeyValuePairs(configuration, idThenNormalizedPixelPercentageCollection, incorrectIdThenNormalizedPixelPercentageCollection, idThenNormalizedPixelPercentageKeyValuePairs, incorrectIdThenNormalizedPixelPercentageKeyValuePairs);
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") {collection.Count:000} ticks Director(ies) - C - {unableToMatchCount} Unable To Match Count / {collection.Count} Collection - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(collection.Count, message, options);
foreach (KeyValuePair<int, Dictionary<int, PersonBirthday[]>> keyValuePair in idThenNormalizedPixelPercentageKeyValuePairs)
{
progressBar.Tick();
foreach (KeyValuePair<int, PersonBirthday[]> keyValue in keyValuePair.Value)
idThenNormalizedPixelPercentagePersonKeys.AddRange(from l in keyValue.Value select l.Value.Ticks);
}
@ -337,7 +452,7 @@ public class ByDeterministicHashCode
{
int? approximateYears = null;
PersonBirthday? personBirthday;
const string displayDirectoryName = Property.Models.Stateless.IResult.AllInOne;
string displayDirectoryName = propertyConfiguration.ResultAllInOne;
foreach (long personKey in idThenNormalizedPixelPercentagePersonKeys)
{
if (!peopleKeyValuePairs.ContainsKey(personKey))

View File

@ -78,7 +78,7 @@ public class B_Metadata
return results;
}
public (int, List<KeyValuePair<string, string>>) GetMetadataCollection(string bResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Item item)
public (int, List<KeyValuePair<string, string>>) GetMetadataCollection(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Item item)
{
List<KeyValuePair<string, string>> results = new();
if (item.Property?.Id is null)
@ -90,7 +90,7 @@ public class B_Metadata
Dictionary<string, List<KeyValuePair<string, string>>>? dictionary;
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "{}"), string.Concat(item.ImageFileHolder.NameWithoutExtension, ".json"));
string bMetadataSingletonFile = Path.Combine(bResultsFullGroupDirectory, "{}", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
string bMetadataSingletonFile = Path.Combine(bResultsFullGroupDirectory, "{}", propertyConfiguration.ResultAllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
FileInfo fileInfo = new(bMetadataSingletonFile);
if (!fileInfo.Exists)
{

View File

@ -144,8 +144,8 @@ public class A_Property
}
else if (!isIgnoreExtension && isValidImageFormatExtension)
{
// if (populateId && (id is null || !indices.Any()) && !_IndicesFromNew.Any() && !_KeyValuePairs.Any())
// throw new Exception("In order to keep six character indices at least one need to have an item!");
if (populateId && (id is null || !indices.Any()) && !_IndicesFromNew.Any() && !_KeyValuePairs.Any())
throw new Exception("May need to move mapLogic constructor! In order to keep six character indices at least one need to have an item!");
try
{
using Image image = Image.FromFile(filteredSourceDirectoryFileHolder.FullName);
@ -641,7 +641,7 @@ public class A_Property
continue;
SetAngleBracketCollection(container.SourceDirectory);
totalSeconds = (int)Math.Truncate(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $"{i:000}.{container.G} / {containersCount:000}) {filteredItems.Length:000} file(s) - {totalSeconds} total second(s) - {container.SourceDirectory}";
message = $"{i + 1:000}.{container.G} / {containersCount:000}) {filteredItems.Length:000} file(s) - {totalSeconds} total second(s) - {container.SourceDirectory}";
ParallelWork(firstPass, exceptions, sourceDirectoryChanges, container, filteredItems, message);
foreach (Exception exception in exceptions)
_Log.Error(string.Concat(container.SourceDirectory, Environment.NewLine, exception.Message, Environment.NewLine, exception.StackTrace), exception);

View File

@ -19,6 +19,10 @@ public class Configuration
[Display(Name = "Populate Properties Id"), Required] public bool? PopulatePropertyId { get; set; }
[Display(Name = "Properties Changed For Property"), Required] public bool? PropertiesChangedForProperty { get; set; }
[Display(Name = "Property Content Collection Files"), Required] public string[] PropertyContentCollectionFiles { get; set; }
[Display(Name = "Result All In One"), Required] public string ResultAllInOne { get; set; }
[Display(Name = "Result Collection"), Required] public string ResultCollection { get; set; }
[Display(Name = "Result Content"), Required] public string ResultContent { get; set; }
[Display(Name = "Result Singleton"), Required] public string ResultSingleton { get; set; }
[Display(Name = "Root Directory"), Required] public string RootDirectory { get; set; }
[Display(Name = "Valid Image Format Extensions"), Required] public string[] ValidImageFormatExtensions { get; set; }
[Display(Name = "Valid Metadata Extensions"), Required] public string[] ValidMetadataExtensions { get; set; }
@ -44,6 +48,14 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.PopulatePropertyId));
if (configuration.PropertiesChangedForProperty is null)
throw new NullReferenceException(nameof(configuration.PropertiesChangedForProperty));
if (configuration.ResultAllInOne is null)
throw new NullReferenceException(nameof(configuration.ResultAllInOne));
if (configuration.ResultCollection is null)
throw new NullReferenceException(nameof(configuration.ResultCollection));
if (configuration.ResultContent is null)
throw new NullReferenceException(nameof(configuration.ResultContent));
if (configuration.ResultSingleton is null)
throw new NullReferenceException(nameof(configuration.ResultSingleton));
if (configuration.WriteBitmapDataBytes is null)
throw new NullReferenceException(nameof(configuration.WriteBitmapDataBytes));
if (configuration.IgnoreExtensions is null)
@ -65,6 +77,10 @@ public class Configuration
configuration.PopulatePropertyId.Value,
configuration.PropertiesChangedForProperty.Value,
configuration.PropertyContentCollectionFiles,
configuration.ResultAllInOne,
configuration.ResultCollection,
configuration.ResultContent,
configuration.ResultSingleton,
configuration.RootDirectory,
configuration.ValidImageFormatExtensions,
configuration.ValidMetadataExtensions,

View File

@ -18,13 +18,34 @@ public class Configuration
public bool PopulatePropertyId { init; get; }
public bool PropertiesChangedForProperty { init; get; }
public string[] PropertyContentCollectionFiles { init; get; }
public string ResultAllInOne { init; get; }
public string ResultCollection { init; get; }
public string ResultContent { init; get; }
public string ResultSingleton { init; get; }
public string[] ValidImageFormatExtensions { init; get; }
public string[] ValidMetadataExtensions { init; get; }
public string[] VerifyToSeason { init; get; }
public bool WriteBitmapDataBytes { init; get; }
[JsonConstructor]
public Configuration(string dateGroup, string fileNameDirectorySeparator, bool forcePropertyLastWriteTimeToCreationTime, string[] ignoreExtensions, int maxImagesInDirectoryForTopLevelFirstPass, string pattern, bool populatePropertyId, bool propertiesChangedForProperty, string[] propertyContentCollectionFiles, string rootDirectory, string[] validImageFormatExtensions, string[] validMetadataExtensions, string[] verifyToSeason, bool writeBitmapDataBytes)
public Configuration(string dateGroup,
string fileNameDirectorySeparator,
bool forcePropertyLastWriteTimeToCreationTime,
string[] ignoreExtensions,
int maxImagesInDirectoryForTopLevelFirstPass,
string pattern,
bool populatePropertyId,
bool propertiesChangedForProperty,
string[] propertyContentCollectionFiles,
string resultAllInOne,
string resultCollection,
string resultContent,
string resultSingleton,
string rootDirectory,
string[] validImageFormatExtensions,
string[] validMetadataExtensions,
string[] verifyToSeason,
bool writeBitmapDataBytes)
{
DateGroup = dateGroup;
FileNameDirectorySeparator = fileNameDirectorySeparator;
@ -35,6 +56,10 @@ public class Configuration
PopulatePropertyId = populatePropertyId;
PropertiesChangedForProperty = propertiesChangedForProperty;
PropertyContentCollectionFiles = propertyContentCollectionFiles;
ResultAllInOne = resultAllInOne;
ResultCollection = resultCollection;
ResultContent = resultContent;
ResultSingleton = resultSingleton;
_RootDirectory = rootDirectory;
ValidImageFormatExtensions = validImageFormatExtensions;
ValidMetadataExtensions = validMetadataExtensions;

View File

@ -15,7 +15,7 @@ public class Container
string[] sourceDirectoryFiles;
List<string[]> fileCollections = new();
if (!topDirectories.Any())
topDirectories.AddRange(from l in Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly) orderby Path.GetFileName(l)[..1], l select Path.GetFullPath(l));
topDirectories.AddRange(from l in Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly) select Path.GetFullPath(l));
for (int g = 1; g < 5; g++)
{
if (g == 4)
@ -31,7 +31,6 @@ public class Container
}
else if (g == 2)
{
fileCollections = (from l in fileCollections orderby l.Length descending select l).ToList();
for (int i = fileCollections.Count - 1; i > -1; i--)
{
if (fileCollections[i].Length > maxImagesInDirectoryForTopLevelFirstPass * g)

View File

@ -5,11 +5,6 @@ namespace View_by_Distance.Property.Models.Stateless;
public interface IResult
{
const string Content = "()";
const string Singleton = "{}";
const string Collection = "[]";
const string AllInOne = "_ _ _";
string TestStatic_GetRelativePath(Configuration configuration, string path);
static string GetRelativePath(Configuration configuration, string path)
=> Result.GetRelativePath(configuration, path);

View File

@ -64,13 +64,13 @@ internal class Result
return result;
}
private static void CheckContent(string dateGroupDirectory, string contentDescription, string result)
private static void CheckContent(Configuration configuration, string dateGroupDirectory, string contentDescription, string result)
{
string checkDirectory;
checkDirectory = Path.Combine(dateGroupDirectory, IResult.Content, IResult.AllInOne);
checkDirectory = Path.Combine(dateGroupDirectory, configuration.ResultContent, configuration.ResultAllInOne);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
string contentDirectory = new(result.Replace("<>", IResult.Content));
string contentDirectory = new(result.Replace("<>", configuration.ResultContent));
if (!Directory.Exists(contentDirectory))
_ = Directory.CreateDirectory(contentDirectory);
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("() - ", contentDescription));
@ -78,15 +78,15 @@ internal class Result
_ = Directory.CreateDirectory(checkDirectory);
}
private static void CheckSingleton(string dateGroupDirectory, string singletonDescription, bool converted, string result)
private static void CheckSingleton(Configuration configuration, string dateGroupDirectory, string singletonDescription, bool converted, string result)
{
string checkDirectory;
checkDirectory = Path.Combine(dateGroupDirectory, IResult.Singleton, IResult.AllInOne);
checkDirectory = Path.Combine(dateGroupDirectory, configuration.ResultSingleton, configuration.ResultAllInOne);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
if (!converted)
{
string singletonDirectory = new(result.Replace("<>", IResult.Singleton));
string singletonDirectory = new(result.Replace("<>", configuration.ResultSingleton));
if (!Directory.Exists(singletonDirectory))
_ = Directory.CreateDirectory(singletonDirectory);
}
@ -95,14 +95,14 @@ internal class Result
_ = Directory.CreateDirectory(checkDirectory);
}
private static void CheckCollection(string dateGroupDirectory, string collectionDescription, bool converted, string result)
private static void CheckCollection(Configuration configuration, string dateGroupDirectory, string collectionDescription, bool converted, string result)
{
string checkDirectory = Path.Combine(dateGroupDirectory, IResult.Collection, IResult.AllInOne);
string checkDirectory = Path.Combine(dateGroupDirectory, configuration.ResultCollection, configuration.ResultAllInOne);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
if (!converted)
{
string collectionDirectory = new(result.Replace("<>", IResult.Collection));
string collectionDirectory = new(result.Replace("<>", configuration.ResultCollection));
if (!Directory.Exists(collectionDirectory))
_ = Directory.CreateDirectory(collectionDirectory);
}
@ -117,11 +117,11 @@ internal class Result
string sourceDirectorySegment = GetRelativePath(configuration, sourceDirectory);
string result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment);
if (!string.IsNullOrEmpty(contentDescription))
CheckContent(dateGroupDirectory, contentDescription, result);
CheckContent(configuration, dateGroupDirectory, contentDescription, result);
if (!string.IsNullOrEmpty(singletonDescription))
CheckSingleton(dateGroupDirectory, singletonDescription, converted, result);
CheckSingleton(configuration, dateGroupDirectory, singletonDescription, converted, result);
if (!string.IsNullOrEmpty(collectionDescription))
CheckCollection(dateGroupDirectory, collectionDescription, converted, result);
CheckCollection(configuration, dateGroupDirectory, collectionDescription, converted, result);
results.Add(result);
return results;
}

View File

@ -451,7 +451,7 @@ public class C_Resize
return results;
}
public Dictionary<string, int[]> GetResizeKeyValuePairs(string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string original, List<KeyValuePair<string, string>> metadataCollection, Shared.Models.Item item)
public Dictionary<string, int[]> GetResizeKeyValuePairs(Property.Models.Configuration configuration, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string original, List<KeyValuePair<string, string>> metadataCollection, Shared.Models.Item item)
{
Dictionary<string, int[]> results;
if (item.Property?.Id is null)
@ -462,7 +462,7 @@ public class C_Resize
string[] changesFrom = new string[] { nameof(Property.Models.A_Property), nameof(B_Metadata) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "{}"), string.Concat(item.ImageFileHolder.NameWithoutExtension, ".json"));
string cResizeSingletonFile = Path.Combine(cResultsFullGroupDirectory, "{}", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
string cResizeSingletonFile = Path.Combine(cResultsFullGroupDirectory, "{}", configuration.ResultAllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
FileInfo fileInfo = new(cResizeSingletonFile);
if (!fileInfo.Exists)
{

View File

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

View File

@ -0,0 +1,8 @@
namespace View_by_Distance.Shared.Models.Methods;
public interface IFaceDistance
{
List<Face> GetMatchingFaces(double faceDistanceTolerance, string checkFile, List<Face> faces);
}

View File

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

View File

@ -1,15 +0,0 @@
namespace View_by_Distance.Shared.Models.Stateless;
public interface IFaceDistance
{
const int HiddenImageFactor = 2;
const int Permyriad = 10000;
const double MinimumConfidence = 1.25d;
const double Tolerance = 0.23d;
// (637987888254767613) Tolerance = 0.31d; MinimumConfidence = 0.80d; => 1003 in 20 minutes with 9 failures
// (637987913910140924) Tolerance = 0.21d; MinimumConfidence = 0.95d; => 0254 in 04 minutes with 1 failures
// (??????????????????) Tolerance = 0.23d; MinimumConfidence = 1.25d; => ____ in __ minutes with _ failures
}

View File

@ -1,9 +0,0 @@
namespace View_by_Distance.Shared.Models.Stateless;
public interface IMapping
{
const bool SaveFaceEncoding = false;
const bool SaveMapped = false;
}

View File

@ -1,7 +0,0 @@
namespace View_by_Distance.Shared.Models.Stateless;
public interface IPerson
{
const string KeyFormat = "yyyy-MM-dd_HH";
}

View File

@ -1,9 +0,0 @@
namespace View_by_Distance.Shared.Models.Stateless;
public interface IPersonBirthday
{
const int FirstYear = 1500;
const string Format = "yyyy-MM-dd_HH";
}

View File

@ -1,16 +0,0 @@
namespace View_by_Distance.Shared.Models.Stateless;
public interface ISorting
{
const int DaysDeltaTolerance = 700;
const int FacesToSkipAfterSortBeforeLoad = 0;
const int FacesToTakeAfterSortBeforeLoad = 123000;
const int ForceSingleImage = 3;
const int Mapping = 1;
const int MaximumPerFaceShouldBeHigh = 1000;
const int MaximumPerKey = 27;
const int Sigma = 3;
const int Sorting = 2;
}

View File

@ -23,4 +23,18 @@ public interface ILocation
static int GetNormalizedPixelPercentage(int bottom, int height, int left, int locationDigits, int locationFactor, int right, int top, int width, int zCount) =>
Location.GetNormalizedPixelPercentage(bottom, height, left, locationDigits, locationFactor, right, top, width, zCount);
Models.Location TestStatic_GetTrimBound(double detectionConfidence, System.Drawing.Rectangle rectangle, int width, int height, int facesCount) =>
TrimBound(detectionConfidence, rectangle, width, height, facesCount);
static Models.Location TrimBound(double detectionConfidence, System.Drawing.Rectangle rectangle, int width, int height, int facesCount) =>
new(Math.Min(rectangle.Bottom, height),
detectionConfidence,
height,
Math.Max(rectangle.Left, 0),
Stateless.ILocation.Digits,
Stateless.ILocation.Factor,
Math.Min(rectangle.Right, width),
Math.Max(rectangle.Top, 0),
width,
facesCount);
}

View File

@ -3,15 +3,12 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IMapping
{ // ...
static string GetDeterministicHashCodeKeyDisplay(int id, int normalizedPixelPercentage)
static string GetDeterministicHashCodeKey(int id, int normalizedPixelPercentage)
=> $"{id}.{normalizedPixelPercentage}";
static double GetDeterministicHashCodeKeyValue(int locationDigits, int id, int normalizedPixelPercentage)
=> Math.Round(double.Parse($"{id}.{normalizedPixelPercentage}"), locationDigits);
(int?, int?) TestStatic_GetReversedDeterministicHashCodeKey(int locationDigits, bool keyValuePairsAny, Dictionary<int, List<Models.Face>> keyValuePairs, string file) =>
(int?, int?, List<Models.Face>?) TestStatic_GetReversedDeterministicHashCodeKey(int locationDigits, bool keyValuePairsAny, Dictionary<int, List<Models.Face>> keyValuePairs, string file) =>
GetReversedDeterministicHashCodeKey(locationDigits, keyValuePairsAny, keyValuePairs, file);
static (int?, int?) GetReversedDeterministicHashCodeKey(int locationDigits, bool keyValuePairsAny, Dictionary<int, List<Models.Face>> keyValuePairs, string file) =>
static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(int locationDigits, bool keyValuePairsAny, Dictionary<int, List<Models.Face>> keyValuePairs, string file) =>
Mapping.GetReversedDeterministicHashCodeKey(locationDigits, keyValuePairsAny, keyValuePairs, file);
}

View File

@ -1,80 +1,68 @@
using System.Text.Json;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class Mapping
{
private static void UseKeyValuePairsSaveFaceEncoding(int locationDigits, Dictionary<int, List<Models.Face>> keyValuePairs, string file, int id, int normalizedPixelPercentageValue, double deterministicHashCodeKey, string extensionLowered)
private static void IfNotAlreadyFileMove(string file, int idValue, int normalizedPixelPercentageValue, string extensionLowered)
{
string json;
string checkFile;
string? directoryName;
List<Models.Face> collection = new();
List<Models.Face> faces = keyValuePairs[id];
foreach (Models.Face face in faces)
{
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
continue;
if (normalizedPixelPercentageValue != face.Location.NormalizedPixelPercentage.Value && deterministicHashCodeKey != IMapping.GetDeterministicHashCodeKeyValue(locationDigits, id, face.Location.NormalizedPixelPercentage.Value))
continue;
collection.Add(face);
}
if (collection.Count != 1)
string? directoryName = Path.GetDirectoryName(file);
if (string.IsNullOrEmpty(directoryName))
throw new Exception();
foreach (Models.Face face in collection)
{
directoryName = Path.GetDirectoryName(file);
if (string.IsNullOrEmpty(directoryName))
continue;
checkFile = Path.Combine(directoryName, $"{deterministicHashCodeKey}{extensionLowered}.json");
if (File.Exists(checkFile))
continue;
json = JsonSerializer.Serialize(face.FaceEncoding);
_ = IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
}
string checkFile = Path.Combine(directoryName, $"{IMapping.GetDeterministicHashCodeKey(idValue, normalizedPixelPercentageValue)}{extensionLowered}");
if (!File.Exists(checkFile))
File.Move(file, checkFile);
}
private static (int?, int?, double?) GetReversedDeterministicHashCodeKeysFromSegments(int locationDigits, bool keyValuePairsAny, Dictionary<int, List<Models.Face>> keyValuePairs, string file, string[] segments)
{
double? result;
if (segments.Length != 3)
throw new Exception();
string id = segments[0];
int normalizedPixelPercentageValue;
string normalizedPixelPercentage = segments[1];
if (!int.TryParse(id, out int idValue) | !int.TryParse(normalizedPixelPercentage, out normalizedPixelPercentageValue))
result = null;
else
{
result = IMapping.GetDeterministicHashCodeKeyValue(locationDigits, idValue, normalizedPixelPercentageValue);
if (keyValuePairsAny && keyValuePairs.ContainsKey(idValue))
UseKeyValuePairsSaveFaceEncoding(locationDigits, keyValuePairs, file, idValue, normalizedPixelPercentageValue, result.Value, $".{segments[2]}");
}
return new(idValue, normalizedPixelPercentageValue, result);
}
internal static (int?, int?) GetReversedDeterministicHashCodeKey(int locationDigits, bool keyValuePairsAny, Dictionary<int, List<Models.Face>> keyValuePairs, string file)
private static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKeysFromSegments(int locationDigits, bool keyValuePairsAny, Dictionary<int, List<Models.Face>> keyValuePairs, string file, string[] segments)
{
int? id;
List<Models.Face>? faces;
int? normalizedPixelPercentage;
if (segments.Length != 3)
{
id = null;
faces = null;
normalizedPixelPercentage = null;
}
else if (!int.TryParse(segments[0], out int idValue) || !int.TryParse(segments[1].PadRight(locationDigits, '0'), out int normalizedPixelPercentageValue))
{
id = null;
faces = null;
normalizedPixelPercentage = null;
}
else
{
id = idValue;
string extensionLowered = $".{segments[2]}";
normalizedPixelPercentage = normalizedPixelPercentageValue;
if (segments[1].Length != locationDigits)
IfNotAlreadyFileMove(file, idValue, normalizedPixelPercentageValue, extensionLowered);
if (!keyValuePairsAny || !keyValuePairs.ContainsKey(idValue))
faces = null;
else
faces = keyValuePairs[idValue];
}
return new(id, normalizedPixelPercentage, faces);
}
internal static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(int locationDigits, bool keyValuePairsAny, Dictionary<int, List<Models.Face>> keyValuePairs, string file)
{
int? id;
List<Models.Face>? faces;
int? normalizedPixelPercentage;
string fileName = Path.GetFileName(file);
if (fileName.Length < 2 || fileName[1..].Contains('-'))
{
id = null;
faces = null;
normalizedPixelPercentage = null;
}
else
{
string[] segments = fileName.Split('.');
(id, normalizedPixelPercentage, double? result) = GetReversedDeterministicHashCodeKeysFromSegments(locationDigits, keyValuePairsAny, keyValuePairs, file, segments);
if (result is null)
{
id = null;
normalizedPixelPercentage = null;
}
(id, normalizedPixelPercentage, faces) = GetReversedDeterministicHashCodeKeysFromSegments(locationDigits, keyValuePairsAny, keyValuePairs, file, segments);
}
return new(id, normalizedPixelPercentage);
return new(id, normalizedPixelPercentage, faces);
}
}

View File

@ -94,25 +94,4 @@ public class UnitTestCalculations
Assert.IsTrue(checkB > checkA);
}
[TestMethod]
public void TestMethodRoundB()
{
const int DistanceDigits = 3;
const int DistanceFactor = 1000;
const int ToleranceAfterFactor = 600;
Assert.IsTrue(DistanceDigits == 3);
Assert.IsTrue(DistanceFactor == 1000);
Assert.IsTrue(Shared.Models.Stateless.IFaceDistance.Tolerance == 0.6d);
Assert.IsTrue(ToleranceAfterFactor == 600);
double valueA = 0.00001d;
int checkA = (int)(Math.Round(valueA, Shared.Models.Stateless.ILocation.Digits) * Shared.Models.Stateless.ILocation.Factor);
Assert.IsTrue(checkA == 10);
double valueB = 0.01d;
int checkB = (int)(Math.Round(valueB, Shared.Models.Stateless.ILocation.Digits) * Shared.Models.Stateless.ILocation.Factor);
Assert.IsTrue(checkB == 10000);
Assert.IsTrue(checkB > checkA);
int checkC = (int)(Shared.Models.Stateless.IFaceDistance.Tolerance * DistanceFactor);
Assert.IsTrue(checkC == ToleranceAfterFactor);
}
}

View File

@ -242,8 +242,8 @@ public class UnitTestResize
property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions);
item.Update(property);
}
(int _, metadataCollection) = metadata.GetMetadataCollection(bResultsFullGroupDirectory, subFileTuples, parseExceptions, item);
imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
(int _, metadataCollection) = metadata.GetMetadataCollection(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, subFileTuples, parseExceptions, item);
imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
Assert.IsNotNull(item.ResizedFileHolder);
resize.SaveResizedSubfile(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, original, imageResizeKeyValuePairs);
}

View File

@ -13,6 +13,10 @@ public class Configuration
[Display(Name = "Check Json For Distance Results"), Required] public bool? CheckJsonForDistanceResults { get; set; }
[Display(Name = "CrossDirectory Max Items In Distance Collection"), Required] public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; }
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
[Display(Name = "Face Distance Hidden Image Factor"), Required] public int? FaceDistanceHiddenImageFactor { get; set; }
[Display(Name = "Location Minimum Confidence"), Required] public double? FaceDistanceMinimumConfidence { get; set; }
[Display(Name = "Face Distance Permyriad"), Required] public int? FaceDistancePermyriad { get; set; }
[Display(Name = "Face Distance Tolerance"), Required] public double? FaceDistanceTolerance { get; set; }
[Display(Name = "Force Face Last Write Time to Creation Time"), Required] public bool? ForceFaceLastWriteTimeToCreationTime { get; set; }
[Display(Name = "Force Metadata Last Write Time to Creation Time"), Required] public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; }
[Display(Name = "Force Resize Last Write Time to Creation Time"), Required] public bool? ForceResizeLastWriteTimeToCreationTime { get; set; }
@ -23,7 +27,14 @@ public class Configuration
[Display(Name = "Load Or Create Then Save Image Faces Results"), Required] public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
[Display(Name = "Load Or Create Then Save Index"), Required] public bool? LoadOrCreateThenSaveIndex { get; set; }
[Display(Name = "Location Confidence Factor"), Required] public int? LocationConfidenceFactor { get; set; }
[Display(Name = "Location Digits"), Required] public int? LocationDigits { get; set; }
[Display(Name = "Location Factor"), Required] public int? LocationFactor { get; set; }
[Display(Name = "Map Logic Sigma"), Required] public int? MapLogicSigma { get; set; }
[Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; }
[Display(Name = "Mapping Save Face Encoding"), Required] public bool? MappingSaveFaceEncoding { get; set; }
[Display(Name = "MappingSaveMapped"), Required] public bool? MappingSaveMapped { get; set; }
[Display(Name = "Mapping Use Deterministic Hash Code Unknown Face Key Value Pairs for Add to Mapping"), Required] public bool? MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { get; set; }
[Display(Name = "Mapping Use Deterministic Hash Code Unknown Face Key Value Pairs for Save Mapping"), Required] public bool? MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping { get; set; }
[Display(Name = "Max Items In Distance Collection"), Required] public int? MaxItemsInDistanceCollection { get; set; }
[Display(Name = "Mixed Year Relative Paths"), Required] public string[] MixedYearRelativePaths { get; set; }
[Display(Name = "Model Directory"), Required] public string ModelDirectory { get; set; }
@ -37,6 +48,9 @@ public class Configuration
[Display(Name = "Override For Face Landmark Images"), Required] public bool? OverrideForFaceLandmarkImages { get; set; }
[Display(Name = "Override For Resize Images"), Required] public bool? OverrideForResizeImages { get; set; }
[Display(Name = "Padding Loops"), Required] public int? PaddingLoops { get; set; }
[Display(Name = "Person Birthday First Year"), Required] public int? PersonBirthdayFirstYear { get; set; }
[Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; }
[Display(Name = "PersonKey Format"), Required] public string PersonKeyFormat { get; set; }
[Display(Name = "Predictor Model Name"), Required] public string PredictorModelName { get; set; }
[Display(Name = "Properties Changed For Distance"), Required] public bool? PropertiesChangedForDistance { get; set; }
[Display(Name = "Properties Changed For Faces"), Required] public bool? PropertiesChangedForFaces { get; set; }
@ -50,6 +64,12 @@ public class Configuration
[Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; }
[Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; }
[Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; }
[Display(Name = "Sorting Days Delta Tolerance"), Required] public int? SortingDaysDeltaTolerance { get; set; }
[Display(Name = "Sorting Faces To Skip After Sort Before Load"), Required] public int? SortingFacesToSkipAfterSortBeforeLoad { get; set; }
[Display(Name = "Sorting Faces To Take After Sort Before Load"), Required] public int? SortingFacesToTakeAfterSortBeforeLoad { get; set; }
[Display(Name = "SortingMaximumPerFaceShould be High"), Required] public int? SortingMaximumPerFaceShouldBeHigh { get; set; }
[Display(Name = "Sorting Maximum Per Key"), Required] public int? SortingMaximumPerKey { get; set; }
[Display(Name = "Sorting Sigma"), Required] public int? SortingSigma { get; set; }
[Display(Name = "Test Distance Results"), Required] public bool? TestDistanceResults { get; set; }
[Display(Name = "Valid Resolutions"), Required] public string[] ValidResolutions { get; set; }
@ -70,6 +90,14 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
if (configuration.DistanceFactor is null)
throw new NullReferenceException(nameof(configuration.DistanceFactor));
if (configuration.FaceDistanceHiddenImageFactor is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceHiddenImageFactor));
if (configuration.FaceDistanceMinimumConfidence is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceMinimumConfidence));
if (configuration.FaceDistancePermyriad is null)
throw new NullReferenceException(nameof(configuration.FaceDistancePermyriad));
if (configuration.FaceDistanceTolerance is null)
throw new NullReferenceException(nameof(configuration.FaceDistanceTolerance));
if (configuration.ForceFaceLastWriteTimeToCreationTime is null)
throw new NullReferenceException(nameof(configuration.ForceFaceLastWriteTimeToCreationTime));
if (configuration.ForceMetadataLastWriteTimeToCreationTime is null)
@ -80,10 +108,28 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
if (configuration.IgnoreRelativePaths is null)
throw new NullReferenceException(nameof(configuration.IgnoreRelativePaths));
if (configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions is null)
configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions = Array.Empty<string>();
if (configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions is null)
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions = Array.Empty<string>();
if (configuration.LoadOrCreateThenSaveIndex is null)
throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveIndex));
if (configuration.LocationConfidenceFactor is null)
throw new NullReferenceException(nameof(configuration.LocationConfidenceFactor));
if (configuration.LocationDigits is null)
throw new NullReferenceException(nameof(configuration.LocationDigits));
if (configuration.LocationFactor is null)
throw new NullReferenceException(nameof(configuration.LocationFactor));
if (configuration.MapLogicSigma is null)
throw new NullReferenceException(nameof(configuration.MapLogicSigma));
if (configuration.MappingSaveFaceEncoding is null)
throw new NullReferenceException(nameof(configuration.MappingSaveFaceEncoding));
if (configuration.MappingSaveMapped is null)
throw new NullReferenceException(nameof(configuration.MappingSaveMapped));
if (configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping is null)
throw new NullReferenceException(nameof(configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping));
if (configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping is null)
throw new NullReferenceException(nameof(configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping));
if (configuration.MaxItemsInDistanceCollection is null)
throw new NullReferenceException(nameof(configuration.MaxItemsInDistanceCollection));
if (configuration.MixedYearRelativePaths is null)
@ -104,6 +150,12 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.OverrideForResizeImages));
if (configuration.PaddingLoops is null)
throw new NullReferenceException(nameof(configuration.PaddingLoops));
if (configuration.PersonBirthdayFirstYear is null)
throw new NullReferenceException(nameof(configuration.PersonBirthdayFirstYear));
if (configuration.PersonBirthdayFormat is null)
throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
if (configuration.PersonKeyFormat is null)
throw new NullReferenceException(nameof(configuration.PersonKeyFormat));
if (configuration.PropertiesChangedForDistance is null)
throw new NullReferenceException(nameof(configuration.PropertiesChangedForDistance));
if (configuration.PropertiesChangedForFaces is null)
@ -116,14 +168,30 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize));
if (configuration.Reverse is null)
throw new NullReferenceException(nameof(configuration.Reverse));
if (configuration.SaveFaceLandmarkForOutputResolutions is null)
configuration.SaveFaceLandmarkForOutputResolutions = Array.Empty<string>();
if (configuration.SaveFaceLandmarkForOutputResolutions is null)
throw new NullReferenceException(nameof(configuration.SaveFaceLandmarkForOutputResolutions));
if (configuration.SaveFullYearOfRandomFiles is null)
throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles));
if (configuration.SaveResizedSubfiles is null)
throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles));
if (configuration.SaveShortcutsForOutputResolutions is null)
configuration.SaveShortcutsForOutputResolutions = Array.Empty<string>();
if (configuration.SkipSearch is null)
throw new NullReferenceException(nameof(configuration.SkipSearch));
if (configuration.SortingDaysDeltaTolerance is null)
throw new NullReferenceException(nameof(configuration.SortingDaysDeltaTolerance));
if (configuration.SortingFacesToSkipAfterSortBeforeLoad is null)
throw new NullReferenceException(nameof(configuration.SortingFacesToSkipAfterSortBeforeLoad));
if (configuration.SortingFacesToTakeAfterSortBeforeLoad is null)
throw new NullReferenceException(nameof(configuration.SortingFacesToTakeAfterSortBeforeLoad));
if (configuration.SortingMaximumPerFaceShouldBeHigh is null)
throw new NullReferenceException(nameof(configuration.SortingMaximumPerFaceShouldBeHigh));
if (configuration.SortingMaximumPerKey is null)
throw new NullReferenceException(nameof(configuration.SortingMaximumPerKey));
if (configuration.SortingSigma is null)
throw new NullReferenceException(nameof(configuration.SortingSigma));
if (configuration.TestDistanceResults is null)
throw new NullReferenceException(nameof(configuration.TestDistanceResults));
if (configuration.ValidResolutions is null)
@ -140,6 +208,10 @@ public class Configuration
configuration.CheckJsonForDistanceResults.Value,
configuration.CrossDirectoryMaxItemsInDistanceCollection.Value,
configuration.DistanceFactor.Value,
configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistanceMinimumConfidence.Value,
configuration.FaceDistancePermyriad.Value,
configuration.FaceDistanceTolerance.Value,
configuration.ForceFaceLastWriteTimeToCreationTime.Value,
configuration.ForceMetadataLastWriteTimeToCreationTime.Value,
configuration.ForceResizeLastWriteTimeToCreationTime.Value,
@ -150,7 +222,14 @@ public class Configuration
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions,
configuration.LoadOrCreateThenSaveIndex.Value,
configuration.LocationConfidenceFactor.Value,
configuration.LocationDigits.Value,
configuration.LocationFactor.Value,
configuration.MapLogicSigma.Value,
configuration.MappedMaxIndex,
configuration.MappingSaveFaceEncoding.Value,
configuration.MappingSaveMapped.Value,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping.Value,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping.Value,
configuration.MaxItemsInDistanceCollection.Value,
configuration.MixedYearRelativePaths,
configuration.ModelDirectory,
@ -164,6 +243,9 @@ public class Configuration
configuration.OverrideForFaceLandmarkImages.Value,
configuration.OverrideForResizeImages.Value,
configuration.PaddingLoops.Value,
configuration.PersonBirthdayFirstYear.Value,
configuration.PersonBirthdayFormat,
configuration.PersonKeyFormat,
configuration.PredictorModelName,
configuration.PropertiesChangedForDistance.Value,
configuration.PropertiesChangedForFaces.Value,
@ -176,6 +258,12 @@ public class Configuration
configuration.SaveResizedSubfiles.Value,
configuration.SaveShortcutsForOutputResolutions,
configuration.SkipSearch.Value,
configuration.SortingDaysDeltaTolerance.Value,
configuration.SortingFacesToSkipAfterSortBeforeLoad.Value,
configuration.SortingFacesToTakeAfterSortBeforeLoad.Value,
configuration.SortingMaximumPerFaceShouldBeHigh.Value,
configuration.SortingMaximumPerKey.Value,
configuration.SortingSigma.Value,
configuration.TestDistanceResults.Value,
configuration.ValidResolutions);
return result;

View File

@ -12,6 +12,10 @@ public class Configuration
public bool CheckJsonForDistanceResults { init; get; }
public int CrossDirectoryMaxItemsInDistanceCollection { init; get; }
public int DistanceFactor { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; }
public double FaceDistanceMinimumConfidence { init; get; }
public int FaceDistancePermyriad { init; get; }
public double FaceDistanceTolerance { init; get; }
public bool ForceFaceLastWriteTimeToCreationTime { init; get; }
public bool ForceMetadataLastWriteTimeToCreationTime { init; get; }
public bool ForceResizeLastWriteTimeToCreationTime { init; get; }
@ -22,7 +26,14 @@ public class Configuration
public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { init; get; }
public bool LoadOrCreateThenSaveIndex { init; get; }
public int LocationConfidenceFactor { init; get; }
public int LocationDigits { init; get; }
public int LocationFactor { init; get; }
public int MapLogicSigma { init; get; }
public int? MappedMaxIndex { init; get; }
public bool MappingSaveFaceEncoding { init; get; }
public bool MappingSaveMapped { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping { init; get; }
public int MaxItemsInDistanceCollection { init; get; }
public string[] MixedYearRelativePaths { init; get; }
public string ModelDirectory { init; get; }
@ -36,6 +47,9 @@ public class Configuration
public bool OverrideForFaceLandmarkImages { init; get; }
public bool OverrideForResizeImages { init; get; }
public int PaddingLoops { init; get; }
public int PersonBirthdayFirstYear { init; get; }
public string PersonBirthdayFormat { init; get; }
public string PersonKeyFormat { init; get; }
public string PredictorModelName { init; get; }
public bool PropertiesChangedForDistance { init; get; }
public bool PropertiesChangedForFaces { init; get; }
@ -48,16 +62,87 @@ public class Configuration
public bool SaveResizedSubfiles { init; get; }
public string[] SaveShortcutsForOutputResolutions { init; get; }
public bool SkipSearch { init; get; }
public int SortingDaysDeltaTolerance { init; get; }
public int SortingFacesToSkipAfterSortBeforeLoad { init; get; }
public int SortingFacesToTakeAfterSortBeforeLoad { init; get; }
public int SortingMaximumPerFaceShouldBeHigh { init; get; }
public int SortingMaximumPerKey { init; get; }
public int SortingSigma { init; get; }
public bool TestDistanceResults { init; get; }
public string[] ValidResolutions { init; get; }
[JsonConstructor]
public Configuration(Property.Models.Configuration propertyConfiguration, bool checkJsonForDistanceResults, int crossDirectoryMaxItemsInDistanceCollection, int distanceFactor, bool forceFaceLastWriteTimeToCreationTime, bool forceMetadataLastWriteTimeToCreationTime, bool forceResizeLastWriteTimeToCreationTime, string[] ignoreExtensions, string[] ignoreRelativePaths, string[] juliePhares, string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions, string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions, bool loadOrCreateThenSaveIndex, int locationConfidenceFactor, int? mappedMaxIndex, int maxItemsInDistanceCollection, string[] mixedYearRelativePaths, string modelDirectory, string modelName, int numberOfJitters, int numberOfTimesToUpsample, string outputExtension, int outputQuality, string[] outputResolutions, bool overrideForFaceImages, bool overrideForFaceLandmarkImages, bool overrideForResizeImages, int paddingLoops, string predictorModelName, bool propertiesChangedForDistance, bool propertiesChangedForFaces, bool propertiesChangedForIndex, bool propertiesChangedForMetadata, bool propertiesChangedForResize, bool reverse, string[] saveFaceLandmarkForOutputResolutions, bool saveFullYearOfRandomFiles, bool saveResizedSubfiles, string[] saveShortcutsForOutputResolutions, bool skipSearch, bool testDistanceResults, string[] validResolutions)
public Configuration(Property.Models.Configuration propertyConfiguration,
bool checkJsonForDistanceResults,
int crossDirectoryMaxItemsInDistanceCollection,
int distanceFactor,
int faceDistanceHiddenImageFactor,
double faceDistanceMinimumConfidence,
int faceDistancePermyriad,
double faceDistanceTolerance,
bool forceFaceLastWriteTimeToCreationTime,
bool forceMetadataLastWriteTimeToCreationTime,
bool forceResizeLastWriteTimeToCreationTime,
string[] ignoreExtensions,
string[] ignoreRelativePaths,
string[] juliePhares,
string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions,
string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions,
bool loadOrCreateThenSaveIndex,
int locationConfidenceFactor,
int locationDigits,
int locationFactor,
int mapLogicSigma,
int? mappedMaxIndex,
bool mappingSaveFaceEncoding,
bool mappingSaveMapped,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping,
int maxItemsInDistanceCollection,
string[] mixedYearRelativePaths,
string modelDirectory,
string modelName,
int numberOfJitters,
int numberOfTimesToUpsample,
string outputExtension,
int outputQuality,
string[] outputResolutions,
bool overrideForFaceImages,
bool overrideForFaceLandmarkImages,
bool overrideForResizeImages,
int paddingLoops,
int personBirthdayFirstYear,
string personBirthdayFormat,
string personKeyFormat,
string predictorModelName,
bool propertiesChangedForDistance,
bool propertiesChangedForFaces,
bool propertiesChangedForIndex,
bool propertiesChangedForMetadata,
bool propertiesChangedForResize,
bool reverse,
string[] saveFaceLandmarkForOutputResolutions,
bool saveFullYearOfRandomFiles,
bool saveResizedSubfiles,
string[] saveShortcutsForOutputResolutions,
bool skipSearch,
int sortingDaysDeltaTolerance,
int sortingFacesToSkipAfterSortBeforeLoad,
int sortingFacesToTakeAfterSortBeforeLoad,
int sortingMaximumPerFaceShouldBeHigh,
int sortingMaximumPerKey,
int sortingSigma,
bool testDistanceResults,
string[] validResolutions)
{
_PropertyConfiguration = propertyConfiguration;
CheckJsonForDistanceResults = checkJsonForDistanceResults;
CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
DistanceFactor = distanceFactor;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistanceMinimumConfidence = faceDistanceMinimumConfidence;
FaceDistancePermyriad = faceDistancePermyriad;
FaceDistanceTolerance = faceDistanceTolerance;
ForceFaceLastWriteTimeToCreationTime = forceFaceLastWriteTimeToCreationTime;
ForceMetadataLastWriteTimeToCreationTime = forceMetadataLastWriteTimeToCreationTime;
ForceResizeLastWriteTimeToCreationTime = forceResizeLastWriteTimeToCreationTime;
@ -68,7 +153,14 @@ public class Configuration
LoadOrCreateThenSaveImageFacesResultsForOutputResolutions = loadOrCreateThenSaveImageFacesResultsForOutputResolutions;
LoadOrCreateThenSaveIndex = loadOrCreateThenSaveIndex;
LocationConfidenceFactor = locationConfidenceFactor;
LocationDigits = locationDigits;
LocationFactor = locationFactor;
MapLogicSigma = mapLogicSigma;
MappedMaxIndex = mappedMaxIndex;
MappingSaveFaceEncoding = mappingSaveFaceEncoding;
MappingSaveMapped = mappingSaveMapped;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping;
MaxItemsInDistanceCollection = maxItemsInDistanceCollection;
MixedYearRelativePaths = mixedYearRelativePaths;
ModelDirectory = modelDirectory;
@ -82,6 +174,9 @@ public class Configuration
OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages;
OverrideForResizeImages = overrideForResizeImages;
PaddingLoops = paddingLoops;
PersonBirthdayFirstYear = personBirthdayFirstYear;
PersonBirthdayFormat = personBirthdayFormat;
PersonKeyFormat = personKeyFormat;
PredictorModelName = predictorModelName;
PropertiesChangedForDistance = propertiesChangedForDistance;
PropertiesChangedForFaces = propertiesChangedForFaces;
@ -94,6 +189,12 @@ public class Configuration
SaveResizedSubfiles = saveResizedSubfiles;
SaveShortcutsForOutputResolutions = saveShortcutsForOutputResolutions;
SkipSearch = skipSearch;
SortingDaysDeltaTolerance = sortingDaysDeltaTolerance;
SortingFacesToSkipAfterSortBeforeLoad = sortingFacesToSkipAfterSortBeforeLoad;
SortingFacesToTakeAfterSortBeforeLoad = sortingFacesToTakeAfterSortBeforeLoad;
SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
SortingMaximumPerKey = sortingMaximumPerKey;
SortingSigma = sortingSigma;
TestDistanceResults = testDistanceResults;
ValidResolutions = validResolutions;
}

View File

@ -62,6 +62,15 @@ public class UnitTestFace
_PropertyConfiguration = propertyConfiguration;
}
[TestMethod]
public void TestConfiguration()
{
if (_Configuration.LocationDigits != Shared.Models.Stateless.ILocation.Digits)
throw new Exception("Configuration has to match interface!");
if (_Configuration.LocationFactor != Shared.Models.Stateless.ILocation.Factor)
throw new Exception("Configuration has to match interface!");
}
[TestMethod]
public void TestMethodNull()
{
@ -124,6 +133,27 @@ public class UnitTestFace
return result;
}
[TestMethod]
public void TestMethodRoundB()
{
const int DistanceDigits = 3;
const int DistanceFactor = 1000;
const int ToleranceAfterFactor = 600;
Assert.IsTrue(DistanceDigits == 3);
Assert.IsTrue(DistanceFactor == 1000);
Assert.IsTrue(_Configuration.FaceDistanceTolerance == 0.6d);
Assert.IsTrue(ToleranceAfterFactor == 600);
double valueA = 0.00001d;
int checkA = (int)(Math.Round(valueA, _Configuration.LocationDigits) * _Configuration.LocationFactor);
Assert.IsTrue(checkA == 10);
double valueB = 0.01d;
int checkB = (int)(Math.Round(valueB, _Configuration.LocationDigits) * _Configuration.LocationFactor);
Assert.IsTrue(checkB == 10000);
Assert.IsTrue(checkB > checkA);
int checkC = (int)(_Configuration.FaceDistanceTolerance * DistanceFactor);
Assert.IsTrue(checkC == ToleranceAfterFactor);
}
[TestMethod]
public void TestMethodFace()
{
@ -204,8 +234,8 @@ public class UnitTestFace
property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions);
item.Update(property);
}
(int _, metadataCollection) = metadata.GetMetadataCollection(bResultsFullGroupDirectory, subFileTuples, parseExceptions, item);
imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
(int _, metadataCollection) = metadata.GetMetadataCollection(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, subFileTuples, parseExceptions, item);
imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
Assert.IsNotNull(item.ResizedFileHolder);
resize.SaveResizedSubfile(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, original, imageResizeKeyValuePairs);
Image image = FaceRecognition.LoadImageFile(item.ResizedFileHolder.FullName);