Re-write
This commit is contained in:
@ -26,14 +26,14 @@ public class DlibDotNet
|
||||
private readonly B_Metadata _Metadata;
|
||||
private readonly E_Distance _Distance;
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly D2_FaceParts _FaceParts;
|
||||
private readonly AppSettings _AppSettings;
|
||||
private readonly List<string> _Exceptions;
|
||||
private readonly IsEnvironment _IsEnvironment;
|
||||
private readonly D2_FaceLandmarks _FaceLandmarks;
|
||||
private readonly Models.Configuration _Configuration;
|
||||
private readonly bool _ArgZeroIsConfigurationRootDirectory;
|
||||
private readonly List<KeyValuePair<string, string>> _FileKeyValuePairs;
|
||||
private readonly Dictionary<string, List<Tuple<string, A_Property>>> _FilePropertiesKeyValuePairs;
|
||||
private readonly Dictionary<string, List<Tuple<string, Shared.Models.Property>>> _FilePropertiesKeyValuePairs;
|
||||
|
||||
public DlibDotNet(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
|
||||
{
|
||||
@ -44,8 +44,8 @@ public class DlibDotNet
|
||||
_Exceptions = new List<string>();
|
||||
_Log = Serilog.Log.ForContext<DlibDotNet>();
|
||||
_FileKeyValuePairs = new List<KeyValuePair<string, string>>();
|
||||
_FilePropertiesKeyValuePairs = new Dictionary<string, List<Tuple<string, A_Property>>>();
|
||||
Property.Models.Configuration propertyConfiguration = Property.Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory);
|
||||
_FilePropertiesKeyValuePairs = new Dictionary<string, List<Tuple<string, Shared.Models.Property>>>();
|
||||
Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
|
||||
_Log.Information(propertyConfiguration.RootDirectory);
|
||||
Property.Models.Configuration.Verify(propertyConfiguration);
|
||||
Models.Configuration configuration = Models.Binder.Configuration.Get(isEnvironment, configurationRoot, propertyConfiguration);
|
||||
@ -57,7 +57,6 @@ public class DlibDotNet
|
||||
_People = new A2_People(configuration);
|
||||
_Rename = new E3_Rename(configuration);
|
||||
_Distance = new E_Distance(configuration);
|
||||
_FaceLandmarks = new D2_FaceLandmarks(configuration);
|
||||
if (configuration.IgnoreExtensions is null)
|
||||
throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||
_Metadata = new(configuration.ForceMetadataLastWriteTimeToCreationTime, configuration.PropertiesChangedForMetadata);
|
||||
@ -66,11 +65,8 @@ public class DlibDotNet
|
||||
else
|
||||
argZero = Path.GetFullPath(propertyConfiguration.RootDirectory);
|
||||
_ArgZeroIsConfigurationRootDirectory = propertyConfiguration.RootDirectory == argZero;
|
||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters) = C_Resize.GetTuple(configuration.OutputExtension, configuration.OutputQuality);
|
||||
_Resize = new C_Resize(configuration.ForceResizeLastWriteTimeToCreationTime, configuration.OverrideForResizeImages, configuration.PropertiesChangedForResize, configuration.ValidResolutions, imageCodecInfo, encoderParameters);
|
||||
_Log.Information(configuration.ModelDirectory);
|
||||
(Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(configuration);
|
||||
_Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel);
|
||||
if (!_ArgZeroIsConfigurationRootDirectory)
|
||||
people = Array.Empty<Person>();
|
||||
else
|
||||
@ -81,6 +77,18 @@ public class DlibDotNet
|
||||
e2Navigate.Navigate(propertyConfiguration, model, predictorModel, configuration.OutputResolutions[0]);
|
||||
_Log.Information(propertyConfiguration.RootDirectory);
|
||||
}
|
||||
{
|
||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
|
||||
_FaceParts = new D2_FaceParts(configuration, imageCodecInfo, encoderParameters, filenameExtension);
|
||||
}
|
||||
{
|
||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality();
|
||||
_Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel, imageCodecInfo, encoderParameters, filenameExtension);
|
||||
}
|
||||
{
|
||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetTuple(configuration.OutputExtension, configuration.OutputQuality);
|
||||
_Resize = new C_Resize(configuration.ForceResizeLastWriteTimeToCreationTime, configuration.OverrideForResizeImages, configuration.PropertiesChangedForResize, configuration.ValidResolutions, imageCodecInfo, encoderParameters, filenameExtension);
|
||||
}
|
||||
if (!configuration.SkipSearch)
|
||||
Search(propertyConfiguration, configuration.Reverse, model, predictorModel, argZero, people, isSilent);
|
||||
if (_Exceptions.Count == 0 && _ArgZeroIsConfigurationRootDirectory)
|
||||
@ -90,13 +98,13 @@ public class DlibDotNet
|
||||
foreach (string[] directoryCollection in directoryCollections)
|
||||
{
|
||||
_Log.Information(string.Concat("Cleaning <", directoryCollection[0], ">"));
|
||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(directoryCollection[0]);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directoryCollection[0]);
|
||||
}
|
||||
string d2FaceLandmarksRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(D2_FaceLandmarks));
|
||||
_Log.Information(string.Concat("Cleaning <", d2FaceLandmarksRootDirectory, ">"));
|
||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(d2FaceLandmarksRootDirectory);
|
||||
string d2FacePartsRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(D2_FaceParts));
|
||||
_Log.Information(string.Concat("Cleaning <", d2FacePartsRootDirectory, ">"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(d2FacePartsRootDirectory);
|
||||
if (appSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(Property.Models.Stateless.IPath.DeleteEmptyDirectories));
|
||||
ticks = LogDelta(ticks, nameof(Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories));
|
||||
}
|
||||
string message = $"There were {_Exceptions.Count} exception(s) thrown! {Environment.NewLine}{string.Join(Environment.NewLine, _Exceptions)}";
|
||||
_Log.Information(message);
|
||||
@ -112,7 +120,7 @@ public class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private long LogDelta(long ticks, string methodName)
|
||||
private long LogDelta(long ticks, string? methodName)
|
||||
{
|
||||
long result;
|
||||
if (_Log is null)
|
||||
@ -245,16 +253,12 @@ public class DlibDotNet
|
||||
throw new Exception("Input directory should be the source and not a resized directory!");
|
||||
}
|
||||
|
||||
private void FullParallelForWork(PropertyLogic propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<D_Face>> imageFaceCollections, string sourceDirectory, int index, Item item)
|
||||
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, string sourceDirectory, int index, Item item)
|
||||
{
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||
if (_Configuration.PropertyConfiguration.WriteBitmapDataBytes is null)
|
||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration.WriteBitmapDataBytes));
|
||||
A_Property property;
|
||||
List<D_Face> faceCollection;
|
||||
Shared.Models.Property property;
|
||||
List<Face> faceCollection;
|
||||
string original = "Original";
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
DateTime dateTime = DateTime.Now;
|
||||
@ -282,7 +286,7 @@ public class DlibDotNet
|
||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection));
|
||||
FileHolder resizedFileHolder = new(Path.Combine(_Resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName)));
|
||||
item.SetResizedFileHolder(resizedFileHolder);
|
||||
item.SetResizedFileHolder(_Resize.FilenameExtension, resizedFileHolder);
|
||||
imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
|
||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs));
|
||||
@ -291,7 +295,7 @@ public class DlibDotNet
|
||||
_Resize.SaveResizedSubfile(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, original, imageResizeKeyValuePairs);
|
||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(C_Resize.SaveResizedSubfile));
|
||||
item.SetResizedFileHolder(FileHolder.Refresh(resizedFileHolder));
|
||||
item.SetResizedFileHolder(_Resize.FilenameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(resizedFileHolder));
|
||||
}
|
||||
else if (outputResolution == _Configuration.OutputResolutions[0] && false)
|
||||
{
|
||||
@ -315,11 +319,14 @@ public class DlibDotNet
|
||||
_Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faceCollection);
|
||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(D_Face.SaveFaces));
|
||||
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||
int?[] normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(faceCollection);
|
||||
int normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
||||
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length || _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||
{
|
||||
_FaceLandmarks.SaveFaceLandmarkImages(d2ResultsFullGroupDirectory, sourceDirectory, subFileTuples, parseExceptions, item, faceCollection);
|
||||
bool saveRotated = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution);
|
||||
_FaceParts.SaveFaceLandmarkImages(d2ResultsFullGroupDirectory, sourceDirectory, subFileTuples, parseExceptions, item, faceCollection, saveRotated);
|
||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(D2_FaceLandmarks.SaveFaceLandmarkImages));
|
||||
ticks = LogDelta(ticks, nameof(D2_FaceParts.SaveFaceLandmarkImages));
|
||||
}
|
||||
}
|
||||
lock (sourceDirectoryChanges)
|
||||
@ -333,7 +340,7 @@ public class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private int FullParallelWork(long ticks, PropertyLogic propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<D_Face>> faceCollections, int containersCount, Container container, Item[] filteredItems)
|
||||
private int FullParallelWork(long ticks, 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>> faceCollections, int containersCount, Container container, Item[] filteredItems)
|
||||
{
|
||||
int result = 0;
|
||||
if (_Log is null)
|
||||
@ -345,9 +352,9 @@ public class DlibDotNet
|
||||
for (int i = 0; i < filteredItems.Length; i++)
|
||||
{
|
||||
faceCollections.Add(new());
|
||||
propertyCollection.Add(null);
|
||||
metadataCollection.Add(new());
|
||||
resizeKeyValuePairs.Add(new());
|
||||
propertyCollection.Add(new());
|
||||
propertyFileHolderCollection.Add(null);
|
||||
}
|
||||
}
|
||||
@ -401,7 +408,7 @@ public class DlibDotNet
|
||||
if (metadataIdLines.Any())
|
||||
{
|
||||
text = string.Join(Environment.NewLine, from l in metadataIdLines orderby l.Id select l.Line);
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, text, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, text, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -410,25 +417,23 @@ public class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteGroup(Property.Models.Configuration configuration, PropertyLogic propertyLogic, List<A_Property> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<List<D_Face>> faceCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, string sourceDirectory, string outputResolution, Item[] filteredItems)
|
||||
private void WriteGroup(Property.Models.Configuration configuration, A_Property propertyLogic, Shared.Models.Property[] propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<List<Face>> faceCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, string sourceDirectory, string outputResolution, Item[] filteredItems)
|
||||
{
|
||||
if (configuration.PropertiesChangedForProperty is null)
|
||||
throw new NullReferenceException(nameof(configuration.PropertiesChangedForProperty));
|
||||
Item item;
|
||||
string key;
|
||||
string json;
|
||||
string checkFile;
|
||||
int sourceDirectoryLength = sourceDirectory.Length;
|
||||
_FilePropertiesKeyValuePairs.Add(sourceDirectory, new List<Tuple<string, A_Property>>());
|
||||
_FilePropertiesKeyValuePairs.Add(sourceDirectory, new List<Tuple<string, Shared.Models.Property>>());
|
||||
JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = false };
|
||||
if (!(from l in propertyCollection where l?.Width is null select true).Any())
|
||||
{
|
||||
string checkDirectory;
|
||||
List<KeyValuePair<string, List<D_Face>>> faceCollectionsKeyValuePairs = new();
|
||||
List<KeyValuePair<string, A_Property>> propertyCollectionKeyValuePairs = new();
|
||||
List<KeyValuePair<string, List<Face>>> faceCollectionsKeyValuePairs = new();
|
||||
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) = Property.Models.Stateless.IPath.Get(configuration.RootDirectory, sourceDirectory);
|
||||
(int level, List<string> directories) = Shared.Models.Stateless.Methods.IPath.Get(configuration.RootDirectory, sourceDirectory);
|
||||
string fileName = string.Concat(string.Join(configuration.FileNameDirectorySeparator, directories), ".json");
|
||||
for (int i = 0; i < filteredItems.Length; i++)
|
||||
{
|
||||
@ -437,53 +442,53 @@ public class DlibDotNet
|
||||
continue;
|
||||
if (item.ImageFileHolder is null)
|
||||
continue;
|
||||
key = Property.Models.Stateless.IPath.GetRelativePath(item.ImageFileHolder.FullName, sourceDirectoryLength);
|
||||
key = Shared.Models.Stateless.Methods.IPath.GetRelativePath(item.ImageFileHolder.FullName, sourceDirectoryLength);
|
||||
_FileKeyValuePairs.Add(new KeyValuePair<string, string>(sourceDirectory, key));
|
||||
_FilePropertiesKeyValuePairs[sourceDirectory].Add(new Tuple<string, A_Property>(key, propertyCollection[i]));
|
||||
faceCollectionsKeyValuePairs.Add(new KeyValuePair<string, List<D_Face>>(key, faceCollections[i]));
|
||||
propertyCollectionKeyValuePairs.Add(new KeyValuePair<string, A_Property>(key, propertyCollection[i]));
|
||||
_FilePropertiesKeyValuePairs[sourceDirectory].Add(new Tuple<string, Shared.Models.Property>(key, propertyCollection[i]));
|
||||
faceCollectionsKeyValuePairs.Add(new KeyValuePair<string, List<Face>>(key, faceCollections[i]));
|
||||
propertyCollectionKeyValuePairs.Add(new KeyValuePair<string, Shared.Models.Property>(key, propertyCollection[i]));
|
||||
resizeKeyValuePairsCollections.Add(new KeyValuePair<string, Dictionary<string, int[]>>(key, resizeKeyValuePairs[i]));
|
||||
metadataCollectionKeyValuePairs.Add(new KeyValuePair<string, List<KeyValuePair<string, string>>>(key, metadataCollection[i]));
|
||||
}
|
||||
if (propertyLogic.AngleBracketCollection.Any())
|
||||
{
|
||||
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(propertyLogic.AngleBracketCollection[0], level, "[{}]");
|
||||
checkDirectory = Shared.Models.Stateless.Methods.IPath.GetDirectory(propertyLogic.AngleBracketCollection[0], level, "[{}]");
|
||||
checkFile = Path.Combine(checkDirectory, fileName);
|
||||
if (File.Exists(checkFile))
|
||||
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
||||
checkFile = Path.Combine(checkDirectory, fileName);
|
||||
json = JsonSerializer.Serialize(propertyCollectionKeyValuePairs, writeIndentedJsonSerializerOptions);
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||
}
|
||||
if (_Metadata.AngleBracketCollection.Any())
|
||||
{
|
||||
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(_Metadata.AngleBracketCollection[0], level, "[{}]");
|
||||
checkDirectory = Shared.Models.Stateless.Methods.IPath.GetDirectory(_Metadata.AngleBracketCollection[0], level, "[{}]");
|
||||
checkFile = Path.Combine(checkDirectory, fileName);
|
||||
if (File.Exists(checkFile))
|
||||
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
||||
checkFile = Path.Combine(checkDirectory, fileName);
|
||||
json = JsonSerializer.Serialize(metadataCollectionKeyValuePairs, writeIndentedJsonSerializerOptions);
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||
}
|
||||
if (_Resize.AngleBracketCollection.Any())
|
||||
{
|
||||
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(_Resize.AngleBracketCollection[0], level, "[{}]");
|
||||
checkDirectory = Shared.Models.Stateless.Methods.IPath.GetDirectory(_Resize.AngleBracketCollection[0], level, "[{}]");
|
||||
checkFile = Path.Combine(checkDirectory, fileName);
|
||||
if (File.Exists(checkFile))
|
||||
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
||||
checkFile = Path.Combine(checkDirectory, fileName);
|
||||
json = JsonSerializer.Serialize(resizeKeyValuePairsCollections, writeIndentedJsonSerializerOptions);
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||
}
|
||||
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution) && _Faces.AngleBracketCollection.Any())
|
||||
{
|
||||
checkDirectory = Property.Models.Stateless.IPath.GetDirectory(_Faces.AngleBracketCollection[0], level, "[{}]");
|
||||
checkDirectory = Shared.Models.Stateless.Methods.IPath.GetDirectory(_Faces.AngleBracketCollection[0], level, "[{}]");
|
||||
checkFile = Path.Combine(checkDirectory, fileName);
|
||||
if (File.Exists(checkFile))
|
||||
File.Move(checkFile, Path.Combine(checkDirectory, fileName));
|
||||
checkFile = Path.Combine(checkDirectory, fileName);
|
||||
json = JsonSerializer.Serialize(faceCollectionsKeyValuePairs, writeIndentedJsonSerializerOptions);
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -499,7 +504,7 @@ public class DlibDotNet
|
||||
string dResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||
configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
|
||||
string d2ResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||
configuration, model, predictorModel, nameof(D2_FaceLandmarks), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
|
||||
configuration, 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);
|
||||
string zResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||
@ -507,7 +512,7 @@ public class DlibDotNet
|
||||
return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory, zResultsFullGroupDirectory);
|
||||
}
|
||||
|
||||
private void SetAngleBracketCollections(Property.Models.Configuration configuration, PropertyLogic propertyLogic, string outputResolution, Container container, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory)
|
||||
private void SetAngleBracketCollections(Property.Models.Configuration configuration, A_Property propertyLogic, string outputResolution, Container container, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory)
|
||||
{
|
||||
_Faces.AngleBracketCollection.Clear();
|
||||
_Resize.AngleBracketCollection.Clear();
|
||||
@ -544,7 +549,7 @@ public class DlibDotNet
|
||||
converted: true));
|
||||
}
|
||||
|
||||
private void FullDoWork(bool isSilent, string argZero, Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, long ticks, Dictionary<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, List<Container> containers)
|
||||
private void FullDoWork(string argZero, Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, long ticks, Map.Models.MapLogic mapLogic, A_Property propertyLogic, List<Container> containers)
|
||||
{
|
||||
if (_Log is null)
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
@ -559,11 +564,12 @@ public class DlibDotNet
|
||||
string eResultsFullGroupDirectory;
|
||||
string zResultsFullGroupDirectory;
|
||||
string d2ResultsFullGroupDirectory;
|
||||
List<List<D_Face>> faceCollections = new();
|
||||
List<A_Property> propertyCollection = new();
|
||||
List<List<Face>> faceCollections = new();
|
||||
Shared.Models.Property[] propertyCollection;
|
||||
List<FileHolder?> propertyFileHolderCollection = new();
|
||||
List<Dictionary<string, int[]>> resizeKeyValuePairs = new();
|
||||
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
|
||||
List<Shared.Models.Property?> nullablePropertyCollection = new();
|
||||
List<List<KeyValuePair<string, string>>> metadataCollection = new();
|
||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||
string propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(A_Property));
|
||||
@ -583,28 +589,29 @@ public class DlibDotNet
|
||||
continue;
|
||||
faceCollections.Clear();
|
||||
metadataCollection.Clear();
|
||||
propertyCollection.Clear();
|
||||
resizeKeyValuePairs.Clear();
|
||||
sourceDirectoryChanges.Clear();
|
||||
nullablePropertyCollection.Clear();
|
||||
propertyFileHolderCollection.Clear();
|
||||
SetAngleBracketCollections(configuration, propertyLogic, outputResolution, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory);
|
||||
exceptionCount = FullParallelWork(ticks, propertyLogic, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, sourceDirectoryChanges, propertyFileHolderCollection, propertyCollection, metadataCollection, resizeKeyValuePairs, faceCollections, containers.Count, container, filteredItems);
|
||||
exceptionCount = FullParallelWork(ticks, propertyLogic, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, sourceDirectoryChanges, propertyFileHolderCollection, nullablePropertyCollection, metadataCollection, resizeKeyValuePairs, faceCollections, containers.Count, container, filteredItems);
|
||||
#pragma warning disable
|
||||
ids = (from l in filteredItems where l.Property?.Id is not null select l.Property.Id.Value).ToArray();
|
||||
#pragma warning restore
|
||||
distinctCount = ids.Distinct().Count();
|
||||
if (ids.Length != distinctCount)
|
||||
_Log.Information($"{ids.Length} != {distinctCount} <{container.SourceDirectory}>");
|
||||
if (metadataCollection.Count != filteredItems.Length || propertyCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || faceCollections.Count != filteredItems.Length)
|
||||
if (metadataCollection.Count != filteredItems.Length || nullablePropertyCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || faceCollections.Count != filteredItems.Length)
|
||||
throw new Exception("Counts don't match!");
|
||||
if (exceptionCount != 0)
|
||||
_Exceptions.Add(container.SourceDirectory);
|
||||
for (int i = 0; i < faceCollections.Count; i++)
|
||||
filteredItems[i].Faces.AddRange(from l in faceCollections[i] select l);
|
||||
propertyCollection = (from l in nullablePropertyCollection where l is not null select l).ToArray();
|
||||
if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0)
|
||||
WriteGroup(configuration, propertyLogic, propertyCollection, metadataCollection, faceCollections, resizeKeyValuePairs, container.SourceDirectory, outputResolution, filteredItems);
|
||||
if (_ArgZeroIsConfigurationRootDirectory && exceptionCount == 0 && outputResolution == _Configuration.OutputResolutions[0])
|
||||
propertyLogic.AddToPropertyLogicAllCollection(filteredItems);
|
||||
mapLogic.AddToMapLogicAllCollection(filteredItems);
|
||||
if (exceptionCount == 0 && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution))
|
||||
_Distance.LoadOrCreateThenSaveDistanceResults(configuration, eResultsFullGroupDirectory, container.SourceDirectory, outputResolution, sourceDirectoryChanges, filteredItems);
|
||||
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
|
||||
@ -633,15 +640,6 @@ public class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private PropertyLogic GetPropertyLogic(bool reverse, Model? model, PredictorModel? predictorModel)
|
||||
{
|
||||
PropertyLogic result;
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||
result = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, reverse, model, predictorModel);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void Search(Property.Models.Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel, string argZero, Person[] people, bool isSilent)
|
||||
{
|
||||
if (_Log is null)
|
||||
@ -656,26 +654,27 @@ public class DlibDotNet
|
||||
string zResultsFullGroupDirectory;
|
||||
string d2ResultsFullGroupDirectory;
|
||||
Dictionary<string, List<Person>> peopleCollection = A2_People.Convert(people);
|
||||
PropertyLogic propertyLogic = GetPropertyLogic(reverse, model, predictorModel);
|
||||
Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration);
|
||||
A_Property propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FilenameExtension, reverse, model, predictorModel, mapLogic.IndicesFromNew, mapLogic.KeyValuePairs);
|
||||
if (string.IsNullOrEmpty(configuration.RootDirectory))
|
||||
containers = Property.Models.Stateless.A_Property.Get(configuration, propertyLogic);
|
||||
containers = A_Property.Get(configuration, propertyLogic);
|
||||
else
|
||||
containers = Property.Models.Stateless.Container.GetContainers(configuration, propertyLogic);
|
||||
FullDoWork(isSilent, argZero, configuration, model, predictorModel, ticks, peopleCollection, propertyLogic, containers);
|
||||
FullDoWork(argZero, configuration, model, predictorModel, ticks, mapLogic, propertyLogic, containers);
|
||||
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||
{
|
||||
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory, zResultsFullGroupDirectory) = GetResultsFullGroupDirectories(configuration, model, predictorModel, outputResolution);
|
||||
if (_ArgZeroIsConfigurationRootDirectory && _Exceptions.Count == 0 && outputResolution == _Configuration.OutputResolutions[0] && (propertyLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs.Any() || propertyLogic.NamedDeterministicHashCodeKeyValuePairs.Any()))
|
||||
if (_ArgZeroIsConfigurationRootDirectory && _Exceptions.Count == 0 && outputResolution == _Configuration.OutputResolutions[0] && (mapLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs.Any() || mapLogic.NamedDeterministicHashCodeKeyValuePairs.Any()))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(propertyLogic.DeterministicHashCodeRootDirectory) && !propertyLogic.IncorrectDeterministicHashCodeKeyValuePairs.Any())
|
||||
propertyLogic.UpdateKeyValuePairs(containers);
|
||||
if (!string.IsNullOrEmpty(mapLogic.DeterministicHashCodeRootDirectory) && !mapLogic.IncorrectDeterministicHashCodeKeyValuePairs.Any())
|
||||
mapLogic.UpdateKeyValuePairs(containers);
|
||||
foreach (Container container in containers)
|
||||
{
|
||||
Item.AddToNamed(propertyLogic, container.Items);
|
||||
Map.Models.MapLogic.AddToNamed(mapLogic, container.Items);
|
||||
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
|
||||
D_Face.SaveShortcuts(_Configuration.JuliePhares, dResultsFullGroupDirectory, ticks, peopleCollection, propertyLogic, container.Items);
|
||||
D_Face.SaveShortcuts(_Configuration.JuliePhares, dResultsFullGroupDirectory, ticks, peopleCollection, mapLogic, container.Items);
|
||||
}
|
||||
propertyLogic.SaveAllCollection();
|
||||
mapLogic.SaveAllCollection();
|
||||
if (_Configuration.SaveResizedSubfiles)
|
||||
{
|
||||
string dFacesContentDirectory;
|
||||
@ -687,13 +686,13 @@ public class DlibDotNet
|
||||
zPropertyHolderSingletonDirectory = Path.Combine(zResultsFullGroupDirectory, "{}");
|
||||
eDistanceCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, $"[{ticks}]");
|
||||
List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection;
|
||||
collection = E_Distance.ParallelWork(_AppSettings.MaxDegreeOfParallelism, argZero, propertyLogic, containers);
|
||||
collection = E_Distance.ParallelWork(_AppSettings.MaxDegreeOfParallelism, argZero, mapLogic, containers);
|
||||
_ = LogDeltaInSeconds(ticks, nameof(E_Distance.ParallelWork));
|
||||
E_Distance.SavePropertyHolders(argZero, containers, zPropertyHolderSingletonDirectory);
|
||||
_ = LogDeltaInSeconds(ticks, nameof(E_Distance.SavePropertyHolders));
|
||||
E_Distance.SaveThreeSigmaFaceEncodings(collection, peopleCollection, eDistanceCollectionDirectory);
|
||||
_ = LogDeltaInSeconds(ticks, nameof(E_Distance.SaveThreeSigmaFaceEncodings));
|
||||
E_Distance.SaveClosest(argZero, containers, peopleCollection, eDistanceContentDirectory, dFacesContentDirectory);
|
||||
E_Distance.SaveClosest(argZero, containers, peopleCollection, dFacesContentDirectory, d2ResultsFullGroupDirectory, eDistanceContentDirectory);
|
||||
_ = LogDeltaInMinutes(ticks, nameof(E_Distance.SaveClosest));
|
||||
}
|
||||
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
|
||||
@ -708,18 +707,18 @@ public class DlibDotNet
|
||||
identify.WriteAllText(configuration, _Configuration.OutputResolutions[0], identifiedCollection);
|
||||
if (_Configuration.LoadOrCreateThenSaveIndex && _FilePropertiesKeyValuePairs.Any())
|
||||
_Index.SetIndex(configuration, model, predictorModel, _Configuration.OutputResolutions[0], _FilePropertiesKeyValuePairs);
|
||||
}
|
||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, "{}"));
|
||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(bResultsFullGroupDirectory, "{}"));
|
||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, "{}"));
|
||||
}
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, "{}"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(bResultsFullGroupDirectory, "{}"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, "{}"));
|
||||
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
|
||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(dResultsFullGroupDirectory, "[]"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(dResultsFullGroupDirectory, "[]"));
|
||||
if (_Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution))
|
||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]"));
|
||||
if (_Configuration.LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions.Contains(outputResolution))
|
||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "[]"));
|
||||
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(Path.Combine(d2ResultsFullGroupDirectory, "[]"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(d2ResultsFullGroupDirectory, "[]"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
<PropertyGroup>
|
||||
<PackageId>Phares.View.by.Distance.Instance</PackageId>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<Version>5.0.402.104</Version>
|
||||
<Version>6.0.100.1</Version>
|
||||
<Authors>Mike Phares</Authors>
|
||||
<Company>Phares</Company>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
@ -53,12 +53,13 @@
|
||||
<PackageReference Include="WindowsShortcutFactory" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
<ProjectReference Include="..\Property\Property.csproj" />
|
||||
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
||||
<ProjectReference Include="..\Resize\Resize.csproj" />
|
||||
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />
|
||||
<ProjectReference Include="..\Map\Map.csproj" />
|
||||
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
||||
<ProjectReference Include="..\Property-Compare\Property-Compare.csproj" />
|
||||
<ProjectReference Include="..\Property\Property.csproj" />
|
||||
<ProjectReference Include="..\Resize\Resize.csproj" />
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="appsettings.json">
|
||||
|
@ -1,48 +0,0 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using View_by_Distance.FaceRecognitionDotNet;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
internal class DistanceHolder
|
||||
{
|
||||
|
||||
public IFace Face { init; get; }
|
||||
public FaceEncoding? FaceEncoding { init; get; }
|
||||
public FileHolder FileHolder { init; get; }
|
||||
public int Id { init; get; }
|
||||
public string JSONDirectory { init; get; }
|
||||
public ILocation Location { init; get; }
|
||||
public string TSVDirectory { init; get; }
|
||||
public double Sort { get; set; }
|
||||
|
||||
[JsonConstructor]
|
||||
public DistanceHolder(
|
||||
IFace face,
|
||||
FaceEncoding? faceEncoding,
|
||||
FileHolder fileHolder,
|
||||
int id,
|
||||
string jsonDirectory,
|
||||
ILocation location,
|
||||
string tsvDirectory
|
||||
)
|
||||
{
|
||||
FileHolder = fileHolder;
|
||||
Sort = double.MaxValue;
|
||||
Face = face;
|
||||
FaceEncoding = faceEncoding;
|
||||
Id = id;
|
||||
JSONDirectory = jsonDirectory;
|
||||
Location = location;
|
||||
TSVDirectory = tsvDirectory;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
@ -37,7 +36,7 @@ internal class A2_People
|
||||
string directoryFullName;
|
||||
Dictionary<string, List<G2_Identify>> keyValuePairs = new();
|
||||
string hPeopleCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People), "[]");
|
||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "{}");
|
||||
foreach (G2_Identify identified in identifiedCollection)
|
||||
{
|
||||
fileInfo = new FileInfo(string.Concat(aPropertySingletonDirectory, identified.RelativePath));
|
||||
@ -56,7 +55,7 @@ internal class A2_People
|
||||
_ = Directory.CreateDirectory(directoryFullName);
|
||||
jsonFile = Path.Combine(directoryFullName, $"{segments[1]}.json");
|
||||
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
|
||||
if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -64,8 +63,6 @@ internal class A2_People
|
||||
internal Person[] GetPeople(Property.Models.Configuration configuration)
|
||||
{
|
||||
Person[] results;
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||
string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
|
||||
string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People));
|
||||
string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory));
|
||||
|
@ -1,8 +1,9 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
@ -11,16 +12,22 @@ namespace View_by_Distance.Instance.Models;
|
||||
/// <summary>
|
||||
// *.png
|
||||
/// </summary>
|
||||
internal class D2_FaceLandmarks
|
||||
internal class D2_FaceParts
|
||||
{
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly string _FilenameExtension;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly ImageCodecInfo _ImageCodecInfo;
|
||||
private readonly EncoderParameters _EncoderParameters;
|
||||
|
||||
internal D2_FaceLandmarks(Configuration configuration)
|
||||
internal D2_FaceParts(Configuration configuration, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension)
|
||||
{
|
||||
_Configuration = configuration;
|
||||
_Log = Serilog.Log.ForContext<D2_FaceLandmarks>();
|
||||
_ImageCodecInfo = imageCodecInfo;
|
||||
_EncoderParameters = encoderParameters;
|
||||
_FilenameExtension = filenameExtension;
|
||||
_Log = Serilog.Log.ForContext<D2_FaceParts>();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -41,60 +48,64 @@ internal class D2_FaceLandmarks
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SaveFaceLandmarkImages(List<D_Face> faceCollections, List<string[]> imageFiles, int pointSize, FileHolder resizedFileHolder)
|
||||
private void SaveFaceParts(int pointSize, IFileHolder resizedFileHolder, bool saveRotated, List<(Face, string, string)> collection)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
double? α;
|
||||
int width;
|
||||
int height;
|
||||
D_Face face;
|
||||
string imageFileFullName;
|
||||
Bitmap rotated;
|
||||
string rotatedImageFileFullName;
|
||||
Shared.Models.FacePoint[] facePoints;
|
||||
for (int i = 0; i < faceCollections.Count; i++)
|
||||
foreach ((Face face, string fileName, string rotatedFileName) in collection)
|
||||
{
|
||||
if (!faceCollections[i].Populated)
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
continue;
|
||||
face = faceCollections[i];
|
||||
imageFileFullName = imageFiles[i][0];
|
||||
rotatedImageFileFullName = imageFiles[i][1];
|
||||
try
|
||||
{
|
||||
using (Image image = Image.FromFile(resizedFileHolder.FullName))
|
||||
{
|
||||
using Graphics graphic = Graphics.FromImage(image);
|
||||
if (face.FaceLandmarks is null || !face.FaceLandmarks.Any())
|
||||
if (face.FaceParts is null || !face.FaceParts.Any())
|
||||
{
|
||||
if (face.Location is null)
|
||||
continue;
|
||||
width = face.Location.Right - face.Location.Left;
|
||||
height = face.Location.Bottom - face.Location.Top;
|
||||
graphic.DrawEllipse(Pens.Red, face.Location.Left, face.Location.Top, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (KeyValuePair<string, Shared.Models.FacePoint[]> keyValuePair in face.FaceLandmarks)
|
||||
foreach ((FacePart facePart, FacePoint[] facePoints) in face.FaceParts)
|
||||
{
|
||||
facePoints = keyValuePair.Value.ToArray();
|
||||
foreach (Shared.Models.FacePoint facePoint in facePoints)
|
||||
foreach (FacePoint facePoint in facePoints)
|
||||
{
|
||||
if (face.Location is null)
|
||||
continue;
|
||||
graphic.DrawEllipse(Pens.GreenYellow, face.Location.Left + facePoint.X - pointSize, face.Location.Top + facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
|
||||
if (keyValuePair.Key == FacePart.Chin.ToString())
|
||||
}
|
||||
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, face.Location.Left + x - pointSize, face.Location.Top + y - pointSize, pointSize * 2, pointSize * 2);
|
||||
}
|
||||
}
|
||||
image.Save(imageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
|
||||
image.Save(fileName, _ImageCodecInfo, _EncoderParameters);
|
||||
}
|
||||
if (face.α.HasValue)
|
||||
if (saveRotated && face.FaceParts is not null)
|
||||
{
|
||||
α = Shared.Models.Stateless.Methods.IFace.Getα(face.FaceParts);
|
||||
if (α is null)
|
||||
continue;
|
||||
using Image image = Image.FromFile(resizedFileHolder.FullName);
|
||||
rotated = RotateBitmap(image, (float)face.α.Value);
|
||||
rotated = RotateBitmap(image, (float)α.Value);
|
||||
if (rotated is not null)
|
||||
{
|
||||
rotated.Save(rotatedImageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
|
||||
rotated.Save(rotatedFileName, _ImageCodecInfo, _EncoderParameters);
|
||||
rotated.Dispose();
|
||||
}
|
||||
}
|
||||
@ -105,10 +116,8 @@ internal class D2_FaceLandmarks
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
internal void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, string sourceDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<D_Face> faceCollection)
|
||||
internal void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, string sourceDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Face> faceCollection, bool saveRotated)
|
||||
{
|
||||
if (_Configuration.PropertyConfiguration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
if (item.ResizedFileHolder is null)
|
||||
@ -121,31 +130,31 @@ internal class D2_FaceLandmarks
|
||||
DateTime? dateTime = null;
|
||||
double deterministicHashCodeKey;
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
List<string[]> imageFiles = new();
|
||||
bool updateDateWhenMatches = false;
|
||||
List<string> angleBracketCollection = new();
|
||||
List<(Face, string, string)> collection = new();
|
||||
angleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(
|
||||
_Configuration.PropertyConfiguration,
|
||||
sourceDirectory,
|
||||
d2ResultsFullGroupDirectory,
|
||||
contentDescription: "n x 2 png file(s) for each face found",
|
||||
contentDescription: "n x 2 gif file(s) for each face found",
|
||||
singletonDescription: string.Empty,
|
||||
collectionDescription: string.Empty,
|
||||
converted: false));
|
||||
string facesDirectory = Path.Combine(angleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
|
||||
string[] changesFrom = new string[] { nameof(Property.Models.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(facesDirectory))
|
||||
_ = Directory.CreateDirectory(facesDirectory);
|
||||
foreach (IFace face in faceCollection)
|
||||
foreach (Face face in faceCollection)
|
||||
{
|
||||
if (!face.Populated || face.Location?.NormalizedPixelPercentage is null)
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
{
|
||||
imageFiles.Add(Array.Empty<string>());
|
||||
collection.Add(new(face, string.Empty, string.Empty));
|
||||
continue;
|
||||
}
|
||||
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face);
|
||||
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
|
||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.INamed.GetDeterministicHashCodeKey(item, face);
|
||||
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FilenameExtension}"));
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
if (fileInfo.Directory?.Parent is null)
|
||||
@ -156,15 +165,15 @@ internal class D2_FaceLandmarks
|
||||
}
|
||||
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
|
||||
continue;
|
||||
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKey} - R{item.ImageFileHolder.ExtensionLowered}"));
|
||||
imageFiles.Add(new string[] { fileInfo.FullName, rotatedFileInfo.FullName });
|
||||
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKey} - R{item.ImageFileHolder.ExtensionLowered}{_FilenameExtension}"));
|
||||
collection.Add(new(face, fileInfo.FullName, rotatedFileInfo.FullName));
|
||||
if (check)
|
||||
continue;
|
||||
else if (_Configuration.OverrideForFaceLandmarkImages)
|
||||
check = true;
|
||||
else if (!fileInfo.Exists)
|
||||
check = true;
|
||||
else if (!rotatedFileInfo.Exists)
|
||||
else if (saveRotated && !rotatedFileInfo.Exists)
|
||||
check = true;
|
||||
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
check = true;
|
||||
@ -175,7 +184,7 @@ internal class D2_FaceLandmarks
|
||||
}
|
||||
}
|
||||
if (check)
|
||||
SaveFaceLandmarkImages(faceCollection, imageFiles, pointSize, item.ResizedFileHolder);
|
||||
SaveFaceParts(pointSize, item.ResizedFileHolder, saveRotated, collection);
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +1,13 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
using View_by_Distance.FaceRecognitionDotNet;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
using WindowsShortcutFactory;
|
||||
|
||||
@ -17,7 +16,7 @@ namespace View_by_Distance.Instance.Models;
|
||||
/// <summary>
|
||||
// List<D_Faces>
|
||||
/// </summary>
|
||||
public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
public class D_Face
|
||||
{
|
||||
|
||||
internal List<string> AngleBracketCollection { get; }
|
||||
@ -25,112 +24,29 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
private readonly Model _Model;
|
||||
private readonly string _ArgZero;
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly string _FilenameExtension;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly ModelParameter _ModelParameter;
|
||||
private readonly PredictorModel _PredictorModel;
|
||||
private readonly ImageCodecInfo _ImageCodecInfo;
|
||||
private readonly EncoderParameters _EncoderParameters;
|
||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||
|
||||
protected double? _Α;
|
||||
protected DateTime _DateTime;
|
||||
protected Shared.Models.FaceEncoding _FaceEncoding;
|
||||
protected Dictionary<string, FacePoint[]> _FaceLandmarks;
|
||||
protected Location _Location;
|
||||
protected int? _LocationIndex;
|
||||
protected OutputResolution _OutputResolution;
|
||||
protected bool _Populated;
|
||||
protected string _RelativePath;
|
||||
public double? α => _Α;
|
||||
public DateTime DateTime => _DateTime;
|
||||
public Shared.Models.FaceEncoding FaceEncoding => _FaceEncoding;
|
||||
public Dictionary<string, FacePoint[]> FaceLandmarks => _FaceLandmarks;
|
||||
public OutputResolution OutputResolution => _OutputResolution;
|
||||
public Location Location => _Location;
|
||||
public int? LocationIndex => _LocationIndex;
|
||||
public bool Populated => _Populated;
|
||||
public string RelativePath => _RelativePath;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[JsonConstructor]
|
||||
public D_Face(double? α, DateTime dateTime, Shared.Models.FaceEncoding faceEncoding, Dictionary<string, FacePoint[]> faceLandmarks, Location location, int? locationIndex, OutputResolution outputResolution, bool populated, string relativePath)
|
||||
{
|
||||
_Α = α;
|
||||
_DateTime = dateTime;
|
||||
_FaceEncoding = faceEncoding;
|
||||
_FaceLandmarks = faceLandmarks;
|
||||
_Location = location;
|
||||
_LocationIndex = locationIndex;
|
||||
_OutputResolution = outputResolution;
|
||||
_Populated = populated;
|
||||
_RelativePath = relativePath;
|
||||
}
|
||||
|
||||
internal D_Face(Configuration configuration, string argZero, Model model, ModelParameter modelParameter, PredictorModel predictorModel)
|
||||
internal D_Face(Configuration configuration, string argZero, Model model, ModelParameter modelParameter, PredictorModel predictorModel, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension)
|
||||
{
|
||||
_Model = model;
|
||||
_ArgZero = argZero;
|
||||
_Configuration = configuration;
|
||||
_ModelParameter = modelParameter;
|
||||
_PredictorModel = predictorModel;
|
||||
_ImageCodecInfo = imageCodecInfo;
|
||||
_EncoderParameters = encoderParameters;
|
||||
_FilenameExtension = filenameExtension;
|
||||
AngleBracketCollection = new List<string>();
|
||||
_Log = Serilog.Log.ForContext<D_Face>();
|
||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
||||
}
|
||||
|
||||
private D_Face(Location location)
|
||||
{
|
||||
_Α = α;
|
||||
_DateTime = DateTime.MinValue;
|
||||
_FaceEncoding = null;
|
||||
_FaceLandmarks = null;
|
||||
_OutputResolution = null;
|
||||
_Location = location;
|
||||
_LocationIndex = null;
|
||||
_Populated = false;
|
||||
_RelativePath = string.Empty;
|
||||
}
|
||||
|
||||
private D_Face()
|
||||
{
|
||||
_Α = α;
|
||||
_DateTime = DateTime.MinValue;
|
||||
_FaceEncoding = null;
|
||||
_FaceLandmarks = null;
|
||||
_OutputResolution = null;
|
||||
_Location = null;
|
||||
_LocationIndex = null;
|
||||
_Populated = false;
|
||||
_RelativePath = string.Empty;
|
||||
}
|
||||
|
||||
private D_Face(A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string relativePath, int? i, Location location)
|
||||
{
|
||||
DateTime?[] dateTimes;
|
||||
dateTimes = new DateTime?[] { property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
|
||||
_DateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
|
||||
_FaceLandmarks = new Dictionary<string, FacePoint[]>();
|
||||
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
|
||||
_Location = location;
|
||||
_LocationIndex = i;
|
||||
_Populated = false;
|
||||
_RelativePath = relativePath;
|
||||
}
|
||||
|
||||
private D_Face(int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, IFace face)
|
||||
{
|
||||
_Α = face.α;
|
||||
_DateTime = face.DateTime;
|
||||
_FaceEncoding = face.FaceEncoding;
|
||||
_FaceLandmarks = face.FaceLandmarks;
|
||||
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
|
||||
_Location = face.Location;
|
||||
_LocationIndex = face.LocationIndex;
|
||||
_Populated = face.Populated;
|
||||
_RelativePath = face.RelativePath;
|
||||
}
|
||||
|
||||
#nullable restore
|
||||
|
||||
private static void GetPointBounds(PointF[] points, out float xMinimum, out float xMaximum, out float yMinimum, out float yMaximum)
|
||||
{
|
||||
xMinimum = points[0].X;
|
||||
@ -219,26 +135,22 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SaveFaces(List<D_Face> faceCollection, FileHolder resizedFileHolder, List<string> imageFiles)
|
||||
private void SaveFaces(FileHolder resizedFileHolder, List<(Face, string)> collection)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
Graphics graphics;
|
||||
Location location;
|
||||
Location? location;
|
||||
Bitmap preRotated;
|
||||
Rectangle rectangle;
|
||||
using Bitmap source = new(resizedFileHolder.FullName);
|
||||
for (int i = 0; i < faceCollection.Count; i++)
|
||||
foreach ((Face face, string fileName) in collection)
|
||||
{
|
||||
if (!faceCollection[i].Populated || faceCollection[i]?.Location is null)
|
||||
if (face.FaceEncoding is null || face?.Location is null)
|
||||
continue;
|
||||
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, source.Height, source.Width, collection.Count);
|
||||
if (location is null)
|
||||
continue;
|
||||
location = new Location(faceCollection[i].Location.Confidence,
|
||||
faceCollection[i].Location.Bottom,
|
||||
faceCollection[i].Location.Left,
|
||||
faceCollection[i].Location.Right,
|
||||
faceCollection[i].Location.Top,
|
||||
source.Width,
|
||||
source.Height);
|
||||
width = location.Right - location.Left;
|
||||
height = location.Bottom - location.Top;
|
||||
rectangle = new Rectangle(location.Left, location.Top, width, height);
|
||||
@ -246,149 +158,54 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
{
|
||||
using (graphics = Graphics.FromImage(preRotated))
|
||||
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||
preRotated.Save(imageFiles[i], System.Drawing.Imaging.ImageFormat.Png);
|
||||
preRotated.Save(fileName, _ImageCodecInfo, _EncoderParameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<D_Face> GetFaces(FileHolder resizedFileHolder, Item item, A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string facesDirectory)
|
||||
private List<Face> GetFaces(FileHolder resizedFileHolder, Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
|
||||
{
|
||||
List<D_Face> results = new();
|
||||
List<Face> results = new();
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
List<Location> locations;
|
||||
FaceRecognitionDotNet.Image? unknownImage = null;
|
||||
if (resizedFileHolder.Exists)
|
||||
FaceRecognitionDotNet.Image? unknownImage;
|
||||
if (!resizedFileHolder.Exists)
|
||||
unknownImage = null;
|
||||
else
|
||||
{
|
||||
try
|
||||
{ unknownImage = FaceRecognition.LoadImageFile(resizedFileHolder.FullName); }
|
||||
catch (Exception) { }
|
||||
catch (Exception)
|
||||
{ unknownImage = null; }
|
||||
}
|
||||
if (unknownImage is null)
|
||||
results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null));
|
||||
results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null));
|
||||
else
|
||||
{
|
||||
FaceRecognition faceRecognition = FaceRecognition.Create(_ModelParameter);
|
||||
locations = faceRecognition.FaceLocations(_Model, unknownImage, _Configuration.NumberOfTimesToUpsample, sortByNormalizedPixelPercentage: true);
|
||||
if (!locations.Any())
|
||||
results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null));
|
||||
List<(Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection;
|
||||
FaceRecognition faceRecognition = new(_Configuration.NumberOfTimesToUpsample, _Configuration.NumberOfJitters, _PredictorModel, _Model, _ModelParameter);
|
||||
collection = faceRecognition.GetCollection(unknownImage, includeFaceEncoding: true, includeFaceParts: true, sortByNormalizedPixelPercentage: true);
|
||||
if (!collection.Any())
|
||||
results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null));
|
||||
else
|
||||
{
|
||||
double? α;
|
||||
int width;
|
||||
int height;
|
||||
int padding;
|
||||
int? leftEyeX;
|
||||
int? leftEyeY;
|
||||
int? rightEyeX;
|
||||
int? rightEyeY;
|
||||
Bitmap rotated;
|
||||
string faceFile;
|
||||
Location location;
|
||||
Bitmap preRotated;
|
||||
Graphics graphics;
|
||||
D_Face? face = null;
|
||||
Rectangle rectangle;
|
||||
int i = 0;
|
||||
Face face;
|
||||
double[] rawEncoding;
|
||||
double deterministicHashCodeKey;
|
||||
Shared.Models.FaceEncoding faceEncoding;
|
||||
FaceRecognitionDotNet.Image? knownImage;
|
||||
FaceRecognitionDotNet.Image? rotatedImage;
|
||||
List<(FacePart, FacePoint[])[]> facesLandmarks;
|
||||
List<FaceRecognitionDotNet.FaceEncoding> faceEncodings;
|
||||
using Bitmap source = unknownImage.ToBitmap();
|
||||
padding = (int)((source.Width + source.Height) / 2 * .01);
|
||||
for (int i = 0; i < locations.Count; i++)
|
||||
Shared.Models.FaceEncoding convertedFaceEncoding;
|
||||
foreach ((Location location, FaceRecognitionDotNet.FaceEncoding? faceEncoding, Dictionary<FacePart, FacePoint[]>? faceParts) in collection)
|
||||
{
|
||||
for (int p = 0; p <= _Configuration.PaddingLoops; p++)
|
||||
face = new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i, location);
|
||||
if (faceEncoding is not null)
|
||||
{
|
||||
location = new(locations[i].Confidence,
|
||||
locations[i].Bottom + (padding * p),
|
||||
locations[i].Left - (padding * p),
|
||||
locations[i].Right + (padding * p),
|
||||
locations[i].Top - (padding * p),
|
||||
source.Width,
|
||||
source.Height);
|
||||
face = new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i, location);
|
||||
width = location.Right - location.Left;
|
||||
height = location.Bottom - location.Top;
|
||||
rectangle = new Rectangle(location.Left, location.Top, width, height);
|
||||
using (preRotated = new Bitmap(width, height))
|
||||
{
|
||||
leftEyeX = null;
|
||||
leftEyeY = null;
|
||||
rightEyeX = null;
|
||||
rightEyeY = null;
|
||||
using (graphics = Graphics.FromImage(preRotated))
|
||||
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||
// source.Save(Path.Combine(_Configuration.RootDirectory, "source.jpg"));
|
||||
// preRotated.Save(Path.Combine(_Configuration.RootDirectory, $"{p} - preRotated.jpg"));
|
||||
using (knownImage = FaceRecognition.LoadImage(preRotated))
|
||||
{
|
||||
if (knownImage is null || knownImage.IsDisposed)
|
||||
throw new NullReferenceException(nameof(knownImage));
|
||||
facesLandmarks = faceRecognition.GetFaceLandmarkCollection(knownImage, _Configuration.NumberOfTimesToUpsample, faceLocations: null, _PredictorModel, _Model);
|
||||
}
|
||||
if (facesLandmarks.Count == 0 && p < _Configuration.PaddingLoops)
|
||||
continue;
|
||||
else if (facesLandmarks.Count != 1)
|
||||
continue;
|
||||
foreach ((FacePart facePart, FacePoint[] facePoints) in facesLandmarks[0])
|
||||
{
|
||||
face.FaceLandmarks.Add(facePart.ToString(), facePoints);
|
||||
if (facePart is not FacePart.LeftEye and not FacePart.RightEye)
|
||||
continue;
|
||||
if (facePart is FacePart.LeftEye)
|
||||
{
|
||||
leftEyeX = (int)(from l in facePoints select l.X).Average();
|
||||
leftEyeY = (int)(from l in facePoints select l.Y).Average();
|
||||
}
|
||||
if (facePart is FacePart.RightEye)
|
||||
{
|
||||
rightEyeX = (int)(from l in facePoints select l.X).Average();
|
||||
rightEyeY = (int)(from l in facePoints select l.Y).Average();
|
||||
}
|
||||
}
|
||||
if (rightEyeX is null || leftEyeX is null || rightEyeY is null || leftEyeY is null)
|
||||
continue;
|
||||
α = Shared.Models.Stateless.Methods.IFace.Getα(rightEyeX.Value, leftEyeX.Value, rightEyeY.Value, leftEyeY.Value);
|
||||
using (rotated = RotateBitmap(preRotated, (float)α.Value))
|
||||
{
|
||||
// rotated.Save(Path.Combine(_Configuration.RootDirectory, $"{p} - rotated.jpg"));
|
||||
using (rotatedImage = FaceRecognition.LoadImage(rotated))
|
||||
{
|
||||
if (rotatedImage is null || rotatedImage.IsDisposed)
|
||||
throw new NullReferenceException(nameof(rotatedImage));
|
||||
faceEncodings = faceRecognition.FaceEncodings(rotatedImage, _Configuration.NumberOfTimesToUpsample, knownFaceLocation: null, _Configuration.NumberOfJitters, _PredictorModel, _Model);
|
||||
}
|
||||
if (faceEncodings.Count == 0 && p < _Configuration.PaddingLoops)
|
||||
continue;
|
||||
else if (faceEncodings.Count != 1)
|
||||
continue;
|
||||
rawEncoding = faceEncodings[0].GetRawEncoding();
|
||||
faceEncoding = new(rawEncoding, faceEncodings[0].Size);
|
||||
face.Update(α, faceEncoding, populated: true);
|
||||
}
|
||||
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face);
|
||||
faceFile = Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png");
|
||||
preRotated.Save(faceFile, System.Drawing.Imaging.ImageFormat.Png);
|
||||
results.Add(face);
|
||||
}
|
||||
if (face.Populated)
|
||||
break;
|
||||
}
|
||||
if (face is null || !face.Populated)
|
||||
{
|
||||
location = new(locations[i].Confidence,
|
||||
locations[i].Bottom,
|
||||
locations[i].Left,
|
||||
locations[i].Right,
|
||||
locations[i].Top,
|
||||
source.Width,
|
||||
source.Height);
|
||||
face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i, location);
|
||||
results.Add(face);
|
||||
rawEncoding = faceEncoding.GetRawEncoding();
|
||||
convertedFaceEncoding = new(rawEncoding, faceEncoding.Size);
|
||||
face.SetFaceEncoding(convertedFaceEncoding);
|
||||
}
|
||||
if (faceParts is not null)
|
||||
face.SetFaceParts(faceParts);
|
||||
results.Add(face);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
unknownImage.Dispose();
|
||||
@ -401,16 +218,9 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
private void Update(double? α, Shared.Models.FaceEncoding faceEncoding, bool populated)
|
||||
internal List<Face> GetFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, Shared.Models.Property property, FileHolder resizedFileHolder, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
|
||||
{
|
||||
_Α = α;
|
||||
_FaceEncoding = faceEncoding;
|
||||
_Populated = populated;
|
||||
}
|
||||
|
||||
internal List<D_Face> GetFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, A_Property property, FileHolder resizedFileHolder, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
|
||||
{
|
||||
List<D_Face>? results;
|
||||
List<Face>? results;
|
||||
if (item.Property?.Id is null)
|
||||
throw new NullReferenceException(nameof(item.Property.Id));
|
||||
if (item.ImageFileHolder is null)
|
||||
@ -418,9 +228,10 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
|
||||
throw new NullReferenceException(nameof(dResultsFullGroupDirectory));
|
||||
string json;
|
||||
int?[] normalizedPixelPercentageCollection;
|
||||
int normalizedPixelPercentageDistinctCount;
|
||||
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 facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
|
||||
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");
|
||||
FileInfo fileInfo = new(dCollectionFile);
|
||||
@ -443,8 +254,6 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Directory.Exists(facesDirectory))
|
||||
_ = Directory.CreateDirectory(facesDirectory);
|
||||
if (_Configuration.ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
||||
{
|
||||
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
||||
@ -466,9 +275,18 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
json = Shared.Models.Stateless.Methods.IFace.GetJson(fileInfo.FullName);
|
||||
try
|
||||
{
|
||||
results = JsonSerializer.Deserialize<List<D_Face>>(json);
|
||||
results = JsonSerializer.Deserialize<List<Face>>(json);
|
||||
if (results is null)
|
||||
throw new NullReferenceException(nameof(results));
|
||||
if (!_Configuration.ForceFaceLastWriteTimeToCreationTime)
|
||||
{
|
||||
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
|
||||
if (normalizedPixelPercentageCollection.Contains(3))
|
||||
throw new Exception($"Not allowed! <{fileInfo.FullName}>");
|
||||
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
||||
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
|
||||
throw new Exception($"Not distinct! <{fileInfo.FullName}>");
|
||||
}
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), fileInfo.LastWriteTime));
|
||||
}
|
||||
catch (Exception)
|
||||
@ -479,19 +297,24 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
}
|
||||
if (results is null)
|
||||
{
|
||||
results = GetFaces(resizedFileHolder, item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, facesDirectory);
|
||||
results = GetFaces(resizedFileHolder, item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation);
|
||||
json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
|
||||
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
|
||||
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
|
||||
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
||||
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now));
|
||||
}
|
||||
if (_Configuration.ForceFaceLastWriteTimeToCreationTime)
|
||||
{
|
||||
results = (from l in results select new Face(results.Count, l)).ToList();
|
||||
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
|
||||
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
||||
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
|
||||
throw new Exception($"Not distinct! <{fileInfo.FullName}>");
|
||||
json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
|
||||
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
|
||||
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
|
||||
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
||||
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
||||
{
|
||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
||||
fileInfo.Refresh();
|
||||
@ -501,7 +324,7 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
return results;
|
||||
}
|
||||
|
||||
internal void SaveFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<D_Face> faceCollection)
|
||||
internal void SaveFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Face> faceCollection)
|
||||
{
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
@ -511,22 +334,22 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
bool check = false;
|
||||
string parentCheck;
|
||||
double deterministicHashCodeKey;
|
||||
List<string> imageFiles = new();
|
||||
List<(Face, string)> collection = new();
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
|
||||
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
|
||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
bool facesDirectoryExisted = Directory.Exists(facesDirectory);
|
||||
if (!facesDirectoryExisted)
|
||||
_ = Directory.CreateDirectory(facesDirectory);
|
||||
foreach (IFace face in faceCollection)
|
||||
foreach (Face face in faceCollection)
|
||||
{
|
||||
if (!face.Populated || face.Location?.NormalizedPixelPercentage is null)
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
{
|
||||
imageFiles.Add(string.Empty);
|
||||
collection.Add(new(face, string.Empty));
|
||||
continue;
|
||||
}
|
||||
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face);
|
||||
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
|
||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.INamed.GetDeterministicHashCodeKey(item, face);
|
||||
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FilenameExtension}"));
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
if (fileInfo.Directory?.Parent is null)
|
||||
@ -535,7 +358,7 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
if (File.Exists(parentCheck))
|
||||
File.Delete(parentCheck);
|
||||
}
|
||||
imageFiles.Add(fileInfo.FullName);
|
||||
collection.Add(new(face, fileInfo.FullName));
|
||||
if (_Configuration.OverrideForFaceImages)
|
||||
check = true;
|
||||
else if (!fileInfo.Exists)
|
||||
@ -544,10 +367,10 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
check = true;
|
||||
}
|
||||
if (check)
|
||||
SaveFaces(faceCollection, item.ResizedFileHolder, imageFiles);
|
||||
SaveFaces(item.ResizedFileHolder, collection);
|
||||
}
|
||||
|
||||
internal static void SaveShortcuts(string[] juliePhares, string dResultsFullGroupDirectory, long ticks, Dictionary<string, List<Person>> peopleCollection, PropertyLogic propertyLogic, List<Item> items)
|
||||
internal static void SaveShortcuts(string[] juliePhares, string dResultsFullGroupDirectory, long ticks, Dictionary<string, List<Person>> peopleCollection, Map.Models.MapLogic mapLogic, List<Item> items)
|
||||
{
|
||||
Person person;
|
||||
string fileName;
|
||||
@ -556,18 +379,18 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
WindowsShortcut windowsShortcut;
|
||||
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
|
||||
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, $"({ticks})");
|
||||
List<(Item, (string, IFace?, (string, string, string, string))[])> collections = Item.GetCollection(propertyLogic, items, dFacesContentDirectory);
|
||||
foreach ((Item item, (string personKey, IFace? _, (string, string, string, string))[] collection) in collections)
|
||||
List<(Item, (string, Face?, (string, string, string, string))[])> collections = Map.Models.MapLogic.GetCollection(mapLogic, items, dFacesContentDirectory);
|
||||
foreach ((Item item, (string personKey, Face? _, (string, string, string, string))[] collection) in collections)
|
||||
{
|
||||
if (collection.Length != 1)
|
||||
continue;
|
||||
foreach ((string personKey, IFace? _, (string directory, string copyDirectory, string copyFileName, string shortcutFileName)) in collection)
|
||||
foreach ((string personKey, Face? _, (string directory, string copyDirectory, string copyFileName, string shortcutFileName)) in collection)
|
||||
{
|
||||
if (string.IsNullOrEmpty(personKey))
|
||||
continue;
|
||||
if (item.Property?.Id is null || item.ImageFileHolder is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
minimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(item.Property);
|
||||
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||
if (minimumDateTime is null)
|
||||
continue;
|
||||
if (!Directory.Exists(directory))
|
||||
@ -601,24 +424,16 @@ public class D_Face : IFace, Shared.Models.Methods.IFace
|
||||
}
|
||||
}
|
||||
|
||||
double Shared.Models.Stateless.Methods.IFace.TestStatic_Getα(int x1, int x2, int y1, int y2) => throw new NotImplementedException();
|
||||
|
||||
string Shared.Models.Stateless.Methods.IFace.TestStatic_GetJson(string jsonFileFullName) => throw new NotImplementedException();
|
||||
|
||||
Face Shared.Models.Stateless.Methods.IFace.TestStatic_GetFace(string jsonFileFullName) => throw new NotImplementedException();
|
||||
|
||||
Face[] Shared.Models.Stateless.Methods.IFace.TestStatic_GetFaces(string jsonFileFullName) => throw new NotImplementedException();
|
||||
|
||||
private static bool HasLeftAndRight(Dictionary<string, FacePoint[]> faceLandmarks)
|
||||
private static bool HasLeftAndRight(Dictionary<string, FacePoint[]> faceParts)
|
||||
{
|
||||
bool result = true;
|
||||
if (!faceLandmarks.ContainsKey(FacePart.LeftEye.ToString()))
|
||||
if (!faceParts.ContainsKey(FacePart.LeftEye.ToString()))
|
||||
result = false;
|
||||
else if (!faceLandmarks.ContainsKey(FacePart.RightEye.ToString()))
|
||||
else if (!faceParts.ContainsKey(FacePart.RightEye.ToString()))
|
||||
result = false;
|
||||
else if (!faceLandmarks.ContainsKey(FacePart.LeftEyebrow.ToString()))
|
||||
else if (!faceParts.ContainsKey(FacePart.LeftEyebrow.ToString()))
|
||||
result = false;
|
||||
else if (!faceLandmarks.ContainsKey(FacePart.RightEyebrow.ToString()))
|
||||
else if (!faceParts.ContainsKey(FacePart.RightEyebrow.ToString()))
|
||||
result = false;
|
||||
return result;
|
||||
}
|
||||
|
@ -96,8 +96,6 @@ internal class E2_Navigate
|
||||
string result;
|
||||
if (_Log is null)
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||
_Log.Warn(string.Concat("What is the new name for [", Path.GetFileName(subSourceDirectory), "]<", subSourceDirectory, ">?"));
|
||||
string? newDirectoryName = _Console.ReadLine();
|
||||
_Log.Warn("Are you sure y[es] || n[o]?");
|
||||
@ -111,7 +109,7 @@ internal class E2_Navigate
|
||||
{
|
||||
_Log.Warn(string.Empty);
|
||||
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||
string relativePath = Property.Models.Stateless.IPath.GetRelativePath(subSourceDirectory, eDistanceCollectionDirectory.Length);
|
||||
string relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(subSourceDirectory, eDistanceCollectionDirectory.Length);
|
||||
if (relativePath.Length == 1)
|
||||
throw new Exception();
|
||||
if (Directory.Exists(Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName)))
|
||||
|
@ -1,6 +1,5 @@
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
@ -40,10 +39,10 @@ internal class E3_Rename
|
||||
string cResizeSingletonDirectory;
|
||||
string eDistanceContentDirectory;
|
||||
string aPropertySingletonDirectory;
|
||||
string d2FacePartsContentDirectory;
|
||||
string bMetadataSingletonDirectory;
|
||||
string eDistanceCollectionDirectory;
|
||||
string g2IdentifyCollectionDirectory;
|
||||
string d2FaceLandmarksContentDirectory;
|
||||
add = Directory.Exists(string.Concat(Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(C_Resize), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()"), relativePath));
|
||||
bMetadataSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(B_Metadata), "{}");
|
||||
if (Directory.Exists(bMetadataSingletonDirectory))
|
||||
@ -51,7 +50,7 @@ internal class E3_Rename
|
||||
to = Path.Combine(string.Concat(bMetadataSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "{}");
|
||||
if (Directory.Exists(aPropertySingletonDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(aPropertySingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
@ -83,10 +82,10 @@ internal class E3_Rename
|
||||
to = Path.Combine(string.Concat(dFacesCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
d2FaceLandmarksContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D2_FaceLandmarks), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
if (add && _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution) && Directory.Exists(d2FaceLandmarksContentDirectory))
|
||||
d2FacePartsContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D2_FaceParts), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
if (add && _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution) && Directory.Exists(d2FacePartsContentDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(d2FaceLandmarksContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
to = Path.Combine(string.Concat(d2FacePartsContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
eDistanceContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
@ -114,8 +113,6 @@ internal class E3_Rename
|
||||
internal List<string[]> GetDirectoryRenameCollections(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string relativePath, string newDirectoryName, bool jsonFiles4InfoAny)
|
||||
{
|
||||
List<string[]> results = new();
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||
bool add;
|
||||
string to;
|
||||
bool exists;
|
||||
@ -127,9 +124,9 @@ internal class E3_Rename
|
||||
string eDistanceContentDirectory;
|
||||
string bMetadataSingletonDirectory;
|
||||
string aPropertySingletonDirectory;
|
||||
string d2FacePartsContentDirectory;
|
||||
string eDistanceCollectionDirectory;
|
||||
string g2IdentifyCollectionDirectory;
|
||||
string d2FaceLandmarksContentDirectory;
|
||||
if (!string.IsNullOrEmpty(relativePath))
|
||||
{
|
||||
from = string.Concat(_Configuration.PropertyConfiguration.RootDirectory, relativePath);
|
||||
@ -147,7 +144,7 @@ internal class E3_Rename
|
||||
to = Path.Combine(string.Concat(bMetadataSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "{}");
|
||||
from = string.Concat(aPropertySingletonDirectory, relativePath);
|
||||
exists = Directory.Exists(aPropertySingletonDirectory);
|
||||
if (exists)
|
||||
@ -187,14 +184,14 @@ internal class E3_Rename
|
||||
to = Path.Combine(string.Concat(dFacesCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
d2FaceLandmarksContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D2_FaceLandmarks), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
from = string.Concat(d2FaceLandmarksContentDirectory, relativePath);
|
||||
exists = Directory.Exists(d2FaceLandmarksContentDirectory);
|
||||
d2FacePartsContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D2_FaceParts), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
from = string.Concat(d2FacePartsContentDirectory, relativePath);
|
||||
exists = Directory.Exists(d2FacePartsContentDirectory);
|
||||
if (!exists && add && _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||
results.Add(new string[] { from });
|
||||
else if (exists)
|
||||
{
|
||||
to = Path.Combine(string.Concat(d2FaceLandmarksContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
to = Path.Combine(string.Concat(d2FacePartsContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
eDistanceContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
@ -229,15 +226,13 @@ internal class E3_Rename
|
||||
|
||||
internal void DirectoryRename(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string relativePath, string newDirectoryName)
|
||||
{
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||
string json;
|
||||
FileInfo current;
|
||||
FileInfo fileInfo;
|
||||
string error = "Error";
|
||||
string target = "Target";
|
||||
string pending = "Pending";
|
||||
System.IO.DirectoryInfo directoryInfo;
|
||||
DirectoryInfo directoryInfo;
|
||||
IEnumerator<FileInfo> fileInfoCollection;
|
||||
string oldValue = string.Concat("\"", relativePath);
|
||||
string oldDirectoryName = Path.GetFileName(relativePath);
|
||||
@ -249,7 +244,7 @@ internal class E3_Rename
|
||||
string newValue = string.Concat("\"", Path.Combine(relativePathParent, newDirectoryName));
|
||||
string e3RenameContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(E3_Rename), "()");
|
||||
string jsonRootDirectory = Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, " - Copied"), string.Concat(directoryName, " - 4) Info"), _Configuration.PropertyConfiguration.DateGroup, "[]");
|
||||
directoryInfo = new System.IO.DirectoryInfo(jsonRootDirectory);
|
||||
directoryInfo = new DirectoryInfo(jsonRootDirectory);
|
||||
if (!directoryInfo.Exists)
|
||||
directoryInfo.Create();
|
||||
IEnumerator<FileInfo> fileInfoCollection4 = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
|
||||
@ -278,7 +273,7 @@ internal class E3_Rename
|
||||
{
|
||||
foreach (string[] directoryCollection in directoryCollections)
|
||||
{
|
||||
directoryInfo = new System.IO.DirectoryInfo(directoryCollection[0]);
|
||||
directoryInfo = new DirectoryInfo(directoryCollection[0]);
|
||||
if (!directoryInfo.Exists)
|
||||
continue;
|
||||
fileInfoCollection = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
|
||||
@ -299,7 +294,7 @@ internal class E3_Rename
|
||||
if (json.Contains(oldValue))
|
||||
{
|
||||
json = json.Replace(oldValue, newValue);
|
||||
if (!Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
continue;
|
||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.LastWriteTime);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ using View_by_Distance.FaceRecognitionDotNet;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
using WindowsShortcutFactory;
|
||||
@ -30,14 +31,14 @@ internal class E_Distance
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<DistanceHolder> GetDistanceHolder(Item[] items, List<(string JSONDirectory, string TSVDirectory)> directories)
|
||||
private static List<(DistanceHolder, FaceRecognitionDotNet.FaceEncoding?)> GetDistanceHolder(Item[] items, List<(string JSONDirectory, string TSVDirectory)> directories)
|
||||
{
|
||||
List<DistanceHolder> results = new();
|
||||
List<(DistanceHolder, FaceRecognitionDotNet.FaceEncoding?)> results = new();
|
||||
Item item;
|
||||
const int zero = 0;
|
||||
string tsvDirectory;
|
||||
string jsonDirectory;
|
||||
FaceEncoding? faceEncoding;
|
||||
FaceRecognitionDotNet.FaceEncoding? faceEncoding;
|
||||
if (items.Length != directories.Count)
|
||||
throw new Exception();
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
@ -48,38 +49,19 @@ internal class E_Distance
|
||||
continue;
|
||||
tsvDirectory = directories[i].TSVDirectory;
|
||||
jsonDirectory = directories[i].JSONDirectory;
|
||||
foreach (IFace face in item.Faces)
|
||||
foreach (Face face in item.Faces)
|
||||
{
|
||||
if (!face.Populated)
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
continue;
|
||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||
results.Add(new(face, faceEncoding, item.ImageFileHolder, item.Property.Id.Value, jsonDirectory, item.Faces[zero].Location, tsvDirectory));
|
||||
results.Add(new(new(face, item.ImageFileHolder, item.Property.Id.Value, jsonDirectory, item.Faces[zero].Location, tsvDirectory), faceEncoding));
|
||||
}
|
||||
if (faceEncoding is null)
|
||||
results.Add(new(item.Faces[zero], null, item.ImageFileHolder, item.Property.Id.Value, jsonDirectory, item.Faces[zero].Location, tsvDirectory));
|
||||
results.Add(new(new(item.Faces[zero], item.ImageFileHolder, item.Property.Id.Value, jsonDirectory, item.Faces[zero].Location, tsvDirectory), null));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<Tuple<IFace, string>> GetOrderedNoFaceCollection(List<List<IFace>> faceCollections, int i, IFace face)
|
||||
{
|
||||
List<Tuple<IFace, string>> results = new() { new(face, string.Empty) };
|
||||
for (int n = 0; n < faceCollections.Count; n++)
|
||||
{
|
||||
if (i == n)
|
||||
continue;
|
||||
for (int j = 0; j < faceCollections[n].Count; j++)
|
||||
{
|
||||
if (!faceCollections[n][j].Populated)
|
||||
continue;
|
||||
results.Add(new(faceCollections[n][j], string.Empty));
|
||||
}
|
||||
}
|
||||
for (int r = results.Count - 1; r > _Configuration.MaxItemsInDistanceCollection; r--)
|
||||
results.RemoveAt(r);
|
||||
return results;
|
||||
}
|
||||
|
||||
private void WriteNoFaceCollection(bool updateDateWhenMatches, DateTime? updateToWhenMatches, List<Tuple<string, DateTime>> subFileTuples, List<DistanceHolder> distanceHolders)
|
||||
{
|
||||
string json;
|
||||
@ -87,7 +69,7 @@ internal class E_Distance
|
||||
string jsonFile;
|
||||
const int zero = 0;
|
||||
DistanceHolder distanceHolder;
|
||||
List<Tuple<IFace, string>> tupleCollection;
|
||||
List<Tuple<Face, string>> tupleCollection;
|
||||
for (int i = 0; i < distanceHolders.Count; i++)
|
||||
{
|
||||
distanceHolder = distanceHolders[i];
|
||||
@ -108,24 +90,24 @@ internal class E_Distance
|
||||
break;
|
||||
}
|
||||
json = JsonSerializer.Serialize(tupleCollection, _WriteIndentedJsonSerializerOptions);
|
||||
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: updateToWhenMatches))
|
||||
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: updateToWhenMatches))
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
|
||||
}
|
||||
}
|
||||
|
||||
private static List<FaceEncoding> GetFaceEncodings(List<DistanceHolder> distanceHolders)
|
||||
private static List<FaceRecognitionDotNet.FaceEncoding> GetFaceEncodings((DistanceHolder, FaceRecognitionDotNet.FaceEncoding?)[] distanceHoldersAfterSort)
|
||||
{
|
||||
List<FaceEncoding> results = new();
|
||||
foreach (DistanceHolder distanceHolder in distanceHolders)
|
||||
List<FaceRecognitionDotNet.FaceEncoding> results = new();
|
||||
foreach ((DistanceHolder distanceHolder, FaceRecognitionDotNet.FaceEncoding? faceEncoding) in distanceHoldersAfterSort)
|
||||
{
|
||||
if (!distanceHolder.Face.Populated || distanceHolder.FaceEncoding is null)
|
||||
if (distanceHolder.Face.FaceEncoding is null || distanceHolder.Face.Location?.NormalizedPixelPercentage is null || faceEncoding is null)
|
||||
continue;
|
||||
results.Add(distanceHolder.FaceEncoding);
|
||||
results.Add(faceEncoding);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private void SaveDistanceResults(bool updateDateWhenMatches, DateTime? updateToWhenMatches, List<Tuple<string, DateTime>> subFileTuples, List<DistanceHolder> distanceHolders)
|
||||
private void SaveDistanceResults(bool updateDateWhenMatches, DateTime? updateToWhenMatches, List<Tuple<string, DateTime>> subFileTuples, List<(DistanceHolder DistanceHolder, FaceRecognitionDotNet.FaceEncoding? _)> distanceHolders)
|
||||
{
|
||||
string json;
|
||||
string check;
|
||||
@ -135,13 +117,16 @@ internal class E_Distance
|
||||
DistanceHolder distanceHolder;
|
||||
int normalizedPixelPercentage;
|
||||
DistanceHolder[] sortedDistanceHolders;
|
||||
List<Tuple<IFace, string>> tupleCollection;
|
||||
List<Tuple<Face, string>> tupleCollection;
|
||||
List<(int Index, double Distance)> collection;
|
||||
distanceHolders = distanceHolders.OrderByDescending(l => l.Face.Populated).ToList();
|
||||
List<FaceEncoding> faceEncodings = GetFaceEncodings(distanceHolders);
|
||||
for (int i = 0; i < distanceHolders.Count; i++)
|
||||
FaceRecognitionDotNet.FaceEncoding? faceEncoding;
|
||||
(DistanceHolder DistanceHolder, FaceRecognitionDotNet.FaceEncoding? FaceEncoding)[] distanceHoldersAfterSort =
|
||||
distanceHolders.OrderByDescending(l => l.DistanceHolder.Face.FaceEncoding is not null && l.DistanceHolder.Face.Location?.NormalizedPixelPercentage is not null).ToArray();
|
||||
List<FaceRecognitionDotNet.FaceEncoding> faceEncodings = GetFaceEncodings(distanceHoldersAfterSort);
|
||||
for (int i = 0; i < distanceHoldersAfterSort.Length; i++)
|
||||
{
|
||||
distanceHolder = distanceHolders[i];
|
||||
faceEncoding = distanceHoldersAfterSort[i].FaceEncoding;
|
||||
distanceHolder = distanceHoldersAfterSort[i].DistanceHolder;
|
||||
collection = new();
|
||||
tupleCollection = new();
|
||||
distanceHolder.Sort = 0d;
|
||||
@ -149,7 +134,7 @@ internal class E_Distance
|
||||
locationIndex = 0;
|
||||
else
|
||||
locationIndex = distanceHolder.Face.LocationIndex.Value;
|
||||
if (!distanceHolder.Face.Populated || distanceHolder.Face.Location?.NormalizedPixelPercentage is null)
|
||||
if (distanceHolder.Face.FaceEncoding is null || distanceHolder.Face.Location?.NormalizedPixelPercentage is null)
|
||||
normalizedPixelPercentage = 0;
|
||||
else
|
||||
normalizedPixelPercentage = distanceHolder.Face.Location.NormalizedPixelPercentage.Value;
|
||||
@ -161,27 +146,32 @@ internal class E_Distance
|
||||
File.Move(check, jsonFile);
|
||||
if (faceEncodings.Count == 1)
|
||||
faceDistances = new() { 0d };
|
||||
else if (distanceHolder.FaceEncoding is null)
|
||||
else if (faceEncoding is null)
|
||||
faceDistances = Enumerable.Repeat(9d, faceEncodings.Count).ToList();
|
||||
else
|
||||
faceDistances = FaceRecognition.FaceDistances(faceEncodings, distanceHolder.FaceEncoding);
|
||||
if (distanceHolder.Face.Populated && distanceHolder.FaceEncoding is not null && faceDistances[i] != 0d)
|
||||
faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncoding);
|
||||
if (distanceHolder.Face.FaceEncoding is not null && faceEncoding is not null && faceDistances[i] != 0d)
|
||||
faceDistances[i] = 0d;
|
||||
for (int d = 0; d < faceDistances.Count; d++)
|
||||
collection.Add(new(d, faceDistances[d]));
|
||||
collection = collection.OrderBy(l => l.Distance).ToList();
|
||||
foreach ((int index, double distance) in collection)
|
||||
distanceHolders[index].Sort = ((distance * _Configuration.DistanceFactor) + (distanceHolders[index].Location.Confidence * _Configuration.LocationConfidenceFactor)) / 10;
|
||||
sortedDistanceHolders = distanceHolders.OrderBy(l => l.Sort).ToArray();
|
||||
{
|
||||
distanceHolder = distanceHoldersAfterSort[index].DistanceHolder;
|
||||
if (distanceHolder.Location is null)
|
||||
continue;
|
||||
distanceHolder.Sort = ((distance * _Configuration.DistanceFactor) + (distanceHolder.Location.Confidence * _Configuration.LocationConfidenceFactor)) / 10;
|
||||
}
|
||||
sortedDistanceHolders = (from l in distanceHoldersAfterSort orderby l.DistanceHolder.Sort select l.DistanceHolder).ToArray();
|
||||
for (int j = 0; j < sortedDistanceHolders.Length; j++)
|
||||
{
|
||||
distanceHolder = sortedDistanceHolders[j];
|
||||
tupleCollection.Add(new(distanceHolders[j].Face, string.Empty));
|
||||
tupleCollection.Add(new(distanceHoldersAfterSort[j].DistanceHolder.Face, string.Empty));
|
||||
if (tupleCollection.Count > _Configuration.MaxItemsInDistanceCollection)
|
||||
break;
|
||||
}
|
||||
json = JsonSerializer.Serialize(tupleCollection, _WriteIndentedJsonSerializerOptions);
|
||||
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: updateToWhenMatches))
|
||||
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: updateToWhenMatches))
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
|
||||
}
|
||||
}
|
||||
@ -196,10 +186,12 @@ internal class E_Distance
|
||||
string usingRelativePath;
|
||||
DateTime? dateTime = null;
|
||||
string dCollectionDirectory;
|
||||
FileInfo[] fileInfoCollection;
|
||||
bool updateDateWhenMatches = false;
|
||||
System.IO.DirectoryInfo directoryInfo;
|
||||
System.IO.DirectoryInfo tvsDirectoryInfo;
|
||||
IEnumerator<FileInfo> fileInfoCollection;
|
||||
int?[] normalizedPixelPercentageCollection;
|
||||
int normalizedPixelPercentageDistinctCount;
|
||||
List<(string, string)> directories = new();
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
|
||||
List<DateTime> dateTimes = (from l in sourceDirectoryChanges where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
@ -216,7 +208,7 @@ internal class E_Distance
|
||||
item = filteredItems[i];
|
||||
if (item.ImageFileHolder is null || item.Property?.Id is null)
|
||||
continue;
|
||||
hasPopulatedFace = (from l in item.Faces where l.Populated select true).Any();
|
||||
hasPopulatedFace = (from l in item.Faces where l.FaceEncoding is not null && l.Location?.NormalizedPixelPercentage is not null select true).Any();
|
||||
usingRelativePath = Path.Combine(directoryInfoCollection[0].Replace("<>", "[]"), item.ImageFileHolder.NameWithoutExtension);
|
||||
dCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, "[]", Property.Models.Stateless.IResult.AllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}");
|
||||
directoryInfo = new System.IO.DirectoryInfo(dCollectionDirectory);
|
||||
@ -242,23 +234,30 @@ internal class E_Distance
|
||||
}
|
||||
tvsDirectoryInfo = new System.IO.DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension));
|
||||
directories.Add(new(directoryInfo.FullName, tvsDirectoryInfo.FullName));
|
||||
if (_Configuration.CheckJsonForDistanceResults && directoryInfo.Exists)
|
||||
if (directoryInfo.Exists && (!check || _Configuration.CheckJsonForDistanceResults))
|
||||
{
|
||||
json = string.Empty;
|
||||
fileInfoCollection = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
|
||||
for (int j = 0; j < int.MaxValue; j++)
|
||||
{
|
||||
if (!fileInfoCollection.MoveNext())
|
||||
break;
|
||||
json = Shared.Models.Stateless.Methods.IIndex.GetJson(fileInfoCollection.Current.FullName, fileInfoCollection.Current);
|
||||
if (!_Configuration.PropertiesChangedForDistance && Shared.Models.Stateless.Methods.IFace.GetFace(fileInfoCollection.Current.FullName) is null)
|
||||
{
|
||||
check = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!check && string.IsNullOrEmpty(json))
|
||||
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(item.Faces);
|
||||
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
||||
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
|
||||
check = true;
|
||||
fileInfoCollection = directoryInfo.GetFiles($"{item.Property.Id.Value}*.json", SearchOption.TopDirectoryOnly);
|
||||
if (fileInfoCollection.Length < normalizedPixelPercentageDistinctCount)
|
||||
check = true;
|
||||
if (!check && _Configuration.CheckJsonForDistanceResults)
|
||||
{
|
||||
for (int j = 0; j < fileInfoCollection.Length; j++)
|
||||
{
|
||||
json = Shared.Models.Stateless.Methods.IIndex.GetJson(fileInfoCollection[j].FullName, fileInfoCollection[j]);
|
||||
if (!_Configuration.PropertiesChangedForDistance && Shared.Models.Stateless.Methods.IFace.GetFace(fileInfoCollection[j].FullName) is null)
|
||||
{
|
||||
check = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!check && string.IsNullOrEmpty(json))
|
||||
check = true;
|
||||
}
|
||||
}
|
||||
if (check)
|
||||
continue;
|
||||
@ -278,23 +277,23 @@ internal class E_Distance
|
||||
{
|
||||
DateTime? updateToWhenMatches = dateTime;
|
||||
List<Tuple<string, DateTime>> subFileTuples = new();
|
||||
List<DistanceHolder> distanceHolders = GetDistanceHolder(filteredItems, directories);
|
||||
List<(DistanceHolder, FaceRecognitionDotNet.FaceEncoding?)> distanceHolders = GetDistanceHolder(filteredItems, directories);
|
||||
SaveDistanceResults(updateDateWhenMatches, updateToWhenMatches, subFileTuples, distanceHolders);
|
||||
}
|
||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(directoryInfoCollection[0].Replace("<>", "()"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directoryInfoCollection[0].Replace("<>", "()"));
|
||||
}
|
||||
|
||||
private List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> GetFiles(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution)
|
||||
private List<(string, List<KeyValuePair<string, Face[]>>)> GetFiles(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution)
|
||||
{
|
||||
string json;
|
||||
List<KeyValuePair<string, Shared.Models.Face[]>>? facesKeyValuePairCollection;
|
||||
List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> results = new();
|
||||
List<KeyValuePair<string, Face[]>>? facesKeyValuePairCollection;
|
||||
List<(string, List<KeyValuePair<string, Face[]>>)> results = new();
|
||||
string dFacesCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[[]]");
|
||||
string[] dFacesCollectionFiles = Directory.GetFiles(dFacesCollectionDirectory, "*.json", SearchOption.TopDirectoryOnly);
|
||||
foreach (string dFacesCollectionFile in dFacesCollectionFiles)
|
||||
{
|
||||
json = File.ReadAllText(dFacesCollectionFile);
|
||||
facesKeyValuePairCollection = JsonSerializer.Deserialize<List<KeyValuePair<string, Shared.Models.Face[]>>>(json);
|
||||
facesKeyValuePairCollection = JsonSerializer.Deserialize<List<KeyValuePair<string, Face[]>>>(json);
|
||||
if (facesKeyValuePairCollection is null)
|
||||
continue;
|
||||
results.Add(new(dFacesCollectionFile, facesKeyValuePairCollection));
|
||||
@ -302,21 +301,21 @@ internal class E_Distance
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> GetMatches(List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> files)
|
||||
private static List<(string, List<Face>, List<FaceRecognitionDotNet.FaceEncoding>)> GetMatches(List<(string, List<KeyValuePair<string, Face[]>>)> files)
|
||||
{
|
||||
List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> results = new();
|
||||
FaceEncoding faceEncoding;
|
||||
List<Shared.Models.Face> faces;
|
||||
List<FaceEncoding> faceEncodings;
|
||||
foreach ((string, List<KeyValuePair<string, Shared.Models.Face[]>>) file in files)
|
||||
List<(string, List<Face>, List<FaceRecognitionDotNet.FaceEncoding>)> results = new();
|
||||
FaceRecognitionDotNet.FaceEncoding faceEncoding;
|
||||
List<Face> faces;
|
||||
List<FaceRecognitionDotNet.FaceEncoding> faceEncodings;
|
||||
foreach ((string, List<KeyValuePair<string, Face[]>>) file in files)
|
||||
{
|
||||
faces = new();
|
||||
faceEncodings = new();
|
||||
foreach (KeyValuePair<string, Shared.Models.Face[]> keyValuePair in file.Item2)
|
||||
foreach (KeyValuePair<string, Face[]> keyValuePair in file.Item2)
|
||||
{
|
||||
foreach (Shared.Models.Face face in keyValuePair.Value)
|
||||
foreach (Face face in keyValuePair.Value)
|
||||
{
|
||||
if (!face.Populated)
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
continue;
|
||||
faces.Add(face);
|
||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||
@ -339,7 +338,7 @@ internal class E_Distance
|
||||
return result;
|
||||
}
|
||||
|
||||
private void Save(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string eDistanceCollectionDirectory, int k, string relativePath, Shared.Models.Face face, List<Tuple<Shared.Models.Face, string>> faceAndFaceDistanceCollection)
|
||||
private void Save(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, string eDistanceCollectionDirectory, int k, string relativePath, Face face, List<Tuple<Face, string>> faceAndFaceDistanceCollection)
|
||||
{
|
||||
if (string.IsNullOrEmpty(eDistanceCollectionDirectory))
|
||||
eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||
@ -349,12 +348,12 @@ internal class E_Distance
|
||||
_ = Directory.CreateDirectory(jsonDirectory);
|
||||
string json = JsonSerializer.Serialize(faceAndFaceDistanceCollection, _WriteIndentedJsonSerializerOptions);
|
||||
string jsonFile = Path.Combine(jsonDirectory, $"{k} - {fileNameWithoutExtension}.nosj");
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||
}
|
||||
|
||||
private static Tuple<Shared.Models.Face, double> Get(FaceEncoding faceEncoding, (string, List<Shared.Models.Face>, List<FaceEncoding>) match)
|
||||
private static Tuple<Face, double> Get(FaceRecognitionDotNet.FaceEncoding faceEncoding, (string, List<Face>, List<FaceRecognitionDotNet.FaceEncoding>) match)
|
||||
{
|
||||
Tuple<Shared.Models.Face, double> result;
|
||||
Tuple<Face, double> result;
|
||||
double[] faceDistances = FaceRecognition.FaceDistances(match.Item3, faceEncoding).ToArray();
|
||||
int index = GetIndex(faceDistances);
|
||||
result = new(match.Item2[index], faceDistances[index]);
|
||||
@ -366,14 +365,14 @@ internal class E_Distance
|
||||
if (_Log is null)
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
string? relativePath;
|
||||
Shared.Models.Face face;
|
||||
Face face;
|
||||
ParallelOptions parallelOptions = new();
|
||||
FaceEncoding faceEncoding;
|
||||
FaceRecognitionDotNet.FaceEncoding faceEncoding;
|
||||
string eDistanceCollectionDirectory = string.Empty;
|
||||
Tuple<Shared.Models.Face, double> faceAndFaceDistance;
|
||||
List<Tuple<Shared.Models.Face, string>> faceAndFaceDistanceCollection;
|
||||
List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> files = GetFiles(configuration, model, predictorModel, outputResolution);
|
||||
List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> matches = GetMatches(files);
|
||||
Tuple<Face, double> faceAndFaceDistance;
|
||||
List<Tuple<Face, string>> faceAndFaceDistanceCollection;
|
||||
List<(string, List<KeyValuePair<string, Face[]>>)> files = GetFiles(configuration, model, predictorModel, outputResolution);
|
||||
List<(string, List<Face>, List<FaceRecognitionDotNet.FaceEncoding>)> matches = GetMatches(files);
|
||||
if (files.Count != matches.Count)
|
||||
throw new Exception();
|
||||
int filesCount = files.Count;
|
||||
@ -386,13 +385,15 @@ internal class E_Distance
|
||||
continue;
|
||||
for (int k = 0; k < files[i].Item2[j].Value.Length; k++)
|
||||
{
|
||||
if (!files[i].Item2[j].Value[k].Populated)
|
||||
continue;
|
||||
face = files[i].Item2[j].Value[k];
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
continue;
|
||||
faceAndFaceDistanceCollection = new(matches.Count);
|
||||
relativePath = Path.GetDirectoryName(face.RelativePath);
|
||||
if (string.IsNullOrEmpty(relativePath))
|
||||
continue;
|
||||
if (face.FaceEncoding is null)
|
||||
continue;
|
||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||
_ = Parallel.For(0, matches.Count, parallelOptions, z =>
|
||||
{
|
||||
@ -423,32 +424,32 @@ internal class E_Distance
|
||||
return result;
|
||||
}
|
||||
|
||||
private static FaceEncoding? GetFaceEncoding(IFace face)
|
||||
private static FaceRecognitionDotNet.FaceEncoding? GetFaceEncoding(Face face)
|
||||
{
|
||||
FaceEncoding? result;
|
||||
if (!face.Populated)
|
||||
FaceRecognitionDotNet.FaceEncoding? result;
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
result = null;
|
||||
else
|
||||
result = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static (int index, double sum) GetIndexAndSum(int i, List<FaceEncoding> results)
|
||||
private static (int index, double sum) GetIndexAndSum(int i, List<FaceRecognitionDotNet.FaceEncoding> results)
|
||||
{
|
||||
List<double> faceDistances = FaceRecognition.FaceDistances(results, results[i]);
|
||||
return new(i, faceDistances.Sum());
|
||||
}
|
||||
|
||||
private static List<FaceEncoding> GetFaceEncodings(int maxDegreeOfParallelism, List<(DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, IFace Face)> collection)
|
||||
private static List<FaceRecognitionDotNet.FaceEncoding> GetFaceEncodings(int maxDegreeOfParallelism, List<(DateTime MinimumDateTime, bool? IsWrongYear, PersonBirthday PersonBirthday, Face Face)> collection)
|
||||
{
|
||||
List<FaceEncoding> results;
|
||||
List<FaceRecognitionDotNet.FaceEncoding> results;
|
||||
if (maxDegreeOfParallelism == 1)
|
||||
{
|
||||
results = new();
|
||||
FaceEncoding faceEncoding;
|
||||
foreach ((DateTime _, bool? _, Shared.Models.PersonBirthday _, IFace face) in collection)
|
||||
FaceRecognitionDotNet.FaceEncoding faceEncoding;
|
||||
foreach ((DateTime _, bool? _, PersonBirthday _, Face face) in collection)
|
||||
{
|
||||
if (!face.Populated)
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
continue;
|
||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||
results.Add(faceEncoding);
|
||||
@ -460,7 +461,7 @@ internal class E_Distance
|
||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
||||
_ = Parallel.For(0, collection.Count, parallelOptions, i =>
|
||||
{
|
||||
FaceEncoding? faceEncoding = GetFaceEncoding(collection[i].Face);
|
||||
FaceRecognitionDotNet.FaceEncoding? faceEncoding = GetFaceEncoding(collection[i].Face);
|
||||
if (faceEncoding is not null)
|
||||
{
|
||||
lock (results)
|
||||
@ -518,12 +519,12 @@ internal class E_Distance
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> GetThreeSigmaFaceEncodings(int maxDegreeOfParallelism, Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, IFace)>> keyValuePairs)
|
||||
private static List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> GetThreeSigmaFaceEncodings(int maxDegreeOfParallelism, Dictionary<string, List<(DateTime, bool?, PersonBirthday, Face)>> keyValuePairs)
|
||||
{
|
||||
List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> results = new();
|
||||
List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> results = new();
|
||||
const int zero = 0;
|
||||
List<FaceEncoding> faceEncodings;
|
||||
foreach (KeyValuePair<string, List<(DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, IFace _)>> keyValuePair in keyValuePairs)
|
||||
List<FaceRecognitionDotNet.FaceEncoding> faceEncodings;
|
||||
foreach (KeyValuePair<string, List<(DateTime MinimumDateTime, bool? IsWrongYear, PersonBirthday PersonBirthday, Face _)>> keyValuePair in keyValuePairs)
|
||||
{
|
||||
faceEncodings = GetFaceEncodings(maxDegreeOfParallelism, keyValuePair.Value);
|
||||
results.Add(new(keyValuePair.Value[zero].MinimumDateTime, keyValuePair.Value[zero].IsWrongYear, keyValuePair.Value[zero].PersonBirthday, faceEncodings.ToArray()));
|
||||
@ -531,7 +532,7 @@ internal class E_Distance
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Closest? GetClosestParallelFor(DateTime minimumDateTime, bool? isWrongYear, IFace face, FaceEncoding faceEncoding, (DateTime MinimumDateTime, bool? IsWrongYear, Shared.Models.PersonBirthday PersonBirthday, FaceEncoding[] FaceEncodings) tuple)
|
||||
private static Closest? GetClosestParallelFor(DateTime minimumDateTime, bool? isWrongYear, Face face, FaceRecognitionDotNet.FaceEncoding faceEncoding, (DateTime MinimumDateTime, bool? IsWrongYear, PersonBirthday PersonBirthday, FaceRecognitionDotNet.FaceEncoding[] FaceEncodings) tuple)
|
||||
{
|
||||
Closest? result;
|
||||
if (isWrongYear.HasValue && !isWrongYear.Value && minimumDateTime < tuple.PersonBirthday.Value)
|
||||
@ -540,29 +541,31 @@ internal class E_Distance
|
||||
{
|
||||
List<double> faceDistances = FaceRecognition.FaceDistances(tuple.FaceEncodings, faceEncoding);
|
||||
result = new(face.Location?.NormalizedPixelPercentage, tuple.MinimumDateTime, tuple.IsWrongYear, tuple.PersonBirthday, faceDistances);
|
||||
if (result.Minimum > Closest.MaximumMinimum)
|
||||
if (result.Minimum > Shared.Models.Stateless.Methods.IClosest.MaximumMinimum)
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Closest[] GetClosestCollection(int maxDegreeOfParallelism, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, DateTime itemMinimumDateTime, bool? itemIsWrongYear, IFace face)
|
||||
private static Closest[] GetClosestCollection(int maxDegreeOfParallelism, List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection, DateTime itemMinimumDateTime, bool? itemIsWrongYear, Face face)
|
||||
{
|
||||
Closest[] results;
|
||||
List<Closest> closestCollection;
|
||||
FaceEncoding faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||
if (face.FaceEncoding is null)
|
||||
throw new NullReferenceException(nameof(face.FaceEncoding));
|
||||
FaceRecognitionDotNet.FaceEncoding faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||
if (maxDegreeOfParallelism == 1)
|
||||
{
|
||||
closestCollection = new();
|
||||
Closest closest;
|
||||
List<double> faceDistances;
|
||||
foreach ((DateTime minimumDateTime, bool? isWrongYear, Shared.Models.PersonBirthday personBirthday, FaceEncoding[] faceEncodings) in collection)
|
||||
foreach ((DateTime minimumDateTime, bool? isWrongYear, PersonBirthday personBirthday, FaceRecognitionDotNet.FaceEncoding[] faceEncodings) in collection)
|
||||
{
|
||||
if (itemIsWrongYear.HasValue && !itemIsWrongYear.Value && itemMinimumDateTime < personBirthday.Value)
|
||||
continue;
|
||||
faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncoding);
|
||||
closest = new(face.Location?.NormalizedPixelPercentage, minimumDateTime, isWrongYear, personBirthday, faceDistances);
|
||||
if (closest.Minimum > Closest.MaximumMinimum)
|
||||
if (closest.Minimum > Shared.Models.Stateless.Methods.IClosest.MaximumMinimum)
|
||||
continue;
|
||||
closestCollection.Add(closest);
|
||||
}
|
||||
@ -581,14 +584,14 @@ internal class E_Distance
|
||||
}
|
||||
});
|
||||
}
|
||||
results = Closest.Get(closestCollection);
|
||||
results = Shared.Models.Stateless.Methods.IClosest.Get(closestCollection);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void AddClosest(int maxDegreeOfParallelism, string argZero, PropertyLogic propertyLogic, List<Container> containers, List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection)
|
||||
private static void AddClosest(int maxDegreeOfParallelism, string argZero, Map.Models.MapLogic mapLogic, List<Container> containers, List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection)
|
||||
{
|
||||
string key;
|
||||
IFace face;
|
||||
Face face;
|
||||
Closest closest;
|
||||
string personKey;
|
||||
bool? itemIsWrongYear;
|
||||
@ -606,11 +609,11 @@ internal class E_Distance
|
||||
{
|
||||
if (item.ImageFileHolder is null || item.Property is null || item.Named.Any())
|
||||
continue;
|
||||
itemMinimumDateTime = Property.Models.Stateless.A_Property.GetMinimumDateTime(item.Property);
|
||||
itemMinimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||
if (itemMinimumDateTime is null)
|
||||
continue;
|
||||
(itemIsWrongYear, _) = item.IsWrongYear();
|
||||
if (Closest.SkipIsWrongYear && itemIsWrongYear.HasValue && itemIsWrongYear.Value)
|
||||
(itemIsWrongYear, _) = Map.Models.MapLogic.IsWrongYear(item);
|
||||
if (Shared.Models.Stateless.Methods.IClosest.SkipIsWrongYear && itemIsWrongYear.HasValue && itemIsWrongYear.Value)
|
||||
continue;
|
||||
item.Closest.Clear();
|
||||
for (int i = 0; i < item.Faces.Count; i++)
|
||||
@ -618,9 +621,9 @@ internal class E_Distance
|
||||
face = item.Faces[i];
|
||||
closest = new(face.Location?.NormalizedPixelPercentage, itemMinimumDateTime.Value, itemIsWrongYear);
|
||||
item.Closest.Add(closest);
|
||||
if (!face.Populated)
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
continue;
|
||||
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, face);
|
||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.INamed.GetDeterministicHashCodeKey(item, face);
|
||||
closestCollection = GetClosestCollection(maxDegreeOfParallelism, collection, itemMinimumDateTime.Value, itemIsWrongYear, face);
|
||||
for (int j = 0; j < closestCollection.Length; j++)
|
||||
{
|
||||
@ -628,12 +631,12 @@ internal class E_Distance
|
||||
if (closest.PersonBirthday is null)
|
||||
continue;
|
||||
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(closest.PersonBirthday);
|
||||
if (propertyLogic.IncorrectDeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey) && propertyLogic.IncorrectDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey].Contains(personKey))
|
||||
if (mapLogic.IncorrectDeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey) && mapLogic.IncorrectDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey].Contains(personKey))
|
||||
continue;
|
||||
key = Item.GetKey(closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday);
|
||||
key = Map.Models.MapLogic.GetKey(closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday);
|
||||
if (!results.ContainsKey(key))
|
||||
results.Add(key, 0);
|
||||
else if (results[key] > Closest.MaximumPer)
|
||||
else if (results[key] > Shared.Models.Stateless.Methods.IClosest.MaximumPer)
|
||||
continue;
|
||||
results[key] += 1;
|
||||
item.Closest[0] = closest;
|
||||
@ -644,12 +647,12 @@ internal class E_Distance
|
||||
}
|
||||
}
|
||||
|
||||
internal static List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> ParallelWork(int maxDegreeOfParallelism, string argZero, PropertyLogic propertyLogic, List<Container> containers)
|
||||
internal static List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> ParallelWork(int maxDegreeOfParallelism, string argZero, Map.Models.MapLogic mapLogic, List<Container> containers)
|
||||
{
|
||||
List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> results;
|
||||
Dictionary<string, List<(DateTime, bool?, Shared.Models.PersonBirthday, IFace)>> keyValuePairs = Item.GetKeyValuePairs(argZero, containers);
|
||||
List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> results;
|
||||
Dictionary<string, List<(DateTime, bool?, PersonBirthday, Face)>> keyValuePairs = Map.Models.MapLogic.GetKeyValuePairs(argZero, containers);
|
||||
results = GetThreeSigmaFaceEncodings(maxDegreeOfParallelism, keyValuePairs);
|
||||
AddClosest(maxDegreeOfParallelism, argZero, propertyLogic, containers, results);
|
||||
AddClosest(maxDegreeOfParallelism, argZero, mapLogic, containers, results);
|
||||
return results;
|
||||
}
|
||||
|
||||
@ -677,27 +680,27 @@ internal class E_Distance
|
||||
continue;
|
||||
if (!fileInfo.Directory.Exists)
|
||||
fileInfo.Directory.Create();
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void SaveThreeSigmaFaceEncodings(List<(DateTime, bool?, Shared.Models.PersonBirthday, FaceEncoding[])> collection, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string eDistanceCollectionDirectory)
|
||||
internal static void SaveThreeSigmaFaceEncodings(List<(DateTime, bool?, PersonBirthday, FaceRecognitionDotNet.FaceEncoding[])> collection, Dictionary<string, List<Person>> peopleCollection, string eDistanceCollectionDirectory)
|
||||
{
|
||||
string json;
|
||||
string checkFile;
|
||||
string personKey;
|
||||
string directory;
|
||||
List<double[]> rawEncodings;
|
||||
Shared.Models.Person person;
|
||||
Person person;
|
||||
const string facePopulatedKey = "ThreeSigma";
|
||||
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
|
||||
foreach ((DateTime minimumDateTime, bool? isWrongYear, Shared.Models.PersonBirthday personBirthday, FaceEncoding[] faceEncodings) in collection)
|
||||
foreach ((DateTime minimumDateTime, bool? isWrongYear, PersonBirthday personBirthday, FaceRecognitionDotNet.FaceEncoding[] faceEncodings) in collection)
|
||||
{
|
||||
rawEncodings = new();
|
||||
checkFile = string.Empty;
|
||||
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
|
||||
directory = Item.GetDirectory(eDistanceCollectionDirectory, facePopulatedKey, minimumDateTime, isWrongYear, personBirthday, personKey);
|
||||
directory = Map.Models.MapLogic.GetDirectory(eDistanceCollectionDirectory, facePopulatedKey, minimumDateTime, isWrongYear, personBirthday, personKey);
|
||||
if (!peopleCollection.ContainsKey(personKey))
|
||||
continue;
|
||||
person = peopleCollection[personKey][0];
|
||||
@ -709,13 +712,14 @@ internal class E_Distance
|
||||
for (int i = 0; i < faceEncodings.Length; i++)
|
||||
rawEncodings.Add(faceEncodings[i].GetRawEncoding());
|
||||
json = JsonSerializer.Serialize(rawEncodings, new JsonSerializerOptions { WriteIndented = true });
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||
}
|
||||
}
|
||||
|
||||
internal static List<(FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> GetClosest(string argZero, List<Container> containers, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string eDistanceContentDirectory, string dFacesContentDirectory)
|
||||
internal static List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> GetClosest(string argZero, List<Container> containers, Dictionary<string, List<Person>> peopleCollection, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string eDistanceContentDirectory)
|
||||
{
|
||||
List<(FileHolder?, string, FileInfo?, string, string)> results = new();
|
||||
List<(IFileHolder?, string, FileInfo?, string, string)> results = new();
|
||||
Person person;
|
||||
string checkFile;
|
||||
string directory;
|
||||
string personKey;
|
||||
@ -725,7 +729,8 @@ internal class E_Distance
|
||||
string? directoryName;
|
||||
string facesDirectory;
|
||||
string personDirectory;
|
||||
Shared.Models.Person person;
|
||||
FileInfo landmarkFileInfo;
|
||||
string landmarksDirectory;
|
||||
double deterministicHashCodeKey;
|
||||
const string facePopulatedKey = "Closest";
|
||||
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
|
||||
@ -749,7 +754,7 @@ internal class E_Distance
|
||||
if (closest.Average is null || closest.NormalizedPixelPercentage is null || closest.PersonBirthday is null)
|
||||
continue;
|
||||
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(closest.PersonBirthday);
|
||||
directory = Item.GetDirectory(eDistanceContentDirectory, facePopulatedKey, closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday, personKey);
|
||||
directory = Map.Models.MapLogic.GetDirectory(eDistanceContentDirectory, facePopulatedKey, closest.MinimumDateTime, closest.IsWrongYear, closest.PersonBirthday, personKey);
|
||||
if (!peopleCollection.ContainsKey(personKey))
|
||||
personDirectory = string.Empty;
|
||||
else
|
||||
@ -760,9 +765,11 @@ internal class E_Distance
|
||||
results.Add(new(null, personDirectory, null, string.Empty, string.Empty));
|
||||
}
|
||||
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
|
||||
deterministicHashCodeKey = Named.GetDeterministicHashCodeKey(item, closest);
|
||||
landmarksDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
|
||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.INamed.GetDeterministicHashCodeKey(item, closest);
|
||||
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
|
||||
faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
|
||||
landmarkFileInfo = new(Path.Combine(landmarksDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.gif"));
|
||||
if (string.IsNullOrEmpty(personDirectory))
|
||||
shortcutFile = string.Empty;
|
||||
else
|
||||
@ -774,10 +781,10 @@ internal class E_Distance
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static void SaveClosest(string argZero, List<Container> containers, Dictionary<string, List<Shared.Models.Person>> peopleCollection, string eDistanceContentDirectory, string dFacesContentDirectory)
|
||||
internal static void SaveClosest(string argZero, List<Container> containers, Dictionary<string, List<Person>> peopleCollection, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string eDistanceContentDirectory)
|
||||
{
|
||||
WindowsShortcut windowsShortcut;
|
||||
List<(FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> collection = GetClosest(argZero, containers, peopleCollection, eDistanceContentDirectory, dFacesContentDirectory);
|
||||
List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile)> collection = GetClosest(argZero, containers, peopleCollection, dFacesContentDirectory, d2ResultsFullGroupDirectory, eDistanceContentDirectory);
|
||||
string[] directories = (from l in collection select l.directory).Distinct().ToArray();
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
@ -786,7 +793,7 @@ internal class E_Distance
|
||||
if (!Directory.Exists(directory))
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
}
|
||||
foreach ((FileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile) in collection)
|
||||
foreach ((IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile) in collection)
|
||||
{
|
||||
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null || faceFileInfo is null)
|
||||
continue;
|
||||
@ -797,7 +804,7 @@ internal class E_Distance
|
||||
else
|
||||
File.Copy(resizedFileHolder.FullName, checkFile);
|
||||
}
|
||||
foreach ((FileHolder? resizedFileHolder, string directory, FileInfo? _, string checkFile, string shortcutFile) in collection)
|
||||
foreach ((IFileHolder? resizedFileHolder, string directory, FileInfo? _, string checkFile, string shortcutFile) in collection)
|
||||
{
|
||||
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null)
|
||||
continue;
|
||||
|
@ -28,8 +28,6 @@ internal class F_Random
|
||||
private bool IsIgnoreRelativePath(string directory)
|
||||
{
|
||||
bool result = false;
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration.PropertyConfiguration));
|
||||
string? checkDirectory = Path.GetFullPath(directory);
|
||||
for (int i = 0; i < int.MaxValue; i++)
|
||||
{
|
||||
@ -71,7 +69,7 @@ internal class F_Random
|
||||
relativePaths = (from l in relativePaths orderby random.NextDouble() select l).ToList();
|
||||
jsonFile = Path.Combine(fRandomCollectionDirectory, $"{dateTime.AddDays(i):MM-dd}.json");
|
||||
json = JsonSerializer.Serialize(relativePaths, _WriteIndentedJsonSerializerOptions);
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
|
||||
if (!_Configuration.SaveFullYearOfRandomFiles)
|
||||
break;
|
||||
}
|
||||
@ -81,7 +79,7 @@ internal class F_Random
|
||||
ignoreRelativePaths = (from l in ignoreRelativePaths orderby random.NextDouble() select l).ToList();
|
||||
jsonFile = Path.Combine(fRandomCollectionDirectory, "01-01.txt");
|
||||
json = JsonSerializer.Serialize(ignoreRelativePaths, _WriteIndentedJsonSerializerOptions);
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: false, compareBeforeWrite: false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
using Phares.Shared;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
|
||||
@ -103,7 +102,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
||||
json = JsonSerializer.Serialize(resultKeyValuePairs, _WriteIndentedJsonSerializerOptions);
|
||||
if (!isEnvironment.DebuggerWasAttachedDuringConstructor)
|
||||
throw new Exception("Only allowed when debugger is attached during constructor!");
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(named.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(named.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +188,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
||||
string jsonFile;
|
||||
string directoryFullName;
|
||||
string fileNameWithoutExtension;
|
||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "{}");
|
||||
string g2IdentifyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
|
||||
Dictionary<string, List<KeyValuePair<string, string>>> keyValuePairs = new();
|
||||
foreach (G2_Identify identified in identifiedCollection)
|
||||
@ -221,7 +220,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
||||
_ = Directory.CreateDirectory(directoryFullName);
|
||||
jsonFile = string.Concat(g2IdentifyCollectionDirectory, keyValuePair.Key, ".json");
|
||||
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
|
||||
if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
@ -76,11 +75,11 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
||||
return result;
|
||||
}
|
||||
|
||||
private void WriteNeeded(List<int> indices, List<Tuple<List<string>, string, A_Property>> neededTuples)
|
||||
private void WriteNeeded(List<int> indices, List<Tuple<List<string>, string, Shared.Models.Property>> neededTuples)
|
||||
{
|
||||
string json;
|
||||
DateTime dateTime;
|
||||
A_Property property;
|
||||
Shared.Models.Property property;
|
||||
G_Index indexInfo;
|
||||
int maxIndexPlusOne;
|
||||
DateTime?[] dateTimes;
|
||||
@ -91,7 +90,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
||||
maxIndexPlusOne = 1000000;
|
||||
throw new Exception("Are you sure exception. Use debugger to step over.");
|
||||
}
|
||||
foreach (Tuple<List<string>, string, A_Property> tuple in neededTuples)
|
||||
foreach (Tuple<List<string>, string, Shared.Models.Property> tuple in neededTuples)
|
||||
{
|
||||
maxIndexPlusOne += 1;
|
||||
property = tuple.Item3;
|
||||
@ -99,7 +98,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
||||
dateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
|
||||
indexInfo = new(dateTime, maxIndexPlusOne, tuple.Item1);
|
||||
json = JsonSerializer.Serialize(indexInfo, _WriteIndentedJsonSerializerOptions);
|
||||
if (!Property.Models.Stateless.IPath.WriteAllText(tuple.Item2, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(tuple.Item2, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -114,24 +113,24 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
||||
indices = (from l in tuple.Item2 select l.Value).ToArray();
|
||||
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, tuple.Item1, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: string.Empty, collectionDescription: "Unknown A");
|
||||
json = JsonSerializer.Serialize(indices, _WriteIndentedJsonSerializerOptions);
|
||||
if (!Property.Models.Stateless.IPath.WriteAllText(string.Concat(directoryInfoCollection[0].Replace("<>", "[]"), ".json"), json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(string.Concat(directoryInfoCollection[0].Replace("<>", "[]"), ".json"), json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendTSV(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, Dictionary<string, List<Tuple<string, A_Property>>> filePropertiesKeyValuePairs)
|
||||
private void AppendTSV(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, Dictionary<string, List<Tuple<string, Shared.Models.Property>>> filePropertiesKeyValuePairs)
|
||||
{
|
||||
A_Property property;
|
||||
Shared.Models.Property property;
|
||||
DateTime?[] dateTimes;
|
||||
DateTime? maximumDateTime;
|
||||
DateTime? minimumDateTime;
|
||||
List<string> directoryInfoCollection;
|
||||
long ticks = System.DateTime.Now.Ticks;
|
||||
foreach (KeyValuePair<string, List<Tuple<string, A_Property>>> tuples in filePropertiesKeyValuePairs)
|
||||
foreach (KeyValuePair<string, List<Tuple<string, Shared.Models.Property>>> tuples in filePropertiesKeyValuePairs)
|
||||
{
|
||||
maximumDateTime = null;
|
||||
minimumDateTime = null;
|
||||
foreach (Tuple<string, A_Property> tuple in tuples.Value)
|
||||
foreach (Tuple<string, Shared.Models.Property> tuple in tuples.Value)
|
||||
{
|
||||
property = tuple.Item2;
|
||||
dateTimes = new DateTime?[] { maximumDateTime, minimumDateTime, property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
|
||||
@ -142,7 +141,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetIndex(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, Dictionary<string, List<Tuple<string, A_Property>>> filePropertiesKeyValuePairs)
|
||||
internal void SetIndex(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string outputResolution, Dictionary<string, List<Tuple<string, Shared.Models.Property>>> filePropertiesKeyValuePairs)
|
||||
{
|
||||
FileInfo fileInfo;
|
||||
G_Index indexInfo;
|
||||
@ -151,7 +150,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
||||
Dictionary<int, G_Index> valuePairs;
|
||||
List<string> directoryInfoCollection;
|
||||
List<string> parseExceptions = new();
|
||||
List<Tuple<List<string>, string, A_Property>> neededTuples = new();
|
||||
List<Tuple<List<string>, string, Shared.Models.Property>> neededTuples = new();
|
||||
List<Tuple<string, Dictionary<int, G_Index>>> indexInfoTuples = new();
|
||||
for (short i = 0; i < short.MaxValue; i++)
|
||||
{
|
||||
@ -164,11 +163,11 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
||||
parseExceptions.Clear();
|
||||
}
|
||||
neededTuples.Clear();
|
||||
foreach (KeyValuePair<string, List<Tuple<string, A_Property>>> tuples in filePropertiesKeyValuePairs)
|
||||
foreach (KeyValuePair<string, List<Tuple<string, Shared.Models.Property>>> tuples in filePropertiesKeyValuePairs)
|
||||
{
|
||||
valuePairs = new Dictionary<int, G_Index>();
|
||||
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, model, predictorModel, tuples.Key, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: "Unknown C", collectionDescription: string.Empty);
|
||||
foreach (Tuple<string, A_Property> tuple in tuples.Value)
|
||||
foreach (Tuple<string, Shared.Models.Property> tuple in tuples.Value)
|
||||
{
|
||||
fileInfo = new FileInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "{}"), string.Concat(Path.GetFileNameWithoutExtension(tuple.Item1), ".json")));
|
||||
if (!fileInfo.Exists)
|
||||
@ -191,7 +190,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
||||
valuePairs.Add(indexInfo.Index.Value, indexInfo);
|
||||
}
|
||||
else
|
||||
neededTuples.Add(new Tuple<List<string>, string, A_Property>(new List<string> { tuple.Item1 }, fileInfo.FullName, tuple.Item2));
|
||||
neededTuples.Add(new Tuple<List<string>, string, Shared.Models.Property>(new List<string> { tuple.Item1 }, fileInfo.FullName, tuple.Item2));
|
||||
}
|
||||
indexInfoTuples.Add(new Tuple<string, Dictionary<int, G_Index>>(tuples.Key, valuePairs));
|
||||
}
|
||||
|
@ -52,7 +52,7 @@
|
||||
"Configuration": {
|
||||
"CheckJsonForDistanceResults": false,
|
||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||
"DateGroup": "2022-08-14",
|
||||
"DateGroup": "2022-08-22",
|
||||
"DistanceFactor": 8,
|
||||
"FileNameDirectorySeparator": ".Z.",
|
||||
"ForceFaceLastWriteTimeToCreationTime": false,
|
||||
@ -62,7 +62,7 @@
|
||||
"LoadOrCreateThenSaveIndex": false,
|
||||
"LocationConfidenceFactor": 2,
|
||||
"MappedMaxIndex": 1034720,
|
||||
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
|
||||
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||
"MaxItemsInDistanceCollection": 50,
|
||||
"ModelDirectory": "C:/GitHub/dlib-models",
|
||||
"ModelName": "Hog",
|
||||
@ -85,7 +85,7 @@
|
||||
"PropertiesChangedForResize": false,
|
||||
"Reverse": false,
|
||||
"xRootDirectory": "C:/Tmp/phares/Pictures",
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-08-14 - b756859b616424dc98b7742a64c15a8951632473 - III",
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-08-22 - b756859b616424dc98b7742a64c15a8951632473 - III",
|
||||
"SaveFullYearOfRandomFiles": true,
|
||||
"SaveResizedSubFiles": true,
|
||||
"SkipSearch": false,
|
||||
|
@ -52,7 +52,7 @@
|
||||
"Configuration": {
|
||||
"CheckJsonForDistanceResults": false,
|
||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||
"DateGroup": "2022-08-14",
|
||||
"DateGroup": "2022-08-22",
|
||||
"DistanceFactor": 8,
|
||||
"FileNameDirectorySeparator": ".Z.",
|
||||
"ForceFaceLastWriteTimeToCreationTime": false,
|
||||
@ -62,7 +62,7 @@
|
||||
"LoadOrCreateThenSaveIndex": false,
|
||||
"LocationConfidenceFactor": 2,
|
||||
"MappedMaxIndex": 1034720,
|
||||
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
|
||||
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||
"MaxItemsInDistanceCollection": 50,
|
||||
"ModelDirectory": "L:/GitHub/dlib-models",
|
||||
"ModelName": "Hog",
|
||||
|
@ -52,7 +52,7 @@
|
||||
"Configuration": {
|
||||
"CheckJsonForDistanceResults": false,
|
||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||
"DateGroup": "2022-08-14",
|
||||
"DateGroup": "2022-08-22",
|
||||
"DistanceFactor": 8,
|
||||
"FileNameDirectorySeparator": ".Z.",
|
||||
"ForceFaceLastWriteTimeToCreationTime": false,
|
||||
@ -62,7 +62,7 @@
|
||||
"LoadOrCreateThenSaveIndex": false,
|
||||
"LocationConfidenceFactor": 2,
|
||||
"MappedMaxIndex": 1034720,
|
||||
"MaxImagesInDirectoryForTopLevelFirstPass": 50,
|
||||
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||
"MaxItemsInDistanceCollection": 50,
|
||||
"ModelDirectory": "C:/GitHub/dlib-models",
|
||||
"ModelName": "Hog",
|
||||
|
Reference in New Issue
Block a user