SaveRandomForOutputResolutions

This commit is contained in:
2022-12-29 15:24:23 -07:00
parent 26edd826d5
commit 06a1207285
9 changed files with 209 additions and 109 deletions

View File

@ -173,7 +173,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
return results; return results;
} }
private static FaceDistanceContainer[] GetFaceDistanceContainers(Face[] distinctFilteredFaces) private static FaceDistanceContainer[] GetFaceDistanceContainers(List<Face> distinctFilteredFaces)
{ {
FaceDistanceContainer[] results; FaceDistanceContainer[] results;
FaceDistance faceDistance; FaceDistance faceDistance;
@ -211,7 +211,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
return faceDistanceEncodings; return faceDistanceEncodings;
} }
public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, long ticks, MapLogic mapLogic, Face[] distinctFilteredFaces, List<FaceDistanceContainer> missingFaceDistanceContainers, int? useFiltersCounter) public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, long ticks, MapLogic mapLogic, List<Face> distinctFilteredFaces, List<FaceDistanceContainer> missingFaceDistanceContainers, int? useFiltersCounter)
{ {
SortingContainer[] results; SortingContainer[] results;
List<SortingContainer> collection = new(); List<SortingContainer> collection = new();
@ -248,22 +248,22 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
return results; return results;
} }
public static Mapping[] GetSelectedMappingCollection(Face[] distinctFilteredFaces) public static Mapping[] GetSelectedMappingCollection(List<Face> distinctFilteredFaces)
{ {
Mapping[] results; Mapping[] results;
IEnumerable<Mapping> collection = from l in distinctFilteredFaces orderby l.Mapping?.MappingFromItem.MinimumDateTime descending select l.Mapping; IEnumerable<Mapping> collection = from l in distinctFilteredFaces orderby l.Mapping?.MappingFromItem.Id select l.Mapping;
results = (from l in collection where l is not null select l).ToArray(); results = (from l in collection where l is not null select l).ToArray();
return results; return results;
} }
public static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, Face[] distinctFilteredFaces) public static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, List<Face> distinctFilteredFaces)
{ {
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
string message = $") {distinctFilteredFaces.Length:000} Load Face Encoding - {totalSeconds} total second(s)"; string message = $") {distinctFilteredFaces.Count:000} Load Face Encoding - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(distinctFilteredFaces.Length, message, options); using ProgressBar progressBar = new(distinctFilteredFaces.Count, message, options);
_ = Parallel.For(0, distinctFilteredFaces.Length, parallelOptions, (i, state) => _ = Parallel.For(0, distinctFilteredFaces.Count, parallelOptions, (i, state) =>
{ {
Face face = distinctFilteredFaces[i]; Face face = distinctFilteredFaces[i];
if (face.FaceEncoding is null || face.Mapping is null) if (face.FaceEncoding is null || face.Mapping is null)
@ -331,12 +331,15 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
public static Dictionary<int, Dictionary<int, Mapping>> GetIdToNormalizedRectangleToFace(Mapping[] mappingCollection) public static Dictionary<int, Dictionary<int, Mapping>> GetIdToNormalizedRectangleToFace(Mapping[] mappingCollection)
{ {
Dictionary<int, Dictionary<int, Mapping>> results = new(); Dictionary<int, Dictionary<int, Mapping>> results = new();
Dictionary<int, Mapping> keyValuePairs; Dictionary<int, Mapping>? keyValuePairs;
foreach (Mapping mapping in mappingCollection) foreach (Mapping mapping in mappingCollection)
{ {
if (!results.ContainsKey(mapping.MappingFromItem.Id)) if (!results.TryGetValue(mapping.MappingFromItem.Id, out keyValuePairs))
{
results.Add(mapping.MappingFromItem.Id, new()); results.Add(mapping.MappingFromItem.Id, new());
keyValuePairs = results[mapping.MappingFromItem.Id]; if (!results.TryGetValue(mapping.MappingFromItem.Id, out keyValuePairs))
throw new Exception();
}
if (keyValuePairs.ContainsKey(mapping.MappingFromLocation.NormalizedRectangle)) if (keyValuePairs.ContainsKey(mapping.MappingFromLocation.NormalizedRectangle))
continue; continue;
keyValuePairs.Add(mapping.MappingFromLocation.NormalizedRectangle, mapping); keyValuePairs.Add(mapping.MappingFromLocation.NormalizedRectangle, mapping);

View File

@ -796,13 +796,12 @@ public partial class DlibDotNet
} }
} }
private Shared.Models.Face[] GetFilteredDistinctFaces(string argZero, Container[] containers) private List<Shared.Models.Face> GetFilteredDistinctFaces(string argZero, Container[] containers)
{ {
Shared.Models.Face[] results; List<Shared.Models.Face> results = new();
Item[] filteredItems; Item[] filteredItems;
bool isIgnoreRelativePath; bool isIgnoreRelativePath;
List<int> distinct = new(); List<int> distinct = new();
List<Shared.Models.Face> collection = new();
foreach (Container container in containers) foreach (Container container in containers)
{ {
if (!container.Items.Any()) if (!container.Items.Any())
@ -826,11 +825,10 @@ public partial class DlibDotNet
{ {
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
continue; continue;
collection.Add(face); results.Add(face);
} }
} }
} }
results = (from l in collection orderby l.Mapping?.MappingFromItem.Id select l).ToArray();
return results; return results;
} }
@ -860,16 +858,15 @@ public partial class DlibDotNet
return items; return items;
} }
private void MapLogic(string argZero, long ticks, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string fPhotoPrismContentDirectory, MapLogicSupport mapLogicSupport, MapLogic mapLogic, string outputResolution) private void MapLogic(string argZero, long ticks, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string fPhotoPrismContentDirectory, MapLogicSupport mapLogicSupport, MapLogic mapLogic, string outputResolution, List<Shared.Models.Face> distinctFilteredFaces, Mapping[] mappingCollection, int totalNotMapped)
{ {
int? useFiltersCounter = null; int? useFiltersCounter = null;
SortingContainer[] sortingContainers; SortingContainer[] sortingContainers;
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()"); string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, "()"); string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, "()");
Shared.Models.Face[] distinctFilteredFaces = GetFilteredDistinctFaces(argZero, containers); Dictionary<long, int> personKeyToCount = mapLogic.GetPersonKeyToCount(mappingCollection);
Mapping[] mappingCollection = MapLogicSupport.GetSelectedMappingCollection(distinctFilteredFaces);
string dFacesCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.PropertyConfiguration.ResultAllInOne); string dFacesCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.PropertyConfiguration.ResultAllInOne);
(Dictionary<long, int> personKeyToCount, int totalNotMapped) = mapLogic.AddToMapping(mappingCollection); Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping = MapLogicSupport.GetIdToNormalizedRectangleToFace(mappingCollection);
if (Directory.Exists(fPhotoPrismContentDirectory)) if (Directory.Exists(fPhotoPrismContentDirectory))
F_PhotoPrism.WriteMatches(fPhotoPrismContentDirectory, _Configuration.PersonBirthdayFormat, ticks, distinctFilteredFaces, mapLogic); F_PhotoPrism.WriteMatches(fPhotoPrismContentDirectory, _Configuration.PersonBirthdayFormat, ticks, distinctFilteredFaces, mapLogic);
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
@ -879,7 +876,6 @@ public partial class DlibDotNet
} }
if (_Configuration.PersonCharactersToCopyTo.Length == 1 && _Configuration.PersonCharacters.ToArray().Contains(_Configuration.PersonCharactersToCopyTo[0])) if (_Configuration.PersonCharactersToCopyTo.Length == 1 && _Configuration.PersonCharacters.ToArray().Contains(_Configuration.PersonCharactersToCopyTo[0]))
mapLogic.CopyAtLeastOneMappedFiles(_Configuration.PersonCharactersToCopyTo[0], dFacesContentDirectory, a2PeopleSingletonDirectory, mappingCollection); mapLogic.CopyAtLeastOneMappedFiles(_Configuration.PersonCharactersToCopyTo[0], dFacesContentDirectory, a2PeopleSingletonDirectory, mappingCollection);
Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping = MapLogicSupport.GetIdToNormalizedRectangleToFace(mappingCollection);
mapLogic.CopyManualFiles(dFacesContentDirectory, idToNormalizedRectangleToMapping); mapLogic.CopyManualFiles(dFacesContentDirectory, idToNormalizedRectangleToMapping);
if (_Configuration.SaveNotMappedForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveNotMappedForOutputResolutions.Contains(outputResolution))
mapLogic.CopyNotMappedFaces(_Configuration.RangeFaceAreaPermilleTolerance, dFacesContentDirectory, idToNormalizedRectangleToMapping); mapLogic.CopyNotMappedFaces(_Configuration.RangeFaceAreaPermilleTolerance, dFacesContentDirectory, idToNormalizedRectangleToMapping);
@ -906,7 +902,7 @@ public partial class DlibDotNet
MapLogicSupport.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers); MapLogicSupport.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers);
if (totalNotMapped > 0) if (totalNotMapped > 0)
{ {
bool saveNullPerson = !personKeyToCount.Any() || _Configuration.RangeDistanceTolerance[1] < (_Configuration.RangeDistanceTolerance[2] * .5); bool saveNullPerson = !personKeyToCount.Any() || _Configuration.RangeDistanceTolerance[1] < (_Configuration.RangeDistanceTolerance[2] * .66);
int updated = mapLogic.UpdateFromSortingContainers(sortingContainers, saveNullPerson); int updated = mapLogic.UpdateFromSortingContainers(sortingContainers, saveNullPerson);
List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, useFiltersCounter, saveNullPerson); List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, useFiltersCounter, saveNullPerson);
mapLogic.SaveContainers(totalNotMapped, updated, saveContainers); mapLogic.SaveContainers(totalNotMapped, updated, saveContainers);
@ -984,33 +980,6 @@ public partial class DlibDotNet
return result; return result;
} }
private List<MappingFromItem> GetMappingFromItemCollection(Container[] containers)
{
List<MappingFromItem> results = new();
Item[] filteredItems;
DateTime[] containerDateTimes;
MappingFromItem mappingFromItem;
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (_Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, container.SourceDirectory))
continue;
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(_Configuration.PropertyConfiguration, container);
if (!filteredItems.Any())
continue;
containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
foreach (Item item in filteredItems)
{
if (item.Property?.Id is null)
continue;
mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(containerDateTimes, item);
results.Add(mappingFromItem);
}
}
return results;
}
private void ParallelFor(string eDistanceContentDirectory, List<(bool, string, int, int, IReadOnlyList<MetadataExtractor.Directory>)> collection, string file) private void ParallelFor(string eDistanceContentDirectory, List<(bool, string, int, int, IReadOnlyList<MetadataExtractor.Directory>)> collection, string file)
{ {
const string lnk = ".lnk"; const string lnk = ".lnk";
@ -1082,12 +1051,14 @@ public partial class DlibDotNet
private void Search(long ticks, string argZero, string propertyRoot) private void Search(long ticks, string argZero, string propertyRoot)
{ {
int j;
int f; int f;
int j;
int t; int t;
int totalNotMapped;
Container[] containers; Container[] containers;
string? a2PeopleContentDirectory; Mapping[] mappingCollection;
string eDistanceContentDirectory; string eDistanceContentDirectory;
string? a2PeopleContentDirectory;
string aResultsFullGroupDirectory; string aResultsFullGroupDirectory;
string bResultsFullGroupDirectory; string bResultsFullGroupDirectory;
string cResultsFullGroupDirectory; string cResultsFullGroupDirectory;
@ -1095,6 +1066,7 @@ public partial class DlibDotNet
string d2ResultsFullGroupDirectory; string d2ResultsFullGroupDirectory;
string fPhotoPrismContentDirectory; string fPhotoPrismContentDirectory;
string fPhotoPrismSingletonDirectory; string fPhotoPrismSingletonDirectory;
List<Shared.Models.Face> distinctFilteredFaces;
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "{}"); string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "{}");
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Container(s) - {totalSeconds} total second(s)"; string message = $") Building Container(s) - {totalSeconds} total second(s)";
@ -1150,6 +1122,10 @@ public partial class DlibDotNet
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution); (aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
if (_Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution))
MapLogicSupport.BeforeSaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, a2PeopleSingletonDirectory); MapLogicSupport.BeforeSaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, a2PeopleSingletonDirectory);
SetMapping(_FileNameToCollection, argZero, containers);
distinctFilteredFaces = GetFilteredDistinctFaces(argZero, containers);
mappingCollection = MapLogicSupport.GetSelectedMappingCollection(distinctFilteredFaces);
totalNotMapped = mapLogic.UpdateMappingFromPerson(mappingCollection);
if (_ArgZeroIsConfigurationRootDirectory if (_ArgZeroIsConfigurationRootDirectory
&& _Configuration.SaveResizedSubfiles && _Configuration.SaveResizedSubfiles
&& outputResolution == _Configuration.OutputResolutions[0] && outputResolution == _Configuration.OutputResolutions[0]
@ -1158,18 +1134,17 @@ public partial class DlibDotNet
{ {
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any()) if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
break; break;
SetMapping(_FileNameToCollection, argZero, containers); MapLogic(argZero, ticks, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, fPhotoPrismContentDirectory, mapLogicSupport, mapLogic, outputResolution, distinctFilteredFaces, mappingCollection, totalNotMapped);
MapLogic(argZero, ticks, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, fPhotoPrismContentDirectory, mapLogicSupport, mapLogic, outputResolution);
if (_IsEnvironment.Development) if (_IsEnvironment.Development)
continue; continue;
List<MappingFromItem> mappingFromItemCollection = GetMappingFromItemCollection(containers);
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], mappingFromItemCollection);
G2_Identify identify = new(_Configuration); G2_Identify identify = new(_Configuration);
List<G2_Identify> identifiedCollection = identify.GetIdentifiedCollection(_IsEnvironment, _Configuration.PropertyConfiguration, _Faces.FileNameExtension); List<G2_Identify> identifiedCollection = identify.GetIdentifiedCollection(_IsEnvironment, _Configuration.PropertyConfiguration, _Faces.FileNameExtension);
identify.WriteAllText(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], identifiedCollection); identify.WriteAllText(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], identifiedCollection);
if (_Configuration.LoadOrCreateThenSaveIndex) if (_Configuration.LoadOrCreateThenSaveIndex)
_Index.SetIndex(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0]); _Index.SetIndex(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0]);
} }
if (_Configuration.SaveRandomForOutputResolutions.Contains(outputResolution))
_Random.Random(_Configuration.PropertyConfiguration, mapLogic, outputResolution, mappingCollection);
if (!_IsEnvironment.Development) if (!_IsEnvironment.Development)
{ {
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, "{}")); _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, "{}"));

