CopyFacesAndSaveFaceLandmarkImage

This commit is contained in:
Mike Phares 2023-03-25 22:07:08 -07:00
parent 90b3f93e6e
commit bea7a172c5
7 changed files with 134 additions and 115 deletions

View File

@ -157,7 +157,7 @@ public class D_Face
return result;
}
private void SaveFaces(FileHolder resizedFileHolder, List<(Shared.Models.Face, FileInfo?, string)> collection)
private void SaveFaces(FileHolder resizedFileHolder, List<(Shared.Models.Face, FileInfo?, string, bool)> collection)
{
int width;
int height;
@ -173,8 +173,10 @@ public class D_Face
int fileSource = (int)IExif.Tags.FileSource;
int userComment = (int)IExif.Tags.UserComment;
using Bitmap source = new(resizedFileHolder.FullName);
foreach ((Shared.Models.Face face, FileInfo? fileInfo, string fileName) in collection)
foreach ((Shared.Models.Face face, FileInfo? fileInfo, string fileName, bool save) in collection)
{
if (!save)
continue;
if (fileInfo is null)
continue;
if (face.FaceEncoding is null || face?.Location is null || face?.OutputResolution is null)
@ -425,36 +427,37 @@ public class D_Face
return results;
}
public bool SaveFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, string facesDirectory, List<Shared.Models.Face> faces)
public List<(Shared.Models.Face, FileInfo?, string, bool)> SaveFaces(string f, string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, string facesDirectory, List<Shared.Models.Face> faces)
{
List<(Shared.Models.Face, FileInfo?, string, bool Save)> results = new();
bool save;
FileInfo fileInfo;
bool result = false;
string deterministicHashCodeKey;
List<(Shared.Models.Face, FileInfo?, string)> collection = new();
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();
if (!Directory.Exists(facesDirectory))
_ = Directory.CreateDirectory(facesDirectory);
foreach (Shared.Models.Face face in faces)
{
save = false;
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
{
collection.Add(new(face, null, string.Empty));
results.Add(new(face, null, string.Empty, save));
continue;
}
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(mappingFromItem.Id, face.Location, ILocation.Digits, face.OutputResolution);
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
collection.Add(new(face, fileInfo, Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_HiddenFileNameExtension}")));
if (_OverrideForFaceImages)
result = true;
save = true;
else if (!fileInfo.Exists)
result = true;
save = true;
else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
result = true;
save = true;
results.Add(new(face, fileInfo, Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_HiddenFileNameExtension}"), save));
}
if (result)
SaveFaces(mappingFromItem.ResizedFileHolder, collection);
return result;
if (results.Any(l => l.Save))
SaveFaces(mappingFromItem.ResizedFileHolder, results);
return results;
}
}

View File

@ -4,6 +4,7 @@ using System.Drawing.Imaging;
using System.Text.Json;
using View_by_Distance.Face.Models;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Property.Models;
using View_by_Distance.Property.Models.Stateless;
using View_by_Distance.Resize.Models;
using View_by_Distance.Shared.Models;
@ -45,7 +46,7 @@ public class D2_FaceParts
return result;
}
public void SetAngleBracketCollection(Property.Models.Configuration configuration, string d2ResultsFullGroupDirectory, string sourceDirectory)
public void SetAngleBracketCollection(Configuration configuration, string d2ResultsFullGroupDirectory, string sourceDirectory)
{
_AngleBracketCollection.Clear();
_AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(configuration,
@ -57,7 +58,7 @@ public class D2_FaceParts
converted: true));
}
public string GetFacePartsDirectory(Property.Models.Configuration configuration, string dResultsFullGroupDirectory, Item item, bool includeNameWithoutExtension)
public string GetFacePartsDirectory(Configuration configuration, string dResultsFullGroupDirectory, Item item, bool includeNameWithoutExtension)
{
string result;
bool angleBracketCollectionAny = _AngleBracketCollection.Any();
@ -67,10 +68,14 @@ public class D2_FaceParts
throw new NullReferenceException(nameof(item.ImageFileHolder.DirectoryName));
SetAngleBracketCollection(configuration, dResultsFullGroupDirectory, item.ImageFileHolder.DirectoryName);
}
if (!includeNameWithoutExtension)
result = _AngleBracketCollection[0].Replace("<>", "[()]");
else
if (includeNameWithoutExtension)
result = Path.Combine(_AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
else
{
result = _AngleBracketCollection[0].Replace("<>", "[()]");
if (!Directory.Exists(result))
_ = Directory.CreateDirectory(result);
}
if (!angleBracketCollectionAny)
_AngleBracketCollection.Clear();
return result;
@ -105,7 +110,7 @@ public class D2_FaceParts
#elif OSX
throw new Exception("Built on macOS!");
#elif Windows
// Make a Matrix to represent rotation
// Make save Matrix to represent rotation
// by this angle.
Matrix rotate_at_origin = new();
rotate_at_origin.Rotate(angle);
@ -123,7 +128,7 @@ public class D2_FaceParts
float xMinimum, xMaximum, yMinimum, yMaximum;
GetPointBounds(points, out xMinimum, out xMaximum, out yMinimum, out yMaximum);
// Make a bitmap to hold the rotated result.
// Make save bitmap to hold the rotated result.
int wid = (int)Math.Round(xMaximum - xMinimum);
int hgt = (int)Math.Round(yMaximum - yMinimum);
result = new Bitmap(wid, hgt);
@ -177,7 +182,7 @@ public class D2_FaceParts
Bitmap rotated;
foreach ((Shared.Models.Face face, string fileName, string rotatedFileName) in collection)
{
if (face.FaceEncoding is null || face.Location is null)
if (face.FaceEncoding is null)
continue;
try
{
@ -197,19 +202,13 @@ public class D2_FaceParts
foreach ((FacePart facePart, FacePoint[] facePoints) in face.FaceParts)
{
foreach (FacePoint facePoint in facePoints)
{
if (face.Location is null)
continue;
graphic.DrawEllipse(Pens.GreenYellow, facePoint.X - pointSize, facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
}
if (facePart == FacePart.Chin)
continue;
if (facePoints.Length < 3)
continue;
x = (int)(from l in facePoints select l.X).Average();
y = (int)(from l in facePoints select l.Y).Average();
if (face.Location is null)
continue;
graphic.DrawEllipse(Pens.Purple, x - pointSize, y - pointSize, pointSize * 2, pointSize * 2);
}
}
@ -233,53 +232,12 @@ public class D2_FaceParts
}
}
private void SaveFaceParts(int pointSize, IFileHolder resizedFileHolder, List<(Shared.Models.Face, string, string)> collection)
{
int x;
int y;
Pen pen;
string? firstFileName = null;
using Image image = Image.FromFile(resizedFileHolder.FullName);
using Graphics graphic = Graphics.FromImage(image);
foreach ((Shared.Models.Face face, string fileName, string _) in collection)
{
firstFileName ??= fileName;
try
{
if (face.FaceParts is null || !face.FaceParts.Any())
continue;
foreach ((FacePart facePart, FacePoint[] facePoints) in face.FaceParts)
{
foreach (FacePoint facePoint in facePoints)
{
if (face.Location is null)
continue;
pen = face.Mapping?.MappingFromPerson is null ? Pens.Red : Pens.GreenYellow;
graphic.DrawEllipse(pen, facePoint.X - pointSize, facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
}
if (facePart == FacePart.Chin)
continue;
if (facePoints.Length < 3)
continue;
x = (int)(from l in facePoints select l.X).Average();
y = (int)(from l in facePoints select l.Y).Average();
if (face.Location is null)
continue;
graphic.DrawEllipse(Pens.Purple, x - pointSize, y - pointSize, pointSize * 2, pointSize * 2);
}
}
catch (Exception) { }
}
if (!string.IsNullOrEmpty(firstFileName))
image.Save(firstFileName, _ImageCodecInfo, _EncoderParameters);
}
#pragma warning restore CA1416
public void SaveFaceLandmarkImages(Property.Models.Configuration configuration, string facePartsDirectory, string facePartsCollectionDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, List<Shared.Models.Face> faces, bool saveRotated)
public void SaveFaceLandmarkImages(Configuration configuration, string facePartsDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, List<Shared.Models.Face> faces, bool saveRotated)
{
bool check;
FileInfo fileInfo;
bool check = false;
const int pointSize = 2;
FileInfo rotatedFileInfo;
DateTime? dateTime = null;
@ -287,41 +245,10 @@ public class D2_FaceParts
string deterministicHashCodeKey;
bool updateDateWhenMatches = false;
List<(Shared.Models.Face, string, string)> collection = new();
string[] changesFrom = new string[] { nameof(Property.Models.A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (!Directory.Exists(facePartsDirectory))
_ = Directory.CreateDirectory(facePartsDirectory);
if (!Directory.Exists(facePartsCollectionDirectory))
_ = Directory.CreateDirectory(facePartsCollectionDirectory);
fileInfo = new FileInfo(Path.Combine(facePartsCollectionDirectory, $"{mappingFromItem.ImageFileHolder.Name}{_FileNameExtension}"));
if (_OverrideForFaceLandmarkImages)
check = true;
else if (!fileInfo.Exists)
check = true;
else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
check = true;
else
check = false;
if (check && !updateDateWhenMatches)
{
updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
}
if (check)
{
foreach (Shared.Models.Face face in faces)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
continue;
if (face.FaceParts is null || !face.FaceParts.Any())
continue;
collection.Add(new(face, fileInfo.FullName, string.Empty));
}
}
if (check && collection.Any())
SaveFaceParts(pointSize, mappingFromItem.ResizedFileHolder, collection);
check = false;
collection.Clear();
foreach (Shared.Models.Face face in faces)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
@ -355,4 +282,77 @@ public class D2_FaceParts
SaveFaceParts(pointSize, mappingFromItem.ResizedFileHolder, saveRotated, collection);
}
#pragma warning disable CA1416
private void SaveFaceLandmarkImage(MappingFromItem mappingFromItem, List<(Shared.Models.Face, FileInfo?, string, bool)> faceCollection, string fileName)
{
int x;
int y;
Pen pen;
const int pointSize = 2;
using Image image = Image.FromFile(mappingFromItem.ResizedFileHolder.FullName);
using Graphics graphic = Graphics.FromImage(image);
foreach ((Shared.Models.Face face, FileInfo? fileInfo, string _, bool _) in faceCollection)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.FaceParts is null || !face.FaceParts.Any())
continue;
try
{
foreach ((FacePart facePart, FacePoint[] facePoints) in face.FaceParts)
{
foreach (FacePoint facePoint in facePoints)
{
pen = face.Mapping?.MappingFromPerson is null ? Pens.Red : Pens.GreenYellow;
graphic.DrawEllipse(pen, facePoint.X - pointSize, facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
}
if (facePart == FacePart.Chin)
continue;
if (facePoints.Length < 3)
continue;
x = (int)(from l in facePoints select l.X).Average();
y = (int)(from l in facePoints select l.Y).Average();
graphic.DrawEllipse(Pens.Purple, x - pointSize, y - pointSize, pointSize * 2, pointSize * 2);
}
}
catch (Exception) { }
}
image.Save(fileName, _ImageCodecInfo, _EncoderParameters);
}
#pragma warning restore CA1416
public void CopyFacesAndSaveFaceLandmarkImage(string facePartsCollectionDirectory, MappingFromItem mappingFromItem, List<(Shared.Models.Face Face, FileInfo?, string, bool)> faceCollection)
{
string checkFile;
bool hasNotMapped = false;
string fileName = Path.Combine(facePartsCollectionDirectory, $"{mappingFromItem.ImageFileHolder.Name}{_FileNameExtension}");
bool save = faceCollection.Any(l => l.Face.FaceEncoding is not null && l.Face.Location is not null && l.Face.OutputResolution is not null && l.Face.FaceParts is not null && l.Face.FaceParts.Any());
FileInfo newFileInfo = new(fileName);
foreach ((Shared.Models.Face face, FileInfo? fileInfo, string _, bool _) in faceCollection)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
continue;
if (fileInfo is not null)
{
checkFile = Path.Combine(facePartsCollectionDirectory, fileInfo.Name);
if (face.Mapping?.MappingFromPerson is not null)
{
if (File.Exists(checkFile))
File.Delete(checkFile);
}
else
{
if (!hasNotMapped)
hasNotMapped = true;
if (!File.Exists(checkFile))
File.Copy(fileInfo.FullName, checkFile);
}
}
}
if (save && !newFileInfo.Exists)
SaveFaceLandmarkImage(mappingFromItem, faceCollection, fileName);
if (!hasNotMapped && !newFileInfo.Attributes.HasFlag(FileAttributes.Hidden) && (newFileInfo.Exists || save))
File.SetAttributes(fileName, FileAttributes.Hidden);
}
}

