Ready to test
This commit is contained in:
@ -3,11 +3,13 @@ using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
using WindowsShortcutFactory;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
@ -47,6 +49,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
|
||||
public string RelativePath => _RelativePath;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[JsonConstructor]
|
||||
public D_Face(double? α, DateTime dateTime, Shared.Models.FaceEncoding faceEncoding, Dictionary<string, Shared.Models.FacePoint[]> faceLandmarks, Shared.Models.Location location, int? locationIndex, OutputResolution outputResolution, bool populated, string relativePath)
|
||||
{
|
||||
@ -125,22 +128,24 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
|
||||
_RelativePath = face.RelativePath;
|
||||
}
|
||||
|
||||
private static void GetPointBounds(PointF[] points, out float xmin, out float xmax, out float ymin, out float ymax)
|
||||
#nullable restore
|
||||
|
||||
private static void GetPointBounds(PointF[] points, out float xMinimum, out float xMaximum, out float yMinimum, out float yMaximum)
|
||||
{
|
||||
xmin = points[0].X;
|
||||
xmax = xmin;
|
||||
ymin = points[0].Y;
|
||||
ymax = ymin;
|
||||
xMinimum = points[0].X;
|
||||
xMaximum = xMinimum;
|
||||
yMinimum = points[0].Y;
|
||||
yMaximum = yMinimum;
|
||||
foreach (PointF point in points)
|
||||
{
|
||||
if (xmin > point.X)
|
||||
xmin = point.X;
|
||||
if (xmax < point.X)
|
||||
xmax = point.X;
|
||||
if (ymin > point.Y)
|
||||
ymin = point.Y;
|
||||
if (ymax < point.Y)
|
||||
ymax = point.Y;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,12 +180,12 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
|
||||
new PointF(0, bitmap.Height),
|
||||
};
|
||||
rotate_at_origin.TransformPoints(points);
|
||||
float xmin, xmax, ymin, ymax;
|
||||
GetPointBounds(points, out xmin, out xmax, out ymin, out ymax);
|
||||
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(xmax - xmin);
|
||||
int hgt = (int)Math.Round(ymax - ymin);
|
||||
int wid = (int)Math.Round(xMaximum - xMinimum);
|
||||
int hgt = (int)Math.Round(yMaximum - yMinimum);
|
||||
result = new Bitmap(wid, hgt);
|
||||
|
||||
// Create the real rotation transformation.
|
||||
@ -251,7 +256,8 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
|
||||
if (_Configuration.NumJitters is null)
|
||||
throw new Exception();
|
||||
FaceRecognitionDotNet.Location[] locations;
|
||||
FaceRecognitionDotNet.Image unknownImage = null;
|
||||
const int numberOfTimesToUpSample = 1;
|
||||
FaceRecognitionDotNet.Image? unknownImage = null;
|
||||
if (resizedFileInfo.Exists)
|
||||
{
|
||||
try
|
||||
@ -263,7 +269,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
|
||||
else
|
||||
{
|
||||
FaceRecognition faceRecognition = FaceRecognition.Create(_ModelParameter);
|
||||
locations = faceRecognition.FaceLocations(unknownImage, numberOfTimesToUpsample: 1, _Model).ToArray();
|
||||
locations = faceRecognition.FaceLocations(unknownImage, numberOfTimesToUpSample, _Model).ToArray();
|
||||
if (!locations.Any())
|
||||
results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, relativePath, i: null, location: null));
|
||||
else
|
||||
@ -276,19 +282,19 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
|
||||
int leftEyeY;
|
||||
int rightEyeX;
|
||||
int rightEyeY;
|
||||
Bitmap rotated;
|
||||
string faceFile;
|
||||
Bitmap preRotated;
|
||||
Graphics graphics;
|
||||
D_Face face = null;
|
||||
D_Face? face = null;
|
||||
Rectangle rectangle;
|
||||
double[] rawEncoding;
|
||||
Bitmap rotated;
|
||||
Bitmap preRotated;
|
||||
FaceRecognitionDotNet.Image knownImage;
|
||||
FaceRecognitionDotNet.Image rotatedImage;
|
||||
Shared.Models.Location location;
|
||||
FaceRecognitionDotNet.Image knownImage;
|
||||
Shared.Models.FaceEncoding faceEncoding;
|
||||
FaceRecognitionDotNet.Image rotatedImage;
|
||||
FaceRecognitionDotNet.FaceEncoding[] faceEncodings;
|
||||
IEnumerable<FaceRecognitionDotNet.FacePoint> facePoints;
|
||||
Shared.Models.FaceEncoding faceEncoding;
|
||||
IDictionary<FacePart, IEnumerable<FaceRecognitionDotNet.FacePoint>>[] faceLandmarks;
|
||||
using Bitmap source = unknownImage.ToBitmap();
|
||||
padding = (int)((source.Width + source.Height) / 2 * .01);
|
||||
@ -380,7 +386,7 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
|
||||
|
||||
internal List<D_Face> GetFaces(Property.Models.Configuration configuration, string outputResolution, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string relativePath, string fileNameWithoutExtension, A_Property property, FileInfo resizedFileInfo, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
|
||||
{
|
||||
List<D_Face> results;
|
||||
List<D_Face>? results;
|
||||
if (_Configuration.PropertiesChangedForFaces is null)
|
||||
throw new Exception();
|
||||
string json;
|
||||
@ -412,6 +418,8 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
|
||||
try
|
||||
{
|
||||
results = JsonSerializer.Deserialize<List<D_Face>>(json);
|
||||
if (results is null)
|
||||
throw new Exception($"{nameof(results)} is null");
|
||||
for (int i = 0; i < results.Count; i++)
|
||||
{
|
||||
face = results[i];
|
||||
@ -487,6 +495,106 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
|
||||
SaveFaces(faceCollection, resizedFileInfo, imageFiles);
|
||||
}
|
||||
|
||||
internal void SaveShortcuts(Property.Models.Configuration configuration, string[] juliePhares, Model model, PredictorModel predictorModel, Person[] people, PropertyLogic propertyLogic, string outputResolution, PropertyHolder[] filteredPropertyHolderCollection, List<A_Property> propertyCollection, List<List<D_Face>> faceCollections)
|
||||
{
|
||||
int oldIndex;
|
||||
string[] keys;
|
||||
string fileName;
|
||||
string fullName;
|
||||
string personKey;
|
||||
string directory;
|
||||
FileInfo fileInfo;
|
||||
string copyDirectory;
|
||||
string? relativePath;
|
||||
List<D_Face> faceCollection;
|
||||
PropertyHolder propertyHolder;
|
||||
WindowsShortcut windowsShortcut;
|
||||
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
|
||||
Dictionary<string, List<Person>> peopleCollection = new();
|
||||
foreach (Person person in people)
|
||||
{
|
||||
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(person.Birthday);
|
||||
if (!peopleCollection.ContainsKey(personKey))
|
||||
peopleCollection.Add(personKey, new List<Person>());
|
||||
peopleCollection[personKey].Add(person);
|
||||
}
|
||||
string dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, model.ToString(), predictorModel.ToString(), nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "(_)");
|
||||
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++)
|
||||
{
|
||||
personKey = string.Empty;
|
||||
copyDirectory = string.Empty;
|
||||
propertyHolder = filteredPropertyHolderCollection[i];
|
||||
if (propertyHolder.FileInfo is null)
|
||||
continue;
|
||||
fileInfo = propertyHolder.FileInfo;
|
||||
relativePath = Path.GetDirectoryName($"C:{propertyHolder.RelativePath}");
|
||||
if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3)
|
||||
continue;
|
||||
if (propertyHolder.Property?.Id is null || propertyHolder.MinimumDateTime is null || propertyHolder.ResizedFileInfo is null)
|
||||
continue;
|
||||
if (propertyHolder.Property.Indices.Length < 2)
|
||||
directory = Path.Combine(dFacesContentDirectory, $"New{relativePath[2..]}");
|
||||
else
|
||||
{
|
||||
oldIndex = propertyHolder.Property.Indices[1];
|
||||
if (!propertyLogic.NamedFaceInfo.ContainsKey(oldIndex))
|
||||
directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}");
|
||||
else
|
||||
{
|
||||
faceCollection = faceCollections[i];
|
||||
keys = propertyLogic.NamedFaceInfo[oldIndex];
|
||||
if (!faceCollection.Any())
|
||||
directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}");
|
||||
else if (keys.Length != 1)
|
||||
directory = Path.Combine(dFacesContentDirectory, $"Not Supported{relativePath[2..]}");
|
||||
else if (faceCollection.Count == 1)
|
||||
{
|
||||
personKey = keys[0];
|
||||
if (juliePhares.Contains(personKey))
|
||||
copyDirectory = Path.Combine(dFacesContentDirectory, "Named Images");
|
||||
directory = Path.Combine(dFacesContentDirectory, "Named Shortcuts", personKey);
|
||||
}
|
||||
else if ((from l in faceCollection where HasLeftAndRight(l.FaceLandmarks) select true).Count() == 1)
|
||||
{
|
||||
personKey = keys[0];
|
||||
if (juliePhares.Contains(personKey))
|
||||
copyDirectory = Path.Combine(dFacesContentDirectory, "Named Images^");
|
||||
directory = Path.Combine(dFacesContentDirectory, "Named Shortcuts", $"{personKey}^");
|
||||
}
|
||||
else
|
||||
directory = Path.Combine(dFacesContentDirectory, $"Many{relativePath[2..]}");
|
||||
}
|
||||
}
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
if (!string.IsNullOrEmpty(personKey) && peopleCollection.ContainsKey(personKey))
|
||||
{
|
||||
Person person = peopleCollection[personKey][0];
|
||||
fullName = Regex.Replace($"{Shared.Models.Stateless.Methods.IPersonName.GetFullName(person.Name)}.txt", pattern, string.Empty);
|
||||
File.WriteAllText(Path.Combine(directory, fullName), string.Empty);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(copyDirectory))
|
||||
{
|
||||
if (!Directory.Exists(copyDirectory))
|
||||
_ = Directory.CreateDirectory(copyDirectory);
|
||||
fileName = Path.Combine(copyDirectory, $"{propertyHolder.Property.Id.Value}{propertyHolder.ResizedFileInfo.Extension}");
|
||||
if (!File.Exists(fileName))
|
||||
File.Copy(propertyHolder.ResizedFileInfo.FullName, fileName);
|
||||
}
|
||||
fileName = Path.Combine(directory, $"{propertyHolder.Property.Id.Value}.lnk");
|
||||
if (File.Exists(fileName))
|
||||
continue;
|
||||
windowsShortcut = new() { Path = fileInfo.FullName };
|
||||
windowsShortcut.Save(fileName);
|
||||
windowsShortcut.Dispose();
|
||||
if (!File.Exists(fileName))
|
||||
continue;
|
||||
File.SetLastWriteTime(fileName, propertyHolder.MinimumDateTime.Value);
|
||||
}
|
||||
}
|
||||
|
||||
double Shared.Models.Stateless.Methods.IFace.TestStatic_Getα(int x1, int x2, int y1, int y2) => throw new NotImplementedException();
|
||||
|
||||
string Shared.Models.Stateless.Methods.IFace.TestStatic_GetJson(string jsonFileFullName) => throw new NotImplementedException();
|
||||
@ -495,4 +603,18 @@ public class D_Face : Shared.Models.Properties.IFace, IFace
|
||||
|
||||
Face[] Shared.Models.Stateless.Methods.IFace.TestStatic_GetFaces(string jsonFileFullName) => throw new NotImplementedException();
|
||||
|
||||
private static bool HasLeftAndRight(Dictionary<string, Shared.Models.FacePoint[]> faceLandmarks)
|
||||
{
|
||||
bool result = true;
|
||||
if (!faceLandmarks.ContainsKey(FacePart.LeftEye.ToString()))
|
||||
result = false;
|
||||
else if (!faceLandmarks.ContainsKey(FacePart.RightEye.ToString()))
|
||||
result = false;
|
||||
else if (!faceLandmarks.ContainsKey(FacePart.LeftEyebrow.ToString()))
|
||||
result = false;
|
||||
else if (!faceLandmarks.ContainsKey(FacePart.RightEyebrow.ToString()))
|
||||
result = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user