View File

@ -70,6 +70,7 @@ public class Configuration
[Display(Name = "Save Mapped"), Required] public string[] SaveMappedForOutputResolutions { get; set; } [Display(Name = "Save Mapped"), Required] public string[] SaveMappedForOutputResolutions { get; set; }
[Display(Name = "Save Not Mapped"), Required] public string[] SaveNotMappedForOutputResolutions { get; set; } [Display(Name = "Save Not Mapped"), Required] public string[] SaveNotMappedForOutputResolutions { get; set; }
[Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; } [Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; }
[Display(Name = "Save Random For Output Resolutions"), Required] public string[] SaveRandomForOutputResolutions { get; set; }
[Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; } [Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; }
[Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; } [Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; }
[Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; } [Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; }
@ -191,6 +192,7 @@ public class Configuration
configuration.SaveMappedForOutputResolutions ??= Array.Empty<string>(); configuration.SaveMappedForOutputResolutions ??= Array.Empty<string>();
configuration.SaveNotMappedForOutputResolutions ??= Array.Empty<string>(); configuration.SaveNotMappedForOutputResolutions ??= Array.Empty<string>();
configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ??= Array.Empty<string>(); configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ??= Array.Empty<string>();
configuration.SaveRandomForOutputResolutions ??= Array.Empty<string>();
if (configuration.SaveResizedSubfiles is null) if (configuration.SaveResizedSubfiles is null)
throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles)); throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles));
configuration.SaveShortcutsForOutputResolutions ??= Array.Empty<string>(); configuration.SaveShortcutsForOutputResolutions ??= Array.Empty<string>();
@ -217,8 +219,8 @@ public class Configuration
configuration.DistancePixelDistanceTolerance.Value, configuration.DistancePixelDistanceTolerance.Value,
configuration.DistanceRenameToMatch.Value, configuration.DistanceRenameToMatch.Value,
configuration.FaceAreaPermille.Value, configuration.FaceAreaPermille.Value,
configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceConfidencePercent.Value, configuration.FaceConfidencePercent.Value,
configuration.FaceDistanceHiddenImageFactor.Value,
configuration.FaceDistancePermyriad.Value, configuration.FaceDistancePermyriad.Value,
configuration.ForceFaceLastWriteTimeToCreationTime.Value, configuration.ForceFaceLastWriteTimeToCreationTime.Value,
configuration.ForceMetadataLastWriteTimeToCreationTime.Value, configuration.ForceMetadataLastWriteTimeToCreationTime.Value,
@ -256,16 +258,17 @@ public class Configuration
configuration.PropertiesChangedForMetadata.Value, configuration.PropertiesChangedForMetadata.Value,
configuration.PropertiesChangedForResize.Value, configuration.PropertiesChangedForResize.Value,
configuration.RangeDaysDeltaTolerance, configuration.RangeDaysDeltaTolerance,
configuration.RangeDistanceTolerance,
configuration.RangeFaceAreaPermilleTolerance, configuration.RangeFaceAreaPermilleTolerance,
configuration.RangeFaceConfidence, configuration.RangeFaceConfidence,
configuration.RangeDistanceTolerance,
configuration.Reverse.Value, configuration.Reverse.Value,
configuration.SaveFaceDistancesForOutputResolutions, configuration.SaveFaceDistancesForOutputResolutions,
configuration.SaveFaceLandmarkForOutputResolutions, configuration.SaveFaceLandmarkForOutputResolutions,
configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions,
configuration.SaveFullYearOfRandomFiles.Value, configuration.SaveFullYearOfRandomFiles.Value,
configuration.SaveMappedForOutputResolutions, configuration.SaveMappedForOutputResolutions,
configuration.SaveNotMappedForOutputResolutions, configuration.SaveNotMappedForOutputResolutions,
configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions, configuration.SaveRandomForOutputResolutions,
configuration.SaveResizedSubfiles.Value, configuration.SaveResizedSubfiles.Value,
configuration.SaveShortcutsForOutputResolutions, configuration.SaveShortcutsForOutputResolutions,
configuration.SkipSearch.Value, configuration.SkipSearch.Value,