View File

@ -327,7 +327,8 @@ public partial class DlibDotNet
Item item,
DateTime[] containerDateTimes,
bool? isFocusRelativePath,
bool? isIgnoreRelativePath)
bool? isIgnoreRelativePath,
string facePartsCollectionDirectory)
{
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
@ -379,7 +380,6 @@ public partial class DlibDotNet
item.SetResizedFileHolder(_Resize.FileNameExtension, resizedFileHolder);
string facesDirectory = _Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution) ? _Faces.GetFacesDirectory(dResultsFullGroupDirectory, item) : string.Empty;
string facePartsDirectory = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution) ? _FaceParts.GetFacePartsDirectory(_Configuration.PropertyConfiguration, dResultsFullGroupDirectory, item, includeNameWithoutExtension: true) : string.Empty;
string facePartsCollectionDirectory = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution) ? _FaceParts.GetFacePartsDirectory(_Configuration.PropertyConfiguration, dResultsFullGroupDirectory, item, includeNameWithoutExtension: false) : string.Empty;
MappingFromItem mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(containerDateTimes, item, resizedFileHolder);
(int metadataGroups, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, mappingFromItem);
if (_AppSettings.MaxDegreeOfParallelism < 2)
@ -410,19 +410,21 @@ public partial class DlibDotNet
faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, collection, mappingFromPhotoPrismCollection);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
bool anyFacesSaved = _Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, facesDirectory, faces);
List<(Shared.Models.Face, FileInfo?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, facesDirectory, faces);
SetMapping(idToLocationContainers, mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem, mappingFromPhotoPrismCollection, faces);
if (_Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D_Face.SaveFaces));
if ((_Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch)
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
&& !anyFacesSaved && collection is not null)
&& collection is not null && faceCollection.All(l => !l.Saved))
_Distance.LookForMatchFacesAndPossiblyRename(_Faces.FileNameExtension, eDistanceContentDirectory, mappingFromItem, faces, collection);
SetMapping(idToLocationContainers, mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem, mappingFromPhotoPrismCollection, faces);
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
{
bool saveRotated = false;
string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory);
_FaceParts.SaveFaceLandmarkImages(_Configuration.PropertyConfiguration, facePartsDirectory, facePartsCollectionDirectory, subFileTuples, parseExceptions, mappingFromItem, faces, saveRotated);
_FaceParts.SaveFaceLandmarkImages(_Configuration.PropertyConfiguration, facePartsDirectory, subFileTuples, parseExceptions, mappingFromItem, faces, saveRotated);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D2_FaceParts.SaveFaceLandmarkImages));
}
@ -443,6 +445,7 @@ public partial class DlibDotNet
string cResultsFullGroupDirectory,
string dResultsDateGroupDirectory,
string dResultsFullGroupDirectory,
string d2ResultsFullGroupDirectory,
string eDistanceContentDirectory,
List<Tuple<string, DateTime>> sourceDirectoryChanges,
Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection,
@ -456,10 +459,11 @@ public partial class DlibDotNet
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
DateTime[] containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(filteredItems.Length, message, options);
string focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory));
bool? isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath);
bool? isIgnoreRelativePath = !_Configuration.IgnoreRelativePaths.Any() ? null : _Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, container.SourceDirectory);
string facePartsCollectionDirectory = _Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution) || _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution) ? _FaceParts.GetFacePartsDirectory(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, item: filteredItems.First(), includeNameWithoutExtension: false) : string.Empty;
using ProgressBar progressBar = new(filteredItems.Length, message, options);
_ = Parallel.For(0, filteredItems.Length, parallelOptions, (i, state) =>
{
try
@ -480,7 +484,8 @@ public partial class DlibDotNet
filteredItems[i],
containerDateTimes,
isFocusRelativePath,
isIgnoreRelativePath);
isIgnoreRelativePath,
facePartsCollectionDirectory);
if (i == 0 || sourceDirectoryChanges.Any())
progressBar.Tick();
}
@ -626,6 +631,7 @@ public partial class DlibDotNet
cResultsFullGroupDirectory,
dResultsDateGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
eDistanceContentDirectory,
sourceDirectoryChanges,
fileNameToCollection,

