Forgot pad left
This commit is contained in:
parent
751a61529c
commit
d789f295c6
29
.vscode/launch.json
vendored
29
.vscode/launch.json
vendored
@ -53,4 +53,31 @@
|
||||
// Notes at 9/18/2022 10:29 PM
|
||||
// (637987913910140924) 9/14/2022 10:29 PM - 113 *.jpg && 109 *.json
|
||||
// (637989361172096980) 9/16/2022 02:41 PM - 094 *.jpg && 026 *.json
|
||||
// All including (637991052364021796) 9/18/2022 1:40 PM - 17435 *.jpg && 16237 *.json = 93.128763980499% with int match only
|
||||
// All including (637991052364021796) 9/18/2022 1:40 PM - 17435 *.jpg && 16237 *.json = 93.128763980499% with int match only
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/49158951_2264915190186558_112485584324263936_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=84a396&_nc_ohc=Q78znguHVeMAX88OKg9&_nc_ht=scontent-lax3-2.xx&oh=00_AT_gJFk9xytYuXp9p5smDm0mMDXzsPnFS_EfKEbiL3KYqg&oe=63523F37
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t39.30808-6/290625560_10217841255422109_3297482250419620718_n.jpg?_nc_cat=104&ccb=1-7&_nc_sid=730e14&_nc_ohc=O3ybqwDLK9AAX_V0FGP&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT-9rtBghXU7lAGkOy4KPHbV9Kyj8DGm-BGtUabWgQJbOg&oe=63335209
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t39.30808-6/243093116_10216723829287154_8982585928017225043_n.jpg?_nc_cat=104&ccb=1-7&_nc_sid=730e14&_nc_ohc=TW6UDC8v9egAX-_YcWf&_nc_ht=scontent-lax3-1.xx&oh=00_AT8rE2JOfkJINSsA5imGVBDbXNDvxx1_uZn0sLM-6ITDUw&oe=633238A9
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/281249_1450445399251_3598212_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=ihKT3xtvWXoAX-kiat-&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT9cmbHu00fc0-aR-k6MP7T_cja6geiAkobbvU4pdfG6KQ&oe=63527F21
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/62557_157063120990498_3918482_n.jpg?_nc_cat=110&ccb=1-7&_nc_sid=de6eea&_nc_ohc=lV8bmtAes-0AX8Uk9pG&_nc_ht=scontent-lax3-1.xx&oh=00_AT-ieBL8wIZ4gQmRWAvTWDu9wBzAsPV5s4c82MvOs6oU5g&oe=6355846B
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/166577_1634651034600_6777460_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=nEZ0RR0cqn4AX-wA-VH&_nc_ht=scontent-lax3-1.xx&oh=00_AT_ig2HUMDQl1fhXY0Inm0QWC3i2__rPUAWYF2Wqx-pkew&oe=635290D6
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/97107804_10223189072017432_5088375698351980544_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=09cbfe&_nc_ohc=t0rqlgAAd_0AX-ANM1H&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT_hqG2piNkASRB5z94qeY8q7hy90ku9Dka4enL4wsAnTg&oe=6354CD8A
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/121491463_10159438417238072_1207001349879930424_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=rZTiRaFTrCkAX_L4sVS&_nc_ht=scontent-lax3-2.xx&oh=00_AT_uKD2jeNUTwlyN5r6UXRK40aNNgRNCZrrJ9B-WW6tlag&oe=63522946
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/96370874_10158521458082578_8748970895894118400_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=qvIn4gTjvo0AX-dHnuq&_nc_ht=scontent-lax3-1.xx&oh=00_AT8R-D8AsjWKMlUxK-AimPNzxuNT06zQCS43ESdf1LEeoQ&oe=63562F54
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/96681856_10157495047223435_2857053180632498176_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=UwF0qUGoG9QAX-S1LcI&_nc_ht=scontent-lax3-2.xx&oh=00_AT-5j0EiZB6HOOc2jGqGOll2zFoNTdDLKLfJztq0HYWagg&oe=6355A2A9
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t31.18172-8/26850365_1810492538961485_3240264679723665015_o.jpg?_nc_cat=110&ccb=1-7&_nc_sid=0debeb&_nc_ohc=WrJYsgu1eS4AX8kIsyM&_nc_ht=scontent-lax3-1.xx&oh=00_AT-fzFN40kYFjF2-uYL6KcgKPxgFkDZ5BcyIUVFdCTf2tg&oe=635485B7
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/67735718_10219770387799941_2254439277247070208_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=730e14&_nc_ohc=MD8haDYY7uIAX_dwTY4&_nc_ht=scontent-lax3-1.xx&oh=00_AT_zhJpjbWomrihWiSq35KFkmpBfEgbXCSNM68icaABxoA&oe=6355871D
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/59983603_2215207855225638_2271200674882519040_n.jpg?_nc_cat=111&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=-2zmPWdcy9IAX8KXJ_t&_nc_ht=scontent-lax3-2.xx&oh=00_AT_7N0yufGym-cuQfeMK6iceBNI7eEyaScRm3m3_4njTIQ&oe=6354C2B6
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/204501292_10222856568897395_8588510782161393042_n.jpg?_nc_cat=105&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=2gLdnkn19swAX_9mAG1&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-1.xx&oh=00_AT_ha5ncAI7ykhbgFNT1_4NWCvPGFWQLgdq6q20nZSIVQA&oe=63537D09
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/65945099_10217135244827869_3400689284598988800_n.jpg?_nc_cat=110&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=NHnhR9_7UTkAX8wpbxK&_nc_ht=scontent-lax3-1.xx&oh=00_AT_-Q-zUeDoD11B9TY_n_MWEimMiXCokB_5TojplmU6_Eg&oe=6355A2B8
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/22055_581856018827_4131263_n.jpg?_nc_cat=107&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=zsqIe2xzpf0AX8lcyLV&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT_DzvUir_30cauAjp8eaSlYKVADdanzWo1NAQK7_b3M-w&oe=63548E83
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t31.18172-8/14525108_10202312892739292_8313619716862825541_o.jpg?_nc_cat=102&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=lZ4MpT6i_MIAX-3d-nV&_nc_ht=scontent-lax3-1.xx&oh=00_AT_9JoZdMdlNV71PdrkU7AmvFkkwqllEg9sVTvcGyzoESw&oe=6353993A
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/104325415_860091804515928_5960365004832843376_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=174925&_nc_ohc=y1AW-ld80OcAX_927wW&_nc_oc=AQluU8Pwuqxs9xBVYhQJ9ThWOh5vLIKvQdOQnCtZpN2-j-6d9PRMHWHR5aaFBkcJicA&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT8vQwiLvz7cJU61FkIPLtcc8j8tlL2tC6zRlH1i20VUmQ&oe=6356EACE
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/43565411_10217177505092918_6185540976904241152_n.jpg?_nc_cat=105&ccb=1-7&_nc_sid=730e14&_nc_ohc=yBls9BCXhdwAX_doX-2&_nc_ht=scontent-lax3-1.xx&oh=00_AT-PYyffphSxOeGM_3aC4oHSA4U9cEjm2OrappZ_jh6qIg&oe=6355895C
|
||||
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.6435-9/48422692_10157144542022625_3324340889383337984_n.jpg?_nc_cat=108&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=h_gtXGa5nSAAX-CB2E1&_nc_ht=scontent-lax3-1.xx&oh=00_AT8x7vZA5VN27hfoMPcQ39So-1COUnuNjDj4iz8d-cw6wQ&oe=6354B370
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/150153899_10208532293942419_1808101907825622971_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=3NZWKCpJ0VYAX911uCo&_nc_ht=scontent-lax3-2.xx&oh=00_AT_NhKwagHEsPuQVSERZNQ2_6MOIG2UKG5r32c0fIPaeQA&oe=63552624
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t31.18172-8/13641143_10209202266801205_7525162492297688727_o.jpg?_nc_cat=106&ccb=1-7&_nc_sid=174925&_nc_ohc=AETs7fkfLacAX-q9cnO&_nc_ht=scontent-lax3-2.xx&oh=00_AT89DOYAP9GbNvEgmlI0z9VK9Z8uJttFQyuO-tfe5OGbFQ&oe=6355CF5D
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/299875_2023116112081_1500929171_n.jpg?_nc_cat=103&ccb=1-7&_nc_sid=cdbe9c&_nc_ohc=bsY9uckSAQwAX-xxGaU&_nc_ht=scontent-lax3-2.xx&oh=00_AT8OStQmDU_7NLNrYLeNfoULcBA-onU1V3Z4bn35-ipzCQ&oe=63555339
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/1544444_10203587296855592_4576811169900508598_n.jpg?_nc_cat=100&ccb=1-7&_nc_sid=730e14&_nc_ohc=pYUGNkoYGPcAX8X2gtw&_nc_ht=scontent-lax3-2.xx&oh=00_AT_thzQZyWPWDA8t1acXqEzifLMXxcPTUOgqWqmeuk3SfQ&oe=63566033
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t31.18172-8/10887668_10205175511939476_7644367668075304275_o.jpg?_nc_cat=100&ccb=1-7&_nc_sid=730e14&_nc_ohc=2T_utQvqkXYAX94o-WV&_nc_ht=scontent-lax3-2.xx&oh=00_AT8aSCQ4JVgRULd1RxRJ8DYqPtB9EyGY-May2QwwqKSqjQ&oe=6356B098
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/78675669_10102984650797787_175454688261439488_n.jpg?_nc_cat=101&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=7Plv_RW77xoAX9PiH9G&_nc_ht=scontent-lax3-2.xx&oh=00_AT-npzVNkTzAdYgQ4D1ltfyl8llC_xqOHJ9Mi8Vmh2khlw&oe=63571251
|
||||
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.6435-9/59569741_10214142910059142_9219208491263066112_n.jpg?_nc_cat=100&ccb=1-7&_nc_sid=730e14&_nc_ohc=F7GF2uCFljcAX8Skffr&_nc_ht=scontent-lax3-2.xx&oh=00_AT9e3f8x6hSmAcxQ5JDUvDPFEg0wcecKw175Qfj_WMwADQ&oe=635488AA
|
||||
|
@ -75,18 +75,6 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<FaceDistance> GetFaceDistanceEncodings(FaceDistanceContainer[] faceDistanceContainers)
|
||||
{
|
||||
List<FaceDistance> faceDistanceEncodings = new();
|
||||
foreach (FaceDistanceContainer faceDistanceContainer in faceDistanceContainers)
|
||||
{
|
||||
if (faceDistanceContainer.FaceDistance.Encoding is null)
|
||||
continue;
|
||||
faceDistanceEncodings.Add(faceDistanceContainer.FaceDistance);
|
||||
}
|
||||
return faceDistanceEncodings;
|
||||
}
|
||||
|
||||
private static FaceDistanceContainer[] GetOrderedFaceDistanceContainers(List<FaceDistanceContainer> collection)
|
||||
{
|
||||
FaceDistanceContainer[] results;
|
||||
@ -116,6 +104,18 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<FaceDistance> GetFaceDistanceEncodings(FaceDistanceContainer[] faceDistanceContainers)
|
||||
{
|
||||
List<FaceDistance> faceDistanceEncodings = new();
|
||||
foreach (FaceDistanceContainer faceDistanceContainer in faceDistanceContainers)
|
||||
{
|
||||
if (faceDistanceContainer.FaceDistance.Encoding is null)
|
||||
continue;
|
||||
faceDistanceEncodings.Add(faceDistanceContainer.FaceDistance);
|
||||
}
|
||||
return faceDistanceEncodings;
|
||||
}
|
||||
|
||||
public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, long ticks, MapLogic mapLogic, Face[] selectedFilteredFaces)
|
||||
{
|
||||
SortingContainer[] results;
|
||||
@ -175,79 +175,6 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
});
|
||||
}
|
||||
|
||||
private static FaceDistanceContainer[] GetOrderedFaceDistanceContainers(MappingFromItem mappingFromItem, List<Face> faces)
|
||||
{
|
||||
FaceDistanceContainer[] results;
|
||||
FaceDistance faceDistance;
|
||||
int normalizedPixelPercentage;
|
||||
FaceDistanceContainer faceDistanceContainer;
|
||||
List<FaceDistanceContainer> collection = new();
|
||||
foreach (Face face in faces)
|
||||
{
|
||||
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
|
||||
throw new NotSupportedException();
|
||||
normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
|
||||
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
||||
faceDistance = new(face.Location.Confidence, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedPixelPercentage);
|
||||
else
|
||||
{
|
||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||
faceDistance = new(face.Location.Confidence, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedPixelPercentage);
|
||||
lock (faces)
|
||||
face.SetFaceDistance(faceDistance);
|
||||
}
|
||||
faceDistanceContainer = new(face, faceDistance);
|
||||
collection.Add(faceDistanceContainer);
|
||||
}
|
||||
results = GetOrderedFaceDistanceContainers(collection);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<(Face Face, double Length)> GetValues(double faceDistanceTolerance, MappingFromItem mappingFromItem, List<Face> faces, string json)
|
||||
{
|
||||
List<(Face Face, double Length)> results = new();
|
||||
Face face;
|
||||
FaceDistance faceDistanceLength;
|
||||
Shared.Models.FaceEncoding? modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
|
||||
if (modelsFaceEncoding is null)
|
||||
throw new NotSupportedException();
|
||||
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
|
||||
FaceDistance faceDistanceEncoding = new(faceRecognitionDotNetFaceEncoding);
|
||||
FaceDistanceContainer[] faceDistanceContainers = GetOrderedFaceDistanceContainers(mappingFromItem, faces);
|
||||
int faceDistanceContainersLength = faceDistanceContainers.Length;
|
||||
if (faceDistanceContainersLength != faces.Count)
|
||||
throw new NotSupportedException();
|
||||
List<FaceDistance> faceDistanceEncodings = GetFaceDistanceEncodings(faceDistanceContainers);
|
||||
if (faceDistanceEncodings.Count != faces.Count)
|
||||
throw new NotSupportedException();
|
||||
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
|
||||
if (faceDistanceLengths.Count != faceDistanceContainersLength)
|
||||
throw new NotSupportedException();
|
||||
for (int i = 0; i < faces.Count; i++)
|
||||
{
|
||||
face = faces[i];
|
||||
faceDistanceLength = faceDistanceLengths[i];
|
||||
if (faceDistanceLength.Length is null)
|
||||
throw new NotSupportedException();
|
||||
if (faceDistanceLength.Length.Value > faceDistanceTolerance)
|
||||
continue;
|
||||
results.Add(new(face, faceDistanceLength.Length.Value));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<Face> GetMatchingFaces(double faceDistanceTolerance, MappingFromItem mappingFromItem, List<Face> faces, string json)
|
||||
{
|
||||
List<Face> results = new();
|
||||
List<(Face Face, double Length)> collection = GetValues(faceDistanceTolerance, mappingFromItem, faces, json);
|
||||
if (collection.Any())
|
||||
{
|
||||
collection = (from l in collection orderby l.Length select l).ToList();
|
||||
results.Add(collection[0].Face);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
void Shared.Models.Methods.IFaceDistance.SavePossiblyNewPersonContainers(IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, string facesFileNameExtension, string a2PeopleSingletonDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||
{
|
||||
char @char;
|
||||
@ -346,69 +273,6 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
{ }
|
||||
}
|
||||
|
||||
public static string? GetFaceEncoding(string file)
|
||||
{
|
||||
string? result;
|
||||
List<string> results = new();
|
||||
const string comment = "Comment: ";
|
||||
if (File.Exists(file))
|
||||
{
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file);
|
||||
foreach (MetadataExtractor.Directory directory in directories)
|
||||
{
|
||||
if (directory.Name != "PNG-tEXt")
|
||||
continue;
|
||||
foreach (MetadataExtractor.Tag tag in directory.Tags)
|
||||
{
|
||||
if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description))
|
||||
continue;
|
||||
if (!tag.Description.StartsWith(comment))
|
||||
continue;
|
||||
results.Add(tag.Description);
|
||||
}
|
||||
}
|
||||
}
|
||||
result = results.Any() ? results[0][comment.Length..] : null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Face[] GetMatchingFaces(int pixelDistanceTolerance, List<Face> faces)
|
||||
{
|
||||
Face[] results;
|
||||
int? x;
|
||||
int? y;
|
||||
double distance;
|
||||
double center = 2f;
|
||||
double xCenterValue;
|
||||
double yCenterValue;
|
||||
string normalizedPixelPercentagePadded;
|
||||
List<(double Order, Face Face)> collection = new();
|
||||
foreach (Face face in faces)
|
||||
{
|
||||
if (face.Location is null || face.OutputResolution is null || face.Mapping is null)
|
||||
throw new NotSupportedException();
|
||||
xCenterValue = (face.Location.Left + face.Location.Right) / center;
|
||||
yCenterValue = (face.Location.Top + face.Location.Bottom) / center;
|
||||
if (xCenterValue < face.Location.Left || xCenterValue > face.Location.Right)
|
||||
throw new Exception();
|
||||
if (yCenterValue < face.Location.Top || yCenterValue > face.Location.Bottom)
|
||||
throw new Exception();
|
||||
normalizedPixelPercentagePadded = Shared.Models.Stateless.Methods.ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
|
||||
(x, y) = Shared.Models.Stateless.Methods.ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution.Width, face.OutputResolution.Height, normalizedPixelPercentagePadded);
|
||||
if (x is null || y is null)
|
||||
throw new NotSupportedException();
|
||||
distance = Math.Sqrt(Math.Pow(xCenterValue - x.Value, 2) + Math.Pow(yCenterValue - y.Value, 2));
|
||||
collection.Add(new(distance, face));
|
||||
}
|
||||
results = (from l in collection orderby l.Order where l.Order < pixelDistanceTolerance select l.Face).ToArray();
|
||||
if (results.Any())
|
||||
{
|
||||
if (results.Any())
|
||||
{ }
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static string[] GetMatchingDuplicates(string[] mappedFaceFiles, List<string> duplicateMappedFaceFiles, string mappedFaceFile)
|
||||
{
|
||||
string[] results;
|
||||
@ -441,6 +305,141 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
return results;
|
||||
}
|
||||
|
||||
public static string? GetFaceEncoding(string file)
|
||||
{
|
||||
string? result;
|
||||
List<string> results = new();
|
||||
const string comment = "Comment: ";
|
||||
if (File.Exists(file))
|
||||
{
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file);
|
||||
foreach (MetadataExtractor.Directory directory in directories)
|
||||
{
|
||||
if (directory.Name != "PNG-tEXt")
|
||||
continue;
|
||||
foreach (MetadataExtractor.Tag tag in directory.Tags)
|
||||
{
|
||||
if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description))
|
||||
continue;
|
||||
if (!tag.Description.StartsWith(comment))
|
||||
continue;
|
||||
results.Add(tag.Description);
|
||||
}
|
||||
}
|
||||
}
|
||||
result = results.Any() ? results[0][comment.Length..] : null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static FaceDistanceContainer[] GetOrderedFaceDistanceContainers(MappingFromItem mappingFromItem, List<Face> faces)
|
||||
{
|
||||
FaceDistanceContainer[] results;
|
||||
FaceDistance faceDistance;
|
||||
int normalizedPixelPercentage;
|
||||
FaceDistanceContainer faceDistanceContainer;
|
||||
List<FaceDistanceContainer> collection = new();
|
||||
foreach (Face face in faces)
|
||||
{
|
||||
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
|
||||
throw new NotSupportedException();
|
||||
normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
|
||||
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
||||
faceDistance = new(face.Location.Confidence, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedPixelPercentage);
|
||||
else
|
||||
{
|
||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||
faceDistance = new(face.Location.Confidence, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedPixelPercentage);
|
||||
lock (faces)
|
||||
face.SetFaceDistance(faceDistance);
|
||||
}
|
||||
faceDistanceContainer = new(face, faceDistance);
|
||||
collection.Add(faceDistanceContainer);
|
||||
}
|
||||
results = GetOrderedFaceDistanceContainers(collection);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<(Face Face, double Length)> GetValues(double faceDistanceTolerance, MappingFromItem mappingFromItem, List<Face> faces, string json)
|
||||
{
|
||||
List<(Face Face, double Length)> results = new();
|
||||
Face face;
|
||||
FaceDistance faceDistanceLength;
|
||||
Shared.Models.FaceEncoding? modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
|
||||
if (modelsFaceEncoding is null)
|
||||
throw new NotSupportedException();
|
||||
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
|
||||
FaceDistance faceDistanceEncoding = new(faceRecognitionDotNetFaceEncoding);
|
||||
FaceDistanceContainer[] faceDistanceContainers = GetOrderedFaceDistanceContainers(mappingFromItem, faces);
|
||||
int faceDistanceContainersLength = faceDistanceContainers.Length;
|
||||
if (faceDistanceContainersLength != faces.Count)
|
||||
throw new NotSupportedException();
|
||||
List<FaceDistance> faceDistanceEncodings = GetFaceDistanceEncodings(faceDistanceContainers);
|
||||
if (faceDistanceEncodings.Count != faces.Count)
|
||||
throw new NotSupportedException();
|
||||
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
|
||||
if (faceDistanceLengths.Count != faceDistanceContainersLength)
|
||||
throw new NotSupportedException();
|
||||
for (int i = 0; i < faces.Count; i++)
|
||||
{
|
||||
face = faces[i];
|
||||
faceDistanceLength = faceDistanceLengths[i];
|
||||
if (faceDistanceLength.Length is null)
|
||||
throw new NotSupportedException();
|
||||
if (faceDistanceLength.Length.Value > faceDistanceTolerance)
|
||||
continue;
|
||||
results.Add(new(face, faceDistanceLength.Length.Value));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Face[] GetMatchingFaces(double faceDistanceTolerance, MappingFromItem mappingFromItem, List<Face> faces, string json)
|
||||
{
|
||||
Face[] results;
|
||||
List<(Face Face, double Length)> collection = GetValues(faceDistanceTolerance, mappingFromItem, faces, json);
|
||||
if (!collection.Any())
|
||||
results = Array.Empty<Face>();
|
||||
else
|
||||
results = (from l in collection orderby l.Length select l.Face).Take(1).ToArray();
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Face[] GetMatchingFaces(int pixelDistanceTolerance, List<Face> faces)
|
||||
{
|
||||
Face[] results;
|
||||
int? x;
|
||||
int? y;
|
||||
double distance;
|
||||
double center = 2f;
|
||||
double xCenterValue;
|
||||
double yCenterValue;
|
||||
int normalizedPixelPercentage;
|
||||
string normalizedPixelPercentagePadded;
|
||||
List<(double Order, Face Face)> collection = new();
|
||||
foreach (Face face in faces)
|
||||
{
|
||||
if (face.Location is null || face.OutputResolution is null)
|
||||
throw new NotSupportedException();
|
||||
xCenterValue = (face.Location.Left + face.Location.Right) / center;
|
||||
yCenterValue = (face.Location.Top + face.Location.Bottom) / center;
|
||||
if (xCenterValue < face.Location.Left || xCenterValue > face.Location.Right)
|
||||
throw new Exception();
|
||||
if (yCenterValue < face.Location.Top || yCenterValue > face.Location.Bottom)
|
||||
throw new Exception();
|
||||
normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
|
||||
normalizedPixelPercentagePadded = Shared.Models.Stateless.Methods.ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
|
||||
(x, y) = Shared.Models.Stateless.Methods.ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution.Width, face.OutputResolution.Height, normalizedPixelPercentagePadded);
|
||||
if (x is null || y is null)
|
||||
throw new NotSupportedException();
|
||||
distance = Math.Sqrt(Math.Pow(xCenterValue - x.Value, 2) + Math.Pow(yCenterValue - y.Value, 2));
|
||||
collection.Add(new(distance, face));
|
||||
}
|
||||
if (!collection.Any())
|
||||
results = Array.Empty<Face>();
|
||||
else
|
||||
results = (from l in collection orderby l.Order where l.Order < pixelDistanceTolerance select l.Face).Take(1).ToArray();
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<Face> GetMatchingFaces(List<Face> faces, string? json)
|
||||
{
|
||||
List<Face> results = new();
|
||||
@ -485,12 +484,37 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
return result;
|
||||
}
|
||||
|
||||
public (int, int) GetUnableToMatchCountAndRenameMatches(string facesFileNameExtension, string eDistanceContentDirectory, List<string[]> duplicateMappedFaceFilesCollection, Item item, List<Face> faces, string[] mappedFaceFiles)
|
||||
private static List<Face> GetMatchingFaces(List<Face> faces, string[] mappedFaceFiles, List<int> debugChecks, int normalizedPixelPercentageValue, List<int> normalizedPixelPercentages, List<string> duplicateMappedFaceFiles, string mappedFaceFile)
|
||||
{
|
||||
List<Face> results = new();
|
||||
bool check;
|
||||
int normalizedPixelPercentage;
|
||||
foreach (Face face in faces)
|
||||
{
|
||||
if (face.Location is null || face.OutputResolution is null)
|
||||
throw new NotSupportedException();
|
||||
normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
|
||||
debugChecks.Add(normalizedPixelPercentage);
|
||||
if (normalizedPixelPercentage != normalizedPixelPercentageValue)
|
||||
continue;
|
||||
if (normalizedPixelPercentages.Contains(normalizedPixelPercentage))
|
||||
{
|
||||
duplicateMappedFaceFiles.AddRange(GetMatchingDuplicates(mappedFaceFiles, duplicateMappedFaceFiles, mappedFaceFile));
|
||||
continue;
|
||||
}
|
||||
check = true;
|
||||
results.Add(face);
|
||||
if (!check)
|
||||
debugChecks.Add(normalizedPixelPercentage);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public (int, int, int) GetUnableToMatchCountAndRenameMatches(string facesFileNameExtension, string eDistanceContentDirectory, Item item, List<Face> faces, string[] mappedFaceFiles)
|
||||
{
|
||||
int result = 0;
|
||||
int? id;
|
||||
string? json;
|
||||
bool debugCheck;
|
||||
int renamed = 0;
|
||||
bool? isWrongYear;
|
||||
FileInfo? fileInfo;
|
||||
@ -500,7 +524,6 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
List<int> debugChecks = new();
|
||||
int? normalizedPixelPercentage;
|
||||
MappingFromItem mappingFromItem;
|
||||
int normalizedPixelPercentageLoop;
|
||||
List<int> normalizedPixelPercentages;
|
||||
List<string> duplicateMappedFaceFiles = new();
|
||||
Dictionary<int, List<int>> idToNormalizedPixelPercentages = new();
|
||||
@ -513,10 +536,7 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
throw new NotSupportedException();
|
||||
if (duplicateMappedFaceFiles.Contains(mappedFaceFile))
|
||||
continue;
|
||||
(id, normalizedPixelPercentage, _) = Shared.Models.Stateless.Methods.IMapping.GetReversedDeterministicHashCodeKey(
|
||||
Shared.Models.Stateless.ILocation.Digits,
|
||||
facesFileNameExtension,
|
||||
mappedFaceFile);
|
||||
(id, normalizedPixelPercentage, _) = Shared.Models.Stateless.Methods.IMapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, mappedFaceFile);
|
||||
if (id is null || normalizedPixelPercentage is null)
|
||||
{
|
||||
result++;
|
||||
@ -526,34 +546,18 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
continue;
|
||||
if (item.Property?.Id is null || item.ImageFileHolder is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
if (faces.Any(l => l.FaceEncoding is null || l.Location is null || l.OutputResolution is null))
|
||||
continue;
|
||||
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
|
||||
mappingFromItem = new(item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.ResizedFileHolder);
|
||||
json = null;
|
||||
debugCheck = false;
|
||||
checkFaces.Clear();
|
||||
debugChecks.Clear();
|
||||
if (!idToNormalizedPixelPercentages.ContainsKey(id.Value))
|
||||
idToNormalizedPixelPercentages.Add(id.Value, new());
|
||||
normalizedPixelPercentages = idToNormalizedPixelPercentages[id.Value];
|
||||
foreach (Face face in faces)
|
||||
{
|
||||
if (face.Location is null || face.OutputResolution is null)
|
||||
throw new NotSupportedException();
|
||||
normalizedPixelPercentageLoop = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
|
||||
debugChecks.Add(normalizedPixelPercentageLoop);
|
||||
if (normalizedPixelPercentage.Value != normalizedPixelPercentageLoop)
|
||||
continue;
|
||||
if (normalizedPixelPercentages.Contains(normalizedPixelPercentageLoop))
|
||||
{
|
||||
duplicateMappedFaceFiles.AddRange(GetMatchingDuplicates(mappedFaceFiles, duplicateMappedFaceFiles, mappedFaceFile));
|
||||
continue;
|
||||
}
|
||||
debugCheck = true;
|
||||
checkFaces.Add(face);
|
||||
if (!debugCheck)
|
||||
debugChecks.Add(normalizedPixelPercentageLoop);
|
||||
}
|
||||
checkFaces.AddRange(GetMatchingFaces(faces, mappedFaceFiles, debugChecks, normalizedPixelPercentage.Value, normalizedPixelPercentages, duplicateMappedFaceFiles, mappedFaceFile));
|
||||
if (checkFaces.Count != 1)
|
||||
{
|
||||
checkFaces.Clear();
|
||||
@ -571,12 +575,7 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
{
|
||||
checkFaces.Clear();
|
||||
if (json is null)
|
||||
{
|
||||
result++;
|
||||
if (_DistanceMoveUnableToMatch)
|
||||
MoveUnableToMatch(eDistanceContentDirectory, mappedFaceFile);
|
||||
continue;
|
||||
}
|
||||
throw new NotSupportedException();
|
||||
checkFaces.AddRange(GetMatchingFaces(_FaceDistanceTolerance, mappingFromItem, faces, json));
|
||||
}
|
||||
if (checkFaces.Count != 1 && _DistancePixelDistanceTolerance > 0)
|
||||
@ -609,10 +608,9 @@ public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
}
|
||||
if (duplicateMappedFaceFiles.Any())
|
||||
{
|
||||
lock (duplicateMappedFaceFilesCollection)
|
||||
duplicateMappedFaceFilesCollection.Add(duplicateMappedFaceFiles.ToArray());
|
||||
duplicateMappedFaceFiles.Sort();
|
||||
}
|
||||
return new(result, renamed);
|
||||
return new(result, duplicateMappedFaceFiles.Count, renamed);
|
||||
}
|
||||
|
||||
}
|
@ -126,7 +126,6 @@ public class D_Face
|
||||
|
||||
private void SaveFaces(FileHolder resizedFileHolder, List<(Shared.Models.Face, FileInfo?, string)> collection)
|
||||
{
|
||||
int pixel;
|
||||
int width;
|
||||
int height;
|
||||
string json;
|
||||
@ -149,7 +148,6 @@ public class D_Face
|
||||
width = location.Right - location.Left;
|
||||
height = location.Bottom - location.Top;
|
||||
json = JsonSerializer.Serialize(face.FaceEncoding);
|
||||
pixel = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, ILocation.Digits, ILocation.Factor, face.OutputResolution);
|
||||
rectangle = new Rectangle(location.Left, location.Top, width, height);
|
||||
using (bitmap = new(width, height))
|
||||
{
|
||||
|
@ -131,7 +131,6 @@ public partial class DlibDotNet
|
||||
Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory);
|
||||
personContainers = Shared.Models.Stateless.Methods.IPersonContainer.GetPersonContainers(
|
||||
storage,
|
||||
configuration.LocationDigits,
|
||||
configuration.PersonBirthdayFormat,
|
||||
_Faces.FileNameExtension);
|
||||
}
|
||||
@ -349,7 +348,7 @@ public partial class DlibDotNet
|
||||
return result;
|
||||
}
|
||||
|
||||
private void FullParallelForWork(A_Property propertyLogic, string[] mappedFaceFiles, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string eDistanceContentDirectory, 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<Shared.Models.Face>?> imageFaceCollections, List<string[]> duplicateMappedFaceFilesCollection, Container container, int index, Item item)
|
||||
private void FullParallelForWork(A_Property propertyLogic, string[] mappedFaceFiles, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string eDistanceContentDirectory, 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<Shared.Models.Face>?> imageFaceCollections, Container container, int index, Item item)
|
||||
{
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
@ -425,7 +424,7 @@ public partial class DlibDotNet
|
||||
_Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faces);
|
||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(D_Face.SaveFaces));
|
||||
_ = _Distance.GetUnableToMatchCountAndRenameMatches(_Faces.FileNameExtension, eDistanceContentDirectory, duplicateMappedFaceFilesCollection, item, faces, mappedFaceFiles);
|
||||
_ = _Distance.GetUnableToMatchCountAndRenameMatches(_Faces.FileNameExtension, eDistanceContentDirectory, item, faces, mappedFaceFiles);
|
||||
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
@ -448,7 +447,23 @@ public partial class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private int FullParallelWork(int maxDegreeOfParallelism, A_Property propertyLogic, string[] mappedFaceFiles, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string eDistanceContentDirectory, 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<Shared.Models.Face>?> imageFaceCollections, List<string[]> duplicateMappedFaceFilesCollection, Container container, Item[] filteredItems, string message)
|
||||
private int FullParallelWork(int maxDegreeOfParallelism,
|
||||
A_Property propertyLogic,
|
||||
string[] mappedFaceFiles,
|
||||
string outputResolution,
|
||||
string bResultsFullGroupDirectory,
|
||||
string cResultsFullGroupDirectory,
|
||||
string dResultsFullGroupDirectory,
|
||||
string eDistanceContentDirectory,
|
||||
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<Shared.Models.Face>?> imageFaceCollections,
|
||||
Container container,
|
||||
Item[] filteredItems,
|
||||
string message)
|
||||
{
|
||||
if (_Log is null)
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
@ -488,7 +503,6 @@ public partial class DlibDotNet
|
||||
metadataCollection,
|
||||
resizeKeyValuePairs,
|
||||
imageFaceCollections,
|
||||
duplicateMappedFaceFilesCollection,
|
||||
container,
|
||||
index: i,
|
||||
filteredItems[i]);
|
||||
@ -751,7 +765,6 @@ public partial class DlibDotNet
|
||||
int containersLength = containers.Length;
|
||||
Shared.Models.Property[] propertyCollection;
|
||||
List<FileHolder?> propertyFileHolderCollection = new();
|
||||
List<string[]> duplicateMappedFaceFilesCollection = new();
|
||||
List<Dictionary<string, int[]>> resizeKeyValuePairs = new();
|
||||
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
|
||||
List<List<Shared.Models.Face>?> imageFaceCollections = new();
|
||||
@ -762,7 +775,6 @@ public partial class DlibDotNet
|
||||
{
|
||||
total = 0;
|
||||
_FileKeyValuePairs.Clear();
|
||||
duplicateMappedFaceFilesCollection.Clear();
|
||||
_FilePropertiesKeyValuePairs.Clear();
|
||||
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution);
|
||||
for (int i = 0; i < containers.Length; i++)
|
||||
@ -799,7 +811,6 @@ public partial class DlibDotNet
|
||||
metadataCollection,
|
||||
resizeKeyValuePairs,
|
||||
imageFaceCollections,
|
||||
duplicateMappedFaceFilesCollection,
|
||||
container,
|
||||
filteredItems,
|
||||
message);
|
||||
@ -836,11 +847,6 @@ public partial class DlibDotNet
|
||||
// break;
|
||||
total += container.Items.Count;
|
||||
}
|
||||
foreach (string[] duplicateMappedFaceFiles in duplicateMappedFaceFilesCollection)
|
||||
{
|
||||
foreach (string duplicateMappedFaceFile in duplicateMappedFaceFiles)
|
||||
_Log.Information(duplicateMappedFaceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
||||
if (rootResultsDirectory is null)
|
||||
throw new Exception();
|
||||
Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory);
|
||||
PersonContainer[] personContainers = Shared.Models.Stateless.Methods.IPersonContainer.GetPersonContainers(storage, _Configuration.LocationDigits, _Configuration.PersonBirthdayFormat, facesFileNameExtension);
|
||||
PersonContainer[] personContainers = Shared.Models.Stateless.Methods.IPersonContainer.GetPersonContainers(storage, _Configuration.PersonBirthdayFormat, facesFileNameExtension);
|
||||
string[] peopleBirthDates = (from l in personContainers select Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, l.Person.Birthday)).ToArray();
|
||||
Dictionary<string, string[]> sourceKeyValuePairs = JsonSerializer.Deserialize<Dictionary<string, string[]>>(json);
|
||||
foreach (KeyValuePair<string, string[]> keyValuePair in sourceKeyValuePairs)
|
||||
|
@ -723,7 +723,7 @@ public class MapLogic
|
||||
{
|
||||
if (!personDisplayDirectoryAllFile.EndsWith(_FacesFileNameExtension))
|
||||
continue;
|
||||
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(Shared.Models.Stateless.ILocation.Digits, _FacesFileNameExtension, personDisplayDirectoryAllFile);
|
||||
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(_FacesFileNameExtension, personDisplayDirectoryAllFile);
|
||||
if (id is null || normalizedPixelPercentage is null)
|
||||
continue;
|
||||
if (_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(id.Value, out keyValuePairs))
|
||||
|
@ -46,7 +46,7 @@ internal abstract class MapLogic
|
||||
{
|
||||
if (!personDisplayDirectoryAllFile.EndsWith(facesFileNameExtension))
|
||||
continue;
|
||||
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(Shared.Models.Stateless.ILocation.Digits, facesFileNameExtension, personDisplayDirectoryAllFile);
|
||||
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, personDisplayDirectoryAllFile);
|
||||
if (id is null || normalizedPixelPercentage is null)
|
||||
continue;
|
||||
if (!skipCollection.ContainsKey(id.Value))
|
||||
@ -148,7 +148,7 @@ internal abstract class MapLogic
|
||||
{
|
||||
if (file.EndsWith(".lnk") || file.EndsWith(".json"))
|
||||
continue;
|
||||
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(Shared.Models.Stateless.ILocation.Digits, facesFileNameExtension, file);
|
||||
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, file);
|
||||
if (id is null || normalizedPixelPercentage is null)
|
||||
continue;
|
||||
results.Add(new(personKeyFormatted, personDisplayDirectoryNames, file));
|
||||
@ -348,7 +348,6 @@ internal abstract class MapLogic
|
||||
{
|
||||
progressBar.Tick();
|
||||
(id, normalizedPixelPercentage, faces) = IMapping.GetReversedDeterministicHashCodeKey(
|
||||
Shared.Models.Stateless.ILocation.Digits,
|
||||
facesFileNameExtension,
|
||||
idToFacesAny,
|
||||
idToFaces,
|
||||
|
@ -3,24 +3,24 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
public interface IMapping
|
||||
{ // ...
|
||||
|
||||
(string?, string?, string?, bool?) TestStatic_GetSegments(int locationDigits, string facesFileNameExtension, string fileName)
|
||||
=> GetSegments(locationDigits, facesFileNameExtension, fileName);
|
||||
static (string?, string?, string?, bool?) GetSegments(int locationDigits, string facesFileNameExtension, string fileName)
|
||||
=> Mapping.GetSegments(locationDigits, facesFileNameExtension, fileName);
|
||||
(string?, string?, string?, bool?) TestStatic_GetSegments(string facesFileNameExtension, string fileName)
|
||||
=> GetSegments(facesFileNameExtension, fileName);
|
||||
static (string?, string?, string?, bool?) GetSegments(string facesFileNameExtension, string fileName)
|
||||
=> Mapping.GetSegments(facesFileNameExtension, fileName);
|
||||
|
||||
string TestStatic_GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution)
|
||||
=> GetDeterministicHashCodeKey(id, location, locationDigits, locationFactor, outputResolution);
|
||||
static string GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, int locationFactor, OutputResolution outputResolution)
|
||||
=> $"{id}.{ILocation.GetNormalizedPixelPercentage(location, locationDigits, locationFactor, outputResolution)}";
|
||||
=> $"{id}.{ILocation.GetLeftPadded(locationDigits, ILocation.GetNormalizedPixelPercentage(location, locationDigits, locationFactor, outputResolution))}";
|
||||
|
||||
(int?, int?, List<Models.Face>?) TestStatic_GetReversedDeterministicHashCodeKey(int locationDigits, string facesFileNameExtension, string file) =>
|
||||
GetReversedDeterministicHashCodeKey(locationDigits, facesFileNameExtension, file);
|
||||
static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(int locationDigits, string facesFileNameExtension, string file) =>
|
||||
Mapping.GetReversedDeterministicHashCodeKey(locationDigits, facesFileNameExtension, false, new(), file);
|
||||
(int?, int?, List<Models.Face>?) TestStatic_GetReversedDeterministicHashCodeKey(string facesFileNameExtension, string file) =>
|
||||
GetReversedDeterministicHashCodeKey(facesFileNameExtension, file);
|
||||
static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(string facesFileNameExtension, string file) =>
|
||||
Mapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, false, new(), file);
|
||||
|
||||
(int?, int?, List<Models.Face>?) TestStatic_GetReversedDeterministicHashCodeKey(int locationDigits, string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string file) =>
|
||||
GetReversedDeterministicHashCodeKey(locationDigits, facesFileNameExtension, idToFacesAny, idToFaces, file);
|
||||
static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(int locationDigits, string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string file) =>
|
||||
Mapping.GetReversedDeterministicHashCodeKey(locationDigits, facesFileNameExtension, idToFacesAny, idToFaces, file);
|
||||
(int?, int?, List<Models.Face>?) TestStatic_GetReversedDeterministicHashCodeKey(string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string file) =>
|
||||
GetReversedDeterministicHashCodeKey(facesFileNameExtension, idToFacesAny, idToFaces, file);
|
||||
static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string file) =>
|
||||
Mapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, idToFacesAny, idToFaces, file);
|
||||
|
||||
}
|
@ -5,9 +5,9 @@ public interface IPersonContainer
|
||||
|
||||
// ...
|
||||
|
||||
Models.PersonContainer[] TestStatic_GetPersonContainers(Properties.IStorage storage, int locationDigits, string personBirthdayFormat, string facesFileNameExtension) =>
|
||||
GetPersonContainers(storage, locationDigits, personBirthdayFormat, facesFileNameExtension);
|
||||
static Models.PersonContainer[] GetPersonContainers(Properties.IStorage storage, int locationDigits, string personBirthdayFormat, string facesFileNameExtension) =>
|
||||
PersonContainer.GetPersonContainers(storage, locationDigits, personBirthdayFormat, facesFileNameExtension);
|
||||
Models.PersonContainer[] TestStatic_GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat, string facesFileNameExtension) =>
|
||||
GetPersonContainers(storage, personBirthdayFormat, facesFileNameExtension);
|
||||
static Models.PersonContainer[] GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat, string facesFileNameExtension) =>
|
||||
PersonContainer.GetPersonContainers(storage, personBirthdayFormat, facesFileNameExtension);
|
||||
|
||||
}
|
@ -52,9 +52,9 @@ internal abstract class Location
|
||||
{
|
||||
int result;
|
||||
Check(bottom, height, left, right, top, width, zCount);
|
||||
long check;
|
||||
int checksum;
|
||||
decimal center = 2m;
|
||||
string xCenterPadded;
|
||||
string yCenterPadded;
|
||||
decimal factor = locationFactor;
|
||||
// int.MaxPercentage = 21 4748 3647;
|
||||
@ -73,15 +73,14 @@ internal abstract class Location
|
||||
decimal yCenterPercentageFactored = yCenterValue / height * factor;
|
||||
int xCenterRounded = (int)Math.Round(xCenterPercentageFactored, 0);
|
||||
int yCenterRounded = (int)Math.Round(yCenterPercentageFactored, 0);
|
||||
if (xCenterRounded != factor)
|
||||
xCenterPadded = ILocation.GetLeftPadded(length, xCenterRounded);
|
||||
else
|
||||
xCenterPadded = ILocation.GetLeftPadded(length, xCenterRounded - 1);
|
||||
if (yCenterRounded != factor)
|
||||
yCenterPadded = ILocation.GetLeftPadded(length, yCenterRounded);
|
||||
else
|
||||
yCenterPadded = ILocation.GetLeftPadded(length, yCenterRounded - 1);
|
||||
long check = long.Parse(string.Concat(xCenterPadded, yCenterPadded, checksum));
|
||||
if (xCenterRounded != factor)
|
||||
check = long.Parse(string.Concat(xCenterRounded, yCenterPadded, checksum));
|
||||
else
|
||||
check = long.Parse(string.Concat(xCenterRounded - 1, yCenterPadded, checksum));
|
||||
if (check > int.MaxValue)
|
||||
throw new Exception();
|
||||
result = (int)check;
|
||||
|
@ -3,7 +3,7 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
internal abstract class Mapping
|
||||
{
|
||||
|
||||
internal static (string?, string?, string?, bool?) GetSegments(int locationDigits, string facesFileNameExtension, string fileName)
|
||||
internal static (string?, string?, string?, bool?) GetSegments(string facesFileNameExtension, string fileName)
|
||||
{
|
||||
string[] segments = fileName.Split('.');
|
||||
string? id;
|
||||
@ -21,18 +21,18 @@ internal abstract class Mapping
|
||||
{
|
||||
id = segments[0];
|
||||
extensionLowered = $".{segments[2]}";
|
||||
normalizedPixelPercentage = segments[1];
|
||||
needsFacesFileNameExtension = segments.Length == 3;
|
||||
normalizedPixelPercentage = segments[1].Length == locationDigits ? segments[1] : null;
|
||||
}
|
||||
return new(id, normalizedPixelPercentage, extensionLowered, needsFacesFileNameExtension);
|
||||
}
|
||||
|
||||
private static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKeysFromSegments(int locationDigits, string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string fileName)
|
||||
private static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKeysFromSegments(string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string fileName)
|
||||
{
|
||||
int? id;
|
||||
List<Models.Face>? faces;
|
||||
int? normalizedPixelPercentage;
|
||||
(string? Id, string? NormalizedPixelPercentage, string? ExtensionLowered, bool? Check) segments = GetSegments(locationDigits, facesFileNameExtension, fileName);
|
||||
(string? Id, string? NormalizedPixelPercentage, string? ExtensionLowered, bool? Check) segments = GetSegments(facesFileNameExtension, fileName);
|
||||
if (string.IsNullOrEmpty(segments.Id) || string.IsNullOrEmpty(segments.NormalizedPixelPercentage) || string.IsNullOrEmpty(segments.ExtensionLowered) || segments.Check is null)
|
||||
{
|
||||
id = null;
|
||||
@ -48,7 +48,7 @@ internal abstract class Mapping
|
||||
else
|
||||
{
|
||||
id = idValue;
|
||||
normalizedPixelPercentage = segments.NormalizedPixelPercentage.Length == locationDigits ? normalizedPixelPercentageValue : null;
|
||||
normalizedPixelPercentage = normalizedPixelPercentageValue;
|
||||
if (!idToFacesAny || !idToFaces.ContainsKey(idValue))
|
||||
faces = null;
|
||||
else
|
||||
@ -57,7 +57,7 @@ internal abstract class Mapping
|
||||
return new(id, normalizedPixelPercentage, faces);
|
||||
}
|
||||
|
||||
internal static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(int locationDigits, string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string file)
|
||||
internal static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(string facesFileNameExtension, bool idToFacesAny, Dictionary<int, List<Models.Face>> idToFaces, string file)
|
||||
{
|
||||
int? id;
|
||||
List<Models.Face>? faces;
|
||||
@ -71,7 +71,6 @@ internal abstract class Mapping
|
||||
}
|
||||
else
|
||||
(id, normalizedPixelPercentage, faces) = GetReversedDeterministicHashCodeKeysFromSegments(
|
||||
locationDigits,
|
||||
facesFileNameExtension,
|
||||
idToFacesAny,
|
||||
idToFaces,
|
||||
|
@ -3,7 +3,7 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
internal abstract class PersonContainer
|
||||
{
|
||||
|
||||
private static string[] GetFiles(int locationDigits, string facesFileNameExtension, string personDisplayDirectory)
|
||||
private static string[] GetFiles(string facesFileNameExtension, string personDisplayDirectory)
|
||||
{
|
||||
string[] results = Directory.GetFiles(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
int? id;
|
||||
@ -14,7 +14,7 @@ internal abstract class PersonContainer
|
||||
{
|
||||
if (personDisplayDirectoryAllFile.EndsWith(".lnk"))
|
||||
continue;
|
||||
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(locationDigits, facesFileNameExtension, personDisplayDirectoryAllFile);
|
||||
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(facesFileNameExtension, personDisplayDirectoryAllFile);
|
||||
if (id is not null && normalizedPixelPercentage is not null && !personDisplayDirectoryAllFile.EndsWith(".json"))
|
||||
continue;
|
||||
checkDirectory = Path.GetDirectoryName(personDisplayDirectoryAllFile);
|
||||
@ -33,7 +33,7 @@ internal abstract class PersonContainer
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<(long?, Models.PersonContainer)> GetPersonContainersCollections(int locationDigits, string personBirthdayFormat, string facesFileNameExtension, char[] chars, string personDisplayDirectory, string personDisplayDirectoryName, string[] personKeyDirectories, int? approximateYears, List<Models.PersonBirthday> collections)
|
||||
private static List<(long?, Models.PersonContainer)> GetPersonContainersCollections(string personBirthdayFormat, string facesFileNameExtension, char[] chars, string personDisplayDirectory, string personDisplayDirectoryName, string[] personKeyDirectories, int? approximateYears, List<Models.PersonBirthday> collections)
|
||||
{
|
||||
List<(long?, Models.PersonContainer)> results = new();
|
||||
long personKey;
|
||||
@ -44,7 +44,7 @@ internal abstract class PersonContainer
|
||||
Models.PersonBirthday? personBirthday;
|
||||
Models.PersonContainer personContainer;
|
||||
Models.PersonBirthday[] personBirthdays = collections.OrderByDescending(l => l.Value).ToArray();
|
||||
string[] personDisplayDirectoryAllFiles = GetFiles(locationDigits, facesFileNameExtension, personDisplayDirectory);
|
||||
string[] personDisplayDirectoryAllFiles = GetFiles(facesFileNameExtension, personDisplayDirectory);
|
||||
foreach (string personKeyDirectory in personKeyDirectories)
|
||||
{
|
||||
personKeyFormatted = Path.GetFileName(personKeyDirectory);
|
||||
@ -60,15 +60,15 @@ internal abstract class PersonContainer
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Models.PersonContainer GetPersonContainer(int locationDigits, string facesFileNameExtension, string personDisplayDirectory, string personDisplayDirectoryName, int? approximateYears)
|
||||
private static Models.PersonContainer GetPersonContainer(string facesFileNameExtension, string personDisplayDirectory, string personDisplayDirectoryName, int? approximateYears)
|
||||
{
|
||||
Models.PersonContainer result;
|
||||
string[] personDisplayDirectoryAllFiles = GetFiles(locationDigits, facesFileNameExtension, personDisplayDirectory);
|
||||
string[] personDisplayDirectoryAllFiles = GetFiles(facesFileNameExtension, personDisplayDirectory);
|
||||
result = new(approximateYears, personDisplayDirectoryAllFiles, personDisplayDirectoryName);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<(long?, Models.PersonContainer)> GetPersonContainersGroup(int locationDigits, string personBirthdayFormat, string facesFileNameExtension, char[] chars, string[] personDisplayDirectories)
|
||||
private static List<(long?, Models.PersonContainer)> GetPersonContainersGroup(string personBirthdayFormat, string facesFileNameExtension, char[] chars, string[] personDisplayDirectories)
|
||||
{
|
||||
List<(long?, Models.PersonContainer)> results = new();
|
||||
int? approximateYears;
|
||||
@ -85,17 +85,17 @@ internal abstract class PersonContainer
|
||||
personKeyDirectories = Directory.GetDirectories(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
collections = PersonBirthday.GetPersonBirthdays(personBirthdayFormat, personKeyDirectories, personDisplayDirectory);
|
||||
if (collections.Any())
|
||||
results.AddRange(GetPersonContainersCollections(locationDigits, personBirthdayFormat, facesFileNameExtension, chars, personDisplayDirectory, personDisplayDirectoryName, personKeyDirectories, approximateYears, collections));
|
||||
results.AddRange(GetPersonContainersCollections(personBirthdayFormat, facesFileNameExtension, chars, personDisplayDirectory, personDisplayDirectoryName, personKeyDirectories, approximateYears, collections));
|
||||
else
|
||||
{
|
||||
personContainer = GetPersonContainer(locationDigits, facesFileNameExtension, personDisplayDirectory, personDisplayDirectoryName, approximateYears);
|
||||
personContainer = GetPersonContainer(facesFileNameExtension, personDisplayDirectory, personDisplayDirectoryName, approximateYears);
|
||||
results.Add(new(null, personContainer));
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Models.PersonContainer[] GetPersonContainersGroups(int locationDigits, string personBirthdayFormat, string facesFileNameExtension, char[] chars, string[] groupDirectories)
|
||||
private static Models.PersonContainer[] GetPersonContainersGroups(string personBirthdayFormat, string facesFileNameExtension, char[] chars, string[] groupDirectories)
|
||||
{
|
||||
Models.PersonContainer[] results;
|
||||
const int zero = 0;
|
||||
@ -109,14 +109,14 @@ internal abstract class PersonContainer
|
||||
if (!chars.Contains(groupDirectoryName[zero]))
|
||||
continue;
|
||||
personDisplayDirectories = Directory.GetDirectories(groupDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
collection = GetPersonContainersGroup(locationDigits, personBirthdayFormat, facesFileNameExtension, chars, personDisplayDirectories);
|
||||
collection = GetPersonContainersGroup(personBirthdayFormat, facesFileNameExtension, chars, personDisplayDirectories);
|
||||
personContainers.AddRange(collection);
|
||||
}
|
||||
results = (from l in personContainers orderby l.PersonKey is not null, l.PersonKey select l.PersonContainer).ToArray();
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static Models.PersonContainer[] GetPersonContainers(Properties.IStorage storage, int locationDigits, string personBirthdayFormat, string facesFileNameExtension)
|
||||
internal static Models.PersonContainer[] GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat, string facesFileNameExtension)
|
||||
{
|
||||
Models.PersonContainer[] results;
|
||||
char[] chars = IAge.GetChars();
|
||||
@ -134,7 +134,7 @@ internal abstract class PersonContainer
|
||||
if (!groupDirectories.Any())
|
||||
results = Array.Empty<Models.PersonContainer>();
|
||||
else
|
||||
results = GetPersonContainersGroups(locationDigits, personBirthdayFormat, facesFileNameExtension, chars, groupDirectories);
|
||||
results = GetPersonContainersGroups(personBirthdayFormat, facesFileNameExtension, chars, groupDirectories);
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -370,6 +370,36 @@ public class UnitTestCalculations
|
||||
Assert.IsTrue(y.HasValue && y.Value == 641);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestGetPixelPercentageF()
|
||||
{
|
||||
int? x, y;
|
||||
int normalizedPixelPercentage;
|
||||
int bottom, height, left, right, top, width;
|
||||
string normalizedPixelPercentagePadded;
|
||||
width = 2048;
|
||||
height = 1365;
|
||||
normalizedPixelPercentagePadded = "617214031";
|
||||
(x, y) = ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, width, height, normalizedPixelPercentagePadded);
|
||||
if (x is null || y is null)
|
||||
throw new Exception();
|
||||
Assert.IsTrue(x.Value == 1264);
|
||||
Assert.IsTrue(y.Value == 192);
|
||||
left = x.Value;
|
||||
right = x.Value;
|
||||
top = y.Value;
|
||||
bottom = y.Value;
|
||||
normalizedPixelPercentage = ILocation.GetNormalizedPixelPercentage(bottom, height, left, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, right, top, width);
|
||||
Assert.IsTrue(normalizedPixelPercentage == 617214071);
|
||||
double x1, x2, y1, y2;
|
||||
x1 = x.Value;
|
||||
x2 = x.Value;
|
||||
y1 = y.Value;
|
||||
y2 = y.Value - 3;
|
||||
double distance = Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2));
|
||||
Assert.IsTrue(distance == 3);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestGetDistance()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user