Init
This commit is contained in:
161
Instance/Models/_D2_FaceLandmark.cs
Normal file
161
Instance/Models/_D2_FaceLandmark.cs
Normal file
@ -0,0 +1,161 @@
|
||||
using FaceRecognitionDotNet;
|
||||
using System.Drawing;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
/// <summary>
|
||||
// *.png
|
||||
/// </summary>
|
||||
internal class D2_FaceLandmarks
|
||||
{
|
||||
|
||||
internal List<string> AngleBracketCollection { get; }
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly Configuration _Configuration;
|
||||
|
||||
internal D2_FaceLandmarks(Configuration configuration)
|
||||
{
|
||||
_Configuration = configuration;
|
||||
AngleBracketCollection = new List<string>();
|
||||
_Log = Serilog.Log.ForContext<D2_FaceLandmarks>();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
private static Bitmap RotateBitmap(System.Drawing.Image image, float angle)
|
||||
{
|
||||
Bitmap result;
|
||||
Bitmap bitmap = new(image);
|
||||
result = D_Face.RotateBitmap(bitmap, angle);
|
||||
if (bitmap is not null)
|
||||
bitmap.Dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SaveFaceLandmarkImages(List<D_Face> faceCollections, List<string[]> imageFiles, int pointSize, FileInfo resizedFileInfo)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
D_Face face;
|
||||
int width;
|
||||
int height;
|
||||
string imageFileFullName;
|
||||
Bitmap rotated;
|
||||
string rotatedImageFileFullName;
|
||||
Shared.Models.FacePoint[] facePoints;
|
||||
for (int i = 0; i < faceCollections.Count; i++)
|
||||
{
|
||||
if (!faceCollections[i].Populated)
|
||||
continue;
|
||||
face = faceCollections[i];
|
||||
imageFileFullName = imageFiles[i][0];
|
||||
rotatedImageFileFullName = imageFiles[i][1];
|
||||
try
|
||||
{
|
||||
using (System.Drawing.Image image = System.Drawing.Image.FromFile(resizedFileInfo.FullName))
|
||||
{
|
||||
using Graphics graphic = Graphics.FromImage(image);
|
||||
if (face.FaceLandmarks is null || !face.FaceLandmarks.Any())
|
||||
{
|
||||
width = face.Location.Right - face.Location.Left;
|
||||
height = face.Location.Bottom - face.Location.Top;
|
||||
graphic.DrawEllipse(Pens.Red, face.Location.Left, face.Location.Top, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (KeyValuePair<string, Shared.Models.FacePoint[]> keyValuePair in face.FaceLandmarks)
|
||||
{
|
||||
facePoints = keyValuePair.Value.ToArray();
|
||||
foreach (Shared.Models.FacePoint facePoint in facePoints)
|
||||
graphic.DrawEllipse(Pens.GreenYellow, face.Location.Left + facePoint.X - pointSize, face.Location.Top + facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
|
||||
if (keyValuePair.Key == FacePart.Chin.ToString())
|
||||
continue;
|
||||
if (facePoints.Length < 3)
|
||||
continue;
|
||||
x = (int)(from l in facePoints select l.X).Average();
|
||||
y = (int)(from l in facePoints select l.Y).Average();
|
||||
graphic.DrawEllipse(Pens.Purple, face.Location.Left + x - pointSize, face.Location.Top + y - pointSize, pointSize * 2, pointSize * 2);
|
||||
}
|
||||
}
|
||||
image.Save(imageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
|
||||
}
|
||||
if (face.α.HasValue)
|
||||
{
|
||||
using System.Drawing.Image image = System.Drawing.Image.FromFile(resizedFileInfo.FullName);
|
||||
rotated = RotateBitmap(image, (float)face.α.Value);
|
||||
if (rotated is not null)
|
||||
{
|
||||
rotated.Save(rotatedImageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
|
||||
rotated.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
internal void SaveFaceLandmarkImages(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string relativePath, string fileNameWithoutExtension, FileInfo resizedFileInfo, List<D_Face> faceCollections)
|
||||
{
|
||||
FileInfo fileInfo;
|
||||
bool check = false;
|
||||
string parentCheck;
|
||||
const int pointSize = 2;
|
||||
FileInfo rotatedFileInfo;
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
List<string[]> imageFiles = new();
|
||||
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), fileNameWithoutExtension);
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
|
||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
if (!Directory.Exists(facesDirectory))
|
||||
_ = Directory.CreateDirectory(facesDirectory);
|
||||
for (int i = 0; i < faceCollections.Count; i++)
|
||||
{
|
||||
if (!faceCollections[i].Populated)
|
||||
{
|
||||
imageFiles.Add(Array.Empty<string>());
|
||||
continue;
|
||||
}
|
||||
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {fileNameWithoutExtension}.png"));
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
if (fileInfo.Directory?.Parent is null)
|
||||
throw new Exception();
|
||||
parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
|
||||
if (File.Exists(parentCheck))
|
||||
File.Delete(parentCheck);
|
||||
}
|
||||
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
|
||||
continue;
|
||||
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, string.Concat(Path.GetFileNameWithoutExtension(fileInfo.FullName), " - ", i, " - R", Path.GetExtension(fileInfo.FullName))));
|
||||
imageFiles.Add(new string[] { fileInfo.FullName, rotatedFileInfo.FullName });
|
||||
if (check)
|
||||
continue;
|
||||
if (_Configuration.OverrideForFaceLandmarkImages is null)
|
||||
check = false;
|
||||
else if (_Configuration.OverrideForFaceLandmarkImages.Value)
|
||||
check = true;
|
||||
else if (!fileInfo.Exists)
|
||||
check = true;
|
||||
else if (!rotatedFileInfo.Exists)
|
||||
check = true;
|
||||
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
check = true;
|
||||
}
|
||||
if (check)
|
||||
SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, resizedFileInfo);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user