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\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\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\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\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"
|
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";
|
string outputExtension = ".jpg";
|
||||||
PredictorModel? predictorModel = null;
|
PredictorModel? predictorModel = null;
|
||||||
string eResultsFullGroupDirectory = string.Empty;
|
string eResultsFullGroupDirectory = string.Empty;
|
||||||
|
string a2PeopleSingletonDirectory = string.Empty;
|
||||||
Map.Models.Configuration? mapConfiguration = null;
|
Map.Models.Configuration? mapConfiguration = null;
|
||||||
Shared.Models.PersonContainer[] personContainers = Array.Empty<Shared.Models.PersonContainer>();
|
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);
|
A_Property propertyLogic = GetPropertyLogic(reverse, model, outputExtension, predictorModel, mapLogic);
|
||||||
foreach (string spelling in configuration.Spelling)
|
foreach (string spelling in configuration.Spelling)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
"/zzz Phares Slides/Slides 2015-06-10/Magazine 01"
|
"/zzz Phares Slides/Slides 2015-06-10/Magazine 01"
|
||||||
],
|
],
|
||||||
"Configuration": {
|
"Configuration": {
|
||||||
"DateGroup": "2022-09-15",
|
"DateGroup": "2022-09-22",
|
||||||
"DiffPropertyDirectory": "",
|
"DiffPropertyDirectory": "",
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||||
@ -87,20 +87,20 @@
|
|||||||
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
||||||
"PopulatePropertyId": true,
|
"PopulatePropertyId": true,
|
||||||
"PropertiesChangedForProperty": false,
|
"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,
|
"WriteBitmapDataBytes": false,
|
||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF"
|
".GIF"
|
||||||
],
|
],
|
||||||
"PropertyContentCollectionFiles": [
|
"PropertyContentCollectionFiles": [
|
||||||
"/Images 2022-09-15 - 7390c13 - III - Results/A) Property/2022-09-15/[()]/637869381676042455.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-15/[()]/637869733124119330.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-15/[()]/637869734240700328.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-15/[()]/637869734970730630.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-15/[()]/637869743752078399.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-15/[()]/637869744751177715.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-15/[()]/637869745134124462.json"
|
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-09-22/[()]/637869745134124462.json"
|
||||||
],
|
],
|
||||||
"ValidImageFormatExtensions": [
|
"ValidImageFormatExtensions": [
|
||||||
".bmp",
|
".bmp",
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
"WorkingDirectoryName": "PharesApps",
|
"WorkingDirectoryName": "PharesApps",
|
||||||
"Windows": {
|
"Windows": {
|
||||||
"Configuration": {
|
"Configuration": {
|
||||||
"DateGroup": "2022-09-15",
|
"DateGroup": "2022-09-22",
|
||||||
"DiffPropertyDirectory": "",
|
"DiffPropertyDirectory": "",
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||||
@ -94,13 +94,13 @@
|
|||||||
".GIF"
|
".GIF"
|
||||||
],
|
],
|
||||||
"PropertyContentCollectionFiles": [
|
"PropertyContentCollectionFiles": [
|
||||||
"/Images 2022-09-15 - 7390c13 - III - Results/A) Property/2022-09-15/[()]/637869381676042455.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-15/[()]/637869733124119330.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-15/[()]/637869734240700328.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-15/[()]/637869734970730630.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-15/[()]/637869743752078399.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-15/[()]/637869744751177715.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-15/[()]/637869745134124462.json"
|
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-09-22/[()]/637869745134124462.json"
|
||||||
],
|
],
|
||||||
"ValidImageFormatExtensions": [
|
"ValidImageFormatExtensions": [
|
||||||
".bmp",
|
".bmp",
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
"ByHash": false,
|
"ByHash": false,
|
||||||
"BySeason": false,
|
"BySeason": false,
|
||||||
"ByWeek": false,
|
"ByWeek": false,
|
||||||
"DateGroup": "2022-09-15",
|
"DateGroup": "2022-09-22",
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||||
"KeepFullPath": false,
|
"KeepFullPath": false,
|
||||||
@ -63,7 +63,7 @@
|
|||||||
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
||||||
"PopulatePropertyId": true,
|
"PopulatePropertyId": true,
|
||||||
"PropertiesChangedForProperty": false,
|
"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,
|
"WriteBitmapDataBytes": false,
|
||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".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;
|
||||||
using View_by_Distance.Shared.Models.Properties;
|
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, "([])");
|
string eDistanceContentCollectionDirectory = Path.Combine(eResultsFullGroupDirectory, "([])");
|
||||||
if (!Directory.Exists(eDistanceContentCollectionDirectory))
|
if (!Directory.Exists(eDistanceContentCollectionDirectory))
|
||||||
@ -22,7 +22,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
|||||||
File.WriteAllLines(eDistanceContentFileName, results);
|
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<Sorting> results;
|
||||||
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
|
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
|
||||||
@ -33,7 +33,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
|||||||
return results;
|
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();
|
List<SortingContainer> results = new();
|
||||||
SortingContainer sortingContainer;
|
SortingContainer sortingContainer;
|
||||||
@ -64,7 +64,29 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
|||||||
return faceDistanceEncodings;
|
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;
|
SortingContainer[] results;
|
||||||
List<SortingContainer> collection = new();
|
List<SortingContainer> collection = new();
|
||||||
@ -94,29 +116,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FaceDistanceContainer[] GetFaceDistanceContainers(List<Face> selectedFilteredFaces)
|
public static List<Face> GetSelectedFilteredFaces(List<Face> distinctFilteredFaces)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
List<Face> results;
|
List<Face> results;
|
||||||
Face[] orderedFilteredFaces = (from l in distinctFilteredFaces orderby l.Mapping is not null, l.Mapping?.MappingFromItem.MinimumDateTime descending select l).ToArray();
|
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;
|
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);
|
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
||||||
@ -186,7 +186,7 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
|||||||
return results;
|
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;
|
char @char;
|
||||||
string json;
|
string json;
|
||||||
@ -202,7 +202,6 @@ internal class E_Distance : Shared.Models.Methods.IFaceDistance
|
|||||||
string checkPersonKeyFormattedDirectory;
|
string checkPersonKeyFormattedDirectory;
|
||||||
char[] chars = Shared.Models.Stateless.Methods.IAge.GetChars();
|
char[] chars = Shared.Models.Stateless.Methods.IAge.GetChars();
|
||||||
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
|
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
|
||||||
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People), "{}");
|
|
||||||
foreach ((string[] personDisplayDirectoryNames, PersonContainer personContainer) in possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
foreach ((string[] personDisplayDirectoryNames, PersonContainer personContainer) in possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||||
{
|
{
|
||||||
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
|
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;
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
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;
|
||||||
using View_by_Distance.Shared.Models.Stateless;
|
using View_by_Distance.Shared.Models.Stateless;
|
||||||
|
|
||||||
namespace View_by_Distance.Instance.Models;
|
namespace View_by_Distance.Face.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
// List<D_Faces>
|
// List<D_Faces>
|
||||||
@ -19,7 +18,7 @@ namespace View_by_Distance.Instance.Models;
|
|||||||
public class D_Face
|
public class D_Face
|
||||||
{
|
{
|
||||||
|
|
||||||
internal List<string> AngleBracketCollection { get; }
|
public List<string> AngleBracketCollection { get; }
|
||||||
|
|
||||||
protected readonly string _FileNameExtension;
|
protected readonly string _FileNameExtension;
|
||||||
public string FileNameExtension => _FileNameExtension;
|
public string FileNameExtension => _FileNameExtension;
|
||||||
@ -40,21 +39,60 @@ public class D_Face
|
|||||||
private readonly EncoderParameters _HiddenEncoderParameters;
|
private readonly EncoderParameters _HiddenEncoderParameters;
|
||||||
private readonly JsonSerializerOptions _WriteIndentedAndWhenWritingNull;
|
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;
|
_Model = model;
|
||||||
_ArgZero = argZero;
|
_ArgZero = argZero;
|
||||||
_Configuration = configuration;
|
_Configuration = configuration;
|
||||||
_ImageCodecInfo = imageCodecInfo;
|
_ImageCodecInfo = imageCodecInfo;
|
||||||
|
_LocationDigits = locationDigits;
|
||||||
|
_LocationFactor = locationFactor;
|
||||||
_ModelParameter = modelParameter;
|
_ModelParameter = modelParameter;
|
||||||
_PredictorModel = predictorModel;
|
_PredictorModel = predictorModel;
|
||||||
|
_NumberOfJitters = numberOfJitters;
|
||||||
_EncoderParameters = encoderParameters;
|
_EncoderParameters = encoderParameters;
|
||||||
_FileNameExtension = filenameExtension;
|
_FileNameExtension = filenameExtension;
|
||||||
_Log = Serilog.Log.ForContext<D_Face>();
|
_Log = Serilog.Log.ForContext<D_Face>();
|
||||||
AngleBracketCollection = new List<string>();
|
AngleBracketCollection = new List<string>();
|
||||||
_HiddenImageCodecInfo = hiddenImageCodecInfo;
|
_HiddenImageCodecInfo = hiddenImageCodecInfo;
|
||||||
|
_OverrideForFaceImages = overrideForFaceImages;
|
||||||
_HiddenEncoderParameters = hiddenEncoderParameters;
|
_HiddenEncoderParameters = hiddenEncoderParameters;
|
||||||
_HiddenFileNameExtension = hiddenFileNameExtension;
|
_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);
|
ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null);
|
||||||
if (constructorInfo is null)
|
if (constructorInfo is null)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
@ -62,25 +100,6 @@ public class D_Face
|
|||||||
_WriteIndentedAndWhenWritingNull = new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull };
|
_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()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
@ -89,67 +108,6 @@ public class D_Face
|
|||||||
|
|
||||||
#pragma warning disable CA1416
|
#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)
|
private static byte[] GetBytes(string value)
|
||||||
{
|
{
|
||||||
byte[] results = new byte[value.Length + 1];
|
byte[] results = new byte[value.Length + 1];
|
||||||
@ -170,7 +128,7 @@ public class D_Face
|
|||||||
return result;
|
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 pixel;
|
||||||
int width;
|
int width;
|
||||||
@ -181,23 +139,21 @@ public class D_Face
|
|||||||
Location? location;
|
Location? location;
|
||||||
Rectangle rectangle;
|
Rectangle rectangle;
|
||||||
PropertyItem? propertyItem;
|
PropertyItem? propertyItem;
|
||||||
int software = (int)IExif.Tags.Software;
|
|
||||||
int userComment = (int)IExif.Tags.UserComment;
|
int userComment = (int)IExif.Tags.UserComment;
|
||||||
using Bitmap source = new(resizedFileHolder.FullName);
|
using Bitmap source = new(resizedFileHolder.FullName);
|
||||||
int imageDescription = (int)IExif.Tags.ImageDescription;
|
foreach ((Shared.Models.Face face, FileInfo? fileInfo, string fileName) in collection)
|
||||||
foreach ((Face face, FileInfo? fileInfo, string fileName) in collection)
|
|
||||||
{
|
{
|
||||||
if (fileInfo is null)
|
if (fileInfo is null)
|
||||||
continue;
|
continue;
|
||||||
if (face.FaceEncoding is null || face?.Location?.NormalizedPixelPercentage is null || face?.OutputResolution is null)
|
if (face.FaceEncoding is null || face?.Location?.NormalizedPixelPercentage is null || face?.OutputResolution is null)
|
||||||
continue;
|
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)
|
if (location is null)
|
||||||
continue;
|
continue;
|
||||||
width = location.Right - location.Left;
|
width = location.Right - location.Left;
|
||||||
height = location.Bottom - location.Top;
|
height = location.Bottom - location.Top;
|
||||||
json = JsonSerializer.Serialize(face.FaceEncoding);
|
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);
|
rectangle = new Rectangle(location.Left, location.Top, width, height);
|
||||||
using (bitmap = new(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);
|
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||||
propertyItem = GetPropertyItem(userComment, json);
|
propertyItem = GetPropertyItem(userComment, json);
|
||||||
bitmap.SetPropertyItem(propertyItem);
|
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);
|
bitmap.Save(fileInfo.FullName, _ImageCodecInfo, _EncoderParameters);
|
||||||
}
|
}
|
||||||
if (File.Exists(fileName))
|
if (File.Exists(fileName))
|
||||||
File.Delete(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)
|
if (location is null)
|
||||||
continue;
|
continue;
|
||||||
width = location.Right - location.Left;
|
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)
|
if (item.ImageFileHolder is null)
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
if (item.ResizedFileHolder is null)
|
if (item.ResizedFileHolder is null)
|
||||||
@ -251,14 +203,14 @@ public class D_Face
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<(int, Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection;
|
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);
|
collection = faceRecognition.GetCollection(unknownImage, includeFaceEncoding: true, includeFaceParts: true, sortByNormalizedPixelPercentage: true);
|
||||||
if (!collection.Any())
|
if (!collection.Any())
|
||||||
results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null));
|
results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, item.RelativePath, i: null, location: null));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Face face;
|
|
||||||
double[] rawEncoding;
|
double[] rawEncoding;
|
||||||
|
Shared.Models.Face face;
|
||||||
Shared.Models.FaceEncoding convertedFaceEncoding;
|
Shared.Models.FaceEncoding convertedFaceEncoding;
|
||||||
foreach ((int locationIndex, Location location, FaceRecognitionDotNet.FaceEncoding? faceEncoding, Dictionary<FacePart, FacePoint[]>? faceParts) in collection)
|
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
|
#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)
|
if (item.Property?.Id is null)
|
||||||
throw new NullReferenceException(nameof(item.Property.Id));
|
throw new NullReferenceException(nameof(item.Property.Id));
|
||||||
if (item.ImageFileHolder is null)
|
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) };
|
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();
|
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 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);
|
FileInfo fileInfo = new(dCollectionFile);
|
||||||
if (!fileInfo.Exists)
|
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);
|
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
||||||
fileInfo.Refresh();
|
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);
|
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
||||||
fileInfo.Refresh();
|
fileInfo.Refresh();
|
||||||
}
|
}
|
||||||
if (_Configuration.PropertiesChangedForFaces)
|
if (_PropertiesChangedForFaces)
|
||||||
results = null;
|
results = null;
|
||||||
else if (!fileInfo.Exists)
|
else if (!fileInfo.Exists)
|
||||||
results = null;
|
results = null;
|
||||||
else if (_Configuration.CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||||
results = null;
|
results = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
json = Shared.Models.Stateless.Methods.IFace.GetJson(fileInfo.FullName);
|
json = Shared.Models.Stateless.Methods.IFace.GetJson(fileInfo.FullName);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
results = JsonSerializer.Deserialize<List<Face>>(json);
|
results = JsonSerializer.Deserialize<List<Shared.Models.Face>>(json);
|
||||||
if (results is null)
|
if (results is null)
|
||||||
throw new NullReferenceException(nameof(results));
|
throw new NullReferenceException(nameof(results));
|
||||||
if (!_Configuration.ForceFaceLastWriteTimeToCreationTime)
|
if (!_ForceFaceLastWriteTimeToCreationTime)
|
||||||
{
|
{
|
||||||
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
|
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
|
||||||
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
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))
|
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));
|
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);
|
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
|
||||||
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
|
||||||
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
|
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
|
||||||
@ -388,7 +340,7 @@ public class D_Face
|
|||||||
return results;
|
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)
|
if (item.ImageFileHolder is null)
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
@ -398,14 +350,13 @@ public class D_Face
|
|||||||
bool check = false;
|
bool check = false;
|
||||||
string parentCheck;
|
string parentCheck;
|
||||||
string deterministicHashCodeKeyDisplay;
|
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[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
|
||||||
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
|
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();
|
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||||
bool facesDirectoryExisted = Directory.Exists(facesDirectory);
|
if (!Directory.Exists(facesDirectory))
|
||||||
if (!facesDirectoryExisted)
|
|
||||||
_ = Directory.CreateDirectory(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)
|
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);
|
File.Delete(parentCheck);
|
||||||
}
|
}
|
||||||
collection.Add(new(face, fileInfo, Path.Combine(facesDirectory, $"{deterministicHashCodeKeyDisplay}{item.ImageFileHolder.ExtensionLowered}{_HiddenFileNameExtension}")));
|
collection.Add(new(face, fileInfo, Path.Combine(facesDirectory, $"{deterministicHashCodeKeyDisplay}{item.ImageFileHolder.ExtensionLowered}{_HiddenFileNameExtension}")));
|
||||||
if (_Configuration.OverrideForFaceImages)
|
if (_OverrideForFaceImages)
|
||||||
check = true;
|
check = true;
|
||||||
else if (!fileInfo.Exists)
|
else if (!fileInfo.Exists)
|
||||||
check = true;
|
check = true;
|
||||||
else if (_Configuration.CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||||
check = true;
|
check = true;
|
||||||
}
|
}
|
||||||
if (check)
|
if (check)
|
||||||
SaveFaces(item.ResizedFileHolder, collection);
|
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;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using View_by_Distance.Face.Models;
|
||||||
using View_by_Distance.Metadata.Models;
|
using View_by_Distance.Metadata.Models;
|
||||||
using View_by_Distance.Resize.Models;
|
using View_by_Distance.Resize.Models;
|
||||||
using View_by_Distance.Shared.Models;
|
using View_by_Distance.Shared.Models;
|
||||||
using View_by_Distance.Shared.Models.Properties;
|
using View_by_Distance.Shared.Models.Properties;
|
||||||
using View_by_Distance.Shared.Models.Stateless;
|
using View_by_Distance.Shared.Models.Stateless;
|
||||||
|
|
||||||
namespace View_by_Distance.Instance.Models;
|
namespace View_by_Distance.FaceParts.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
// *.png
|
// *.png
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class D2_FaceParts
|
public class D2_FaceParts
|
||||||
{
|
{
|
||||||
|
|
||||||
protected readonly string _FileNameExtension;
|
protected readonly string _FileNameExtension;
|
||||||
public string FileNameExtension => _FileNameExtension;
|
public string FileNameExtension => _FileNameExtension;
|
||||||
|
|
||||||
private readonly Serilog.ILogger? _Log;
|
private readonly Serilog.ILogger? _Log;
|
||||||
private readonly Configuration _Configuration;
|
|
||||||
private readonly ImageCodecInfo _ImageCodecInfo;
|
private readonly ImageCodecInfo _ImageCodecInfo;
|
||||||
|
private readonly bool _CheckDFaceAndUpWriteDates;
|
||||||
|
private readonly bool _OverrideForFaceLandmarkImages;
|
||||||
private readonly EncoderParameters _EncoderParameters;
|
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;
|
_ImageCodecInfo = imageCodecInfo;
|
||||||
_EncoderParameters = encoderParameters;
|
_EncoderParameters = encoderParameters;
|
||||||
_FileNameExtension = filenameExtension;
|
_FileNameExtension = filenameExtension;
|
||||||
_Log = Serilog.Log.ForContext<D2_FaceParts>();
|
_Log = Serilog.Log.ForContext<D2_FaceParts>();
|
||||||
|
_CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
|
||||||
|
_OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
@ -38,19 +42,99 @@ internal class D2_FaceParts
|
|||||||
return result;
|
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
|
#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)
|
private static Bitmap RotateBitmap(Image image, float angle)
|
||||||
{
|
{
|
||||||
Bitmap result;
|
Bitmap result;
|
||||||
Bitmap bitmap = new(image);
|
Bitmap bitmap = new(image);
|
||||||
result = D_Face.RotateBitmap(bitmap, angle);
|
result = RotateBitmap(bitmap, angle);
|
||||||
if (bitmap is not null)
|
if (bitmap is not null)
|
||||||
bitmap.Dispose();
|
bitmap.Dispose();
|
||||||
return result;
|
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 x;
|
||||||
int y;
|
int y;
|
||||||
@ -58,7 +142,7 @@ internal class D2_FaceParts
|
|||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
Bitmap rotated;
|
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)
|
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
|
||||||
continue;
|
continue;
|
||||||
@ -118,7 +202,7 @@ internal class D2_FaceParts
|
|||||||
|
|
||||||
#pragma warning restore CA1416
|
#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)
|
if (item.ImageFileHolder is null)
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
@ -133,12 +217,12 @@ internal class D2_FaceParts
|
|||||||
long ticks = DateTime.Now.Ticks;
|
long ticks = DateTime.Now.Ticks;
|
||||||
bool updateDateWhenMatches = false;
|
bool updateDateWhenMatches = false;
|
||||||
string deterministicHashCodeKeyDisplay;
|
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) };
|
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();
|
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||||
if (!Directory.Exists(facesDirectory))
|
if (!Directory.Exists(facesDirectory))
|
||||||
_ = Directory.CreateDirectory(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)
|
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));
|
collection.Add(new(face, fileInfo.FullName, rotatedFileInfo.FullName));
|
||||||
if (check)
|
if (check)
|
||||||
continue;
|
continue;
|
||||||
else if (_Configuration.OverrideForFaceLandmarkImages)
|
else if (_OverrideForFaceLandmarkImages)
|
||||||
check = true;
|
check = true;
|
||||||
else if (!fileInfo.Exists)
|
else if (!fileInfo.Exists)
|
||||||
check = true;
|
check = true;
|
||||||
else if (saveRotated && !rotatedFileInfo.Exists)
|
else if (saveRotated && !rotatedFileInfo.Exists)
|
||||||
check = true;
|
check = true;
|
||||||
else if (_Configuration.CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||||
check = true;
|
check = true;
|
||||||
if (check && !updateDateWhenMatches)
|
if (check && !updateDateWhenMatches)
|
||||||
{
|
{
|
@ -3,6 +3,9 @@ using Phares.Shared;
|
|||||||
using ShellProgressBar;
|
using ShellProgressBar;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.Text.Json;
|
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.FaceRecognitionDotNet;
|
||||||
using View_by_Distance.Instance.Models;
|
using View_by_Distance.Instance.Models;
|
||||||
using View_by_Distance.Map.Models;
|
using View_by_Distance.Map.Models;
|
||||||
@ -37,7 +40,14 @@ public partial class DlibDotNet
|
|||||||
private readonly List<KeyValuePair<string, string>> _FileKeyValuePairs;
|
private readonly List<KeyValuePair<string, string>> _FileKeyValuePairs;
|
||||||
private readonly Dictionary<string, List<Tuple<string, Shared.Models.Property>>> _FilePropertiesKeyValuePairs;
|
private readonly Dictionary<string, List<Tuple<string, Shared.Models.Property>>> _FilePropertiesKeyValuePairs;
|
||||||
|
|
||||||
public DlibDotNet(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
|
public DlibDotNet(
|
||||||
|
List<string> args,
|
||||||
|
IsEnvironment isEnvironment,
|
||||||
|
IConfigurationRoot configurationRoot,
|
||||||
|
AppSettings appSettings,
|
||||||
|
string workingDirectory,
|
||||||
|
bool isSilent,
|
||||||
|
IConsole console)
|
||||||
{
|
{
|
||||||
_Console = console;
|
_Console = console;
|
||||||
string argZero;
|
string argZero;
|
||||||
@ -73,7 +83,27 @@ public partial class DlibDotNet
|
|||||||
{
|
{
|
||||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality();
|
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality();
|
||||||
(ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFileNameExtension) = C_Resize.GetGifLowQuality();
|
(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)
|
if (_FirstRun || !_ArgZeroIsConfigurationRootDirectory)
|
||||||
personContainers = Array.Empty<PersonContainer>();
|
personContainers = Array.Empty<PersonContainer>();
|
||||||
@ -84,7 +114,17 @@ public partial class DlibDotNet
|
|||||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||||
using ProgressBar progressBar = new(1, message, options);
|
using ProgressBar progressBar = new(1, message, options);
|
||||||
progressBar.Tick();
|
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)
|
if (!isSilent && configuration.TestDistanceResults)
|
||||||
{
|
{
|
||||||
@ -94,17 +134,32 @@ public partial class DlibDotNet
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
|
(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);
|
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetTuple(
|
||||||
_Resize = new C_Resize(configuration.ForceResizeLastWriteTimeToCreationTime, configuration.OverrideForResizeImages, configuration.PropertiesChangedForResize, configuration.ValidResolutions, imageCodecInfo, encoderParameters, filenameExtension);
|
configuration.OutputExtension,
|
||||||
|
configuration.OutputQuality);
|
||||||
|
_Resize = new C_Resize(
|
||||||
|
configuration.ForceResizeLastWriteTimeToCreationTime,
|
||||||
|
configuration.OverrideForResizeImages,
|
||||||
|
configuration.PropertiesChangedForResize,
|
||||||
|
configuration.ValidResolutions,
|
||||||
|
imageCodecInfo,
|
||||||
|
encoderParameters,
|
||||||
|
filenameExtension);
|
||||||
}
|
}
|
||||||
if (!configuration.SkipSearch)
|
if (!configuration.SkipSearch)
|
||||||
Search(ticks, model, predictorModel, argZero, propertyRoot, personContainers);
|
Search(ticks, model, predictorModel, argZero, propertyRoot, personContainers);
|
||||||
if (!_FirstRun && !_IsEnvironment.Development && _Exceptions.Count == 0 && _ArgZeroIsConfigurationRootDirectory)
|
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)
|
foreach (string[] directoryCollection in directoryCollections)
|
||||||
{
|
{
|
||||||
_Log.Information(string.Concat("Cleaning <", directoryCollection[0], ">"));
|
_Log.Information(string.Concat("Cleaning <", directoryCollection[0], ">"));
|
||||||
@ -287,17 +342,32 @@ public partial class DlibDotNet
|
|||||||
return result;
|
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)
|
if (item.ImageFileHolder is null)
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||||
List<Face>? faceCollection;
|
|
||||||
string original = "Original";
|
string original = "Original";
|
||||||
FileHolder? resizedFileHolder;
|
FileHolder? resizedFileHolder;
|
||||||
Shared.Models.Property property;
|
Shared.Models.Property property;
|
||||||
long ticks = DateTime.Now.Ticks;
|
long ticks = DateTime.Now.Ticks;
|
||||||
DateTime dateTime = DateTime.Now;
|
DateTime dateTime = DateTime.Now;
|
||||||
List<string> parseExceptions = new();
|
List<string> parseExceptions = new();
|
||||||
|
List<Shared.Models.Face>? faceCollection;
|
||||||
Dictionary<string, int[]> imageResizeKeyValuePairs;
|
Dictionary<string, int[]> imageResizeKeyValuePairs;
|
||||||
List<Tuple<string, DateTime>> subFileTuples = new();
|
List<Tuple<string, DateTime>> subFileTuples = new();
|
||||||
List<KeyValuePair<string, string>> metadataCollection;
|
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()));
|
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)
|
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection));
|
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)
|
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs));
|
ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs));
|
||||||
if (_Configuration.SaveResizedSubfiles)
|
if (_Configuration.SaveResizedSubfiles)
|
||||||
@ -345,7 +427,15 @@ public partial class DlibDotNet
|
|||||||
int outputResolutionWidth = outputResolutionCollection[0];
|
int outputResolutionWidth = outputResolutionCollection[0];
|
||||||
int outputResolutionHeight = outputResolutionCollection[1];
|
int outputResolutionHeight = outputResolutionCollection[1];
|
||||||
int outputResolutionOrientation = outputResolutionCollection[2];
|
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)
|
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
|
ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
|
||||||
_Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faceCollection);
|
_Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faceCollection);
|
||||||
@ -357,7 +447,9 @@ public partial class DlibDotNet
|
|||||||
{
|
{
|
||||||
|
|
||||||
bool saveRotated = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution);
|
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));
|
string facesDirectory = Path.GetFullPath(Path.Combine($"{Path.Combine(d2ResultsFullGroupDirectory, "()")}{sourceDirectorySegment}", item.ImageFileHolder.NameWithoutExtension));
|
||||||
_FaceParts.SaveFaceLandmarkImages(facesDirectory, subFileTuples, parseExceptions, item, faceCollection, saveRotated);
|
_FaceParts.SaveFaceLandmarkImages(facesDirectory, subFileTuples, parseExceptions, item, faceCollection, saveRotated);
|
||||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
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)
|
if (_Log is null)
|
||||||
throw new NullReferenceException(nameof(_Log));
|
throw new NullReferenceException(nameof(_Log));
|
||||||
int result = 0;
|
int result = 0;
|
||||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
||||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
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++)
|
for (int f = 0; f < filteredItems.Length; f++)
|
||||||
{
|
{
|
||||||
@ -398,7 +509,22 @@ public partial class DlibDotNet
|
|||||||
{
|
{
|
||||||
try
|
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())
|
if (i == 0 || sourceDirectoryChanges.Any())
|
||||||
progressBar.Tick();
|
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;
|
Item item;
|
||||||
string key;
|
string key;
|
||||||
@ -461,11 +595,13 @@ public partial class DlibDotNet
|
|||||||
if (!(from l in propertyCollection where l?.Width is null select true).Any())
|
if (!(from l in propertyCollection where l?.Width is null select true).Any())
|
||||||
{
|
{
|
||||||
string checkDirectory;
|
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, Shared.Models.Property>> propertyCollectionKeyValuePairs = new();
|
||||||
List<KeyValuePair<string, Dictionary<string, int[]>>> resizeKeyValuePairsCollections = new();
|
List<KeyValuePair<string, Dictionary<string, int[]>>> resizeKeyValuePairsCollections = new();
|
||||||
List<KeyValuePair<string, List<KeyValuePair<string, string>>>> metadataCollectionKeyValuePairs = 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");
|
string fileName = string.Concat(string.Join(_Configuration.PropertyConfiguration.FileNameDirectorySeparator, directories), ".json");
|
||||||
for (int i = 0; i < filteredItems.Length; i++)
|
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));
|
_FileKeyValuePairs.Add(new KeyValuePair<string, string>(container.SourceDirectory, key));
|
||||||
_FilePropertiesKeyValuePairs[container.SourceDirectory].Add(new Tuple<string, Shared.Models.Property>(key, propertyCollection[i]));
|
_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]));
|
propertyCollectionKeyValuePairs.Add(new KeyValuePair<string, Shared.Models.Property>(key, propertyCollection[i]));
|
||||||
resizeKeyValuePairsCollections.Add(new KeyValuePair<string, Dictionary<string, int[]>>(key, resizeKeyValuePairs[i]));
|
resizeKeyValuePairsCollections.Add(new KeyValuePair<string, Dictionary<string, int[]>>(key, resizeKeyValuePairs[i]));
|
||||||
metadataCollectionKeyValuePairs.Add(new KeyValuePair<string, List<KeyValuePair<string, string>>>(key, metadataCollection[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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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);
|
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();
|
_Faces.AngleBracketCollection.Clear();
|
||||||
_Resize.AngleBracketCollection.Clear();
|
_Resize.AngleBracketCollection.Clear();
|
||||||
@ -595,7 +784,29 @@ public partial class DlibDotNet
|
|||||||
converted: false);
|
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)
|
if (_Log is null)
|
||||||
throw new NullReferenceException(nameof(_Log));
|
throw new NullReferenceException(nameof(_Log));
|
||||||
@ -613,7 +824,7 @@ public partial class DlibDotNet
|
|||||||
string d2ResultsFullGroupDirectory;
|
string d2ResultsFullGroupDirectory;
|
||||||
int containersLength = containers.Length;
|
int containersLength = containers.Length;
|
||||||
Shared.Models.Property[] propertyCollection;
|
Shared.Models.Property[] propertyCollection;
|
||||||
List<List<Face>?> imageFaceCollections = new();
|
List<List<Shared.Models.Face>?> imageFaceCollections = new();
|
||||||
List<FileHolder?> propertyFileHolderCollection = new();
|
List<FileHolder?> propertyFileHolderCollection = new();
|
||||||
List<Dictionary<string, int[]>> resizeKeyValuePairs = new();
|
List<Dictionary<string, int[]>> resizeKeyValuePairs = new();
|
||||||
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
|
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
|
||||||
@ -626,7 +837,15 @@ public partial class DlibDotNet
|
|||||||
total = 0;
|
total = 0;
|
||||||
_FileKeyValuePairs.Clear();
|
_FileKeyValuePairs.Clear();
|
||||||
_FilePropertiesKeyValuePairs.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, "()"));
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(eResultsFullGroupDirectory, "()"));
|
||||||
for (int i = 0; i < containers.Length; i++)
|
for (int i = 0; i < containers.Length; i++)
|
||||||
{
|
{
|
||||||
@ -635,7 +854,7 @@ public partial class DlibDotNet
|
|||||||
continue;
|
continue;
|
||||||
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
||||||
continue;
|
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())
|
if (!filteredItems.Any())
|
||||||
continue;
|
continue;
|
||||||
metadataCollection.Clear();
|
metadataCollection.Clear();
|
||||||
@ -647,7 +866,23 @@ public partial class DlibDotNet
|
|||||||
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
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}";
|
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);
|
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)
|
if (metadataCollection.Count != filteredItems.Length || nullablePropertyCollection.Count != filteredItems.Length || resizeKeyValuePairs.Count != filteredItems.Length || imageFaceCollections.Count != filteredItems.Length)
|
||||||
throw new Exception("Counts don't match!");
|
throw new Exception("Counts don't match!");
|
||||||
if (exceptionCount != 0)
|
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;
|
Mapping mapping;
|
||||||
bool? isWrongYear;
|
bool? isWrongYear;
|
||||||
Item[] filteredItems;
|
Item[] filteredItems;
|
||||||
@ -701,7 +936,7 @@ public partial class DlibDotNet
|
|||||||
continue;
|
continue;
|
||||||
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
||||||
continue;
|
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())
|
if (!filteredItems.Any())
|
||||||
continue;
|
continue;
|
||||||
foreach (Item item in filteredItems)
|
foreach (Item item in filteredItems)
|
||||||
@ -710,7 +945,7 @@ public partial class DlibDotNet
|
|||||||
continue;
|
continue;
|
||||||
if (!item.Faces.Any())
|
if (!item.Faces.Any())
|
||||||
continue;
|
continue;
|
||||||
foreach (Face face in item.Faces)
|
foreach (Shared.Models.Face face in item.Faces)
|
||||||
{
|
{
|
||||||
if (face.RelativePath != item.RelativePath)
|
if (face.RelativePath != item.RelativePath)
|
||||||
break;
|
break;
|
||||||
@ -731,20 +966,55 @@ public partial class DlibDotNet
|
|||||||
return results;
|
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();
|
E_Distance distance = new();
|
||||||
if (string.IsNullOrEmpty(eResultsFullGroupDirectory))
|
if (string.IsNullOrEmpty(eResultsFullGroupDirectory))
|
||||||
throw new NullReferenceException(nameof(eResultsFullGroupDirectory));
|
throw new NullReferenceException(nameof(eResultsFullGroupDirectory));
|
||||||
List<Face> distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers);
|
string eDistanceContentDirectory = Path.Combine(eResultsFullGroupDirectory, "()");
|
||||||
List<Face> selectedFilteredFaces = E_Distance.GetSelectedFilteredFaces(distinctFilteredFaces);
|
List<Shared.Models.Face> distinctFilteredFaces = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers);
|
||||||
|
List<Shared.Models.Face> selectedFilteredFaces = E_Distance.GetSelectedFilteredFaces(distinctFilteredFaces);
|
||||||
E_Distance.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, selectedFilteredFaces);
|
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);
|
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(
|
||||||
SortingContainer[] sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, mapLogic, selectedFilteredFaces);
|
_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);
|
E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, eResultsFullGroupDirectory, sortingContainers);
|
||||||
int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces);
|
int totalNotMapped = mapLogic.AddToMapping(distinctFilteredFaces);
|
||||||
if (totalNotMapped > 0)
|
if (totalNotMapped > 0)
|
||||||
mapLogic.ForceSingleImageThenSaveMapping(dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distinctFilteredFaces, sortingContainers, totalNotMapped);
|
mapLogic.ForceSingleImageThenSaveMapping(
|
||||||
|
dResultsFullGroupDirectory,
|
||||||
|
d2ResultsFullGroupDirectory,
|
||||||
|
distinctFilteredFaces,
|
||||||
|
sortingContainers,
|
||||||
|
totalNotMapped);
|
||||||
mapLogic.CopyManualFiles(dResultsFullGroupDirectory, distinctFilteredFaces);
|
mapLogic.CopyManualFiles(dResultsFullGroupDirectory, distinctFilteredFaces);
|
||||||
if (_MapConfiguration.MappingSaveNotMapped)
|
if (_MapConfiguration.MappingSaveNotMapped)
|
||||||
mapLogic.SaveNotMappedTicks();
|
mapLogic.SaveNotMappedTicks();
|
||||||
@ -818,7 +1088,13 @@ public partial class DlibDotNet
|
|||||||
return result;
|
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 j;
|
||||||
int f;
|
int f;
|
||||||
@ -844,33 +1120,72 @@ public partial class DlibDotNet
|
|||||||
{
|
{
|
||||||
string? newRootDirectory = SaveUrlAndGetNewRootDirectory(container);
|
string? newRootDirectory = SaveUrlAndGetNewRootDirectory(container);
|
||||||
for (int i = 1; i < 10; i++)
|
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;
|
argZero = newRootDirectory;
|
||||||
_Configuration.PropertyConfiguration.ChangeRootDirectory(newRootDirectory);
|
_Configuration.PropertyConfiguration.ChangeRootDirectory(newRootDirectory);
|
||||||
propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), create: false);
|
propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(
|
||||||
propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, model, predictorModel);
|
_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);
|
FullDoWork(argZero, model, predictorModel, propertyRoot, ticks, propertyLogic, t, containers);
|
||||||
foreach (string outputResolution in _Configuration.OutputResolutions)
|
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||||
{
|
{
|
||||||
if (_FirstRun || container is not null)
|
if (_FirstRun || container is not null)
|
||||||
break;
|
break;
|
||||||
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory) = GetResultsFullGroupDirectories(model, predictorModel, outputResolution);
|
(aResultsFullGroupDirectory,
|
||||||
if (_ArgZeroIsConfigurationRootDirectory && _Configuration.SaveResizedSubfiles && outputResolution == _Configuration.OutputResolutions[0] && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) && _Exceptions.Count == 0)
|
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())
|
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
|
||||||
break;
|
break;
|
||||||
DistanceThenMapLogic(argZero, ticks, personContainers, containers, dResultsFullGroupDirectory, eResultsFullGroupDirectory, d2ResultsFullGroupDirectory, outputResolution);
|
DistanceThenMapLogic(
|
||||||
|
argZero,
|
||||||
|
ticks,
|
||||||
|
personContainers,
|
||||||
|
containers,
|
||||||
|
dResultsFullGroupDirectory,
|
||||||
|
eResultsFullGroupDirectory,
|
||||||
|
d2ResultsFullGroupDirectory,
|
||||||
|
outputResolution);
|
||||||
if (_IsEnvironment.Development)
|
if (_IsEnvironment.Development)
|
||||||
continue;
|
continue;
|
||||||
if (_FileKeyValuePairs.Any())
|
if (_FileKeyValuePairs.Any())
|
||||||
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], _FileKeyValuePairs);
|
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], _FileKeyValuePairs);
|
||||||
G2_Identify identify = new(_Configuration);
|
G2_Identify identify = new(_Configuration);
|
||||||
List<G2_Identify> identifiedCollection = identify.GetIdentifiedCollection(_IsEnvironment, _Configuration.PropertyConfiguration, _Faces.FileNameExtension);
|
List<G2_Identify> identifiedCollection = identify.GetIdentifiedCollection(
|
||||||
A2_People.WriteAllText(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], identifiedCollection);
|
_IsEnvironment,
|
||||||
|
_Configuration.PropertyConfiguration,
|
||||||
|
_Faces.FileNameExtension);
|
||||||
identify.WriteAllText(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], identifiedCollection);
|
identify.WriteAllText(_Configuration.PropertyConfiguration, _Configuration.OutputResolutions[0], identifiedCollection);
|
||||||
if (_Configuration.LoadOrCreateThenSaveIndex && _FilePropertiesKeyValuePairs.Any())
|
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)
|
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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />
|
<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="..\Map\Map.csproj" />
|
||||||
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
||||||
<ProjectReference Include="..\Property-Compare\Property-Compare.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;
|
namespace View_by_Distance.Instance.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
// ?
|
// ?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class A2_People
|
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 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.Instance.Models.Stateless;
|
||||||
using View_by_Distance.Metadata.Models;
|
using View_by_Distance.Metadata.Models;
|
||||||
using View_by_Distance.Resize.Models;
|
using View_by_Distance.Resize.Models;
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
using System.Text.Json;
|
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.Metadata.Models;
|
||||||
using View_by_Distance.Resize.Models;
|
using View_by_Distance.Resize.Models;
|
||||||
using View_by_Distance.Shared.Models.Stateless;
|
using View_by_Distance.Shared.Models.Stateless;
|
||||||
|
@ -67,7 +67,7 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
|||||||
return result;
|
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;
|
string json;
|
||||||
FileInfo fileInfo;
|
FileInfo fileInfo;
|
||||||
@ -88,7 +88,13 @@ public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
|||||||
}
|
}
|
||||||
json = File.ReadAllText(named.FullName);
|
json = File.ReadAllText(named.FullName);
|
||||||
Dictionary<string, string[]> resultKeyValuePairs = new();
|
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();
|
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);
|
Dictionary<string, string[]> sourceKeyValuePairs = JsonSerializer.Deserialize<Dictionary<string, string[]>>(json);
|
||||||
foreach (KeyValuePair<string, string[]> keyValuePair in sourceKeyValuePairs)
|
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 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, "[]");
|
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)
|
if (named is not null && named.Exists)
|
||||||
CheckLastWriteTimes(isEnvironment, configuration, facesFileNameExtension, named, g2IdentifySingletonDirectory);
|
CheckLastWriteTimes(isEnvironment, facesFileNameExtension, named, g2IdentifySingletonDirectory);
|
||||||
if (Directory.Exists(jsonRootDirectory))
|
if (Directory.Exists(jsonRootDirectory))
|
||||||
{
|
{
|
||||||
jsonFiles = Directory.GetFiles(jsonRootDirectory, "*.json", SearchOption.AllDirectories);
|
jsonFiles = Directory.GetFiles(jsonRootDirectory, "*.json", SearchOption.AllDirectories);
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
"CheckDFaceAndUpWriteDates": true,
|
"CheckDFaceAndUpWriteDates": true,
|
||||||
"CheckJsonForDistanceResults": false,
|
"CheckJsonForDistanceResults": false,
|
||||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||||
"DateGroup": "2022-09-15",
|
"DateGroup": "2022-09-22",
|
||||||
"DistanceFactor": 8,
|
"DistanceFactor": 8,
|
||||||
"FaceDistanceHiddenImageFactor": 2,
|
"FaceDistanceHiddenImageFactor": 2,
|
||||||
"FaceDistanceMinimumConfidence": 0.8,
|
"FaceDistanceMinimumConfidence": 0.8,
|
||||||
@ -108,7 +108,7 @@
|
|||||||
"ResultSingleton": "{}",
|
"ResultSingleton": "{}",
|
||||||
"Reverse": false,
|
"Reverse": false,
|
||||||
"xRootDirectory": "C:/Tmp/phares/Pictures",
|
"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,
|
"SaveFullYearOfRandomFiles": true,
|
||||||
"SaveResizedSubFiles": true,
|
"SaveResizedSubFiles": true,
|
||||||
"SkipSearch": false,
|
"SkipSearch": false,
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
"CheckDFaceAndUpWriteDates": true,
|
"CheckDFaceAndUpWriteDates": true,
|
||||||
"CheckJsonForDistanceResults": false,
|
"CheckJsonForDistanceResults": false,
|
||||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||||
"DateGroup": "2022-09-15",
|
"DateGroup": "2022-09-22",
|
||||||
"DistanceFactor": 8,
|
"DistanceFactor": 8,
|
||||||
"FaceDistanceHiddenImageFactor": 2,
|
"FaceDistanceHiddenImageFactor": 2,
|
||||||
"FaceDistanceMinimumConfidence": 0.8,
|
"FaceDistanceMinimumConfidence": 0.8,
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
"CheckDFaceAndUpWriteDates": true,
|
"CheckDFaceAndUpWriteDates": true,
|
||||||
"CheckJsonForDistanceResults": false,
|
"CheckJsonForDistanceResults": false,
|
||||||
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
"CrossDirectoryMaxItemsInDistanceCollection": 7,
|
||||||
"DateGroup": "2022-09-15",
|
"DateGroup": "2022-09-22",
|
||||||
"DistanceFactor": 8,
|
"DistanceFactor": 8,
|
||||||
"FaceDistanceHiddenImageFactor": 2,
|
"FaceDistanceHiddenImageFactor": 2,
|
||||||
"FaceDistanceMinimumConfidence": 0.8,
|
"FaceDistanceMinimumConfidence": 0.8,
|
||||||
|
@ -28,7 +28,7 @@ public class MapLogic
|
|||||||
private readonly string _FacesHiddenFileNameExtension;
|
private readonly string _FacesHiddenFileNameExtension;
|
||||||
private readonly string _EDistanceContentTicksDirectory;
|
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;
|
_Ticks = ticks;
|
||||||
_Configuration = configuration;
|
_Configuration = configuration;
|
||||||
@ -49,7 +49,6 @@ public class MapLogic
|
|||||||
Dictionary<int, List<int>> skipCollection = new();
|
Dictionary<int, List<int>> skipCollection = new();
|
||||||
List<PersonContainer> notMappedPersonContainers = new();
|
List<PersonContainer> notMappedPersonContainers = new();
|
||||||
Dictionary<long, PersonContainer> personKeyToPersonContainer = new();
|
Dictionary<long, PersonContainer> personKeyToPersonContainer = new();
|
||||||
string eDistanceContentDirectory = Path.Combine(eResultsFullGroupDirectory, "()");
|
|
||||||
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
|
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
|
||||||
Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges = new();
|
Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges = new();
|
||||||
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})");
|
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})");
|
||||||
@ -71,6 +70,7 @@ public class MapLogic
|
|||||||
facesFileNameExtension,
|
facesFileNameExtension,
|
||||||
ticks,
|
ticks,
|
||||||
personContainerCollection,
|
personContainerCollection,
|
||||||
|
a2PeopleSingletonDirectory,
|
||||||
eDistanceContentDirectory,
|
eDistanceContentDirectory,
|
||||||
distinctFilteredFaces,
|
distinctFilteredFaces,
|
||||||
faceDistance,
|
faceDistance,
|
||||||
@ -102,8 +102,8 @@ public class MapLogic
|
|||||||
_IdThenNormalizedPixelPercentageToPersonContainers = idThenNormalizedPixelPercentageToPersonContainers;
|
_IdThenNormalizedPixelPercentageToPersonContainers = idThenNormalizedPixelPercentageToPersonContainers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, string outputExtension, long ticks, PersonContainer[] personContainers, string eResultsFullGroupDirectory) :
|
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, eResultsFullGroupDirectory, new(), null)
|
this(maxDegreeOfParallelism, propertyConfiguration, configuration, outputExtension, outputExtension, outputExtension, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, new(), null)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override string ToString()
|
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)
|
if (configuration is null)
|
||||||
throw new NullReferenceException(nameof(configuration));
|
throw new NullReferenceException(nameof(configuration));
|
||||||
@ -696,6 +696,7 @@ internal abstract class MapLogic
|
|||||||
propertyConfiguration,
|
propertyConfiguration,
|
||||||
configuration.PersonBirthdayFormat,
|
configuration.PersonBirthdayFormat,
|
||||||
facesFileNameExtension,
|
facesFileNameExtension,
|
||||||
|
a2PeopleSingletonDirectory,
|
||||||
personKeyToPersonContainer,
|
personKeyToPersonContainer,
|
||||||
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,8 @@ public class B_Metadata
|
|||||||
{
|
{
|
||||||
object? @object;
|
object? @object;
|
||||||
string? tagDescription;
|
string? tagDescription;
|
||||||
int type = (int)IExif.Tags.Orientation;
|
|
||||||
List<string> tagNames = new();
|
List<string> tagNames = new();
|
||||||
|
int type = (int)IExif.Tags.Orientation;
|
||||||
string key = nameof(IExif.Tags.Orientation);
|
string key = nameof(IExif.Tags.Orientation);
|
||||||
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(subFile);
|
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(subFile);
|
||||||
foreach (MetadataExtractor.Directory directory in directories)
|
foreach (MetadataExtractor.Directory directory in directories)
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
"WorkingDirectoryName": "PharesApps",
|
"WorkingDirectoryName": "PharesApps",
|
||||||
"Windows": {
|
"Windows": {
|
||||||
"Configuration": {
|
"Configuration": {
|
||||||
"DateGroup": "2022-09-15",
|
"DateGroup": "2022-09-22",
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||||
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
"WorkingDirectoryName": "PharesApps",
|
"WorkingDirectoryName": "PharesApps",
|
||||||
"Windows": {
|
"Windows": {
|
||||||
"Configuration": {
|
"Configuration": {
|
||||||
"DateGroup": "2022-09-15",
|
"DateGroup": "2022-09-22",
|
||||||
"FileNameDirectorySeparator": ".Z.",
|
"FileNameDirectorySeparator": ".Z.",
|
||||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||||
"KeepFullPath": false,
|
"KeepFullPath": false,
|
||||||
|
@ -4,6 +4,6 @@ public interface IFaceDistance
|
|||||||
{
|
{
|
||||||
|
|
||||||
List<Face> GetMatchingFaces(double faceDistanceTolerance, string checkFile, List<Face> faces);
|
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
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Instance", "Instance\Instance.csproj", "{8085C1EE-C4DB-43DE-8888-1C956D69CF91}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Instance", "Instance\Instance.csproj", "{8085C1EE-C4DB-43DE-8888-1C956D69CF91}"
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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}.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.ActiveCfg = Release|Any CPU
|
||||||
{8085C1EE-C4DB-43DE-8888-1C956D69CF91}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
Loading…
x
Reference in New Issue
Block a user