Split out classes
This commit is contained in:
parent
fb1c68e1f5
commit
e64c713926
3
.txt
3
.txt
@ -1,5 +1,8 @@
|
||||
mklink /J "L:\Git\View-by-Distance-MKLink-Console\Compare" "L:\Git\View-by-Distance\Compare"
|
||||
mklink /J "L:\Git\View-by-Distance-MKLink-Console\Date-Group" "L:\Git\View-by-Distance\Date-Group"
|
||||
mklink /J "L:\Git\View-by-Distance-MKLink-Console\Distance" "L:\Git\View-by-Distance\Distance"
|
||||
mklink /J "L:\Git\View-by-Distance-MKLink-Console\Face" "L:\Git\View-by-Distance\Face"
|
||||
mklink /J "L:\Git\View-by-Distance-MKLink-Console\FaceParts" "L:\Git\View-by-Distance\FaceParts"
|
||||
mklink /J "L:\Git\View-by-Distance-MKLink-Console\Instance" "L:\Git\View-by-Distance\Instance"
|
||||
mklink /J "L:\Git\View-by-Distance-MKLink-Console\Metadata" "L:\Git\View-by-Distance\Metadata"
|
||||
mklink /J "L:\Git\View-by-Distance-MKLink-Console\Not-Copy-Copy" "L:\Git\View-by-Distance\Not-Copy-Copy"
|
||||
|
@ -55,9 +55,10 @@ public class Compare
|
||||
string outputExtension = ".jpg";
|
||||
PredictorModel? predictorModel = null;
|
||||
string eResultsFullGroupDirectory = string.Empty;
|
||||
string a2PeopleSingletonDirectory = string.Empty;
|
||||
Map.Models.Configuration? mapConfiguration = null;
|
||||
Shared.Models.PersonContainer[] personContainers = Array.Empty<Shared.Models.PersonContainer>();
|
||||
Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, propertyConfiguration, mapConfiguration, outputExtension, ticks, personContainers, eResultsFullGroupDirectory);
|
||||
Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, propertyConfiguration, mapConfiguration, outputExtension, ticks, personContainers, a2PeopleSingletonDirectory, eResultsFullGroupDirectory);
|
||||
A_Property propertyLogic = GetPropertyLogic(reverse, model, outputExtension, predictorModel, mapLogic);
|
||||
foreach (string spelling in configuration.Spelling)
|
||||
{
|
||||
|
@ -79,7 +79,7 @@
|
||||
"/zzz Phares Slides/Slides 2015-06-10/Magazine 01"
|
||||
],
|
||||
"Configuration": {
|
||||
"DateGroup": "2022-09-15",
|
||||
"DateGroup": "2022-09-22",
|
||||
"DiffPropertyDirectory": "",
|
||||
"FileNameDirectorySeparator": ".Z.",
|
||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||
@ -87,20 +87,20 @@
|
||||
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
||||
"PopulatePropertyId": true,
|
||||
"PropertiesChangedForProperty": false,
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-09-15 - 7390c13 - III",
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-09-22 - fb1c68e - III",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF"
|
||||
],
|
||||
"PropertyContentCollectionFiles": [
|
||||
"/Images 2022-09-15 - 7390c13 - III - Results/A) Property/2022-09-15/[()]/637869381676042455.json",
|
||||
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869733124119330.json",
|
||||
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869734240700328.json",
|
||||
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869734970730630.json",
|
||||
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869743752078399.json",
|
||||
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-09-15/[()]/637869744751177715.json",
|
||||
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-09-15/[()]/637869745134124462.json"
|
||||
"/Images 2022-09-22 - fb1c68e - III - Results/A) Property/2022-09-22/[()]/637869381676042455.json",
|
||||
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869733124119330.json",
|
||||
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869734240700328.json",
|
||||
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869734970730630.json",
|
||||
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869743752078399.json",
|
||||
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-09-22/[()]/637869744751177715.json",
|
||||
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-09-22/[()]/637869745134124462.json"
|
||||
],
|
||||
"ValidImageFormatExtensions": [
|
||||
".bmp",
|
||||
|
@ -50,7 +50,7 @@
|
||||
"WorkingDirectoryName": "PharesApps",
|
||||
"Windows": {
|
||||
"Configuration": {
|
||||
"DateGroup": "2022-09-15",
|
||||
"DateGroup": "2022-09-22",
|
||||
"DiffPropertyDirectory": "",
|
||||
"FileNameDirectorySeparator": ".Z.",
|
||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||
@ -94,13 +94,13 @@
|
||||
".GIF"
|
||||
],
|
||||
"PropertyContentCollectionFiles": [
|
||||
"/Images 2022-09-15 - 7390c13 - III - Results/A) Property/2022-09-15/[()]/637869381676042455.json",
|
||||
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869733124119330.json",
|
||||
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869734240700328.json",
|
||||
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869734970730630.json",
|
||||
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-09-15/[()]/637869743752078399.json",
|
||||
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-09-15/[()]/637869744751177715.json",
|
||||
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-09-15/[()]/637869745134124462.json"
|
||||
"/Images 2022-09-22 - fb1c68e - III - Results/A) Property/2022-09-22/[()]/637869381676042455.json",
|
||||
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869733124119330.json",
|
||||
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869734240700328.json",
|
||||
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869734970730630.json",
|
||||
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-09-22/[()]/637869743752078399.json",
|
||||
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-09-22/[()]/637869744751177715.json",
|
||||
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-09-22/[()]/637869745134124462.json"
|
||||
],
|
||||
"ValidImageFormatExtensions": [
|
||||
".bmp",
|
||||
|
@ -55,7 +55,7 @@
|
||||
"ByHash": false,
|
||||
"BySeason": false,
|
||||
"ByWeek": false,
|
||||
"DateGroup": "2022-09-15",
|
||||
"DateGroup": "2022-09-22",
|
||||
"FileNameDirectorySeparator": ".Z.",
|
||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||
"KeepFullPath": false,
|
||||
@ -63,7 +63,7 @@
|
||||
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
||||
"PopulatePropertyId": true,
|
||||
"PropertiesChangedForProperty": false,
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-09-15 - 7390c13 - III",
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-09-22 - fb1c68e - III",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
|
52
Distance/Distance.csproj
Normal file
52
Distance/Distance.csproj
Normal file
@ -0,0 +1,52 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>library</OutputType>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PackageId>Phares.View.by.Distance.Distance</PackageId>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<Version>6.0.100.1</Version>
|
||||
<Authors>Mike Phares</Authors>
|
||||
<Company>Phares</Company>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
|
||||
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
|
||||
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsWindows)'=='true'">
|
||||
<DefineConstants>Windows</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsOSX)'=='true'">
|
||||
<DefineConstants>OSX</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsLinux)'=='true'">
|
||||
<DefineConstants>Linux</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
|
||||
<SupportedPlatform Include="browser" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Humanizer.Core" Version="2.13.14" />
|
||||
<PackageReference Include="MetadataExtractor" Version="2.7.1" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="ShellProgressBar" Version="5.1.0" />
|
||||
<PackageReference Include="WindowsShortcutFactory" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Text.Json" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />
|
||||
<ProjectReference Include="..\Property\Property.csproj" />
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
<ProjectReference Include="..\Map\Map.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
10
Distance/Models/Stateless/SerilogExtensionMethods.cs
Normal file
10
Distance/Models/Stateless/SerilogExtensionMethods.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace View_by_Distance.Distance.Models.Stateless;
|
||||
|
||||
internal static class SerilogExtensionMethods
|
||||
{
|
||||
|
||||
internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate);
|
||||
|
||||
internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate);
|
||||
|
||||
}
|
@ -5,12 +5,12 @@ using View_by_Distance.Map.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
namespace View_by_Distance.Distance.Models;
|
||||
|
||||
internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
public class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
{
|
||||
|
||||
internal static void SaveFaceDistances(Property.Models.Configuration propertyConfiguration, string eResultsFullGroupDirectory, SortingContainer[] sortingContainers)
|
||||
public static void SaveFaceDistances(Property.Models.Configuration propertyConfiguration, string eResultsFullGroupDirectory, SortingContainer[] sortingContainers)
|
||||
{
|
||||
string eDistanceContentCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, "([])");
|
||||
if (!Directory.Exists(eDistanceContentCollectionDirectory))
|
||||
@ -22,7 +22,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
File.WriteAllLines(eDistanceContentFileName, results);
|
||||
}
|
||||
|
||||
private static List<Sorting> GetSortingCollection(Map.Models.Configuration configuration, MapLogic mapLogic, List<FaceDistance> faceDistanceEncodings, int faceDistanceContainersLength, int i, FaceDistance faceDistanceEncoding)
|
||||
private static List<Sorting> GetSortingCollection(Configuration configuration, MapLogic mapLogic, List<FaceDistance> faceDistanceEncodings, int faceDistanceContainersLength, int i, FaceDistance faceDistanceEncoding)
|
||||
{
|
||||
List<Sorting> results;
|
||||
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
|
||||
@ -33,7 +33,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<SortingContainer> GetSortingContainers(Map.Models.Configuration configuration, Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection)
|
||||
private static List<SortingContainer> GetSortingContainers(Configuration configuration, Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection)
|
||||
{
|
||||
List<SortingContainer> results = new();
|
||||
SortingContainer sortingContainer;
|
||||
@ -64,7 +64,29 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
return faceDistanceEncodings;
|
||||
}
|
||||
|
||||
internal static SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, Map.Models.Configuration configuration, long ticks, MapLogic mapLogic, List<Face> selectedFilteredFaces)
|
||||
private static FaceDistanceContainer[] GetFaceDistanceContainers(List<Face> selectedFilteredFaces)
|
||||
{
|
||||
FaceDistanceContainer[] results;
|
||||
FaceDistance faceDistance;
|
||||
FaceDistanceContainer faceDistanceContainer;
|
||||
List<FaceDistanceContainer> collection = new();
|
||||
foreach (Face face in selectedFilteredFaces)
|
||||
{
|
||||
if (face.Mapping is null)
|
||||
throw new NotSupportedException();
|
||||
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
||||
continue;
|
||||
faceDistance = new(face.Mapping.MappingFromLocation.Confidence, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
|
||||
faceDistanceContainer = new(face, faceDistance);
|
||||
collection.Add(faceDistanceContainer);
|
||||
}
|
||||
results = (from l in collection orderby l.FaceDistance.Encoding is not null select l).ToArray();
|
||||
if (results.Any() && results[0].FaceDistance.Encoding is null)
|
||||
throw new Exception("Sorting failed!");
|
||||
return results;
|
||||
}
|
||||
|
||||
public static SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, MapLogic mapLogic, List<Face> selectedFilteredFaces)
|
||||
{
|
||||
SortingContainer[] results;
|
||||
List<SortingContainer> collection = new();
|
||||
@ -94,29 +116,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
return results;
|
||||
}
|
||||
|
||||
private static FaceDistanceContainer[] GetFaceDistanceContainers(List<Face> selectedFilteredFaces)
|
||||
{
|
||||
FaceDistanceContainer[] results;
|
||||
FaceDistance faceDistance;
|
||||
FaceDistanceContainer faceDistanceContainer;
|
||||
List<FaceDistanceContainer> collection = new();
|
||||
foreach (Face face in selectedFilteredFaces)
|
||||
{
|
||||
if (face.Mapping is null)
|
||||
throw new NotSupportedException();
|
||||
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
||||
continue;
|
||||
faceDistance = new(face.Mapping.MappingFromLocation.Confidence, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
|
||||
faceDistanceContainer = new(face, faceDistance);
|
||||
collection.Add(faceDistanceContainer);
|
||||
}
|
||||
results = (from l in collection orderby l.FaceDistance.Encoding is not null select l).ToArray();
|
||||
if (results.Any() && results[0].FaceDistance.Encoding is null)
|
||||
throw new Exception("Sorting failed!");
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static List<Face> GetSelectedFilteredFaces(List<Face> distinctFilteredFaces)
|
||||
public static List<Face> GetSelectedFilteredFaces(List<Face> distinctFilteredFaces)
|
||||
{
|
||||
List<Face> results;
|
||||
Face[] orderedFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromItem.MinimumDateTime descending select l).ToArray();
|
||||
@ -124,7 +124,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, List<Face> selectedFilteredFaces)
|
||||
public static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, List<Face> selectedFilteredFaces)
|
||||
{
|
||||
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
||||
@ -186,7 +186,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
return results;
|
||||
}
|
||||
|
||||
void Shared.Models.Methods.IFaceDistance.SavePossiblyNewPersonContainers(IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, string facesFileNameExtension, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||
void Shared.Models.Methods.IFaceDistance.SavePossiblyNewPersonContainers(IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, string facesFileNameExtension, string a2PeopleSingletonDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||
{
|
||||
char @char;
|
||||
string json;
|
||||
@ -202,7 +202,6 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
||||
string checkPersonKeyFormattedDirectory;
|
||||
char[] chars = Shared.Models.Stateless.Methods.IAge.GetChars();
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
|
||||
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People), "{}");
|
||||
foreach ((string[] personDisplayDirectoryNames, PersonContainer personContainer) in possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||
{
|
||||
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
|
49
Face/Face.csproj
Normal file
49
Face/Face.csproj
Normal file
@ -0,0 +1,49 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>library</OutputType>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PackageId>Phares.View.by.Distance.Face</PackageId>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<Version>6.0.100.1</Version>
|
||||
<Authors>Mike Phares</Authors>
|
||||
<Company>Phares</Company>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
|
||||
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
|
||||
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsWindows)'=='true'">
|
||||
<DefineConstants>Windows</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsOSX)'=='true'">
|
||||
<DefineConstants>OSX</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsLinux)'=='true'">
|
||||
<DefineConstants>Linux</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
|
||||
<SupportedPlatform Include="browser" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Text.Json" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />
|
||||
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
||||
<ProjectReference Include="..\Property\Property.csproj" />
|
||||
<ProjectReference Include="..\Resize\Resize.csproj" />
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
10
Face/Models/Stateless/SerilogExtensionMethods.cs
Normal file
10
Face/Models/Stateless/SerilogExtensionMethods.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace View_by_Distance.Face.Models.Stateless;
|
||||
|
||||
internal static class SerilogExtensionMethods
|
||||
{
|
||||
|
||||
internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate);
|
||||
|
||||
internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate);
|
||||
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
@ -11,7 +10,7 @@ using View_by_Distance.Resize.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
namespace View_by_Distance.Face.Models;
|
||||
|
||||
/// <summary>
|
||||
// List<D_Faces>
|
||||
@ -19,7 +18,7 @@ namespace View_by_Distance.Instance.Models;
|
||||
public class D_Face
|
||||
{
|
||||
|
||||
internal List<string> AngleBracketCollection { get; }
|
||||
public List<string> AngleBracketCollection { get; }
|
||||
|
||||
protected readonly string _FileNameExtension;
|
||||
public string FileNameExtension => _FileNameExtension;
|
||||
@ -40,21 +39,60 @@ public class D_Face
|
||||
private readonly EncoderParameters _HiddenEncoderParameters;
|
||||
private readonly JsonSerializerOptions _WriteIndentedAndWhenWritingNull;
|
||||
|
||||
internal D_Face(Configuration configuration, string argZero, Model model, ModelParameter modelParameter, PredictorModel predictorModel, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension, ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFileNameExtension)
|
||||
private readonly bool _CheckDFaceAndUpWriteDates;
|
||||
private readonly int _FaceDistanceHiddenImageFactor;
|
||||
private readonly bool _ForceFaceLastWriteTimeToCreationTime;
|
||||
private readonly int _LocationDigits;
|
||||
private readonly int _LocationFactor;
|
||||
private readonly int _NumberOfJitters;
|
||||
private readonly int _NumberOfTimesToUpsample;
|
||||
private readonly bool _OverrideForFaceImages;
|
||||
private readonly bool _PropertiesChangedForFaces;
|
||||
|
||||
public D_Face(
|
||||
string argZero,
|
||||
bool checkDFaceAndUpWriteDates,
|
||||
Configuration configuration,
|
||||
EncoderParameters encoderParameters,
|
||||
int faceDistanceHiddenImageFactor,
|
||||
string filenameExtension,
|
||||
bool forceFaceLastWriteTimeToCreationTime,
|
||||
EncoderParameters hiddenEncoderParameters,
|
||||
string hiddenFileNameExtension,
|
||||
ImageCodecInfo hiddenImageCodecInfo,
|
||||
ImageCodecInfo imageCodecInfo,
|
||||
int locationDigits,
|
||||
int locationFactor,
|
||||
Model model,
|
||||
ModelParameter modelParameter,
|
||||
int numberOfJitters,
|
||||
int numberOfTimesToUpsample,
|
||||
bool overrideForFaceImages,
|
||||
PredictorModel predictorModel,
|
||||
bool propertiesChangedForFaces)
|
||||
{
|
||||
_Model = model;
|
||||
_ArgZero = argZero;
|
||||
_Configuration = configuration;
|
||||
_ImageCodecInfo = imageCodecInfo;
|
||||
_LocationDigits = locationDigits;
|
||||
_LocationFactor = locationFactor;
|
||||
_ModelParameter = modelParameter;
|
||||
_PredictorModel = predictorModel;
|
||||
_NumberOfJitters = numberOfJitters;
|
||||
_EncoderParameters = encoderParameters;
|
||||
_FileNameExtension = filenameExtension;
|
||||
_Log = Serilog.Log.ForContext<D_Face>();
|
||||
AngleBracketCollection = new List<string>();
|
||||
_HiddenImageCodecInfo = hiddenImageCodecInfo;
|
||||
_OverrideForFaceImages = overrideForFaceImages;
|
||||
_HiddenEncoderParameters = hiddenEncoderParameters;
|
||||
_HiddenFileNameExtension = hiddenFileNameExtension;
|
||||
_NumberOfTimesToUpsample = numberOfTimesToUpsample;
|
||||
_CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
|
||||
_PropertiesChangedForFaces = propertiesChangedForFaces;
|
||||
_FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
|
||||
_ForceFaceLastWriteTimeToCreationTime = forceFaceLastWriteTimeToCreationTime;
|
||||
ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null);
|
||||
if (constructorInfo is null)
|
||||
throw new Exception();
|
||||
@ -62,25 +100,6 @@ public class D_Face
|
||||
_WriteIndentedAndWhenWritingNull = new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull };
|
||||
}
|
||||
|
||||
private static void GetPointBounds(PointF[] points, out float xMinimum, out float xMaximum, out float yMinimum, out float yMaximum)
|
||||
{
|
||||
xMinimum = points[0].X;
|
||||
xMaximum = xMinimum;
|
||||
yMinimum = points[0].Y;
|
||||
yMaximum = yMinimum;
|
||||
foreach (PointF point in points)
|
||||
{
|
||||
if (xMinimum > point.X)
|
||||
xMinimum = point.X;
|
||||
if (xMaximum < point.X)
|
||||
xMaximum = point.X;
|
||||
if (yMinimum > point.Y)
|
||||
yMinimum = point.Y;
|
||||
if (yMaximum < point.Y)
|
||||
yMaximum = point.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
@ -89,67 +108,6 @@ public class D_Face
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
internal static Bitmap RotateBitmap(Bitmap bitmap, float angle)
|
||||
{
|
||||
Bitmap result;
|
||||
#if Linux
|
||||
throw new Exception("Built on Linux!");
|
||||
#elif OSX
|
||||
throw new Exception("Built on macOS!");
|
||||
#elif Windows
|
||||
// Make a Matrix to represent rotation
|
||||
// by this angle.
|
||||
Matrix rotate_at_origin = new();
|
||||
rotate_at_origin.Rotate(angle);
|
||||
|
||||
// Rotate the image's corners to see how big
|
||||
// it will be after rotation.
|
||||
PointF[] points =
|
||||
{
|
||||
new PointF(0, 0),
|
||||
new PointF(bitmap.Width, 0),
|
||||
new PointF(bitmap.Width, bitmap.Height),
|
||||
new PointF(0, bitmap.Height),
|
||||
};
|
||||
rotate_at_origin.TransformPoints(points);
|
||||
float xMinimum, xMaximum, yMinimum, yMaximum;
|
||||
GetPointBounds(points, out xMinimum, out xMaximum, out yMinimum, out yMaximum);
|
||||
|
||||
// Make a bitmap to hold the rotated result.
|
||||
int wid = (int)Math.Round(xMaximum - xMinimum);
|
||||
int hgt = (int)Math.Round(yMaximum - yMinimum);
|
||||
result = new Bitmap(wid, hgt);
|
||||
|
||||
// Create the real rotation transformation.
|
||||
Matrix rotate_at_center = new();
|
||||
rotate_at_center.RotateAt(angle,
|
||||
new PointF(wid / 2f, hgt / 2f));
|
||||
|
||||
// Draw the image onto the new bitmap rotated.
|
||||
using (Graphics gr = Graphics.FromImage(result))
|
||||
{
|
||||
// Use smooth image interpolation.
|
||||
gr.InterpolationMode = InterpolationMode.High;
|
||||
|
||||
// Clear with the color in the image's upper left corner.
|
||||
gr.Clear(bitmap.GetPixel(0, 0));
|
||||
|
||||
// For debugging. (It's easier to see the background.)
|
||||
// gr.Clear(Color.LightBlue);
|
||||
|
||||
// Set up the transformation to rotate.
|
||||
gr.Transform = rotate_at_center;
|
||||
|
||||
// Draw the image centered on the bitmap.
|
||||
int x = (wid - bitmap.Width) / 2;
|
||||
int y = (hgt - bitmap.Height) / 2;
|
||||
gr.DrawImage(bitmap, x, y);
|
||||
}
|
||||
#endif
|
||||
// Return the result bitmap.
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] GetBytes(string value)
|
||||
{
|
||||
byte[] results = new byte[value.Length + 1];
|
||||
@ -170,7 +128,7 @@ public class D_Face
|
||||
return result;
|
||||
}
|
||||
|
||||
private void SaveFaces(FileHolder resizedFileHolder, List<(Face, FileInfo?, string)> collection)
|
||||
private void SaveFaces(FileHolder resizedFileHolder, List<(Shared.Models.Face, FileInfo?, string)> collection)
|
||||
{
|
||||
int pixel;
|
||||
int width;
|
||||
@ -181,23 +139,21 @@ public class D_Face
|
||||
Location? location;
|
||||
Rectangle rectangle;
|
||||
PropertyItem? propertyItem;
|
||||
int software = (int)IExif.Tags.Software;
|
||||
int userComment = (int)IExif.Tags.UserComment;
|
||||
using Bitmap source = new(resizedFileHolder.FullName);
|
||||
int imageDescription = (int)IExif.Tags.ImageDescription;
|
||||
foreach ((Face face, FileInfo? fileInfo, string fileName) in collection)
|
||||
foreach ((Shared.Models.Face face, FileInfo? fileInfo, string fileName) in collection)
|
||||
{
|
||||
if (fileInfo is null)
|
||||
continue;
|
||||
if (face.FaceEncoding is null || face?.Location?.NormalizedPixelPercentage is null || face?.OutputResolution is null)
|
||||
continue;
|
||||
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, _Configuration.LocationDigits, _Configuration.LocationFactor, source.Height, source.Width, collection.Count);
|
||||
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, _LocationDigits, _LocationFactor, source.Height, source.Width, collection.Count);
|
||||
if (location is null)
|
||||
continue;
|
||||
width = location.Right - location.Left;
|
||||
height = location.Bottom - location.Top;
|
||||
json = JsonSerializer.Serialize(face.FaceEncoding);
|
||||
pixel = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, _Configuration.LocationDigits, _Configuration.LocationFactor, face.OutputResolution);
|
||||
pixel = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, _LocationDigits, _LocationFactor, face.OutputResolution);
|
||||
rectangle = new Rectangle(location.Left, location.Top, width, height);
|
||||
using (bitmap = new(width, height))
|
||||
{
|
||||
@ -205,15 +161,11 @@ public class D_Face
|
||||
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||
propertyItem = GetPropertyItem(userComment, json);
|
||||
bitmap.SetPropertyItem(propertyItem);
|
||||
propertyItem = GetPropertyItem(imageDescription, pixel.ToString());
|
||||
bitmap.SetPropertyItem(propertyItem);
|
||||
propertyItem = GetPropertyItem(software, face.Location.NormalizedPixelPercentage.Value.ToString());
|
||||
bitmap.SetPropertyItem(propertyItem);
|
||||
bitmap.Save(fileInfo.FullName, _ImageCodecInfo, _EncoderParameters);
|
||||
}
|
||||
if (File.Exists(fileName))
|
||||
File.Delete(fileName);
|
||||
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(_Configuration.FaceDistanceHiddenImageFactor, face.Location, _Configuration.LocationDigits, _Configuration.LocationFactor, source.Height, source.Width, collection.Count);
|
||||
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(_FaceDistanceHiddenImageFactor, face.Location, _LocationDigits, _LocationFactor, source.Height, source.Width, collection.Count);
|
||||
if (location is null)
|
||||
continue;
|
||||
width = location.Right - location.Left;
|
||||
@ -229,9 +181,9 @@ public class D_Face
|
||||
}
|
||||
}
|
||||
|
||||
private List<Face> GetFaces(Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
|
||||
private List<Shared.Models.Face> GetFaces(Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
|
||||
{
|
||||
List<Face> results = new();
|
||||
List<Shared.Models.Face> results = new();
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
if (item.ResizedFileHolder is null)
|
||||
@ -251,14 +203,14 @@ public class D_Face
|
||||
else
|
||||
{
|
||||
List<(int, Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection;
|
||||
FaceRecognition faceRecognition = new(_Configuration.NumberOfTimesToUpsample, _Configuration.NumberOfJitters, _PredictorModel, _Model, _ModelParameter);
|
||||
FaceRecognition faceRecognition = new(_NumberOfTimesToUpsample, _NumberOfJitters, _PredictorModel, _Model, _ModelParameter);
|
||||
collection = faceRecognition.GetCollection(unknownImage, includeFaceEncoding: true, includeFaceParts: true, sortByNormalizedPixelPercentage: true);
|
||||
if (!collection.Any())
|
||||
results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null));
|
||||
else
|
||||
{
|
||||
Face face;
|
||||
double[] rawEncoding;
|
||||
Shared.Models.Face face;
|
||||
Shared.Models.FaceEncoding convertedFaceEncoding;
|
||||
foreach ((int locationIndex, Location location, FaceRecognitionDotNet.FaceEncoding? faceEncoding, Dictionary<FacePart, FacePoint[]>? faceParts) in collection)
|
||||
{
|
||||
@ -284,9 +236,9 @@ public class D_Face
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
internal List<Face> GetFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
|
||||
public List<Shared.Models.Face> GetFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
|
||||
{
|
||||
List<Face>? results;
|
||||
List<Shared.Models.Face>? results;
|
||||
if (item.Property?.Id is null)
|
||||
throw new NullReferenceException(nameof(item.Property.Id));
|
||||
if (item.ImageFileHolder is null)
|
||||
@ -299,7 +251,7 @@ public class D_Face
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
|
||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
string usingRelativePath = Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{item.ImageFileHolder.NameWithoutExtension}.json");
|
||||
string dCollectionFile = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.PropertyConfiguration.ResultAllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
|
||||
string dCollectionFile = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.ResultAllInOne, $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}.json");
|
||||
FileInfo fileInfo = new(dCollectionFile);
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
@ -320,31 +272,31 @@ public class D_Face
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_Configuration.ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
||||
if (_ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
||||
{
|
||||
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
||||
fileInfo.Refresh();
|
||||
}
|
||||
if (_Configuration.ForceFaceLastWriteTimeToCreationTime && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime)
|
||||
if (_ForceFaceLastWriteTimeToCreationTime && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime)
|
||||
{
|
||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
||||
fileInfo.Refresh();
|
||||
}
|
||||
if (_Configuration.PropertiesChangedForFaces)
|
||||
if (_PropertiesChangedForFaces)
|
||||
results = null;
|
||||
else if (!fileInfo.Exists)
|
||||
results = null;
|
||||
else if (_Configuration.CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
results = null;
|
||||
else
|
||||
{
|
||||
json = Shared.Models.Stateless.Methods.IFace.GetJson(fileInfo.FullName);
|
||||
try
|
||||
{
|
||||
results = JsonSerializer.Deserialize<List<Face>>(json);
|
||||
results = JsonSerializer.Deserialize<List<Shared.Models.Face>>(json);
|
||||
if (results is null)
|
||||
throw new NullReferenceException(nameof(results));
|
||||
if (!_Configuration.ForceFaceLastWriteTimeToCreationTime)
|
||||
if (!_ForceFaceLastWriteTimeToCreationTime)
|
||||
{
|
||||
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
|
||||
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
||||
@ -368,9 +320,9 @@ public class D_Face
|
||||
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now));
|
||||
}
|
||||
if (_Configuration.ForceFaceLastWriteTimeToCreationTime)
|
||||
if (_ForceFaceLastWriteTimeToCreationTime)
|
||||
{
|
||||
results = (from l in results select new Face(_Configuration.LocationDigits, _Configuration.LocationFactor, results.Count, l)).ToList();
|
||||
results = (from l in results select new Shared.Models.Face(_LocationDigits, _LocationFactor, results.Count, l)).ToList();
|
||||
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
|
||||
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
||||
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
|
||||
@ -388,7 +340,7 @@ public class D_Face
|
||||
return results;
|
||||
}
|
||||
|
||||
internal void SaveFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Face> faceCollection)
|
||||
public void SaveFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Shared.Models.Face> faceCollection)
|
||||
{
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
@ -398,14 +350,13 @@ public class D_Face
|
||||
bool check = false;
|
||||
string parentCheck;
|
||||
string deterministicHashCodeKeyDisplay;
|
||||
List<(Face, FileInfo?, string)> collection = new();
|
||||
List<(Shared.Models.Face, FileInfo?, string)> collection = new();
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
|
||||
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
|
||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
bool facesDirectoryExisted = Directory.Exists(facesDirectory);
|
||||
if (!facesDirectoryExisted)
|
||||
if (!Directory.Exists(facesDirectory))
|
||||
_ = Directory.CreateDirectory(facesDirectory);
|
||||
foreach (Face face in faceCollection)
|
||||
foreach (Shared.Models.Face face in faceCollection)
|
||||
{
|
||||
if (item.Property?.Id is null || face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
{
|
||||
@ -423,29 +374,15 @@ public class D_Face
|
||||
File.Delete(parentCheck);
|
||||
}
|
||||
collection.Add(new(face, fileInfo, Path.Combine(facesDirectory, $"{deterministicHashCodeKeyDisplay}{item.ImageFileHolder.ExtensionLowered}{_HiddenFileNameExtension}")));
|
||||
if (_Configuration.OverrideForFaceImages)
|
||||
if (_OverrideForFaceImages)
|
||||
check = true;
|
||||
else if (!fileInfo.Exists)
|
||||
check = true;
|
||||
else if (_Configuration.CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
check = true;
|
||||
}
|
||||
if (check)
|
||||
SaveFaces(item.ResizedFileHolder, collection);
|
||||
}
|
||||
|
||||
private static bool HasLeftAndRight(Dictionary<string, FacePoint[]> faceParts)
|
||||
{
|
||||
bool result = true;
|
||||
if (!faceParts.ContainsKey(FacePart.LeftEye.ToString()))
|
||||
result = false;
|
||||
else if (!faceParts.ContainsKey(FacePart.RightEye.ToString()))
|
||||
result = false;
|
||||
else if (!faceParts.ContainsKey(FacePart.LeftEyebrow.ToString()))
|
||||
result = false;
|
||||
else if (!faceParts.ContainsKey(FacePart.RightEyebrow.ToString()))
|
||||
result = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
50
FaceParts/FaceParts.csproj
Normal file
50
FaceParts/FaceParts.csproj
Normal file
@ -0,0 +1,50 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>library</OutputType>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PackageId>Phares.View.by.Distance.FaceParts</PackageId>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<Version>6.0.100.1</Version>
|
||||
<Authors>Mike Phares</Authors>
|
||||
<Company>Phares</Company>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
|
||||
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
|
||||
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsWindows)'=='true'">
|
||||
<DefineConstants>Windows</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsOSX)'=='true'">
|
||||
<DefineConstants>OSX</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsLinux)'=='true'">
|
||||
<DefineConstants>Linux</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
|
||||
<SupportedPlatform Include="browser" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Text.Json" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />
|
||||
<ProjectReference Include="..\Face\Face.csproj" />
|
||||
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
||||
<ProjectReference Include="..\Property\Property.csproj" />
|
||||
<ProjectReference Include="..\Resize\Resize.csproj" />
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
10
FaceParts/Models/Stateless/SerilogExtensionMethods.cs
Normal file
10
FaceParts/Models/Stateless/SerilogExtensionMethods.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace View_by_Distance.FaceParts.Models.Stateless;
|
||||
|
||||
internal static class SerilogExtensionMethods
|
||||
{
|
||||
|
||||
internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate);
|
||||
|
||||
internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate);
|
||||
|
||||
}
|
@ -1,35 +1,39 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Face.Models;
|
||||
using View_by_Distance.Metadata.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;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
namespace View_by_Distance.FaceParts.Models;
|
||||
|
||||
/// <summary>
|
||||
// *.png
|
||||
/// </summary>
|
||||
internal class D2_FaceParts
|
||||
public class D2_FaceParts
|
||||
{
|
||||
|
||||
protected readonly string _FileNameExtension;
|
||||
public string FileNameExtension => _FileNameExtension;
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly ImageCodecInfo _ImageCodecInfo;
|
||||
private readonly bool _CheckDFaceAndUpWriteDates;
|
||||
private readonly bool _OverrideForFaceLandmarkImages;
|
||||
private readonly EncoderParameters _EncoderParameters;
|
||||
|
||||
internal D2_FaceParts(Configuration configuration, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension)
|
||||
public D2_FaceParts(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension, bool checkDFaceAndUpWriteDates, bool overrideForFaceLandmarkImages)
|
||||
{
|
||||
_Configuration = configuration;
|
||||
_ImageCodecInfo = imageCodecInfo;
|
||||
_EncoderParameters = encoderParameters;
|
||||
_FileNameExtension = filenameExtension;
|
||||
_Log = Serilog.Log.ForContext<D2_FaceParts>();
|
||||
_CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
|
||||
_OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -38,19 +42,99 @@ internal class D2_FaceParts
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void GetPointBounds(PointF[] points, out float xMinimum, out float xMaximum, out float yMinimum, out float yMaximum)
|
||||
{
|
||||
xMinimum = points[0].X;
|
||||
xMaximum = xMinimum;
|
||||
yMinimum = points[0].Y;
|
||||
yMaximum = yMinimum;
|
||||
foreach (PointF point in points)
|
||||
{
|
||||
if (xMinimum > point.X)
|
||||
xMinimum = point.X;
|
||||
if (xMaximum < point.X)
|
||||
xMaximum = point.X;
|
||||
if (yMinimum > point.Y)
|
||||
yMinimum = point.Y;
|
||||
if (yMaximum < point.Y)
|
||||
yMaximum = point.Y;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
private static Bitmap RotateBitmap(Bitmap bitmap, float angle)
|
||||
{
|
||||
Bitmap result;
|
||||
#if Linux
|
||||
throw new Exception("Built on Linux!");
|
||||
#elif OSX
|
||||
throw new Exception("Built on macOS!");
|
||||
#elif Windows
|
||||
// Make a Matrix to represent rotation
|
||||
// by this angle.
|
||||
Matrix rotate_at_origin = new();
|
||||
rotate_at_origin.Rotate(angle);
|
||||
|
||||
// Rotate the image's corners to see how big
|
||||
// it will be after rotation.
|
||||
PointF[] points =
|
||||
{
|
||||
new PointF(0, 0),
|
||||
new PointF(bitmap.Width, 0),
|
||||
new PointF(bitmap.Width, bitmap.Height),
|
||||
new PointF(0, bitmap.Height),
|
||||
};
|
||||
rotate_at_origin.TransformPoints(points);
|
||||
float xMinimum, xMaximum, yMinimum, yMaximum;
|
||||
GetPointBounds(points, out xMinimum, out xMaximum, out yMinimum, out yMaximum);
|
||||
|
||||
// Make a bitmap to hold the rotated result.
|
||||
int wid = (int)Math.Round(xMaximum - xMinimum);
|
||||
int hgt = (int)Math.Round(yMaximum - yMinimum);
|
||||
result = new Bitmap(wid, hgt);
|
||||
|
||||
// Create the real rotation transformation.
|
||||
Matrix rotate_at_center = new();
|
||||
rotate_at_center.RotateAt(angle,
|
||||
new PointF(wid / 2f, hgt / 2f));
|
||||
|
||||
// Draw the image onto the new bitmap rotated.
|
||||
using (Graphics gr = Graphics.FromImage(result))
|
||||
{
|
||||
// Use smooth image interpolation.
|
||||
gr.InterpolationMode = InterpolationMode.High;
|
||||
|
||||
// Clear with the color in the image's upper left corner.
|
||||
gr.Clear(bitmap.GetPixel(0, 0));
|
||||
|
||||
// For debugging. (It's easier to see the background.)
|
||||
// gr.Clear(Color.LightBlue);
|
||||
|
||||
// Set up the transformation to rotate.
|
||||
gr.Transform = rotate_at_center;
|
||||
|
||||
// Draw the image centered on the bitmap.
|
||||
int x = (wid - bitmap.Width) / 2;
|
||||
int y = (hgt - bitmap.Height) / 2;
|
||||
gr.DrawImage(bitmap, x, y);
|
||||
}
|
||||
#endif
|
||||
// Return the result bitmap.
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Bitmap RotateBitmap(Image image, float angle)
|
||||
{
|
||||
Bitmap result;
|
||||
Bitmap bitmap = new(image);
|
||||
result = D_Face.RotateBitmap(bitmap, angle);
|
||||
result = RotateBitmap(bitmap, angle);
|
||||
if (bitmap is not null)
|
||||
bitmap.Dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
private void SaveFaceParts(int pointSize, IFileHolder resizedFileHolder, bool saveRotated, List<(Face, string, string)> collection)
|
||||
private void SaveFaceParts(int pointSize, IFileHolder resizedFileHolder, bool saveRotated, List<(Shared.Models.Face, string, string)> collection)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
@ -58,7 +142,7 @@ internal class D2_FaceParts
|
||||
int width;
|
||||
int height;
|
||||
Bitmap rotated;
|
||||
foreach ((Face face, string fileName, string rotatedFileName) in collection)
|
||||
foreach ((Shared.Models.Face face, string fileName, string rotatedFileName) in collection)
|
||||
{
|
||||
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
continue;
|
||||
@ -118,7 +202,7 @@ internal class D2_FaceParts
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
internal void SaveFaceLandmarkImages(string facesDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Face> faceCollection, bool saveRotated)
|
||||
public void SaveFaceLandmarkImages(string facesDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, List<Shared.Models.Face> faceCollection, bool saveRotated)
|
||||
{
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
@ -133,12 +217,12 @@ internal class D2_FaceParts
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
bool updateDateWhenMatches = false;
|
||||
string deterministicHashCodeKeyDisplay;
|
||||
List<(Face, string, string)> collection = new();
|
||||
List<(Shared.Models.Face, string, string)> collection = new();
|
||||
string[] changesFrom = new string[] { nameof(Property.Models.A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
|
||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
if (!Directory.Exists(facesDirectory))
|
||||
_ = Directory.CreateDirectory(facesDirectory);
|
||||
foreach (Face face in faceCollection)
|
||||
foreach (Shared.Models.Face face in faceCollection)
|
||||
{
|
||||
if (item.Property?.Id is null || face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||
{
|
||||
@ -161,13 +245,13 @@ internal class D2_FaceParts
|
||||
collection.Add(new(face, fileInfo.FullName, rotatedFileInfo.FullName));
|
||||
if (check)
|
||||
continue;
|
||||
else if (_Configuration.OverrideForFaceLandmarkImages)
|
||||
else if (_OverrideForFaceLandmarkImages)
|
||||
check = true;
|
||||
else if (!fileInfo.Exists)
|
||||
check = true;
|
||||
else if (saveRotated && !rotatedFileInfo.Exists)
|
||||
check = true;
|
||||
else if (_Configuration.CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
check = true;
|
||||
if (check && !updateDateWhenMatches)
|
||||
{
|
@ -3,6 +3,9 @@ using Phares.Shared;
|
||||
using ShellProgressBar;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Distance.Models;
|
||||
using View_by_Distance.Face.Models;
|
||||
using View_by_Distance.FaceParts.Models;
|
||||
using View_by_Distance.FaceRecognitionDotNet;
|
||||
using View_by_Distance.Instance.Models;
|
||||
using View_by_Distance.Map.Models;
|
||||
@ -37,7 +40,14 @@ public partial class DlibDotNet
|
||||
private readonly List<KeyValuePair<string, string>> _FileKeyValuePairs;
|
||||
private readonly Dictionary<string, List<Tuple<string, Shared.Models.Property>>> _FilePropertiesKeyValuePairs;
|
||||
|
||||
public DlibDotNet(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
|
||||
public DlibDotNet(
|
||||
List<string> args,
|
||||
IsEnvironment isEnvironment,
|
||||
IConfigurationRoot configurationRoot,
|
||||
AppSettings appSettings,
|
||||
string workingDirectory,
|
||||
bool isSilent,
|
||||
IConsole console)
|
||||
{
|
||||
_Console = console;
|
||||
string argZero;
|
||||
@ -73,7 +83,27 @@ public partial class DlibDotNet
|
||||
{
|
||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality();
|
||||
(ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFileNameExtension) = C_Resize.GetGifLowQuality();
|
||||
_Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel, imageCodecInfo, encoderParameters, filenameExtension, hiddenImageCodecInfo, hiddenEncoderParameters, hiddenFileNameExtension);
|
||||
_Faces = new D_Face(
|
||||
argZero,
|
||||
configuration.CheckDFaceAndUpWriteDates,
|
||||
configuration.PropertyConfiguration,
|
||||
encoderParameters,
|
||||
configuration.FaceDistanceHiddenImageFactor,
|
||||
filenameExtension,
|
||||
configuration.ForceFaceLastWriteTimeToCreationTime,
|
||||
hiddenEncoderParameters,
|
||||
hiddenFileNameExtension,
|
||||
hiddenImageCodecInfo,
|
||||
imageCodecInfo,
|
||||
configuration.LocationDigits,
|
||||
configuration.LocationFactor,
|
||||
model,
|
||||
modelParameter,
|
||||
configuration.NumberOfJitters,
|
||||
configuration.NumberOfTimesToUpsample,
|
||||
configuration.OverrideForFaceImages,
|
||||
predictorModel,
|
||||
configuration.PropertiesChangedForFaces);
|
||||
}
|
||||
if (_FirstRun || !_ArgZeroIsConfigurationRootDirectory)
|
||||
personContainers = Array.Empty<PersonContainer>();
|
||||
@ -84,7 +114,17 @@ public partial class DlibDotNet
|
||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||
using ProgressBar progressBar = new(1, message, options);
|
||||
progressBar.Tick();
|
||||
personContainers = A2_People.GetPersonContainers(configuration, propertyConfiguration, _Faces.FileNameExtension);
|
||||
string rootDirectory = propertyConfiguration.RootDirectory;
|
||||
string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People));
|
||||
string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory));
|
||||
if (rootResultsDirectory is null)
|
||||
throw new Exception();
|
||||
Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory);
|
||||
personContainers = Shared.Models.Stateless.Methods.IPersonContainer.GetPersonContainers(
|
||||
storage,
|
||||
configuration.LocationDigits,
|
||||
configuration.PersonBirthdayFormat,
|
||||
_Faces.FileNameExtension);
|
||||
}
|
||||
if (!isSilent && configuration.TestDistanceResults)
|
||||
{
|
||||
@ -94,17 +134,32 @@ public partial class DlibDotNet
|
||||
}
|
||||
{
|
||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
|
||||
_FaceParts = new D2_FaceParts(configuration, imageCodecInfo, encoderParameters, filenameExtension);
|
||||
_FaceParts = new D2_FaceParts(imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages);
|
||||
}
|
||||
{
|
||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetTuple(configuration.OutputExtension, configuration.OutputQuality);
|
||||
_Resize = new C_Resize(configuration.ForceResizeLastWriteTimeToCreationTime, configuration.OverrideForResizeImages, configuration.PropertiesChangedForResize, configuration.ValidResolutions, imageCodecInfo, encoderParameters, filenameExtension);
|
||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetTuple(
|
||||
configuration.OutputExtension,
|
||||
configuration.OutputQuality);
|
||||
_Resize = new C_Resize(
|
||||
configuration.ForceResizeLastWriteTimeToCreationTime,
|
||||
configuration.OverrideForResizeImages,
|
||||
configuration.PropertiesChangedForResize,
|
||||
configuration.ValidResolutions,
|
||||
imageCodecInfo,
|
||||
encoderParameters,
|
||||
filenameExtension);
|
||||
}
|
||||
if (!configuration.SkipSearch)
|
||||
Search(ticks, model, predictorModel, argZero, propertyRoot, personContainers);
|
||||
if (!_FirstRun && !_IsEnvironment.Development && _Exceptions.Count == 0 && _ArgZeroIsConfigurationRootDirectory)
|
||||
{
|
||||
List<string[]> directoryCollections = _Rename.GetDirectoryRenameCollections(propertyConfiguration, model, predictorModel, relativePath: string.Empty, newDirectoryName: string.Empty, jsonFiles4InfoAny: false);
|
||||
List<string[]> directoryCollections = _Rename.GetDirectoryRenameCollections(
|
||||
propertyConfiguration,
|
||||
model,
|
||||
predictorModel,
|
||||
relativePath: string.Empty,
|
||||
newDirectoryName: string.Empty,
|
||||
jsonFiles4InfoAny: false);
|
||||
foreach (string[] directoryCollection in directoryCollections)
|
||||
{
|
||||
_Log.Information(string.Concat("Cleaning <", directoryCollection[0], ">"));
|
||||
@ -287,17 +342,32 @@ public partial class DlibDotNet
|
||||
return result;
|
||||
}
|
||||
|
||||
private void FullParallelForWork(A_Property propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Face>?> imageFaceCollections, Container container, int index, Item item)
|
||||
private void FullParallelForWork(
|
||||
A_Property propertyLogic,
|
||||
string outputResolution,
|
||||
string bResultsFullGroupDirectory,
|
||||
string cResultsFullGroupDirectory,
|
||||
string dResultsFullGroupDirectory,
|
||||
string d2ResultsFullGroupDirectory,
|
||||
List<Tuple<string, DateTime>> sourceDirectoryChanges,
|
||||
List<FileHolder?> propertyFileHolderCollection,
|
||||
List<Shared.Models.Property?> propertyCollection,
|
||||
List<List<KeyValuePair<string, string>>> metadataCollections,
|
||||
List<Dictionary<string, int[]>> resizeKeyValuePairs,
|
||||
List<List<Shared.Models.Face>?> imageFaceCollections,
|
||||
Container container,
|
||||
int index,
|
||||
Item item)
|
||||
{
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
List<Face>? faceCollection;
|
||||
string original = "Original";
|
||||
FileHolder? resizedFileHolder;
|
||||
Shared.Models.Property property;
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
DateTime dateTime = DateTime.Now;
|
||||
List<string> parseExceptions = new();
|
||||
List<Shared.Models.Face>? faceCollection;
|
||||
Dictionary<string, int[]> imageResizeKeyValuePairs;
|
||||
List<Tuple<string, DateTime>> subFileTuples = new();
|
||||
List<KeyValuePair<string, string>> metadataCollection;
|
||||
@ -317,10 +387,22 @@ public partial class DlibDotNet
|
||||
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), (from l in subFileTuples select l.Item2).Max()));
|
||||
}
|
||||
}
|
||||
(int metadataGroups, metadataCollection) = _Metadata.GetMetadataCollection(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, subFileTuples, parseExceptions, item);
|
||||
(int metadataGroups, metadataCollection) = _Metadata.GetMetadataCollection(
|
||||
_Configuration.PropertyConfiguration,
|
||||
bResultsFullGroupDirectory,
|
||||
subFileTuples,
|
||||
parseExceptions,
|
||||
item);
|
||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection));
|
||||
imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
|
||||
imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(
|
||||
_Configuration.PropertyConfiguration,
|
||||
cResultsFullGroupDirectory,
|
||||
subFileTuples,
|
||||
parseExceptions,
|
||||
original,
|
||||
metadataCollection,
|
||||
item);
|
||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs));
|
||||
if (_Configuration.SaveResizedSubfiles)
|
||||
@ -345,7 +427,15 @@ public partial class DlibDotNet
|
||||
int outputResolutionWidth = outputResolutionCollection[0];
|
||||
int outputResolutionHeight = outputResolutionCollection[1];
|
||||
int outputResolutionOrientation = outputResolutionCollection[2];
|
||||
faceCollection = _Faces.GetFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation);
|
||||
faceCollection = _Faces.GetFaces(
|
||||
dResultsFullGroupDirectory,
|
||||
subFileTuples,
|
||||
parseExceptions,
|
||||
item,
|
||||
property,
|
||||
outputResolutionWidth,
|
||||
outputResolutionHeight,
|
||||
outputResolutionOrientation);
|
||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
|
||||
_Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faceCollection);
|
||||
@ -357,7 +447,9 @@ public partial class DlibDotNet
|
||||
{
|
||||
|
||||
bool saveRotated = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution);
|
||||
string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory);
|
||||
string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(
|
||||
_Configuration.PropertyConfiguration,
|
||||
container.SourceDirectory);
|
||||
string facesDirectory = Path.GetFullPath(Path.Combine($"{Path.Combine(d2ResultsFullGroupDirectory, "()")}{sourceDirectorySegment}", item.ImageFileHolder.NameWithoutExtension));
|
||||
_FaceParts.SaveFaceLandmarkImages(facesDirectory, subFileTuples, parseExceptions, item, faceCollection, saveRotated);
|
||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||
@ -375,14 +467,33 @@ public partial class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private int FullParallelWork(int maxDegreeOfParallelism, A_Property propertyLogic, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Face>?> imageFaceCollections, Container container, Item[] filteredItems, string message)
|
||||
private int FullParallelWork(
|
||||
int maxDegreeOfParallelism,
|
||||
A_Property propertyLogic,
|
||||
string outputResolution,
|
||||
string bResultsFullGroupDirectory,
|
||||
string cResultsFullGroupDirectory,
|
||||
string dResultsFullGroupDirectory,
|
||||
string d2ResultsFullGroupDirectory,
|
||||
List<Tuple<string, DateTime>> sourceDirectoryChanges,
|
||||
List<FileHolder?> propertyFileHolderCollection,
|
||||
List<Shared.Models.Property?> propertyCollection,
|
||||
List<List<KeyValuePair<string, string>>> metadataCollection,
|
||||
List<Dictionary<string, int[]>> resizeKeyValuePairs,
|
||||
List<List<Shared.Models.Face>?> imageFaceCollections,
|
||||
Container container,
|
||||
Item[] filteredItems,
|
||||
string message)
|
||||
{
|
||||
if (_Log is null)
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
int result = 0;
|
||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||
if (imageFaceCollections.Count != filteredItems.Length || metadataCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || propertyCollection.Count != filteredItems.Length)
|
||||
if (imageFaceCollections.Count != filteredItems.Length
|
||||
|| metadataCollection.Count != filteredItems.Length
|
||||
|| resizeKeyValuePairs.Count != filteredItems.Length
|
||||
|| propertyCollection.Count != filteredItems.Length)
|
||||
{
|
||||
for (int f = 0; f < filteredItems.Length; f++)
|
||||
{
|
||||
@ -398,7 +509,22 @@ public partial class DlibDotNet
|
||||
{
|
||||
try
|
||||
{
|
||||
FullParallelForWork(propertyLogic, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, sourceDirectoryChanges, propertyFileHolderCollection, propertyCollection, metadataCollection, resizeKeyValuePairs, imageFaceCollections, container, index: i, filteredItems[i]);
|
||||
FullParallelForWork(
|
||||
propertyLogic,
|
||||
outputResolution,
|
||||
bResultsFullGroupDirectory,
|
||||
cResultsFullGroupDirectory,
|
||||
dResultsFullGroupDirectory,
|
||||
d2ResultsFullGroupDirectory,
|
||||
sourceDirectoryChanges,
|
||||
propertyFileHolderCollection,
|
||||
propertyCollection,
|
||||
metadataCollection,
|
||||
resizeKeyValuePairs,
|
||||
imageFaceCollections,
|
||||
container,
|
||||
index: i,
|
||||
filteredItems[i]);
|
||||
if (i == 0 || sourceDirectoryChanges.Any())
|
||||
progressBar.Tick();
|
||||
}
|
||||
@ -448,7 +574,15 @@ public partial class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteGroup(A_Property propertyLogic, Shared.Models.Property[] propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollection, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Face>?> imageFaceCollections, string outputResolution, Container container, Item[] filteredItems)
|
||||
private void WriteGroup(
|
||||
A_Property propertyLogic,
|
||||
Shared.Models.Property[] propertyCollection,
|
||||
List<List<KeyValuePair<string, string>>> metadataCollection,
|
||||
List<Dictionary<string, int[]>> resizeKeyValuePairs,
|
||||
List<List<Shared.Models.Face>?> imageFaceCollections,
|
||||
string outputResolution,
|
||||
Container container,
|
||||
Item[] filteredItems)
|
||||
{
|
||||
Item item;
|
||||
string key;
|
||||
@ -461,11 +595,13 @@ public partial class DlibDotNet
|
||||
if (!(from l in propertyCollection where l?.Width is null select true).Any())
|
||||
{
|
||||
string checkDirectory;
|
||||
List<KeyValuePair<string, List<Face>?>> imageFaceCollectionsKeyValuePairs = new();
|
||||
List<KeyValuePair<string, List<Shared.Models.Face>?>> imageFaceCollectionsKeyValuePairs = new();
|
||||
List<KeyValuePair<string, Shared.Models.Property>> propertyCollectionKeyValuePairs = new();
|
||||
List<KeyValuePair<string, Dictionary<string, int[]>>> resizeKeyValuePairsCollections = new();
|
||||
List<KeyValuePair<string, List<KeyValuePair<string, string>>>> metadataCollectionKeyValuePairs = new();
|
||||
(int level, List<string> directories) = Shared.Models.Stateless.Methods.IPath.Get(_Configuration.PropertyConfiguration.RootDirectory, container.SourceDirectory);
|
||||
(int level, List<string> directories) = Shared.Models.Stateless.Methods.IPath.Get(
|
||||
_Configuration.PropertyConfiguration.RootDirectory,
|
||||
container.SourceDirectory);
|
||||
string fileName = string.Concat(string.Join(_Configuration.PropertyConfiguration.FileNameDirectorySeparator, directories), ".json");
|
||||
for (int i = 0; i < filteredItems.Length; i++)
|
||||
{
|
||||
@ -480,7 +616,7 @@ public partial class DlibDotNet
|
||||
_FileKeyValuePairs.Add(new KeyValuePair<string, string>(container.SourceDirectory, key));
|
||||
_FilePropertiesKeyValuePairs[container.SourceDirectory].Add(new Tuple<string, Shared.Models.Property>(key, propertyCollection[i]));
|
||||
}
|
||||
imageFaceCollectionsKeyValuePairs.Add(new KeyValuePair<string, List<Face>?>(key, imageFaceCollections[i]));
|
||||
imageFaceCollectionsKeyValuePairs.Add(new KeyValuePair<string, List<Shared.Models.Face>?>(key, imageFaceCollections[i]));
|
||||
propertyCollectionKeyValuePairs.Add(new KeyValuePair<string, Shared.Models.Property>(key, propertyCollection[i]));
|
||||
resizeKeyValuePairsCollections.Add(new KeyValuePair<string, Dictionary<string, int[]>>(key, resizeKeyValuePairs[i]));
|
||||
metadataCollectionKeyValuePairs.Add(new KeyValuePair<string, List<KeyValuePair<string, string>>>(key, metadataCollection[i]));
|
||||
@ -528,24 +664,77 @@ public partial class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private (string, string, string, string, string, string) GetResultsFullGroupDirectories(Model? model, PredictorModel? predictorModel, string outputResolution)
|
||||
private (string, string, string, string, string, string) GetResultsFullGroupDirectories(
|
||||
Model? model,
|
||||
PredictorModel? predictorModel,
|
||||
string outputResolution)
|
||||
{
|
||||
string aResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||
_Configuration.PropertyConfiguration, model, predictorModel, nameof(A_Property), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false);
|
||||
_Configuration.PropertyConfiguration,
|
||||
model,
|
||||
predictorModel,
|
||||
nameof(A_Property),
|
||||
outputResolution,
|
||||
includeResizeGroup: false,
|
||||
includeModel: false,
|
||||
includePredictorModel: false);
|
||||
string bResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||
_Configuration.PropertyConfiguration, model, predictorModel, nameof(B_Metadata), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false);
|
||||
_Configuration.PropertyConfiguration,
|
||||
model,
|
||||
predictorModel,
|
||||
nameof(B_Metadata),
|
||||
outputResolution,
|
||||
includeResizeGroup: false,
|
||||
includeModel: false,
|
||||
includePredictorModel: false);
|
||||
string cResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||
_Configuration.PropertyConfiguration, model, predictorModel, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false);
|
||||
_Configuration.PropertyConfiguration,
|
||||
model,
|
||||
predictorModel,
|
||||
nameof(C_Resize),
|
||||
outputResolution,
|
||||
includeResizeGroup: true,
|
||||
includeModel: false,
|
||||
includePredictorModel: false);
|
||||
string dResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||
_Configuration.PropertyConfiguration, model, predictorModel, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
|
||||
_Configuration.PropertyConfiguration,
|
||||
model,
|
||||
predictorModel,
|
||||
nameof(D_Face),
|
||||
outputResolution,
|
||||
includeResizeGroup: true,
|
||||
includeModel: true,
|
||||
includePredictorModel: true);
|
||||
string d2ResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||
_Configuration.PropertyConfiguration, model, predictorModel, nameof(D2_FaceParts), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
|
||||
_Configuration.PropertyConfiguration,
|
||||
model,
|
||||
predictorModel,
|
||||
nameof(D2_FaceParts),
|
||||
outputResolution,
|
||||
includeResizeGroup: true,
|
||||
includeModel: true,
|
||||
includePredictorModel: true);
|
||||
string eResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
|
||||
_Configuration.PropertyConfiguration, model, predictorModel, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true);
|
||||
_Configuration.PropertyConfiguration,
|
||||
model,
|
||||
predictorModel,
|
||||
nameof(E_Distance),
|
||||
outputResolution,
|
||||
includeResizeGroup: true,
|
||||
includeModel: true,
|
||||
includePredictorModel: true);
|
||||
return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory);
|
||||
}
|
||||
|
||||
private void SetAngleBracketCollections(A_Property propertyLogic, string outputResolution, Container container, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory)
|
||||
private void SetAngleBracketCollections(
|
||||
A_Property propertyLogic,
|
||||
string outputResolution,
|
||||
Container container,
|
||||
string aResultsFullGroupDirectory,
|
||||
string bResultsFullGroupDirectory,
|
||||
string cResultsFullGroupDirectory,
|
||||
string dResultsFullGroupDirectory,
|
||||
string d2ResultsFullGroupDirectory)
|
||||
{
|
||||
_Faces.AngleBracketCollection.Clear();
|
||||
_Resize.AngleBracketCollection.Clear();
|
||||
@ -595,7 +784,29 @@ public partial class DlibDotNet
|
||||
converted: false);
|
||||
}
|
||||
|
||||
private void FullDoWork(string argZero, Model? model, PredictorModel? predictorModel, string propertyRoot, long ticks, A_Property propertyLogic, int t, Container[] containers)
|
||||
private Item[] GetFilterItems(Container container)
|
||||
{
|
||||
List<Item> results = new();
|
||||
foreach (Item item in container.Items)
|
||||
{
|
||||
if (item.ImageFileHolder is not null
|
||||
&& (item.Abandoned is null || !item.Abandoned.Value)
|
||||
&& item.ValidImageFormatExtension
|
||||
&& !_Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered))
|
||||
results.Add(item);
|
||||
}
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
private void FullDoWork(
|
||||
string argZero,
|
||||
Model? model,
|
||||
PredictorModel? predictorModel,
|
||||
string propertyRoot,
|
||||
long ticks,
|
||||
A_Property propertyLogic,
|
||||
int t,
|
||||
Container[] containers)
|
||||
{
|
||||
if (_Log is null)
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
@ -613,7 +824,7 @@ public partial class DlibDotNet
|
||||
string d2ResultsFullGroupDirectory;
|
||||
int containersLength = containers.Length;
|
||||
Shared.Models.Property[] propertyCollection;
|
||||
List<List<Face>?> imageFaceCollections = new();
|
||||
List<List<Shared.Models.Face>?> imageFaceCollections = new();
|
||||
List<FileHolder?> propertyFileHolderCollection = new();
|
||||
List<Dictionary<string, int[]>> resizeKeyValuePairs = new();
|
||||
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
|
||||
@ -626,7 +837,15 @@ public partial class DlibDotNet
|
||||
total = 0;
|
||||
_FileKeyValuePairs.Clear();
|
||||
_FilePropertiesKeyValuePairs.Clear();
|
||||
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution);
|
||||
(aResultsFullGroupDirectory,
|
||||
bResultsFullGroupDirectory,
|
||||
cResultsFullGroupDirectory,
|
||||
dResultsFullGroupDirectory,
|
||||
d2ResultsFullGroupDirectory,
|
||||
eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(
|
||||
model,
|
||||
predictorModel,
|
||||
outputResolution);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "()"));
|
||||
for (int i = 0; i < containers.Length; i++)
|
||||
{
|
||||
@ -635,7 +854,7 @@ public partial class DlibDotNet
|
||||
continue;
|
||||
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
||||
continue;
|
||||
filteredItems = (from l in container.Items where l.ImageFileHolder is not null && (l.Abandoned is null || !l.Abandoned.Value) && l.ValidImageFormatExtension && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray();
|
||||
filteredItems = GetFilterItems(container);
|
||||
if (!filteredItems.Any())
|
||||
continue;
|
||||
metadataCollection.Clear();
|
||||
@ -647,7 +866,23 @@ public partial class DlibDotNet
|
||||
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||
message = $"{i + 1:000}.{container.G} [{filteredItems.Length:000} files] / {containersLength:000} - {total} / {t} total files - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}";
|
||||
SetAngleBracketCollections(propertyLogic, outputResolution, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory);
|
||||
exceptionCount = FullParallelWork(maxDegreeOfParallelism, propertyLogic, outputResolution, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, sourceDirectoryChanges, propertyFileHolderCollection, nullablePropertyCollection, metadataCollection, resizeKeyValuePairs, imageFaceCollections, container, filteredItems, message);
|
||||
exceptionCount = FullParallelWork(
|
||||
maxDegreeOfParallelism,
|
||||
propertyLogic,
|
||||
outputResolution,
|
||||
bResultsFullGroupDirectory,
|
||||
cResultsFullGroupDirectory,
|
||||
dResultsFullGroupDirectory,
|
||||
d2ResultsFullGroupDirectory,
|
||||
sourceDirectoryChanges,
|
||||
propertyFileHolderCollection,
|
||||
nullablePropertyCollection,
|
||||
metadataCollection,
|
||||
resizeKeyValuePairs,
|
||||
imageFaceCollections,
|
||||
container,
|
||||
filteredItems,
|
||||
message);
|
||||
if (metadataCollection.Count != filteredItems.Length || nullablePropertyCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || imageFaceCollections.Count != filteredItems.Length)
|
||||
throw new Exception("Counts don't match!");
|
||||
if (exceptionCount != 0)
|
||||
@ -684,9 +919,9 @@ public partial class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private List<Face> SetMappingThenGetDistinctFilteredFacesWithMapping(string argZero, Container[] containers)
|
||||
private List<Shared.Models.Face> SetMappingThenGetDistinctFilteredFacesWithMapping(string argZero, Container[] containers)
|
||||
{
|
||||
List<Face> results = new();
|
||||
List<Shared.Models.Face> results = new();
|
||||
Mapping mapping;
|
||||
bool? isWrongYear;
|
||||
Item[] filteredItems;
|
||||
@ -701,7 +936,7 @@ public partial class DlibDotNet
|
||||
continue;
|
||||
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
||||
continue;
|
||||
filteredItems = (from l in container.Items where l.ImageFileHolder is not null && (l.Abandoned is null || !l.Abandoned.Value) && l.ValidImageFormatExtension && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray();
|
||||
filteredItems = GetFilterItems(container);
|
||||
if (!filteredItems.Any())
|
||||
continue;
|
||||
foreach (Item item in filteredItems)
|
||||
@ -710,7 +945,7 @@ public partial class DlibDotNet
|
||||
continue;
|
||||
if (!item.Faces.Any())
|
||||
continue;
|
||||
foreach (Face face in item.Faces)
|
||||
foreach (Shared.Models.Face face in item.Faces)
|
||||
{
|
||||
if (face.RelativePath != item.RelativePath)
|
||||
break;
|
||||
@ -731,20 +966,55 @@ public partial class DlibDotNet
|
||||
return results;
|
||||
}
|
||||
|
||||
private void DistanceThenMapLogic(string argZero, long ticks, PersonContainer[] personContainers, Container[] containers, string dResultsFullGroupDirectory, string eResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string outputResolution)
|
||||
private void DistanceThenMapLogic(
|
||||
string argZero,
|
||||
long ticks,
|
||||
PersonContainer[] personContainers,
|
||||
Container[] containers,
|
||||
string dResultsFullGroupDirectory,
|
||||
string eResultsFullGroupDirectory,
|
||||
string d2ResultsFullGroupDirectory,
|
||||
string outputResolution)
|
||||
{
|
||||
E_Distance distance = new();
|
||||
if (string.IsNullOrEmpty(eResultsFullGroupDirectory))
|
||||
throw new NullReferenceException(nameof(eResultsFullGroupDirectory));
|
||||
List<Face> distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers);
|
||||
List<Face> selectedFilteredFaces = E_Distance.GetSelectedFilteredFaces(distinctFilteredFaces);
|
||||
string eDistanceContentDirectory = Path.Combine(eResultsFullGroupDirectory, "()");
|
||||
List<Shared.Models.Face> distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers);
|
||||
List<Shared.Models.Face> selectedFilteredFaces = E_Distance.GetSelectedFilteredFaces(distinctFilteredFaces);
|
||||
E_Distance.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, selectedFilteredFaces);
|
||||
MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension, ticks, personContainers, eResultsFullGroupDirectory, distinctFilteredFaces, distance);
|
||||
SortingContainer[] sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, mapLogic, selectedFilteredFaces);
|
||||
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(
|
||||
_Configuration.PropertyConfiguration,
|
||||
nameof(A2_People),
|
||||
"{}");
|
||||
MapLogic mapLogic = new(
|
||||
_AppSettings.MaxDegreeOfParallelism,
|
||||
_Configuration.PropertyConfiguration,
|
||||
_MapConfiguration,
|
||||
_Faces.FileNameExtension,
|
||||
_Faces.HiddenFileNameExtension,
|
||||
_FaceParts.FileNameExtension,
|
||||
ticks,
|
||||
personContainers,
|
||||
eDistanceContentDirectory,
|
||||
a2PeopleSingletonDirectory,
|
||||
distinctFilteredFaces,
|
||||
distance);
|
||||
SortingContainer[] sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(
|
||||
_AppSettings.MaxDegreeOfParallelism,
|
||||
_MapConfiguration,
|
||||
ticks,
|
||||
mapLogic,
|
||||
selectedFilteredFaces);
|
||||
E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, eResultsFullGroupDirectory, sortingContainers);
|
||||
int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces);
|
||||
if (totalNotMapped > 0)
|
||||
mapLogic.ForceSingleImageThenSaveMapping(dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces, sortingContainers, totalNotMapped);
|
||||
mapLogic.ForceSingleImageThenSaveMapping(
|
||||
dResultsFullGroupDirectory,
|
||||
d2ResultsFullGroupDirectory,
|
||||
distinctFilteredFaces,
|
||||
sortingContainers,
|
||||
totalNotMapped);
|
||||
mapLogic.CopyManualFiles(dResultsFullGroupDirectory, distinctFilteredFaces);
|
||||
if (_MapConfiguration.MappingSaveNotMapped)
|
||||
mapLogic.SaveNotMappedTicks();
|
||||
@ -818,7 +1088,13 @@ public partial class DlibDotNet
|
||||
return result;
|
||||
}
|
||||
|
||||
private void Search(long ticks, Model? model, PredictorModel? predictorModel, string argZero, string propertyRoot, PersonContainer[] personContainers)
|
||||
private void Search(
|
||||
long ticks,
|
||||
Model? model,
|
||||
PredictorModel? predictorModel,
|
||||
string argZero,
|
||||
string propertyRoot,
|
||||
PersonContainer[] personContainers)
|
||||
{
|
||||
int j;
|
||||
int f;
|
||||
@ -844,33 +1120,72 @@ public partial class DlibDotNet
|
||||
{
|
||||
string? newRootDirectory = SaveUrlAndGetNewRootDirectory(container);
|
||||
for (int i = 1; i < 10; i++)
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, string.Empty, create: true));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Property.Models.Stateless.IResult.GetResultsGroupDirectory(
|
||||
_Configuration.PropertyConfiguration,
|
||||
string.Empty,
|
||||
create: true));
|
||||
argZero = newRootDirectory;
|
||||
_Configuration.PropertyConfiguration.ChangeRootDirectory(newRootDirectory);
|
||||
propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), create: false);
|
||||
propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, model, predictorModel);
|
||||
propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(
|
||||
_Configuration.PropertyConfiguration,
|
||||
nameof(A_Property),
|
||||
create: false);
|
||||
propertyLogic = new(
|
||||
_AppSettings.MaxDegreeOfParallelism,
|
||||
_Configuration.PropertyConfiguration,
|
||||
_Resize.FileNameExtension,
|
||||
_Configuration.Reverse,
|
||||
model,
|
||||
predictorModel);
|
||||
}
|
||||
FullDoWork(argZero, model, predictorModel, propertyRoot, ticks, propertyLogic, t, containers);
|
||||
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||
{
|
||||
if (_FirstRun || container is not null)
|
||||
break;
|
||||
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution);
|
||||
if (_ArgZeroIsConfigurationRootDirectory && _Configuration.SaveResizedSubfiles && outputResolution == _Configuration.OutputResolutions[0] && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) && _Exceptions.Count == 0)
|
||||
(aResultsFullGroupDirectory,
|
||||
bResultsFullGroupDirectory,
|
||||
cResultsFullGroupDirectory,
|
||||
dResultsFullGroupDirectory,
|
||||
d2ResultsFullGroupDirectory,
|
||||
eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(
|
||||
model,
|
||||
predictorModel,
|
||||
outputResolution);
|
||||
if (_ArgZeroIsConfigurationRootDirectory
|
||||
&& _Configuration.SaveResizedSubfiles
|
||||
&& outputResolution == _Configuration.OutputResolutions[0]
|
||||
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
|
||||
&& _Exceptions.Count == 0)
|
||||
{
|
||||
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
|
||||
break;
|
||||
DistanceThenMapLogic(argZero, ticks, personContainers, containers, dResultsFullGroupDirectory, eResultsFullGroupDirectory, d2ResultsFullGroupDirectory, outputResolution);
|
||||
DistanceThenMapLogic(
|
||||
argZero,
|
||||
ticks,
|
||||
personContainers,
|
||||
containers,
|
||||
dResultsFullGroupDirectory,
|
||||
eResultsFullGroupDirectory,
|
||||
d2ResultsFullGroupDirectory,
|
||||
outputResolution);
|
||||
if (_IsEnvironment.Development)
|
||||
continue;
|
||||
if (_FileKeyValuePairs.Any())
|
||||
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], _FileKeyValuePairs);
|
||||
G2_Identify identify = new(_Configuration);
|
||||
List<G2_Identify> identifiedCollection = identify.GetIdentifiedCollection(_IsEnvironment, _Configuration.PropertyConfiguration, _Faces.FileNameExtension);
|
||||
A2_People.WriteAllText(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], identifiedCollection);
|
||||
List<G2_Identify> identifiedCollection = identify.GetIdentifiedCollection(
|
||||
_IsEnvironment,
|
||||
_Configuration.PropertyConfiguration,
|
||||
_Faces.FileNameExtension);
|
||||
identify.WriteAllText(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], identifiedCollection);
|
||||
if (_Configuration.LoadOrCreateThenSaveIndex && _FilePropertiesKeyValuePairs.Any())
|
||||
_Index.SetIndex(_Configuration.PropertyConfiguration, model, predictorModel, _Configuration.OutputResolutions[0], _FilePropertiesKeyValuePairs);
|
||||
_Index.SetIndex(
|
||||
_Configuration.PropertyConfiguration,
|
||||
model,
|
||||
predictorModel,
|
||||
_Configuration.OutputResolutions[0],
|
||||
_FilePropertiesKeyValuePairs);
|
||||
}
|
||||
if (!_IsEnvironment.Development)
|
||||
{
|
||||
@ -887,6 +1202,9 @@ public partial class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
internal void RenameQueue(Model? model, PredictorModel? predictorModel) => _Rename.RenameQueue(_Configuration.PropertyConfiguration, model, predictorModel);
|
||||
internal void RenameQueue(Model? model, PredictorModel? predictorModel) => _Rename.RenameQueue(
|
||||
_Configuration.PropertyConfiguration,
|
||||
model,
|
||||
predictorModel);
|
||||
|
||||
}
|
@ -54,6 +54,9 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />
|
||||
<ProjectReference Include="..\Distance\Distance.csproj" />
|
||||
<ProjectReference Include="..\Face\Face.csproj" />
|
||||
<ProjectReference Include="..\FaceParts\FaceParts.csproj" />
|
||||
<ProjectReference Include="..\Map\Map.csproj" />
|
||||
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
||||
<ProjectReference Include="..\Property-Compare\Property-Compare.csproj" />
|
||||
|
@ -1,60 +1,7 @@
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Shared.Models;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
/// <summary>
|
||||
// ?
|
||||
/// </summary>
|
||||
internal class A2_People
|
||||
{
|
||||
|
||||
internal static void WriteAllText(Property.Models.Configuration configuration, string outputResolution, List<G2_Identify> identifiedCollection)
|
||||
{
|
||||
string key;
|
||||
string json;
|
||||
string jsonFile;
|
||||
FileInfo fileInfo;
|
||||
string[] segments;
|
||||
string directoryFullName;
|
||||
Dictionary<string, List<G2_Identify>> keyValuePairs = new();
|
||||
JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = true };
|
||||
string a2PeopleCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People), "[]");
|
||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(Property.Models.A_Property), "{}");
|
||||
foreach (G2_Identify identified in identifiedCollection)
|
||||
{
|
||||
fileInfo = new FileInfo(string.Concat(aPropertySingletonDirectory, identified.RelativePath));
|
||||
if (fileInfo?.Directory is null || !fileInfo.Directory.Exists || fileInfo.Exists)
|
||||
continue;
|
||||
key = string.Concat(identified.ParentDirectoryName, '|', identified.Person);
|
||||
if (!keyValuePairs.ContainsKey(key))
|
||||
keyValuePairs.Add(key, new List<G2_Identify>());
|
||||
keyValuePairs[key].Add(identified);
|
||||
}
|
||||
foreach (KeyValuePair<string, List<G2_Identify>> keyValuePair in keyValuePairs)
|
||||
{
|
||||
segments = keyValuePair.Key.Split('|');
|
||||
directoryFullName = Path.Combine(a2PeopleCollectionDirectory, segments[0]);
|
||||
if (!Directory.Exists(directoryFullName))
|
||||
_ = Directory.CreateDirectory(directoryFullName);
|
||||
jsonFile = Path.Combine(directoryFullName, $"{segments[1]}.json");
|
||||
json = JsonSerializer.Serialize(keyValuePair.Value, writeIndentedJsonSerializerOptions);
|
||||
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(jsonFile, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
internal static PersonContainer[] GetPersonContainers(Configuration configuration, Property.Models.Configuration propertyConfiguration, string facesFileNameExtension)
|
||||
{
|
||||
PersonContainer[] results;
|
||||
string rootDirectory = propertyConfiguration.RootDirectory;
|
||||
string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People));
|
||||
string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory));
|
||||
if (rootResultsDirectory is null)
|
||||
throw new Exception();
|
||||
Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory);
|
||||
results = Shared.Models.Stateless.Methods.IPersonContainer.GetPersonContainers(storage, configuration.LocationDigits, configuration.PersonBirthdayFormat, facesFileNameExtension);
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
{ }
|
@ -1,4 +1,6 @@
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Distance.Models;
|
||||
using View_by_Distance.Face.Models;
|
||||
using View_by_Distance.Instance.Models.Stateless;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
|
@ -1,4 +1,7 @@
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Distance.Models;
|
||||
using View_by_Distance.Face.Models;
|
||||
using View_by_Distance.FaceParts.Models;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
|
@ -67,7 +67,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
||||
return result;
|
||||
}
|
||||
|
||||
private void CheckLastWriteTimes(IsEnvironment isEnvironment, Property.Models.Configuration configuration, string facesFileNameExtension, FileInfo named, string g2IdentifySingletonDirectory)
|
||||
private void CheckLastWriteTimes(IsEnvironment isEnvironment, string facesFileNameExtension, FileInfo named, string g2IdentifySingletonDirectory)
|
||||
{
|
||||
string json;
|
||||
FileInfo fileInfo;
|
||||
@ -88,7 +88,13 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
||||
}
|
||||
json = File.ReadAllText(named.FullName);
|
||||
Dictionary<string, string[]> resultKeyValuePairs = new();
|
||||
PersonContainer[] personContainers = A2_People.GetPersonContainers(_Configuration, configuration, facesFileNameExtension);
|
||||
string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
|
||||
string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People));
|
||||
string rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory));
|
||||
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);
|
||||
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)
|
||||
@ -125,7 +131,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
||||
string g2IdentifySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
|
||||
string jsonRootDirectory = Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, " - Copied"), string.Concat(directoryName, " - 4) Info"), _Configuration.PropertyConfiguration.DateGroup, "[]");
|
||||
if (named is not null && named.Exists)
|
||||
CheckLastWriteTimes(isEnvironment, configuration, facesFileNameExtension, named, g2IdentifySingletonDirectory);
|
||||
CheckLastWriteTimes(isEnvironment, facesFileNameExtension, named, g2IdentifySingletonDirectory);
|
||||
if (Directory.Exists(jsonRootDirectory))
|
||||
{
|
||||
jsonFiles = Directory.GetFiles(jsonRootDirectory, "*.json", SearchOption.AllDirectories);
|
||||
|
@ -53,7 +53,7 @@
|
||||
"CheckDFaceAndUpWriteDates": true,
|
||||
"CheckJsonForDistanceResults": false,
|
||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||
"DateGroup": "2022-09-15",
|
||||
"DateGroup": "2022-09-22",
|
||||
"DistanceFactor": 8,
|
||||
"FaceDistanceHiddenImageFactor": 2,
|
||||
"FaceDistanceMinimumConfidence": 0.8,
|
||||
@ -108,7 +108,7 @@
|
||||
"ResultSingleton": "{}",
|
||||
"Reverse": false,
|
||||
"xRootDirectory": "C:/Tmp/phares/Pictures",
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-09-15 - 7390c13 - III",
|
||||
"RootDirectory": "F:/Tmp/Phares/Compare/Images 2022-09-22 - fb1c68e - III",
|
||||
"SaveFullYearOfRandomFiles": true,
|
||||
"SaveResizedSubFiles": true,
|
||||
"SkipSearch": false,
|
||||
|
@ -53,7 +53,7 @@
|
||||
"CheckDFaceAndUpWriteDates": true,
|
||||
"CheckJsonForDistanceResults": false,
|
||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||
"DateGroup": "2022-09-15",
|
||||
"DateGroup": "2022-09-22",
|
||||
"DistanceFactor": 8,
|
||||
"FaceDistanceHiddenImageFactor": 2,
|
||||
"FaceDistanceMinimumConfidence": 0.8,
|
||||
|
@ -53,7 +53,7 @@
|
||||
"CheckDFaceAndUpWriteDates": true,
|
||||
"CheckJsonForDistanceResults": false,
|
||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||
"DateGroup": "2022-09-15",
|
||||
"DateGroup": "2022-09-22",
|
||||
"DistanceFactor": 8,
|
||||
"FaceDistanceHiddenImageFactor": 2,
|
||||
"FaceDistanceMinimumConfidence": 0.8,
|
||||
|
@ -28,7 +28,7 @@ public class MapLogic
|
||||
private readonly string _FacesHiddenFileNameExtension;
|
||||
private readonly string _EDistanceContentTicksDirectory;
|
||||
|
||||
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string facesFileNameExtension, string facesHiddenFileNameExtension, string facePartsFileNameExtension, long ticks, PersonContainer[] personContainers, string eResultsFullGroupDirectory, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance? faceDistance)
|
||||
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string facesFileNameExtension, string facesHiddenFileNameExtension, string facePartsFileNameExtension, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance? faceDistance)
|
||||
{
|
||||
_Ticks = ticks;
|
||||
_Configuration = configuration;
|
||||
@ -49,7 +49,6 @@ public class MapLogic
|
||||
Dictionary<int, List<int>> skipCollection = new();
|
||||
List<PersonContainer> notMappedPersonContainers = new();
|
||||
Dictionary<long, PersonContainer> personKeyToPersonContainer = new();
|
||||
string eDistanceContentDirectory = Path.Combine(eResultsFullGroupDirectory, "()");
|
||||
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
|
||||
Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges = new();
|
||||
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})");
|
||||
@ -71,6 +70,7 @@ public class MapLogic
|
||||
facesFileNameExtension,
|
||||
ticks,
|
||||
personContainerCollection,
|
||||
a2PeopleSingletonDirectory,
|
||||
eDistanceContentDirectory,
|
||||
distinctFilteredFaces,
|
||||
faceDistance,
|
||||
@ -102,8 +102,8 @@ public class MapLogic
|
||||
_IdThenNormalizedPixelPercentageToPersonContainers = idThenNormalizedPixelPercentageToPersonContainers;
|
||||
}
|
||||
|
||||
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string outputExtension, long ticks, PersonContainer[] personContainers, string eResultsFullGroupDirectory) :
|
||||
this(maxDegreeOfParallelism, propertyConfiguration, configuration, outputExtension, outputExtension, outputExtension, ticks, personContainers, eResultsFullGroupDirectory, new(), null)
|
||||
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string outputExtension, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) :
|
||||
this(maxDegreeOfParallelism, propertyConfiguration, configuration, outputExtension, outputExtension, outputExtension, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, new(), null)
|
||||
{ }
|
||||
|
||||
public override string ToString()
|
||||
|
@ -612,7 +612,7 @@ internal abstract class MapLogic
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string facesFileNameExtension, long ticks, List<PersonContainer> personContainers, string eDistanceContentDirectory, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance faceDistance, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers)
|
||||
internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string facesFileNameExtension, long ticks, List<PersonContainer> personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, List<Face> distinctFilteredFaces, Shared.Models.Methods.IFaceDistance faceDistance, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers)
|
||||
{
|
||||
if (configuration is null)
|
||||
throw new NullReferenceException(nameof(configuration));
|
||||
@ -696,6 +696,7 @@ internal abstract class MapLogic
|
||||
propertyConfiguration,
|
||||
configuration.PersonBirthdayFormat,
|
||||
facesFileNameExtension,
|
||||
a2PeopleSingletonDirectory,
|
||||
personKeyToPersonContainer,
|
||||
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
||||
}
|
||||
|
@ -44,8 +44,8 @@ public class B_Metadata
|
||||
{
|
||||
object? @object;
|
||||
string? tagDescription;
|
||||
int type = (int)IExif.Tags.Orientation;
|
||||
List<string> tagNames = new();
|
||||
int type = (int)IExif.Tags.Orientation;
|
||||
string key = nameof(IExif.Tags.Orientation);
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(subFile);
|
||||
foreach (MetadataExtractor.Directory directory in directories)
|
||||
|
@ -50,7 +50,7 @@
|
||||
"WorkingDirectoryName": "PharesApps",
|
||||
"Windows": {
|
||||
"Configuration": {
|
||||
"DateGroup": "2022-09-15",
|
||||
"DateGroup": "2022-09-22",
|
||||
"FileNameDirectorySeparator": ".Z.",
|
||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||
|
@ -50,7 +50,7 @@
|
||||
"WorkingDirectoryName": "PharesApps",
|
||||
"Windows": {
|
||||
"Configuration": {
|
||||
"DateGroup": "2022-09-15",
|
||||
"DateGroup": "2022-09-22",
|
||||
"FileNameDirectorySeparator": ".Z.",
|
||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||
"KeepFullPath": false,
|
||||
|
@ -4,6 +4,6 @@ public interface IFaceDistance
|
||||
{
|
||||
|
||||
List<Face> GetMatchingFaces(double faceDistanceTolerance, string checkFile, List<Face> faces);
|
||||
void SavePossiblyNewPersonContainers(Properties.IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, string facesFileNameExtension, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
||||
void SavePossiblyNewPersonContainers(Properties.IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, string facesFileNameExtension, string a2PeopleContentDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
||||
|
||||
}
|
@ -31,6 +31,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Map", "Map\Map.csproj", "{9
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Instance", "Instance\Instance.csproj", "{8085C1EE-C4DB-43DE-8888-1C956D69CF91}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Distance", "Distance\Distance.csproj", "{8D444B55-933C-40CD-B7FC-226136F16138}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Face", "Face\Face.csproj", "{A12E19E5-59C0-40D4-B807-DF1334D4906D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceParts", "FaceParts\FaceParts.csproj", "{919525B1-60BA-40C6-BA66-6F7F4C526E01}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -96,5 +102,17 @@ Global
|
||||
{8085C1EE-C4DB-43DE-8888-1C956D69CF91}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8085C1EE-C4DB-43DE-8888-1C956D69CF91}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8085C1EE-C4DB-43DE-8888-1C956D69CF91}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8D444B55-933C-40CD-B7FC-226136F16138}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8D444B55-933C-40CD-B7FC-226136F16138}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8D444B55-933C-40CD-B7FC-226136F16138}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8D444B55-933C-40CD-B7FC-226136F16138}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A12E19E5-59C0-40D4-B807-DF1334D4906D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A12E19E5-59C0-40D4-B807-DF1334D4906D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A12E19E5-59C0-40D4-B807-DF1334D4906D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A12E19E5-59C0-40D4-B807-DF1334D4906D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{919525B1-60BA-40C6-BA66-6F7F4C526E01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{919525B1-60BA-40C6-BA66-6F7F4C526E01}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{919525B1-60BA-40C6-BA66-6F7F4C526E01}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{919525B1-60BA-40C6-BA66-6F7F4C526E01}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
Loading…
x
Reference in New Issue
Block a user