View File

@ -66,6 +66,7 @@ public class Configuration
public string[] SaveMappedForOutputResolutions { init; get; } public string[] SaveMappedForOutputResolutions { init; get; }
public string[] SaveNotMappedForOutputResolutions { init; get; } public string[] SaveNotMappedForOutputResolutions { init; get; }
public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { init; get; } public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { init; get; }
public string[] SaveRandomForOutputResolutions { init; get; }
public bool SaveResizedSubfiles { init; get; } public bool SaveResizedSubfiles { init; get; }
public string[] SaveShortcutsForOutputResolutions { init; get; } public string[] SaveShortcutsForOutputResolutions { init; get; }
public bool SkipSearch { init; get; } public bool SkipSearch { init; get; }
@ -85,8 +86,8 @@ public class Configuration
int distancePixelDistanceTolerance, int distancePixelDistanceTolerance,
bool distanceRenameToMatch, bool distanceRenameToMatch,
int faceAreaPermille, int faceAreaPermille,
int faceDistanceHiddenImageFactor,
int faceConfidencePercent, int faceConfidencePercent,
int faceDistanceHiddenImageFactor,
int faceDistancePermyriad, int faceDistancePermyriad,
bool forceFaceLastWriteTimeToCreationTime, bool forceFaceLastWriteTimeToCreationTime,
bool forceMetadataLastWriteTimeToCreationTime, bool forceMetadataLastWriteTimeToCreationTime,
@ -124,16 +125,17 @@ public class Configuration
bool propertiesChangedForMetadata, bool propertiesChangedForMetadata,
bool propertiesChangedForResize, bool propertiesChangedForResize,
int[] rangeDaysDeltaTolerance, int[] rangeDaysDeltaTolerance,
double[] rangeDistanceTolerance,
int[] rangeFaceAreaPermilleTolerance, int[] rangeFaceAreaPermilleTolerance,
double[] rangeFaceConfidence, double[] rangeFaceConfidence,
double[] rangeDistanceTolerance,
bool reverse, bool reverse,
string[] saveFaceDistancesForOutputResolutions, string[] saveFaceDistancesForOutputResolutions,
string[] saveFaceLandmarkForOutputResolutions, string[] saveFaceLandmarkForOutputResolutions,
string[] saveFilteredOriginalImagesFromJLinksForOutputResolutions,
bool saveFullYearOfRandomFiles, bool saveFullYearOfRandomFiles,
string[] saveMappedForOutputResolutions, string[] saveMappedForOutputResolutions,
string[] saveNotMappedForOutputResolutions, string[] saveNotMappedForOutputResolutions,
string[] saveFilteredOriginalImagesFromJLinksForOutputResolutions, string[] saveRandomForOutputResolutions,
bool saveResizedSubfiles, bool saveResizedSubfiles,
string[] saveShortcutsForOutputResolutions, string[] saveShortcutsForOutputResolutions,
bool skipSearch, bool skipSearch,
@ -202,6 +204,7 @@ public class Configuration
SaveNotMappedForOutputResolutions = saveNotMappedForOutputResolutions; SaveNotMappedForOutputResolutions = saveNotMappedForOutputResolutions;
SaveFilteredOriginalImagesFromJLinksForOutputResolutions = saveFilteredOriginalImagesFromJLinksForOutputResolutions; SaveFilteredOriginalImagesFromJLinksForOutputResolutions = saveFilteredOriginalImagesFromJLinksForOutputResolutions;
SaveResizedSubfiles = saveResizedSubfiles; SaveResizedSubfiles = saveResizedSubfiles;
SaveRandomForOutputResolutions = saveRandomForOutputResolutions;
SaveShortcutsForOutputResolutions = saveShortcutsForOutputResolutions; SaveShortcutsForOutputResolutions = saveShortcutsForOutputResolutions;
SkipSearch = skipSearch; SkipSearch = skipSearch;
SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh; SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;