View File

@ -12,6 +12,7 @@ public class Configuration
[Display(Name = "Check D Face and Up Dates"), Required] public bool? CheckDFaceAndUpWriteDates { get; set; }
[Display(Name = "Check Json For Distance Results"), Required] public bool? CheckJsonForDistanceResults { get; set; }
[Display(Name = "Copy Faces and Face Landmark for Output Resolutions"), Required] public string[] CopyFacesAndSaveFaceLandmarkForOutputResolutions { get; set; }
[Display(Name = "CrossDirectory Max Items In Distance Collection"), Required] public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; }
[Display(Name = "Delete Possible Duplicates"), Required] public bool? DeletePossibleDuplicates { get; set; }
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
@ -101,6 +102,7 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.CheckDFaceAndUpWriteDates));
if (configuration.CheckJsonForDistanceResults is null)
throw new NullReferenceException(nameof(configuration.CheckJsonForDistanceResults));
configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions ??= Array.Empty<string>();
if (configuration.CrossDirectoryMaxItemsInDistanceCollection is null)
throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
if (configuration.DeletePossibleDuplicates is null)
@ -225,6 +227,7 @@ public class Configuration
result = new(configuration.PropertyConfiguration,
configuration.CheckDFaceAndUpWriteDates.Value,
configuration.CheckJsonForDistanceResults.Value,
configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions,
configuration.CrossDirectoryMaxItemsInDistanceCollection.Value,
configuration.DeletePossibleDuplicates.Value,
configuration.DistanceFactor.Value,

View File

@ -11,6 +11,7 @@ public class Configuration
public bool CheckDFaceAndUpWriteDates { init; get; }
public bool CheckJsonForDistanceResults { init; get; }
public string[] CopyFacesAndSaveFaceLandmarkForOutputResolutions { init; get; }
public int CrossDirectoryMaxItemsInDistanceCollection { init; get; }
public bool DeletePossibleDuplicates { get; internal set; }
public int DistanceFactor { init; get; }
@ -84,6 +85,7 @@ public class Configuration
public Configuration(Property.Models.Configuration propertyConfiguration,
bool checkDFaceAndUpWriteDates,
bool checkJsonForDistanceResults,
string[] copyFacesAndSaveFaceLandmarkForOutputResolutions,
int crossDirectoryMaxItemsInDistanceCollection,
bool deletePossibleDuplicates,
int distanceFactor,
@ -156,6 +158,7 @@ public class Configuration
_PropertyConfiguration = propertyConfiguration;
CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
CheckJsonForDistanceResults = checkJsonForDistanceResults;
CopyFacesAndSaveFaceLandmarkForOutputResolutions = copyFacesAndSaveFaceLandmarkForOutputResolutions;
CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
DeletePossibleDuplicates = deletePossibleDuplicates;
DistanceFactor = distanceFactor;

View File

@ -28,10 +28,13 @@
"RootDirectory": "D:/1) Images A/Images-45f4401",
"xxxxxRootDirectory": "D:/1) Images A/Images-45f4401/Facebook/=2022.3 Facebook",
"SaveSortingWithoutPerson": true,
"xSkipOlderThanDays": null,
"SkipOlderThanDays": 1800,
"SkipOlderThanDays": null,
"xSkipOlderThanDays": 2200,
"CopyFacesAndSaveFaceLandmarkForOutputResolutions": [
"Original"
],
"JLinks": [
"Julie"
"Mike Phares Jr"
],
"LoadOrCreateThenSaveDistanceResultsForOutputResolutions": [
"Original"
@ -60,8 +63,8 @@
],
"RangeFaceConfidence": [
0,
0.5,
1.6
0.8,
2.4
],
"SaveFaceDistancesForOutputResolutions": [
"Original"

View File

@ -116,6 +116,7 @@
"TestDistanceResults": true,
"UseFilterTries": 0,
"WriteBitmapDataBytes": false,
"CopyFacesAndSaveFaceLandmarkForOutputResolutions": [],
"IgnoreExtensions": [
".gif",
".GIF",