IgnoreExtensions-nef
Config-LoadPhotoPrismLocations TestMethodIntersect
This commit is contained in:
parent
1d0506d74c
commit
6f22929136
@ -13,6 +13,9 @@ completedColumns:
|
|||||||
|
|
||||||
## Todo
|
## Todo
|
||||||
|
|
||||||
|
- [nef-support](tasks/nef-support.md)
|
||||||
|
- [determine-if-location-container-collection-is-needed-in-get-faces](tasks/determine-if-location-container-collection-is-needed-in-get-faces.md)
|
||||||
|
- [use-eyes-to-find-orientation](tasks/use-eyes-to-find-orientation.md)
|
||||||
- [use-photo-prism-to-map](tasks/use-photo-prism-to-map.md)
|
- [use-photo-prism-to-map](tasks/use-photo-prism-to-map.md)
|
||||||
- [import-face-region-metadata](tasks/import-face-region-metadata.md)
|
- [import-face-region-metadata](tasks/import-face-region-metadata.md)
|
||||||
|
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
created: 2023-06-12T15:44:11.932Z
|
||||||
|
updated: 2023-06-12T15:45:59.891Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 0
|
||||||
|
tags: []
|
||||||
|
---
|
||||||
|
|
||||||
|
# determine-if-location-container-collection-is-needed-in-get-faces
|
||||||
|
|
||||||
|
```c#
|
||||||
|
locations = Shared.Models.Stateless.Methods.ILocation.GetLocations(collection, results, mappingFromPhotoPrismCollection, _RectangleIntersectMinimum);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sub-tasks
|
||||||
|
|
||||||
|
- [ ] See code above
|
13
.kanbn/tasks/nef-support.md
Normal file
13
.kanbn/tasks/nef-support.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
created: 2023-06-12T15:44:11.932Z
|
||||||
|
updated: 2023-06-12T15:45:59.891Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 0
|
||||||
|
tags: []
|
||||||
|
---
|
||||||
|
|
||||||
|
# nef-support
|
||||||
|
|
||||||
|
## Sub-tasks
|
||||||
|
|
||||||
|
- [ ] asdf
|
13
.kanbn/tasks/use-eyes-to-find-orientation.md
Normal file
13
.kanbn/tasks/use-eyes-to-find-orientation.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
created: 2023-06-12T15:44:11.932Z
|
||||||
|
updated: 2023-06-12T15:45:59.891Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 0
|
||||||
|
tags: []
|
||||||
|
---
|
||||||
|
|
||||||
|
# use-eyes-to-find-orientation
|
||||||
|
|
||||||
|
## Sub-tasks
|
||||||
|
|
||||||
|
- [ ] asdf
|
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@ -18,6 +18,7 @@
|
|||||||
"Greyscale",
|
"Greyscale",
|
||||||
"Hasher",
|
"Hasher",
|
||||||
"jfif",
|
"jfif",
|
||||||
|
"JOSN",
|
||||||
"mmod",
|
"mmod",
|
||||||
"Nicéphore",
|
"Nicéphore",
|
||||||
"Niépce",
|
"Niépce",
|
||||||
@ -42,5 +43,8 @@
|
|||||||
"**/.git": false
|
"**/.git": false
|
||||||
},
|
},
|
||||||
"coverage-gutters.coverageBaseDir": "./.vscode/ReportGenerator/Cobertura/*",
|
"coverage-gutters.coverageBaseDir": "./.vscode/ReportGenerator/Cobertura/*",
|
||||||
"extensions.ignoreRecommendations": true
|
"extensions.ignoreRecommendations": true,
|
||||||
|
"[markdown]": {
|
||||||
|
"editor.wordWrap": "off"
|
||||||
|
}
|
||||||
}
|
}
|
@ -92,6 +92,8 @@
|
|||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF",
|
".GIF",
|
||||||
|
".nef",
|
||||||
|
".NEF",
|
||||||
".pdf",
|
".pdf",
|
||||||
".PDF"
|
".PDF"
|
||||||
],
|
],
|
||||||
|
@ -72,6 +72,8 @@
|
|||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF",
|
".GIF",
|
||||||
|
".nef",
|
||||||
|
".NEF",
|
||||||
".pdf",
|
".pdf",
|
||||||
".PDF"
|
".PDF"
|
||||||
],
|
],
|
||||||
|
@ -72,6 +72,8 @@
|
|||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF",
|
".GIF",
|
||||||
|
".nef",
|
||||||
|
".NEF",
|
||||||
".pdf",
|
".pdf",
|
||||||
".PDF"
|
".PDF"
|
||||||
],
|
],
|
||||||
|
@ -74,6 +74,8 @@
|
|||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF",
|
".GIF",
|
||||||
|
".nef",
|
||||||
|
".NEF",
|
||||||
".pdf",
|
".pdf",
|
||||||
".PDF"
|
".PDF"
|
||||||
],
|
],
|
||||||
|
@ -69,6 +69,8 @@
|
|||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF",
|
".GIF",
|
||||||
|
".nef",
|
||||||
|
".NEF",
|
||||||
".pdf",
|
".pdf",
|
||||||
".PDF"
|
".PDF"
|
||||||
],
|
],
|
||||||
|
@ -23,7 +23,7 @@ public partial class E_Distance
|
|||||||
private readonly double _RangeDistanceToleranceAverage;
|
private readonly double _RangeDistanceToleranceAverage;
|
||||||
private readonly List<string> _DuplicateMappedFaceFiles;
|
private readonly List<string> _DuplicateMappedFaceFiles;
|
||||||
|
|
||||||
public E_Distance(bool distanceMoveUnableToMatch, bool distanceRenameToMatch, int faceConfidencePercent, float[] rangeDistanceTolerance, float[] rangeFaceConfidence, float[] rectangleIntersectMinimum)
|
public E_Distance(bool distanceMoveUnableToMatch, bool distanceRenameToMatch, int faceConfidencePercent, float[] rangeDistanceTolerance, float[] rangeFaceConfidence, float[] rectangleIntersectMinimums)
|
||||||
{
|
{
|
||||||
_Debug = new();
|
_Debug = new();
|
||||||
_Moved = new();
|
_Moved = new();
|
||||||
@ -36,7 +36,7 @@ public partial class E_Distance
|
|||||||
_DistanceRenameToMatch = distanceRenameToMatch;
|
_DistanceRenameToMatch = distanceRenameToMatch;
|
||||||
_FaceConfidencePercent = faceConfidencePercent;
|
_FaceConfidencePercent = faceConfidencePercent;
|
||||||
_DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
|
_DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
|
||||||
_RectangleIntersectMinimum = rectangleIntersectMinimum.Max();
|
_RectangleIntersectMinimum = rectangleIntersectMinimums.Max();
|
||||||
_RangeDistanceToleranceAverage = rangeDistanceTolerance.Average();
|
_RangeDistanceToleranceAverage = rangeDistanceTolerance.Average();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ public partial class E_Distance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, MappingFromItem mappingFromItem, List<Face> faces, List<LocationContainer<MetadataExtractor.Directory>> collection)
|
public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, MappingFromItem mappingFromItem, List<Face> faces, List<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
||||||
{
|
{
|
||||||
string? json;
|
string? json;
|
||||||
string fileName;
|
string fileName;
|
||||||
@ -211,7 +211,7 @@ public partial class E_Distance
|
|||||||
Face[] filteredFaces = (from l in faces where l.FaceEncoding is not null && l.Location is not null && l.OutputResolution is not null select l).ToArray();
|
Face[] filteredFaces = (from l in faces where l.FaceEncoding is not null && l.Location is not null && l.OutputResolution is not null select l).ToArray();
|
||||||
if (filteredFaces.Length != faces.Count)
|
if (filteredFaces.Length != faces.Count)
|
||||||
checkFaces.Clear();
|
checkFaces.Clear();
|
||||||
foreach (LocationContainer<MetadataExtractor.Directory>? locationContainer in collection)
|
foreach (LocationContainer<MetadataExtractor.Directory>? locationContainer in locationContainers)
|
||||||
{
|
{
|
||||||
if (_Renamed.Contains(locationContainer.File))
|
if (_Renamed.Contains(locationContainer.File))
|
||||||
continue;
|
continue;
|
||||||
|
@ -71,6 +71,8 @@
|
|||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF",
|
".GIF",
|
||||||
|
".nef",
|
||||||
|
".NEF",
|
||||||
".pdf",
|
".pdf",
|
||||||
".PDF"
|
".PDF"
|
||||||
],
|
],
|
||||||
|
@ -34,12 +34,14 @@ public class D_Face
|
|||||||
private readonly Serilog.ILogger? _Log;
|
private readonly Serilog.ILogger? _Log;
|
||||||
private readonly bool _OverrideForFaceImages;
|
private readonly bool _OverrideForFaceImages;
|
||||||
private readonly Configuration _Configuration;
|
private readonly Configuration _Configuration;
|
||||||
|
private readonly bool _LoadPhotoPrismLocations;
|
||||||
private readonly ImageCodecInfo _ImageCodecInfo;
|
private readonly ImageCodecInfo _ImageCodecInfo;
|
||||||
private readonly ModelParameter _ModelParameter;
|
private readonly ModelParameter _ModelParameter;
|
||||||
private readonly PredictorModel _PredictorModel;
|
private readonly PredictorModel _PredictorModel;
|
||||||
private readonly bool _CheckDFaceAndUpWriteDates;
|
private readonly bool _CheckDFaceAndUpWriteDates;
|
||||||
private readonly bool _PropertiesChangedForFaces;
|
private readonly bool _PropertiesChangedForFaces;
|
||||||
private readonly ConstructorInfo _ConstructorInfo;
|
private readonly ConstructorInfo _ConstructorInfo;
|
||||||
|
private readonly float _RectangleIntersectMinimum;
|
||||||
private readonly int _FaceDistanceHiddenImageFactor;
|
private readonly int _FaceDistanceHiddenImageFactor;
|
||||||
private readonly EncoderParameters _EncoderParameters;
|
private readonly EncoderParameters _EncoderParameters;
|
||||||
private readonly ImageCodecInfo _HiddenImageCodecInfo;
|
private readonly ImageCodecInfo _HiddenImageCodecInfo;
|
||||||
@ -59,11 +61,13 @@ public class D_Face
|
|||||||
string hiddenFileNameExtension,
|
string hiddenFileNameExtension,
|
||||||
ImageCodecInfo hiddenImageCodecInfo,
|
ImageCodecInfo hiddenImageCodecInfo,
|
||||||
ImageCodecInfo imageCodecInfo,
|
ImageCodecInfo imageCodecInfo,
|
||||||
|
bool loadPhotoPrismLocations,
|
||||||
string modelDirectory,
|
string modelDirectory,
|
||||||
string modelName,
|
string modelName,
|
||||||
bool overrideForFaceImages,
|
bool overrideForFaceImages,
|
||||||
string predictorModelName,
|
string predictorModelName,
|
||||||
bool propertiesChangedForFaces)
|
bool propertiesChangedForFaces,
|
||||||
|
float[] rectangleIntersectMinimums)
|
||||||
{
|
{
|
||||||
_ArgZero = argZero;
|
_ArgZero = argZero;
|
||||||
_Configuration = configuration;
|
_Configuration = configuration;
|
||||||
@ -76,17 +80,17 @@ public class D_Face
|
|||||||
_OverrideForFaceImages = overrideForFaceImages;
|
_OverrideForFaceImages = overrideForFaceImages;
|
||||||
_HiddenEncoderParameters = hiddenEncoderParameters;
|
_HiddenEncoderParameters = hiddenEncoderParameters;
|
||||||
_HiddenFileNameExtension = hiddenFileNameExtension;
|
_HiddenFileNameExtension = hiddenFileNameExtension;
|
||||||
|
_LoadPhotoPrismLocations = loadPhotoPrismLocations;
|
||||||
_CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
|
_CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
|
||||||
_PropertiesChangedForFaces = propertiesChangedForFaces;
|
_PropertiesChangedForFaces = propertiesChangedForFaces;
|
||||||
|
_RectangleIntersectMinimum = rectangleIntersectMinimums.Min();
|
||||||
_FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
|
_FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
|
||||||
_ForceFaceLastWriteTimeToCreationTime = forceFaceLastWriteTimeToCreationTime;
|
_ForceFaceLastWriteTimeToCreationTime = forceFaceLastWriteTimeToCreationTime;
|
||||||
(Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(modelDirectory, modelName, predictorModelName);
|
(Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(modelDirectory, modelName, predictorModelName);
|
||||||
_Model = model;
|
_Model = model;
|
||||||
_PredictorModel = predictorModel;
|
_PredictorModel = predictorModel;
|
||||||
_ModelParameter = modelParameter;
|
_ModelParameter = modelParameter;
|
||||||
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) ?? throw new Exception();
|
||||||
if (constructorInfo is null)
|
|
||||||
throw new Exception();
|
|
||||||
_ConstructorInfo = constructorInfo;
|
_ConstructorInfo = constructorInfo;
|
||||||
_WriteIndentedAndWhenWritingNull = new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull };
|
_WriteIndentedAndWhenWritingNull = new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull };
|
||||||
}
|
}
|
||||||
@ -294,7 +298,7 @@ public class D_Face
|
|||||||
|
|
||||||
#pragma warning restore CA1416
|
#pragma warning restore CA1416
|
||||||
|
|
||||||
private static List<LocationContainer<MetadataExtractor.Directory>> GetCollection(string outputResolution, List<LocationContainer<MetadataExtractor.Directory>> collection, Dictionary<string, int[]> outputResolutionToResize, List<Shared.Models.Face> faces)
|
private static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(string outputResolution, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, Dictionary<string, int[]> outputResolutionToResize, List<Shared.Models.Face> faces)
|
||||||
{
|
{
|
||||||
List<LocationContainer<MetadataExtractor.Directory>> results = new();
|
List<LocationContainer<MetadataExtractor.Directory>> results = new();
|
||||||
string? json;
|
string? json;
|
||||||
@ -309,7 +313,7 @@ public class D_Face
|
|||||||
continue;
|
continue;
|
||||||
skip.Add(Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, ILocation.Digits, face.OutputResolution));
|
skip.Add(Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, ILocation.Digits, face.OutputResolution));
|
||||||
}
|
}
|
||||||
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in collection)
|
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
|
||||||
{
|
{
|
||||||
if (locationContainer.Directories is null)
|
if (locationContainer.Directories is null)
|
||||||
continue;
|
continue;
|
||||||
@ -340,7 +344,7 @@ public class D_Face
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Shared.Models.Face> GetFaces(string outputResolution, string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<LocationContainer<MetadataExtractor.Directory>>? collection, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection)
|
public List<Shared.Models.Face> GetFaces(string outputResolution, string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<LocationContainer<MetadataExtractor.Directory>>? locationContainers, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection)
|
||||||
{
|
{
|
||||||
List<Shared.Models.Face>? results;
|
List<Shared.Models.Face>? results;
|
||||||
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
|
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
|
||||||
@ -383,15 +387,15 @@ public class D_Face
|
|||||||
parseExceptions.Add(nameof(D_Face));
|
parseExceptions.Add(nameof(D_Face));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<LocationContainer<MetadataExtractor.Directory>> locationContainers;
|
List<LocationContainer<MetadataExtractor.Directory>> collection;
|
||||||
if (results is null || collection is null)
|
if (results is null || locationContainers is null)
|
||||||
locationContainers = new();
|
collection = new();
|
||||||
else
|
else
|
||||||
locationContainers = GetCollection(outputResolution, collection, outputResolutionToResize, results);
|
collection = GetLocationContainers(outputResolution, locationContainers, outputResolutionToResize, results);
|
||||||
if (mappingFromPhotoPrismCollection is null || results is null)
|
if (!_LoadPhotoPrismLocations || mappingFromPhotoPrismCollection is null || results is null)
|
||||||
locations = (from l in locationContainers where l is not null select l.Location).ToList();
|
locations = (from l in collection where l is not null select l.Location).ToList();
|
||||||
else
|
else
|
||||||
locations = Shared.Models.Stateless.Methods.ILocation.GetLocations(mappingFromPhotoPrismCollection, results, locationContainers);
|
locations = Shared.Models.Stateless.Methods.ILocation.GetLocations(collection, results, mappingFromPhotoPrismCollection, _RectangleIntersectMinimum);
|
||||||
if (results is null || (locations is not null && locations.Any()))
|
if (results is null || (locations is not null && locations.Any()))
|
||||||
{
|
{
|
||||||
results = GetFaces(outputResolution, property, mappingFromItem, outputResolutionToResize, locations);
|
results = GetFaces(outputResolution, property, mappingFromItem, outputResolutionToResize, locations);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an ordered pair of integer x- and y-coordinates that defines a point in a two-dimensional plane.
|
/// Represents an ordered pair of integer x- and y-coordinates that defines a point in a two-dimensional plane.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct Point : IEquatable<Point>
|
public readonly struct Point : IEquatable<Point>
|
||||||
{
|
{
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
@ -73,7 +73,9 @@ public struct Point : IEquatable<Point>
|
|||||||
/// Returns the hash code for this <see cref="Point"/>.
|
/// Returns the hash code for this <see cref="Point"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The hash code for this <see cref="Point"/> structure.</returns>
|
/// <returns>The hash code for this <see cref="Point"/> structure.</returns>
|
||||||
|
#pragma warning disable IDE0070
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
|
#pragma warning restore IDE0070
|
||||||
{
|
{
|
||||||
int hashCode = 1861411795;
|
int hashCode = 1861411795;
|
||||||
hashCode = hashCode * -1521134295 + X.GetHashCode();
|
hashCode = hashCode * -1521134295 + X.GetHashCode();
|
||||||
|
@ -95,11 +95,13 @@ public partial class DlibDotNet
|
|||||||
hiddenFileNameExtension,
|
hiddenFileNameExtension,
|
||||||
hiddenImageCodecInfo,
|
hiddenImageCodecInfo,
|
||||||
imageCodecInfo,
|
imageCodecInfo,
|
||||||
|
configuration.LoadPhotoPrismLocations,
|
||||||
configuration.ModelDirectory,
|
configuration.ModelDirectory,
|
||||||
configuration.ModelName,
|
configuration.ModelName,
|
||||||
configuration.OverrideForFaceImages,
|
configuration.OverrideForFaceImages,
|
||||||
configuration.PredictorModelName,
|
configuration.PredictorModelName,
|
||||||
configuration.PropertiesChangedForFaces);
|
configuration.PropertiesChangedForFaces,
|
||||||
|
configuration.RectangleIntersectMinimums);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
|
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
|
||||||
@ -456,14 +458,14 @@ public partial class DlibDotNet
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection;
|
List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection;
|
||||||
List<LocationContainer<MetadataExtractor.Directory>>? collection;
|
List<LocationContainer<MetadataExtractor.Directory>>? locationContainers;
|
||||||
if (item.Property?.Id is null)
|
if (item.Property?.Id is null)
|
||||||
collection = null;
|
locationContainers = null;
|
||||||
else
|
else
|
||||||
_ = idToLocationContainers.TryGetValue(item.Property.Id.Value, out collection);
|
_ = idToLocationContainers.TryGetValue(item.Property.Id.Value, out locationContainers);
|
||||||
if (!fileNameToCollection.TryGetValue(mappingFromItem.Id, out mappingFromPhotoPrismCollection))
|
if (!fileNameToCollection.TryGetValue(mappingFromItem.Id, out mappingFromPhotoPrismCollection))
|
||||||
mappingFromPhotoPrismCollection = null;
|
mappingFromPhotoPrismCollection = null;
|
||||||
faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, collection, mappingFromPhotoPrismCollection);
|
faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, locationContainers, mappingFromPhotoPrismCollection);
|
||||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||||
ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
|
ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
|
||||||
List<(Shared.Models.Face, FileInfo?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, facesDirectory, faces);
|
List<(Shared.Models.Face, FileInfo?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, facesDirectory, faces);
|
||||||
@ -474,8 +476,8 @@ public partial class DlibDotNet
|
|||||||
ticks = LogDelta(ticks, nameof(D_Face.SaveFaces));
|
ticks = LogDelta(ticks, nameof(D_Face.SaveFaces));
|
||||||
if ((_Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch)
|
if ((_Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch)
|
||||||
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
|
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
|
||||||
&& collection is not null && faceCollection.All(l => !l.Saved))
|
&& locationContainers is not null && faceCollection.All(l => !l.Saved))
|
||||||
_Distance.LookForMatchFacesAndPossiblyRename(_Faces.FileNameExtension, mappingFromItem, faces, collection);
|
_Distance.LookForMatchFacesAndPossiblyRename(_Faces.FileNameExtension, mappingFromItem, faces, locationContainers);
|
||||||
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||||
{
|
{
|
||||||
bool saveRotated = false;
|
bool saveRotated = false;
|
||||||
@ -881,11 +883,11 @@ public partial class DlibDotNet
|
|||||||
private static void LookForAbandoned(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, List<int> distinctFilteredIds)
|
private static void LookForAbandoned(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, List<int> distinctFilteredIds)
|
||||||
{
|
{
|
||||||
List<string> renameCollection = new();
|
List<string> renameCollection = new();
|
||||||
foreach (KeyValuePair<int, List<LocationContainer<MetadataExtractor.Directory>>> idToCollection in idToLocationContainers)
|
foreach (KeyValuePair<int, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePair in idToLocationContainers)
|
||||||
{
|
{
|
||||||
if (distinctFilteredIds.Contains(idToCollection.Key))
|
if (distinctFilteredIds.Contains(keyValuePair.Key))
|
||||||
continue;
|
continue;
|
||||||
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in idToCollection.Value)
|
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in keyValuePair.Value)
|
||||||
{
|
{
|
||||||
if (locationContainer.File.Contains('!'))
|
if (locationContainer.File.Contains('!'))
|
||||||
continue;
|
continue;
|
||||||
|
@ -34,6 +34,7 @@ public class Configuration
|
|||||||
[Display(Name = "Julie Phares Copy Birthdays"), Required] public string[] JLinks { get; set; }
|
[Display(Name = "Julie Phares Copy Birthdays"), Required] public string[] JLinks { get; set; }
|
||||||
[Display(Name = "Load Or Create Then Save Distance Results"), Required] public string[] LoadOrCreateThenSaveDistanceResultsForOutputResolutions { get; set; }
|
[Display(Name = "Load Or Create Then Save Distance Results"), Required] public string[] LoadOrCreateThenSaveDistanceResultsForOutputResolutions { get; set; }
|
||||||
[Display(Name = "Load Or Create Then Save Image Faces Results"), Required] public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
|
[Display(Name = "Load Or Create Then Save Image Faces Results"), Required] public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
|
||||||
|
[Display(Name = "Load PhotoPrism Locations"), Required] public bool? LoadPhotoPrismLocations { get; set; }
|
||||||
[Display(Name = "Location Digits"), Required] public int? LocationDigits { get; set; }
|
[Display(Name = "Location Digits"), Required] public int? LocationDigits { get; set; }
|
||||||
[Display(Name = "Location Factor"), Required] public int? LocationFactor { get; set; }
|
[Display(Name = "Location Factor"), Required] public int? LocationFactor { get; set; }
|
||||||
[Display(Name = "Look for Abandoned"), Required] public bool? LookForAbandoned { get; set; }
|
[Display(Name = "Look for Abandoned"), Required] public bool? LookForAbandoned { get; set; }
|
||||||
@ -145,6 +146,8 @@ public class Configuration
|
|||||||
configuration.IgnoreRelativePaths ??= Array.Empty<string>();
|
configuration.IgnoreRelativePaths ??= Array.Empty<string>();
|
||||||
configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions ??= Array.Empty<string>();
|
configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions ??= Array.Empty<string>();
|
||||||
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ??= Array.Empty<string>();
|
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ??= Array.Empty<string>();
|
||||||
|
if (configuration.LoadPhotoPrismLocations is null)
|
||||||
|
throw new NullReferenceException(nameof(configuration.LoadPhotoPrismLocations));
|
||||||
if (configuration.LocationDigits is null)
|
if (configuration.LocationDigits is null)
|
||||||
throw new NullReferenceException(nameof(configuration.LocationDigits));
|
throw new NullReferenceException(nameof(configuration.LocationDigits));
|
||||||
if (configuration.LocationFactor is null)
|
if (configuration.LocationFactor is null)
|
||||||
@ -261,6 +264,7 @@ public class Configuration
|
|||||||
configuration.JLinks,
|
configuration.JLinks,
|
||||||
configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions,
|
configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions,
|
||||||
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions,
|
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions,
|
||||||
|
configuration.LoadPhotoPrismLocations.Value,
|
||||||
configuration.LocationDigits.Value,
|
configuration.LocationDigits.Value,
|
||||||
configuration.LocationFactor.Value,
|
configuration.LocationFactor.Value,
|
||||||
configuration.LookForAbandoned.Value,
|
configuration.LookForAbandoned.Value,
|
||||||
|
@ -33,6 +33,7 @@ public class Configuration
|
|||||||
public string[] JLinks { init; get; }
|
public string[] JLinks { init; get; }
|
||||||
public string[] LoadOrCreateThenSaveDistanceResultsForOutputResolutions { init; get; }
|
public string[] LoadOrCreateThenSaveDistanceResultsForOutputResolutions { init; get; }
|
||||||
public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { init; get; }
|
public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { init; get; }
|
||||||
|
public bool LoadPhotoPrismLocations { init; get; }
|
||||||
public int LocationDigits { init; get; }
|
public int LocationDigits { init; get; }
|
||||||
public int LocationFactor { init; get; }
|
public int LocationFactor { init; get; }
|
||||||
public bool LookForAbandoned { init; get; }
|
public bool LookForAbandoned { init; get; }
|
||||||
@ -112,6 +113,7 @@ public class Configuration
|
|||||||
string[] jLinks,
|
string[] jLinks,
|
||||||
string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions,
|
string[] loadOrCreateThenSaveDistanceResultsForOutputResolutions,
|
||||||
string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions,
|
string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions,
|
||||||
|
bool loadPhotoPrismLocations,
|
||||||
int locationDigits,
|
int locationDigits,
|
||||||
int locationFactor,
|
int locationFactor,
|
||||||
bool lookForAbandoned,
|
bool lookForAbandoned,
|
||||||
@ -190,6 +192,7 @@ public class Configuration
|
|||||||
JLinks = jLinks;
|
JLinks = jLinks;
|
||||||
LoadOrCreateThenSaveDistanceResultsForOutputResolutions = loadOrCreateThenSaveDistanceResultsForOutputResolutions;
|
LoadOrCreateThenSaveDistanceResultsForOutputResolutions = loadOrCreateThenSaveDistanceResultsForOutputResolutions;
|
||||||
LoadOrCreateThenSaveImageFacesResultsForOutputResolutions = loadOrCreateThenSaveImageFacesResultsForOutputResolutions;
|
LoadOrCreateThenSaveImageFacesResultsForOutputResolutions = loadOrCreateThenSaveImageFacesResultsForOutputResolutions;
|
||||||
|
LoadPhotoPrismLocations = loadPhotoPrismLocations;
|
||||||
LocationDigits = locationDigits;
|
LocationDigits = locationDigits;
|
||||||
LocationFactor = locationFactor;
|
LocationFactor = locationFactor;
|
||||||
LookForAbandoned = lookForAbandoned;
|
LookForAbandoned = lookForAbandoned;
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
"FocusDirectory": "",
|
"FocusDirectory": "",
|
||||||
"FocusModel": "",
|
"FocusModel": "",
|
||||||
"GenealogicalDataCommunicationFile": "",
|
"GenealogicalDataCommunicationFile": "",
|
||||||
|
"LoadPhotoPrismLocations": false,
|
||||||
"LocationDigits": 9,
|
"LocationDigits": 9,
|
||||||
"LocationFactor": 10000,
|
"LocationFactor": 10000,
|
||||||
"LookForAbandoned": true,
|
"LookForAbandoned": true,
|
||||||
|
@ -607,7 +607,7 @@ internal abstract class MapLogic
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParallelFor(Configuration configuration, string eDistanceContentDirectory, List<LocationContainer<MetadataExtractor.Directory>> collection, long personKey, string file)
|
private static void ParallelFor(Configuration configuration, string eDistanceContentDirectory, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, long personKey, string file)
|
||||||
{
|
{
|
||||||
const string lnk = ".lnk";
|
const string lnk = ".lnk";
|
||||||
int? id, wholePercentages;
|
int? id, wholePercentages;
|
||||||
@ -623,29 +623,29 @@ internal abstract class MapLogic
|
|||||||
directories = new List<MetadataExtractor.Directory>();
|
directories = new List<MetadataExtractor.Directory>();
|
||||||
else
|
else
|
||||||
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file);
|
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file);
|
||||||
Rectangle? rectangle = ILocation.GetWholePercentages(configuration.LocationDigits, wholePercentages.Value);
|
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
|
||||||
lock (collection)
|
lock (locationContainers)
|
||||||
collection.Add(new(fromDistanceContent, file, personKey, id.Value, wholePercentages.Value, directories, rectangle, null));
|
locationContainers.Add(new(fromDistanceContent, file, personKey, id.Value, wholePercentages.Value, directories, rectangle, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OpenPossibleDuplicates(Configuration configuration, List<(long, int, string, double?)> duplicates)
|
private static void OpenPossibleDuplicates(Configuration configuration, List<(long, int, string, float?)> duplicates)
|
||||||
{
|
{
|
||||||
string personKeyFormatted;
|
string personKeyFormatted;
|
||||||
foreach ((long personKey, int id, string file, double? percent) in duplicates)
|
foreach ((long personKey, int id, string file, float? percent) in duplicates)
|
||||||
{
|
{
|
||||||
if (percent is null)
|
if (percent is null)
|
||||||
continue;
|
continue;
|
||||||
_ = Process.Start("explorer.exe", string.Concat("\"", Path.GetDirectoryName(file), "\""));
|
_ = Process.Start("explorer.exe", string.Concat("\"", Path.GetDirectoryName(file), "\""));
|
||||||
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey);
|
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey);
|
||||||
}
|
}
|
||||||
foreach ((long personKey, int id, string file, double? percent) in duplicates)
|
foreach ((long personKey, int id, string file, float? percent) in duplicates)
|
||||||
{
|
{
|
||||||
if (percent is not null && percent.Value == 0)
|
if (percent is not null && percent.Value == 0)
|
||||||
continue;
|
continue;
|
||||||
_ = Process.Start("explorer.exe", string.Concat("\"", Path.GetDirectoryName(file), "\""));
|
_ = Process.Start("explorer.exe", string.Concat("\"", Path.GetDirectoryName(file), "\""));
|
||||||
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey);
|
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey);
|
||||||
}
|
}
|
||||||
foreach ((long personKey, int id, string file, double? percent) in duplicates)
|
foreach ((long personKey, int id, string file, float? percent) in duplicates)
|
||||||
{
|
{
|
||||||
if (percent is not null && percent.Value > 0)
|
if (percent is not null && percent.Value > 0)
|
||||||
continue;
|
continue;
|
||||||
@ -654,35 +654,30 @@ internal abstract class MapLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void LookForPossibleDuplicates(Configuration configuration, List<LocationContainer<MetadataExtractor.Directory>> collection)
|
private static void LookForPossibleDuplicates(Configuration configuration, List<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
||||||
{
|
{
|
||||||
string key;
|
string key;
|
||||||
double? percent;
|
float? percent;
|
||||||
Rectangle? rectangle;
|
float itemPercentagesArea;
|
||||||
List<string> delete = new();
|
List<string> delete = new();
|
||||||
Rectangle intersectRectangle;
|
RectangleF? itemPercentagesRectangle;
|
||||||
(string File, int WholePercentages) item;
|
(string File, int WholePercentages) item;
|
||||||
Dictionary<string, (string, int)> distinct = new();
|
Dictionary<string, (string, int)> distinct = new();
|
||||||
List<(long, int, string, double?)> duplicates = new();
|
List<(long, int, string, float?)> duplicates = new();
|
||||||
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in collection)
|
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
|
||||||
{
|
{
|
||||||
key = string.Concat(locationContainer.PersonKey, locationContainer.Id);
|
key = string.Concat(locationContainer.PersonKey, locationContainer.Id);
|
||||||
if (distinct.TryGetValue(key, out item))
|
if (distinct.TryGetValue(key, out item))
|
||||||
{
|
{
|
||||||
if (item.WholePercentages == locationContainer.WholePercentages)
|
if (item.WholePercentages == locationContainer.WholePercentages)
|
||||||
continue;
|
continue;
|
||||||
if (locationContainer.Rectangle is null)
|
itemPercentagesRectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, item.WholePercentages);
|
||||||
|
if (itemPercentagesRectangle is null || locationContainer.Rectangle is null)
|
||||||
percent = null;
|
percent = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rectangle = ILocation.GetWholePercentages(configuration.LocationDigits, item.WholePercentages);
|
itemPercentagesArea = itemPercentagesRectangle.Value.Width * itemPercentagesRectangle.Value.Height;
|
||||||
if (locationContainer.Rectangle is null || rectangle is null)
|
percent = ILocation.GetIntersectPercent(itemPercentagesRectangle.Value, itemPercentagesArea, locationContainer.Rectangle.Value);
|
||||||
percent = null;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
intersectRectangle = Rectangle.Intersect(locationContainer.Rectangle.Value, rectangle.Value);
|
|
||||||
percent = intersectRectangle.Width * intersectRectangle.Height;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delete.Add(item.File);
|
delete.Add(item.File);
|
||||||
delete.Add(locationContainer.File);
|
delete.Add(locationContainer.File);
|
||||||
|
@ -72,6 +72,8 @@
|
|||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF",
|
".GIF",
|
||||||
|
".nef",
|
||||||
|
".NEF",
|
||||||
".pdf",
|
".pdf",
|
||||||
".PDF"
|
".PDF"
|
||||||
],
|
],
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF",
|
".GIF",
|
||||||
|
".nef",
|
||||||
|
".NEF",
|
||||||
".pdf",
|
".pdf",
|
||||||
".PDF"
|
".PDF"
|
||||||
],
|
],
|
||||||
@ -137,6 +139,8 @@
|
|||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF",
|
".GIF",
|
||||||
|
".nef",
|
||||||
|
".NEF",
|
||||||
".pdf",
|
".pdf",
|
||||||
".PDF"
|
".PDF"
|
||||||
],
|
],
|
||||||
|
@ -30,7 +30,7 @@ public record Marker(
|
|||||||
internal static Shared.Models.Marker Map(Marker marker)
|
internal static Shared.Models.Marker Map(Marker marker)
|
||||||
{
|
{
|
||||||
Shared.Models.Marker result;
|
Shared.Models.Marker result;
|
||||||
(double x, double y, double w, double h, double score) = (double.Parse(marker.X), double.Parse(marker.Y), double.Parse(marker.W), double.Parse(marker.H), double.Parse(marker.Score));
|
(float x, float y, float w, float h, float score) = (float.Parse(marker.X), float.Parse(marker.Y), float.Parse(marker.W), float.Parse(marker.H), float.Parse(marker.Score));
|
||||||
result = new(
|
result = new(
|
||||||
F_PhotoPrism.HexStringToString(marker.MarkerUid),
|
F_PhotoPrism.HexStringToString(marker.MarkerUid),
|
||||||
F_PhotoPrism.HexStringToString(marker.FileUid),
|
F_PhotoPrism.HexStringToString(marker.FileUid),
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System.Drawing;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using View_by_Distance.Shared.Models;
|
using View_by_Distance.Shared.Models;
|
||||||
@ -139,14 +140,14 @@ public class F_PhotoPrism
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PopulateSubjects(string mappingDefaultName, string personBirthdayFormat, List<string> subjects, StringBuilder stringBuilder, PersonContainer[] personContainers, (MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, double Percent)[] sortedCollection)
|
private static void PopulateSubjects(string mappingDefaultName, string personBirthdayFormat, List<string> subjects, StringBuilder stringBuilder, PersonContainer[] personContainers, (MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)[] sortedCollection)
|
||||||
{
|
{
|
||||||
long? personKey;
|
long? personKey;
|
||||||
string personName;
|
string personName;
|
||||||
const int zero = 0;
|
const int zero = 0;
|
||||||
string personKeyFormatted;
|
string personKeyFormatted;
|
||||||
PersonBirthday personBirthday;
|
PersonBirthday personBirthday;
|
||||||
foreach ((MappingFromPhotoPrism mappingFromPhotoPrism, Shared.Models.Marker marker, double percent) in sortedCollection)
|
foreach ((MappingFromPhotoPrism mappingFromPhotoPrism, Shared.Models.Marker marker, float percent) in sortedCollection)
|
||||||
{
|
{
|
||||||
foreach (PersonContainer personContainer in personContainers)
|
foreach (PersonContainer personContainer in personContainers)
|
||||||
{
|
{
|
||||||
@ -173,18 +174,22 @@ public class F_PhotoPrism
|
|||||||
{
|
{
|
||||||
string file;
|
string file;
|
||||||
string text;
|
string text;
|
||||||
double percent;
|
float dlibArea;
|
||||||
|
float? percent;
|
||||||
|
string directory;
|
||||||
|
int width, height;
|
||||||
int? wholePercentages;
|
int? wholePercentages;
|
||||||
|
RectangleF? prismRectangle;
|
||||||
List<string> subjects = new();
|
List<string> subjects = new();
|
||||||
|
DateTime dateTime = new(ticks);
|
||||||
|
int dlibLocationWholePercentages;
|
||||||
PersonContainer[]? personContainers;
|
PersonContainer[]? personContainers;
|
||||||
StringBuilder stringBuilder = new();
|
StringBuilder stringBuilder = new();
|
||||||
System.Drawing.Rectangle dlibRectangle;
|
RectangleF? dlibPercentagesRectangle;
|
||||||
System.Drawing.Rectangle? prismRectangle;
|
|
||||||
System.Drawing.Rectangle intersectRectangle;
|
|
||||||
float rectangleIntersectMinimum = rectangleIntersectMinimums.Min();
|
float rectangleIntersectMinimum = rectangleIntersectMinimums.Min();
|
||||||
Dictionary<int, PersonContainer[]>? wholePercentagesToPersonContainers;
|
Dictionary<int, PersonContainer[]>? wholePercentagesToPersonContainers;
|
||||||
(MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, double Percent)[] sortedCollection;
|
(MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)[] sortedCollection;
|
||||||
List<(MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, double Percent)> collection = new();
|
List<(MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)> collection = new();
|
||||||
foreach (Face face in distinctFilteredFaces)
|
foreach (Face face in distinctFilteredFaces)
|
||||||
{
|
{
|
||||||
collection.Clear();
|
collection.Clear();
|
||||||
@ -198,21 +203,23 @@ public class F_PhotoPrism
|
|||||||
(_, wholePercentagesToPersonContainers) = mapLogic.GetWholePercentagesToPersonContainers(face.Mapping.MappingFromItem.Id);
|
(_, wholePercentagesToPersonContainers) = mapLogic.GetWholePercentagesToPersonContainers(face.Mapping.MappingFromItem.Id);
|
||||||
if (wholePercentagesToPersonContainers is null || !wholePercentagesToPersonContainers.TryGetValue(wholePercentages.Value, out personContainers))
|
if (wholePercentagesToPersonContainers is null || !wholePercentagesToPersonContainers.TryGetValue(wholePercentages.Value, out personContainers))
|
||||||
continue;
|
continue;
|
||||||
dlibRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
|
(width, height) = IOutputResolution.Get(face.OutputResolution);
|
||||||
|
dlibLocationWholePercentages = ILocation.GetWholePercentages(height, face.Location, Shared.Models.Stateless.ILocation.Digits, width);
|
||||||
|
dlibPercentagesRectangle = ILocation.GetPercentagesRectangle(Shared.Models.Stateless.ILocation.Digits, dlibLocationWholePercentages);
|
||||||
|
if (dlibPercentagesRectangle is null)
|
||||||
|
continue;
|
||||||
|
dlibArea = dlibPercentagesRectangle.Value.Width * dlibPercentagesRectangle.Value.Height;
|
||||||
foreach (MappingFromPhotoPrism mappingFromPhotoPrism in face.Mapping.MappingFromPhotoPrismCollection)
|
foreach (MappingFromPhotoPrism mappingFromPhotoPrism in face.Mapping.MappingFromPhotoPrismCollection)
|
||||||
{
|
{
|
||||||
foreach (Shared.Models.Marker marker in mappingFromPhotoPrism.Markers)
|
foreach (Shared.Models.Marker marker in mappingFromPhotoPrism.Markers)
|
||||||
{
|
{
|
||||||
prismRectangle = ILocation.GetRectangle(mappingFromPhotoPrism.DatabaseFile, marker, face.OutputResolution);
|
prismRectangle = ILocation.GetPercentagesRectangle(mappingFromPhotoPrism.DatabaseFile, marker, face.OutputResolution);
|
||||||
if (prismRectangle is null)
|
if (prismRectangle is null)
|
||||||
continue;
|
continue;
|
||||||
intersectRectangle = System.Drawing.Rectangle.Intersect(dlibRectangle, prismRectangle.Value);
|
percent = ILocation.GetIntersectPercent(dlibPercentagesRectangle.Value, dlibArea, prismRectangle.Value);
|
||||||
if (intersectRectangle.Width == 0 || intersectRectangle.Height == 0)
|
if (percent is null || percent < rectangleIntersectMinimum)
|
||||||
continue;
|
continue;
|
||||||
percent = (double)intersectRectangle.Width * intersectRectangle.Height / (dlibRectangle.Width * dlibRectangle.Height);
|
collection.Add(new(mappingFromPhotoPrism, marker, percent.Value));
|
||||||
if (percent < rectangleIntersectMinimum)
|
|
||||||
continue;
|
|
||||||
collection.Add(new(mappingFromPhotoPrism, marker, percent));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!collection.Any())
|
if (!collection.Any())
|
||||||
@ -222,10 +229,13 @@ public class F_PhotoPrism
|
|||||||
}
|
}
|
||||||
if (subjects.Any())
|
if (subjects.Any())
|
||||||
{
|
{
|
||||||
file = Path.Combine(fPhotoPrismContentDirectory, $"{ticks}-{rectangleIntersectMinimum}-subject_alias_update.sql");
|
directory = Path.Combine(fPhotoPrismContentDirectory, dateTime.ToString("yyyy-MM-dd"));
|
||||||
|
if (!Directory.Exists(directory))
|
||||||
|
_ = Directory.CreateDirectory(directory);
|
||||||
|
file = Path.Combine(directory, $"{ticks}-{rectangleIntersectMinimum}-subject_alias_update.sql");
|
||||||
text = string.Join(Environment.NewLine, subjects.Distinct());
|
text = string.Join(Environment.NewLine, subjects.Distinct());
|
||||||
_ = IPath.WriteAllText(file, text, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
_ = IPath.WriteAllText(file, text, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
||||||
file = Path.Combine(fPhotoPrismContentDirectory, $"{ticks}-{rectangleIntersectMinimum}-marker_name_update.sql");
|
file = Path.Combine(directory, $"{ticks}-{rectangleIntersectMinimum}-marker_name_update.sql");
|
||||||
text = stringBuilder.ToString();
|
text = stringBuilder.ToString();
|
||||||
_ = IPath.WriteAllText(file, text, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
_ = IPath.WriteAllText(file, text, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,8 @@
|
|||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF",
|
".GIF",
|
||||||
|
".nef",
|
||||||
|
".NEF",
|
||||||
".pdf",
|
".pdf",
|
||||||
".PDF"
|
".PDF"
|
||||||
],
|
],
|
||||||
|
@ -73,6 +73,8 @@
|
|||||||
"IgnoreExtensions": [
|
"IgnoreExtensions": [
|
||||||
".gif",
|
".gif",
|
||||||
".GIF",
|
".GIF",
|
||||||
|
".nef",
|
||||||
|
".NEF",
|
||||||
".pdf",
|
".pdf",
|
||||||
".PDF"
|
".PDF"
|
||||||
],
|
],
|
||||||
|
@ -37,7 +37,9 @@ public class FacePoint : Properties.IFacePoint
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning disable IDE0070
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
|
#pragma warning restore IDE0070
|
||||||
{
|
{
|
||||||
int hashCode = 1861411795;
|
int hashCode = 1861411795;
|
||||||
hashCode = hashCode * -1521134295 + _Point.GetHashCode();
|
hashCode = hashCode * -1521134295 + _Point.GetHashCode();
|
||||||
|
@ -74,7 +74,9 @@ public class Location : Properties.ILocation, IEquatable<Location>
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning disable IDE0070
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
|
#pragma warning restore IDE0070
|
||||||
{
|
{
|
||||||
int hashCode = -773114317;
|
int hashCode = -773114317;
|
||||||
hashCode = hashCode * -1521134295 + Bottom.GetHashCode();
|
hashCode = hashCode * -1521134295 + Bottom.GetHashCode();
|
||||||
|
@ -2,5 +2,5 @@ using System.Drawing;
|
|||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public record LocationContainer<T>(bool FromDistanceContent, string File, long PersonKey, int Id, int WholePercentages, IReadOnlyList<T> Directories, Rectangle? Rectangle, Location? Location)
|
public record LocationContainer<T>(bool FromDistanceContent, string File, long PersonKey, int Id, int WholePercentages, IReadOnlyList<T> Directories, RectangleF? Rectangle, Location? Location)
|
||||||
{ }
|
{ }
|
@ -12,13 +12,13 @@ public record Marker(
|
|||||||
string? SubjSrc,
|
string? SubjSrc,
|
||||||
string? FaceId,
|
string? FaceId,
|
||||||
string FaceDist,
|
string FaceDist,
|
||||||
double X,
|
float X,
|
||||||
double Y,
|
float Y,
|
||||||
double W,
|
float W,
|
||||||
double H,
|
float H,
|
||||||
string Q,
|
string Q,
|
||||||
string Size,
|
string Size,
|
||||||
double Score,
|
float Score,
|
||||||
string? Thumb,
|
string? Thumb,
|
||||||
string MatchedAt,
|
string MatchedAt,
|
||||||
string CreatedAt,
|
string CreatedAt,
|
||||||
|
@ -31,9 +31,7 @@ internal abstract class Face
|
|||||||
private static JsonElement[] GetJsonElements(string jsonFileFullName)
|
private static JsonElement[] GetJsonElements(string jsonFileFullName)
|
||||||
{
|
{
|
||||||
string json = GetJson(jsonFileFullName);
|
string json = GetJson(jsonFileFullName);
|
||||||
JsonElement[]? jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json);
|
JsonElement[]? jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json) ?? throw new Exception();
|
||||||
if (jsonElements is null)
|
|
||||||
throw new Exception();
|
|
||||||
return jsonElements;
|
return jsonElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,25 +15,25 @@ public interface ILocation
|
|||||||
static List<Models.Face> FilterByIntersect(Models.Face[] faces, float rectangleIntersectMinimum, int wholePercentages) =>
|
static List<Models.Face> FilterByIntersect(Models.Face[] faces, float rectangleIntersectMinimum, int wholePercentages) =>
|
||||||
Location.FilterByIntersect(faces, rectangleIntersectMinimum, wholePercentages);
|
Location.FilterByIntersect(faces, rectangleIntersectMinimum, wholePercentages);
|
||||||
|
|
||||||
Rectangle? TestStatic_GetRectangle(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
|
RectangleF? TestStatic_GetPercentagesRectangle(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
|
||||||
GetRectangle(databaseFile, marker, outputResolution);
|
GetPercentagesRectangle(databaseFile, marker, outputResolution);
|
||||||
static Rectangle? GetRectangle(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
|
static RectangleF? GetPercentagesRectangle(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
|
||||||
Location.GetRectangle(databaseFile, marker, outputResolution);
|
Location.GetPercentagesRectangle(databaseFile, marker, outputResolution);
|
||||||
|
|
||||||
Models.Location? TestStatic_GetLocation(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
|
Models.Location? TestStatic_GetLocation(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
|
||||||
GetLocation(databaseFile, marker, outputResolution);
|
GetLocation(databaseFile, marker, outputResolution);
|
||||||
static Models.Location? GetLocation(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
|
static Models.Location? GetLocation(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
|
||||||
Location.GetLocation(databaseFile, marker, outputResolution);
|
Location.GetLocation(databaseFile, marker, outputResolution);
|
||||||
|
|
||||||
List<Models.Location> TestStatic_GetLocations<T>(List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, List<Models.Face> faces, List<LocationContainer<T>> containers) =>
|
List<Models.Location> TestStatic_GetLocations<T>(List<LocationContainer<T>> locationContainers, List<Models.Face> faces, List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, float rectangleIntersectMinimum) =>
|
||||||
GetLocations(mappingFromPhotoPrismCollection, faces, containers);
|
GetLocations(locationContainers, faces, mappingFromPhotoPrismCollection, rectangleIntersectMinimum);
|
||||||
static List<Models.Location> GetLocations<T>(List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, List<Models.Face> faces, List<LocationContainer<T>> containers) =>
|
static List<Models.Location> GetLocations<T>(List<LocationContainer<T>> locationContainers, List<Models.Face> faces, List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, float rectangleIntersectMinimum) =>
|
||||||
Location.GetLocations(mappingFromPhotoPrismCollection, faces, containers);
|
Location.GetLocations(locationContainers, faces, mappingFromPhotoPrismCollection, rectangleIntersectMinimum);
|
||||||
|
|
||||||
Rectangle? TestStatic_GetWholePercentages(int locationDigits, int wholePercentages) =>
|
RectangleF? TestStatic_GetPercentagesRectangle(int locationDigits, int wholePercentages) =>
|
||||||
GetWholePercentages(locationDigits, wholePercentages);
|
GetPercentagesRectangle(locationDigits, wholePercentages);
|
||||||
static Rectangle? GetWholePercentages(int locationDigits, int wholePercentages) =>
|
static RectangleF? GetPercentagesRectangle(int locationDigits, int wholePercentages) =>
|
||||||
Location.GetWholePercentages(locationDigits, wholePercentages.ToString());
|
Location.GetPercentagesRectangle(locationDigits, wholePercentages.ToString());
|
||||||
|
|
||||||
Rectangle? TestStatic_GetRectangle(int locationDigits, Models.OutputResolution outputResolution, int wholePercentages) =>
|
Rectangle? TestStatic_GetRectangle(int locationDigits, Models.OutputResolution outputResolution, int wholePercentages) =>
|
||||||
GetRectangle(locationDigits, outputResolution, wholePercentages);
|
GetRectangle(locationDigits, outputResolution, wholePercentages);
|
||||||
@ -90,6 +90,11 @@ public interface ILocation
|
|||||||
static int GetWholePercentages(int locationDigits) =>
|
static int GetWholePercentages(int locationDigits) =>
|
||||||
Location.GetWholePercentages(1, 1, 0, locationDigits, 1, 0, 1, zCount: 1);
|
Location.GetWholePercentages(1, 1, 0, locationDigits, 1, 0, 1, zCount: 1);
|
||||||
|
|
||||||
|
int TestStatic_GetWholePercentages(int height, Models.Location location, int locationDigits, int width) =>
|
||||||
|
GetWholePercentages(height, location, locationDigits, width);
|
||||||
|
static int GetWholePercentages(int height, Models.Location location, int locationDigits, int width) =>
|
||||||
|
Location.GetWholePercentages(height, location, locationDigits, width);
|
||||||
|
|
||||||
int TestStatic_GetWholePercentages(int bottom, int height, int left, int locationDigits, int right, int top, int width) =>
|
int TestStatic_GetWholePercentages(int bottom, int height, int left, int locationDigits, int right, int top, int width) =>
|
||||||
GetWholePercentages(bottom, height, left, locationDigits, right, top, width);
|
GetWholePercentages(bottom, height, left, locationDigits, right, top, width);
|
||||||
static int GetWholePercentages(int bottom, int height, int left, int locationDigits, int right, int top, int width) =>
|
static int GetWholePercentages(int bottom, int height, int left, int locationDigits, int right, int top, int width) =>
|
||||||
@ -109,4 +114,9 @@ public interface ILocation
|
|||||||
width,
|
width,
|
||||||
facesCount);
|
facesCount);
|
||||||
|
|
||||||
|
float? TestStatic_GetIntersectPercent(RectangleF rectangleA, float? areaA, RectangleF rectangleB) =>
|
||||||
|
GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
static float? GetIntersectPercent(RectangleF rectangleA, float? areaA, RectangleF rectangleB) =>
|
||||||
|
Location.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
|
||||||
}
|
}
|
@ -3,6 +3,11 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
|||||||
public interface IOutputResolution
|
public interface IOutputResolution
|
||||||
{ // ...
|
{ // ...
|
||||||
|
|
||||||
|
(int, int) TestStatic_Get(Models.OutputResolution outputResolution) =>
|
||||||
|
Get(outputResolution);
|
||||||
|
static (int, int) Get(Models.OutputResolution outputResolution) =>
|
||||||
|
OutputResolution.Get(outputResolution);
|
||||||
|
|
||||||
int TestStatic_GetHeight(Models.OutputResolution outputResolution) =>
|
int TestStatic_GetHeight(Models.OutputResolution outputResolution) =>
|
||||||
GetHeight(outputResolution);
|
GetHeight(outputResolution);
|
||||||
static int GetHeight(Models.OutputResolution outputResolution) =>
|
static int GetHeight(Models.OutputResolution outputResolution) =>
|
||||||
|
@ -108,15 +108,21 @@ internal abstract class Location
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static int GetWholePercentages(int height, Models.Location location, int locationDigits, int width)
|
||||||
|
{
|
||||||
|
int result = GetWholePercentages(location.Bottom, height, location.Left, locationDigits, location.Right, location.Top, width, zCount: 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
internal static int GetConfidencePercent(int faceConfidencePercent, float[] rangeFaceConfidence, double confidence)
|
internal static int GetConfidencePercent(int faceConfidencePercent, float[] rangeFaceConfidence, double confidence)
|
||||||
{
|
{
|
||||||
int result = (int)(confidence / rangeFaceConfidence[1] * faceConfidencePercent);
|
int result = (int)(confidence / rangeFaceConfidence[1] * faceConfidencePercent);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Rectangle? GetWholePercentages(int locationDigits, string wholePercentages)
|
internal static RectangleF? GetPercentagesRectangle(int locationDigits, string wholePercentages)
|
||||||
{
|
{
|
||||||
Rectangle? result;
|
RectangleF? result;
|
||||||
int length = (locationDigits - 1) / 4;
|
int length = (locationDigits - 1) / 4;
|
||||||
string[] segments = new string[]
|
string[] segments = new string[]
|
||||||
{
|
{
|
||||||
@ -133,7 +139,10 @@ internal abstract class Location
|
|||||||
if (!int.TryParse(segments[1], out int xWholePercent) || !int.TryParse(segments[2], out int yWholePercent) || !int.TryParse(segments[3], out int wWholePercent) || !int.TryParse(segments[4], out int hWholePercent))
|
if (!int.TryParse(segments[1], out int xWholePercent) || !int.TryParse(segments[2], out int yWholePercent) || !int.TryParse(segments[3], out int wWholePercent) || !int.TryParse(segments[4], out int hWholePercent))
|
||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
result = new(xWholePercent, yWholePercent, wWholePercent, hWholePercent);
|
{
|
||||||
|
float factor = 100;
|
||||||
|
result = new(xWholePercent / factor, yWholePercent / factor, wWholePercent / factor, hWholePercent / factor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -144,13 +153,12 @@ internal abstract class Location
|
|||||||
if (wholePercentages.Length != locationDigits || wholePercentages[0] is not '4' and not '8')
|
if (wholePercentages.Length != locationDigits || wholePercentages[0] is not '4' and not '8')
|
||||||
throw new NotSupportedException("Old way has been removed!");
|
throw new NotSupportedException("Old way has been removed!");
|
||||||
(int width, int height) = OutputResolution.Get(outputResolution);
|
(int width, int height) = OutputResolution.Get(outputResolution);
|
||||||
Rectangle? rectangle = GetWholePercentages(locationDigits, wholePercentages);
|
RectangleF? rectangle = GetPercentagesRectangle(locationDigits, wholePercentages);
|
||||||
if (rectangle is null)
|
if (rectangle is null)
|
||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
decimal factor = 100;
|
result = new((int)(rectangle.Value.X * width), (int)(rectangle.Value.Y * height), (int)(rectangle.Value.Width * width), (int)(rectangle.Value.Height * height));
|
||||||
result = new((int)(rectangle.Value.X / factor * width), (int)(rectangle.Value.Y / factor * height), (int)(rectangle.Value.Width / factor * width), (int)(rectangle.Value.Height / factor * height));
|
|
||||||
}
|
}
|
||||||
if (result is null)
|
if (result is null)
|
||||||
throw new NullReferenceException(nameof(result));
|
throw new NullReferenceException(nameof(result));
|
||||||
@ -163,25 +171,29 @@ internal abstract class Location
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Rectangle? GetRectangle(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution)
|
internal static RectangleF? GetPercentagesRectangle(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution)
|
||||||
{
|
{
|
||||||
Rectangle? result;
|
RectangleF? result;
|
||||||
bool matches = Matches(outputResolution, databaseFile);
|
bool matches = Matches(outputResolution, databaseFile);
|
||||||
if (!matches)
|
if (!matches)
|
||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
result = new((int)Math.Ceiling(marker.X * databaseFile.FileWidth), (int)Math.Ceiling(marker.Y * databaseFile.FileHeight), (int)Math.Ceiling(marker.W * databaseFile.FileWidth), (int)Math.Ceiling(marker.H * databaseFile.FileHeight));
|
result = new(marker.X, marker.Y, marker.W, marker.H);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Models.Location? GetLocation(DatabaseFile databaseFile, Marker marker, Rectangle rectangle)
|
private static Models.Location? GetLocation(DatabaseFile databaseFile, Marker marker, RectangleF rectangle)
|
||||||
{
|
{
|
||||||
Models.Location? result;
|
Models.Location? result;
|
||||||
bool verified = Check(rectangle.Bottom, databaseFile.FileHeight, rectangle.Left, rectangle.Right, rectangle.Top, databaseFile.FileWidth, zCount: 1, throwException: false);
|
int top = (int)Math.Ceiling(rectangle.Top * databaseFile.FileHeight);
|
||||||
|
int left = (int)Math.Ceiling(rectangle.Left * databaseFile.FileWidth);
|
||||||
|
int right = (int)Math.Ceiling(rectangle.Right * databaseFile.FileWidth);
|
||||||
|
int bottom = (int)Math.Ceiling(rectangle.Bottom * databaseFile.FileHeight);
|
||||||
|
bool verified = Check(bottom, databaseFile.FileHeight, left, right, top, databaseFile.FileWidth, zCount: 1, throwException: false);
|
||||||
if (!verified)
|
if (!verified)
|
||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
result = new(rectangle.Bottom, marker.Score / 100, rectangle.Left, rectangle.Right, rectangle.Top);
|
result = new(bottom, marker.Score / 100, left, right, top);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +212,7 @@ internal abstract class Location
|
|||||||
internal static Models.Location? GetLocation(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution)
|
internal static Models.Location? GetLocation(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution)
|
||||||
{
|
{
|
||||||
Models.Location? result;
|
Models.Location? result;
|
||||||
Rectangle? rectangle = GetRectangle(databaseFile, marker, outputResolution);
|
RectangleF? rectangle = GetPercentagesRectangle(databaseFile, marker, outputResolution);
|
||||||
if (rectangle is null)
|
if (rectangle is null)
|
||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
@ -208,15 +220,43 @@ internal abstract class Location
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static List<Models.Location> GetLocations<T>(List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, List<Models.Face> faces, List<LocationContainer<T>> containers)
|
internal static float? GetIntersectPercent(RectangleF rectangleA, float? areaA, RectangleF rectangleB)
|
||||||
|
{
|
||||||
|
float? result;
|
||||||
|
if (rectangleA.Equals(rectangleB))
|
||||||
|
result = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float intersectArea;
|
||||||
|
RectangleF intersectRectangle;
|
||||||
|
areaA ??= rectangleA.Width * rectangleA.Height;
|
||||||
|
float areaB = rectangleB.Width * rectangleB.Height;
|
||||||
|
bool check = areaA > areaB;
|
||||||
|
if (check)
|
||||||
|
intersectRectangle = RectangleF.Intersect(rectangleB, rectangleA);
|
||||||
|
else
|
||||||
|
intersectRectangle = RectangleF.Intersect(rectangleA, rectangleB);
|
||||||
|
intersectArea = intersectRectangle.Width * intersectRectangle.Height;
|
||||||
|
if (check)
|
||||||
|
result = intersectArea / areaA;
|
||||||
|
else
|
||||||
|
result = intersectArea / areaB;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static List<Models.Location> GetLocations<T>(List<LocationContainer<T>> locationContainers, List<Models.Face> faces, List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, float rectangleIntersectMinimum)
|
||||||
{
|
{
|
||||||
List<Models.Location> results = new();
|
List<Models.Location> results = new();
|
||||||
bool any;
|
bool any;
|
||||||
bool matches;
|
bool matches;
|
||||||
Rectangle dlibRectangle;
|
float? percent;
|
||||||
Rectangle? prismRectangle;
|
float prismArea;
|
||||||
|
int width, height;
|
||||||
Models.Location? location;
|
Models.Location? location;
|
||||||
Rectangle intersectRectangle;
|
RectangleF? prismRectangle;
|
||||||
|
int dlibLocationWholePercentages;
|
||||||
|
RectangleF? dlibPercentagesRectangle;
|
||||||
Models.OutputResolution? outputResolution = null;
|
Models.OutputResolution? outputResolution = null;
|
||||||
foreach (Models.Face face in faces)
|
foreach (Models.Face face in faces)
|
||||||
{
|
{
|
||||||
@ -226,7 +266,7 @@ internal abstract class Location
|
|||||||
outputResolution ??= face.OutputResolution;
|
outputResolution ??= face.OutputResolution;
|
||||||
}
|
}
|
||||||
int before = results.Count;
|
int before = results.Count;
|
||||||
foreach (LocationContainer<T> locationContainer in containers)
|
foreach (LocationContainer<T> locationContainer in locationContainers)
|
||||||
{
|
{
|
||||||
if (locationContainer.Location is null)
|
if (locationContainer.Location is null)
|
||||||
continue;
|
continue;
|
||||||
@ -242,22 +282,23 @@ internal abstract class Location
|
|||||||
foreach (Marker marker in mappingFromPhotoPrism.Markers)
|
foreach (Marker marker in mappingFromPhotoPrism.Markers)
|
||||||
{
|
{
|
||||||
any = false;
|
any = false;
|
||||||
prismRectangle = GetRectangle(mappingFromPhotoPrism.DatabaseFile, marker, outputResolution);
|
prismRectangle = GetPercentagesRectangle(mappingFromPhotoPrism.DatabaseFile, marker, outputResolution);
|
||||||
if (prismRectangle is null)
|
if (prismRectangle is null)
|
||||||
break;
|
break;
|
||||||
|
prismArea = prismRectangle.Value.Width * prismRectangle.Value.Height;
|
||||||
location = GetLocation(mappingFromPhotoPrism.DatabaseFile, marker, prismRectangle.Value);
|
location = GetLocation(mappingFromPhotoPrism.DatabaseFile, marker, prismRectangle.Value);
|
||||||
if (location is null)
|
if (location is null)
|
||||||
break;
|
break;
|
||||||
foreach (LocationContainer<T> locationContainer in containers)
|
foreach (LocationContainer<T> locationContainer in locationContainers)
|
||||||
{
|
{
|
||||||
if (any)
|
if (any)
|
||||||
continue;
|
continue;
|
||||||
if (locationContainer.Location is null)
|
if (locationContainer.Rectangle is null)
|
||||||
continue;
|
continue;
|
||||||
dlibRectangle = new(locationContainer.Location.Left, locationContainer.Location.Top, locationContainer.Location.Right - locationContainer.Location.Left, locationContainer.Location.Bottom - locationContainer.Location.Top);
|
percent = GetIntersectPercent(prismRectangle.Value, prismArea, locationContainer.Rectangle.Value);
|
||||||
intersectRectangle = Rectangle.Intersect(prismRectangle.Value, dlibRectangle);
|
if (percent is null || percent < rectangleIntersectMinimum)
|
||||||
if (intersectRectangle.Width == 0 && intersectRectangle.Height == 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
if (!any)
|
||||||
any = true;
|
any = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -267,10 +308,15 @@ internal abstract class Location
|
|||||||
continue;
|
continue;
|
||||||
if (face.Location is null || face.OutputResolution is null)
|
if (face.Location is null || face.OutputResolution is null)
|
||||||
continue;
|
continue;
|
||||||
dlibRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
|
(width, height) = OutputResolution.Get(face.OutputResolution);
|
||||||
intersectRectangle = Rectangle.Intersect(prismRectangle.Value, dlibRectangle);
|
dlibLocationWholePercentages = GetWholePercentages(height, face.Location, Stateless.ILocation.Digits, width);
|
||||||
if (intersectRectangle.Width == 0 && intersectRectangle.Height == 0)
|
dlibPercentagesRectangle = GetPercentagesRectangle(Stateless.ILocation.Digits, dlibLocationWholePercentages.ToString());
|
||||||
|
if (dlibPercentagesRectangle is null)
|
||||||
continue;
|
continue;
|
||||||
|
percent = GetIntersectPercent(prismRectangle.Value, prismArea, dlibPercentagesRectangle.Value);
|
||||||
|
if (percent is null || percent < rectangleIntersectMinimum)
|
||||||
|
continue;
|
||||||
|
if (!any)
|
||||||
any = true;
|
any = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -283,31 +329,28 @@ internal abstract class Location
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static double GP(OutputResolution outputResolution,Location location, ){
|
|
||||||
// double result;
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
|
|
||||||
internal static List<Models.Face> FilterByIntersect(Models.Face[] faces, float rectangleIntersectMinimum, int wholePercentages)
|
internal static List<Models.Face> FilterByIntersect(Models.Face[] faces, float rectangleIntersectMinimum, int wholePercentages)
|
||||||
{
|
{
|
||||||
List<Models.Face> results = new();
|
List<Models.Face> results = new();
|
||||||
double? percent;
|
float? percent;
|
||||||
Rectangle checkRectangle;
|
int width, height;
|
||||||
Rectangle? sourceRectangle;
|
int faceLocationWholePercentages;
|
||||||
Rectangle intersectRectangle;
|
RectangleF? facePercentagesRectangle;
|
||||||
|
RectangleF? sourceRectangle = GetPercentagesRectangle(Stateless.ILocation.Digits, wholePercentages.ToString());
|
||||||
|
float? sourceArea = sourceRectangle is null ? null : sourceRectangle.Value.Width * sourceRectangle.Value.Height;
|
||||||
foreach (Models.Face face in faces)
|
foreach (Models.Face face in faces)
|
||||||
{
|
{
|
||||||
|
if (sourceRectangle is null || sourceArea is null)
|
||||||
|
continue;
|
||||||
if (face.Location is null || face.OutputResolution is null)
|
if (face.Location is null || face.OutputResolution is null)
|
||||||
continue;
|
continue;
|
||||||
checkRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
|
(width, height) = OutputResolution.Get(face.OutputResolution);
|
||||||
sourceRectangle = GetRectangle(Stateless.ILocation.Digits, face.OutputResolution, wholePercentages.ToString());
|
faceLocationWholePercentages = GetWholePercentages(height, face.Location, Stateless.ILocation.Digits, width);
|
||||||
if (sourceRectangle is null)
|
facePercentagesRectangle = GetPercentagesRectangle(Stateless.ILocation.Digits, faceLocationWholePercentages.ToString());
|
||||||
|
if (facePercentagesRectangle is null)
|
||||||
continue;
|
continue;
|
||||||
intersectRectangle = Rectangle.Intersect(checkRectangle, sourceRectangle.Value);
|
percent = GetIntersectPercent(sourceRectangle.Value, sourceArea.Value, facePercentagesRectangle.Value);
|
||||||
if (intersectRectangle.Width == 0 || intersectRectangle.Height == 0)
|
if (percent is null || percent < rectangleIntersectMinimum)
|
||||||
continue;
|
|
||||||
percent = (double)intersectRectangle.Width * intersectRectangle.Height / (checkRectangle.Width * checkRectangle.Height);
|
|
||||||
if (percent < rectangleIntersectMinimum)
|
|
||||||
continue;
|
continue;
|
||||||
results.Add(face);
|
results.Add(face);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|||||||
using Phares.Shared;
|
using Phares.Shared;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using View_by_Distance.Shared.Models;
|
using View_by_Distance.Shared.Models;
|
||||||
using View_by_Distance.Shared.Models.Stateless.Methods;
|
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||||
@ -307,4 +308,74 @@ public partial class UnitTestCalculations
|
|||||||
NonThrowTryCatch();
|
NonThrowTryCatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TestMethodIntersect()
|
||||||
|
{
|
||||||
|
float? percent;
|
||||||
|
float? areaA = null;
|
||||||
|
RectangleF rectangleA;
|
||||||
|
RectangleF rectangleB;
|
||||||
|
rectangleA = new(0, 0, 4, 4);
|
||||||
|
rectangleB = new(0, 0, 4, 4);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == 1);
|
||||||
|
rectangleA = new(0, 0, 4, 4);
|
||||||
|
rectangleB = new(0, 0, 2, 2);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == .25);
|
||||||
|
rectangleA = new(0, 0, 4, 4);
|
||||||
|
rectangleB = new(0, 0, 4, 2);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == .5);
|
||||||
|
rectangleA = new(0, 0, 4, 4);
|
||||||
|
rectangleB = new(2, 2, 4, 4);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == .25);
|
||||||
|
rectangleA = new(0, 0, 4, 4);
|
||||||
|
rectangleB = new(2, 0, 4, 4);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == .5);
|
||||||
|
rectangleA = new(0, 0, 4, 4);
|
||||||
|
rectangleB = new(2, 4, 4, 4);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == 0);
|
||||||
|
rectangleB = new(0, 0, 4, 4);
|
||||||
|
rectangleA = new(0, 0, 4, 4);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == 1);
|
||||||
|
rectangleB = new(0, 0, 4, 4);
|
||||||
|
rectangleA = new(0, 0, 2, 2);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == .25);
|
||||||
|
rectangleB = new(0, 0, 4, 4);
|
||||||
|
rectangleA = new(0, 0, 4, 2);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == .5);
|
||||||
|
rectangleB = new(0, 0, 4, 4);
|
||||||
|
rectangleA = new(2, 2, 4, 4);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == .25);
|
||||||
|
rectangleB = new(0, 0, 4, 4);
|
||||||
|
rectangleA = new(2, 0, 4, 4);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == .5);
|
||||||
|
rectangleB = new(0, 0, 4, 4);
|
||||||
|
rectangleA = new(2, 4, 4, 4);
|
||||||
|
percent = ILocation.GetIntersectPercent(rectangleA, areaA, rectangleB);
|
||||||
|
Assert.IsNotNull(percent);
|
||||||
|
Assert.IsTrue(percent.Value == 0);
|
||||||
|
NonThrowTryCatch();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user