View File

@ -43,46 +43,74 @@ internal class F_Random
return result; return result;
} }
internal void Random(Property.Models.Configuration configuration, string outputResolution, List<Shared.Models.MappingFromItem> mappingFromItemCollection) private static Dictionary<string, List<string>> Get(Map.Models.MapLogic mapLogic, Shared.Models.Mapping[] mappingCollection, string dateFormat)
{ {
Dictionary<string, List<string>> results = new();
string key;
DateTime dateTime;
List<long>? personKeys;
List<string>? relativePaths;
Dictionary<int, List<long>> idToPersonKeys = mapLogic.GetIdToPeronKeys();
foreach (Shared.Models.Mapping mapping in mappingCollection)
{
if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null || mapping.MappingFromPerson is null)
continue;
if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys))
continue;
if (!personKeys.Contains(mapping.MappingFromPerson.PersonBirthday.Value.Ticks))
continue;
dateTime = new(mapping.MappingFromPerson.PersonBirthday.Value.Ticks);
key = dateTime.ToString(dateFormat);
if (!results.TryGetValue(key, out relativePaths))
{
results.Add(key, new());
if (!results.TryGetValue(key, out relativePaths))
throw new Exception();
}
relativePaths.Add(mapping.MappingFromItem.RelativePath);
}
return results;
}
internal void Random(Property.Models.Configuration configuration, Map.Models.MapLogic mapLogic, string outputResolution, Shared.Models.Mapping[] mappingCollection)
{
string key;
string json; string json;
string jsonFile; string jsonFile;
Random random = new(); Random random = new();
List<string>? collection;
string dateFormat = "MM-dd";
List<string> relativePaths = new(); List<string> relativePaths = new();
List<string> ignoreRelativePaths = new();
DateTime dateTime = new(2024, 1, 1); //Leap year DateTime dateTime = new(2024, 1, 1); //Leap year
Dictionary<string, List<string>> dayToRelativePaths = Get(mapLogic, mappingCollection, dateFormat);
string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]"); string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]");
string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly); string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files) foreach (string file in files)
File.Delete(file); File.Delete(file);
foreach (Shared.Models.MappingFromItem mappingFromItem in mappingFromItemCollection) foreach (Shared.Models.Mapping mapping in mappingCollection)
{ {
if (mappingFromItem.ImageFileHolder.DirectoryName is null) if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null)
continue; continue;
if (!_Configuration.IgnoreRelativePaths.Any(l => mappingFromItem.ImageFileHolder.DirectoryName.Contains(l)) || !IsIgnoreRelativePath(mappingFromItem.ImageFileHolder.DirectoryName)) if (_Configuration.IgnoreRelativePaths.Any(l => mapping.MappingFromItem.ImageFileHolder.DirectoryName.Contains(l)) && IsIgnoreRelativePath(mapping.MappingFromItem.ImageFileHolder.DirectoryName))
relativePaths.Add(mappingFromItem.RelativePath); continue;
else relativePaths.Add(mapping.MappingFromItem.RelativePath);
ignoreRelativePaths.Add(mappingFromItem.RelativePath);
} }
if (relativePaths.Any()) if (relativePaths.Any())
{ {
for (int i = 0; i < 366; i++) for (int i = 0; i < 366; i++)
{ {
relativePaths = (from l in relativePaths orderby random.NextDouble() select l).ToList(); key = dateTime.AddDays(i).ToString(dateFormat);
jsonFile = Path.Combine(fRandomCollectionDirectory, $"{dateTime.AddDays(i):MM-dd}.json"); if (dayToRelativePaths.TryGetValue(key, out collection) && collection.Count > 10)
json = JsonSerializer.Serialize(relativePaths, _WriteIndentedJsonSerializerOptions); collection = (from l in collection orderby random.NextDouble() select l).ToList();
else
collection = (from l in relativePaths orderby random.NextDouble() select l).ToList();
jsonFile = Path.Combine(fRandomCollectionDirectory, $"{key}.json");
json = JsonSerializer.Serialize(collection, _WriteIndentedJsonSerializerOptions);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false); _ = Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
if (!_Configuration.SaveFullYearOfRandomFiles) if (!_Configuration.SaveFullYearOfRandomFiles)
break; break;
} }
} }
if (ignoreRelativePaths.Any())
{
ignoreRelativePaths = (from l in ignoreRelativePaths orderby random.NextDouble() select l).ToList();
jsonFile = Path.Combine(fRandomCollectionDirectory, "01-01.txt");
json = JsonSerializer.Serialize(ignoreRelativePaths, _WriteIndentedJsonSerializerOptions);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
}
} }
} }

