Re-write
This commit is contained in:
@ -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;
|
||||
|
Reference in New Issue
Block a user