View File

@ -13,6 +13,7 @@
"DistanceRenameToMatch": true, "DistanceRenameToMatch": true,
"DistanceMoveUnableToMatch": true, "DistanceMoveUnableToMatch": true,
"PersonCharacters": "!#]^_`~+", "PersonCharacters": "!#]^_`~+",
"PersonCharactersToCopyTo": "x",
"xPersonCharactersToCopyTo": "!", "xPersonCharactersToCopyTo": "!",
"xxPersonCharactersToCopyTo": "#", "xxPersonCharactersToCopyTo": "#",
"xxxPersonCharactersToCopyTo": "]", "xxxPersonCharactersToCopyTo": "]",
@ -22,9 +23,9 @@
"xxxxxxxPersonCharactersToCopyTo": "~", "xxxxxxxPersonCharactersToCopyTo": "~",
"xxxxxxxxPersonCharactersToCopyTo": "+", "xxxxxxxxPersonCharactersToCopyTo": "+",
"xRootDirectory": "D:/Tmp/phares/Pictures", "xRootDirectory": "D:/Tmp/phares/Pictures",
"xxRootDirectory": "D:/Tmp/Phares/Compare/Not-Copy-Copy-37c7b67", "xxRootDirectory": "D:/Tmp/Phares/Compare/Corrupt",
"xxxRootDirectory": "D:/Tmp/Phares/Compare/Corrupt", "RootDirectory": "D:/Tmp/Phares/Compare/Not-Copy-Copy-37c7b67",
"RootDirectory": "D:/1) Images A/Images-37c7b67", "xxxxRootDirectory": "D:/1) Images A/Images-37c7b67",
"xxxxxRootDirectory": "D:/1) Images A/Images-37c7b67/Facebook/=2022.3 Facebook", "xxxxxRootDirectory": "D:/1) Images A/Images-37c7b67/Facebook/=2022.3 Facebook",
"JLinks": [ "JLinks": [
"Julie" "Julie"
@ -63,9 +64,12 @@
"7680 x 4320" "7680 x 4320"
], ],
"SaveFaceLandmarkForOutputResolutions": [], "SaveFaceLandmarkForOutputResolutions": [],
"SaveFilteredOriginalImagesFromJLinksForOutputResolutions": [],
"SaveMappedForOutputResolutions": [], "SaveMappedForOutputResolutions": [],
"SaveNotMappedForOutputResolutions": [], "SaveNotMappedForOutputResolutions": [],
"SaveFilteredOriginalImagesFromJLinksForOutputResolutions": [], "SaveRandomForOutputResolutions": [
"7680 x 4320"
],
"SaveShortcutsForOutputResolutions": [], "SaveShortcutsForOutputResolutions": [],
"IgnoreRelativePaths": [ "IgnoreRelativePaths": [
"3757 W Whitman 2017", "3757 W Whitman 2017",

View File

@ -147,14 +147,15 @@
0.2, 0.2,
100 100
], ],
"SaveFaceDistancesForOutputResolutions": [],
"SaveFaceLandmarkForOutputResolutions": [],
"SaveMappedForOutputResolutions": [],
"SaveNotMappedForOutputResolutions": [],
"SaveFilteredOriginalImagesFromJLinksForOutputResolutions": [],
"SaveShortcutsForOutputResolutions": [],
"IgnoreRelativePaths": [], "IgnoreRelativePaths": [],
"MixedYearRelativePaths": [], "MixedYearRelativePaths": [],
"SaveFaceDistancesForOutputResolutions": [],
"SaveFaceLandmarkForOutputResolutions": [],
"SaveFilteredOriginalImagesFromJLinksForOutputResolutions": [],
"SaveMappedForOutputResolutions": [],
"SaveNotMappedForOutputResolutions": [],
"SaveRandomForOutputResolutions": [],
"SaveShortcutsForOutputResolutions": [],
"VerifyToSeason": [], "VerifyToSeason": [],
"ValidImageFormatExtensions": [ "ValidImageFormatExtensions": [
".bmp", ".bmp",

View File

@ -101,13 +101,71 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return result; return result;
} }
private static Dictionary<int, List<long>> GetIdToPersonKeys(Dictionary<long, List<int>> keyValuePairs)
{
Dictionary<int, List<long>> results = new();
List<long>? collection;
foreach (KeyValuePair<long, List<int>> keyValuePair in keyValuePairs)
{
foreach (int id in keyValuePair.Value)
{
if (!results.TryGetValue(id, out collection))
{
results.Add(id, new());
if (!results.TryGetValue(id, out collection))
throw new Exception();
}
if (collection.Contains(keyValuePair.Key))
continue;
collection.Add(keyValuePair.Key);
}
}
return results;
}
public Dictionary<int, List<long>> GetIdToPeronKeys()
{
Dictionary<int, List<long>> results;
long key;
const int zero = 0;
List<int>? collection;
PersonBirthday personBirthday;
Dictionary<long, List<int>> keyValuePairs = new();
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> idToCollection in _IdThenNormalizedRectangleToPersonContainers)
{
foreach (KeyValuePair<int, PersonContainer[]> normalizedRectangleToPersonContainers in idToCollection.Value)
{
foreach (PersonContainer personContainer in normalizedRectangleToPersonContainers.Value)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
if (IPersonBirthday.IsCounterPersonBirthday(personBirthday))
continue;
key = personBirthday.Value.Ticks;
if (!keyValuePairs.TryGetValue(key, out collection))
{
keyValuePairs.Add(key, new());
if (!keyValuePairs.TryGetValue(key, out collection))
throw new Exception();
}
if (collection.Contains(idToCollection.Key))
continue;
collection.Add(idToCollection.Key);
}
}
}
results = GetIdToPersonKeys(keyValuePairs);
return results;
}
(bool, Dictionary<int, PersonContainer[]>?) Shared.Models.Methods.IMapLogic.GetNormalizedRectangleToPersonContainers(int id) (bool, Dictionary<int, PersonContainer[]>?) Shared.Models.Methods.IMapLogic.GetNormalizedRectangleToPersonContainers(int id)
{ {
bool result = _IdThenNormalizedRectangleToPersonContainers.TryGetValue(id, out Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers); bool result = _IdThenNormalizedRectangleToPersonContainers.TryGetValue(id, out Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers);
return new(result, normalizedRectangleToPersonContainers); return new(result, normalizedRectangleToPersonContainers);
} }
public (Dictionary<long, int>, int) AddToMapping(Mapping[] mappingCollection) public int UpdateMappingFromPerson(Mapping[] mappingCollection)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -116,21 +174,19 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
const int zero = 0; const int zero = 0;
string mappingSegmentB; string mappingSegmentB;
PersonBirthday personBirthday; PersonBirthday personBirthday;
PersonContainer[]? collection; PersonContainer[]? personContainers;
List<PersonContainer> personContainers = new();
Dictionary<long, int> personKeyToCount = new();
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers; Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
foreach (Mapping mapping in mappingCollection) foreach (Mapping mapping in mappingCollection)
{ {
personContainers.Clear();
if (!_IdThenNormalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out normalizedRectangleToPersonContainers)) if (!_IdThenNormalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out normalizedRectangleToPersonContainers))
result += 1;
else
{ {
if (!normalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromLocation.NormalizedRectangle, out collection))
result += 1; result += 1;
else continue;
personContainers.AddRange(collection); }
if (!normalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromLocation.NormalizedRectangle, out personContainers))
{
result += 1;
continue;
} }
foreach (PersonContainer personContainer in personContainers) foreach (PersonContainer personContainer in personContainers)
{ {
@ -138,14 +194,41 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
continue; continue;
personBirthday = personContainer.Birthdays[zero]; personBirthday = personContainer.Birthdays[zero];
personKey = personBirthday.Value.Ticks; personKey = personBirthday.Value.Ticks;
if (!personKeyToCount.ContainsKey(personKey))
personKeyToCount.Add(personKey, 0);
personKeyToCount[personKey] += 1;
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mapping.MappingFromItem); mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mapping.MappingFromItem);
mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB); mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
} }
} }
return new(personKeyToCount, result); return result;
}
public Dictionary<long, int> GetPersonKeyToCount(Mapping[] mappingCollection)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
Dictionary<long, int> results = new();
long personKey;
const int zero = 0;
PersonBirthday personBirthday;
PersonContainer[]? personContainers;
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
foreach (Mapping mapping in mappingCollection)
{
if (!_IdThenNormalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out normalizedRectangleToPersonContainers))
continue;
if (!normalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromLocation.NormalizedRectangle, out personContainers))
continue;
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
personKey = personBirthday.Value.Ticks;
if (!results.ContainsKey(personKey))
results.Add(personKey, 0);
results[personKey] += 1;
}
}
return results;
} }
public void SaveContainers(int totalNotMapped, int? updated, List<SaveContainer> saveContainers) public void SaveContainers(int totalNotMapped, int? updated, List<SaveContainer> saveContainers)
@ -1200,11 +1283,11 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
public Dictionary<int, Dictionary<int, PersonContainer[]>> GetMissing(Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping) public Dictionary<int, Dictionary<int, PersonContainer[]>> GetMissing(Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping)
{ {
Dictionary<int, Dictionary<int, PersonContainer[]>> results = new(); Dictionary<int, Dictionary<int, PersonContainer[]>> results = new();
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> normalizedRectangleToPersonContainers in _IdThenNormalizedRectangleToPersonContainers) foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> idToCollection in _IdThenNormalizedRectangleToPersonContainers)
{ {
if (idToNormalizedRectangleToMapping.ContainsKey(normalizedRectangleToPersonContainers.Key)) if (idToNormalizedRectangleToMapping.ContainsKey(idToCollection.Key))
continue; continue;
results.Add(normalizedRectangleToPersonContainers.Key, normalizedRectangleToPersonContainers.Value); results.Add(idToCollection.Key, idToCollection.Value);
} }
return results; return results;
} }

View File

@ -88,7 +88,7 @@ public class F_PhotoPrism
return results; return results;
} }
public static void WriteMatches(string fPhotoPrismContentDirectory, string personBirthdayFormat, long ticks, Face[] distinctFilteredFaces, Shared.Models.Methods.IMapLogic mapLogic) public static void WriteMatches(string fPhotoPrismContentDirectory, string personBirthdayFormat, long ticks, List<Face> distinctFilteredFaces, Shared.Models.Methods.IMapLogic mapLogic)
{ {
long? personKey; long? personKey;
const int zero = 0; const int zero = 0;