IgnoreExtensions-nef

Config-LoadPhotoPrismLocations
TestMethodIntersect
This commit is contained in:
2023-06-23 19:19:41 -07:00
parent 1d0506d74c
commit 6f22929136
34 changed files with 364 additions and 140 deletions

View File

@ -37,7 +37,9 @@ public class FacePoint : Properties.IFacePoint
return result;
}
#pragma warning disable IDE0070
public override int GetHashCode()
#pragma warning restore IDE0070
{
int hashCode = 1861411795;
hashCode = hashCode * -1521134295 + _Point.GetHashCode();

View File

@ -74,7 +74,9 @@ public class Location : Properties.ILocation, IEquatable<Location>
return result;
}
#pragma warning disable IDE0070
public override int GetHashCode()
#pragma warning restore IDE0070
{
int hashCode = -773114317;
hashCode = hashCode * -1521134295 + Bottom.GetHashCode();

View File

@ -2,5 +2,5 @@ using System.Drawing;
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)
{ }

View File

@ -12,13 +12,13 @@ public record Marker(
string? SubjSrc,
string? FaceId,
string FaceDist,
double X,
double Y,
double W,
double H,
float X,
float Y,
float W,
float H,
string Q,
string Size,
double Score,
float Score,
string? Thumb,
string MatchedAt,
string CreatedAt,

View File

@ -31,9 +31,7 @@ internal abstract class Face
private static JsonElement[] GetJsonElements(string jsonFileFullName)
{
string json = GetJson(jsonFileFullName);
JsonElement[]? jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json);
if (jsonElements is null)
throw new Exception();
JsonElement[]? jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json) ?? throw new Exception();
return jsonElements;
}

View File

@ -15,25 +15,25 @@ public interface ILocation
static List<Models.Face> FilterByIntersect(Models.Face[] faces, float rectangleIntersectMinimum, int wholePercentages) =>
Location.FilterByIntersect(faces, rectangleIntersectMinimum, wholePercentages);
Rectangle? TestStatic_GetRectangle(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
GetRectangle(databaseFile, marker, outputResolution);
static Rectangle? GetRectangle(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
Location.GetRectangle(databaseFile, marker, outputResolution);
RectangleF? TestStatic_GetPercentagesRectangle(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
GetPercentagesRectangle(databaseFile, marker, outputResolution);
static RectangleF? GetPercentagesRectangle(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
Location.GetPercentagesRectangle(databaseFile, marker, outputResolution);
Models.Location? TestStatic_GetLocation(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
GetLocation(databaseFile, marker, outputResolution);
static Models.Location? GetLocation(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
Location.GetLocation(databaseFile, marker, outputResolution);
List<Models.Location> TestStatic_GetLocations<T>(List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, List<Models.Face> faces, List<LocationContainer<T>> containers) =>
GetLocations(mappingFromPhotoPrismCollection, faces, containers);
static List<Models.Location> GetLocations<T>(List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, List<Models.Face> faces, List<LocationContainer<T>> containers) =>
Location.GetLocations(mappingFromPhotoPrismCollection, faces, containers);
List<Models.Location> TestStatic_GetLocations<T>(List<LocationContainer<T>> locationContainers, List<Models.Face> faces, List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, float rectangleIntersectMinimum) =>
GetLocations(locationContainers, faces, mappingFromPhotoPrismCollection, rectangleIntersectMinimum);
static List<Models.Location> GetLocations<T>(List<LocationContainer<T>> locationContainers, List<Models.Face> faces, List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, float rectangleIntersectMinimum) =>
Location.GetLocations(locationContainers, faces, mappingFromPhotoPrismCollection, rectangleIntersectMinimum);
Rectangle? TestStatic_GetWholePercentages(int locationDigits, int wholePercentages) =>
GetWholePercentages(locationDigits, wholePercentages);
static Rectangle? GetWholePercentages(int locationDigits, int wholePercentages) =>
Location.GetWholePercentages(locationDigits, wholePercentages.ToString());
RectangleF? TestStatic_GetPercentagesRectangle(int locationDigits, int wholePercentages) =>
GetPercentagesRectangle(locationDigits, wholePercentages);
static RectangleF? GetPercentagesRectangle(int locationDigits, int wholePercentages) =>
Location.GetPercentagesRectangle(locationDigits, wholePercentages.ToString());
Rectangle? TestStatic_GetRectangle(int locationDigits, Models.OutputResolution outputResolution, int wholePercentages) =>
GetRectangle(locationDigits, outputResolution, wholePercentages);
@ -90,6 +90,11 @@ public interface ILocation
static int GetWholePercentages(int locationDigits) =>
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) =>
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) =>
@ -109,4 +114,9 @@ public interface ILocation
width,
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);
}

View File

@ -3,6 +3,11 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
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) =>
GetHeight(outputResolution);
static int GetHeight(Models.OutputResolution outputResolution) =>

View File

@ -108,15 +108,21 @@ internal abstract class Location
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)
{
int result = (int)(confidence / rangeFaceConfidence[1] * faceConfidencePercent);
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;
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))
result = null;
else
result = new(xWholePercent, yWholePercent, wWholePercent, hWholePercent);
{
float factor = 100;
result = new(xWholePercent / factor, yWholePercent / factor, wWholePercent / factor, hWholePercent / factor);
}
}
return result;
}
@ -143,14 +152,13 @@ internal abstract class Location
Rectangle? result;
if (wholePercentages.Length != locationDigits || wholePercentages[0] is not '4' and not '8')
throw new NotSupportedException("Old way has been removed!");
(int width, int height) = OutputResolution.Get(outputResolution);
Rectangle? rectangle = GetWholePercentages(locationDigits, wholePercentages);
(int width, int height) = OutputResolution.Get(outputResolution);
RectangleF? rectangle = GetPercentagesRectangle(locationDigits, wholePercentages);
if (rectangle is null)
result = null;
else
{
decimal factor = 100;
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));
result = new((int)(rectangle.Value.X * width), (int)(rectangle.Value.Y * height), (int)(rectangle.Value.Width * width), (int)(rectangle.Value.Height * height));
}
if (result is null)
throw new NullReferenceException(nameof(result));
@ -163,25 +171,29 @@ internal abstract class Location
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);
if (!matches)
result = null;
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;
}
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;
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)
result = null;
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;
}
@ -200,7 +212,7 @@ internal abstract class Location
internal static Models.Location? GetLocation(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution)
{
Models.Location? result;
Rectangle? rectangle = GetRectangle(databaseFile, marker, outputResolution);
RectangleF? rectangle = GetPercentagesRectangle(databaseFile, marker, outputResolution);
if (rectangle is null)
result = null;
else
@ -208,15 +220,43 @@ internal abstract class Location
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();
bool any;
bool matches;
Rectangle dlibRectangle;
Rectangle? prismRectangle;
float? percent;
float prismArea;
int width, height;
Models.Location? location;
Rectangle intersectRectangle;
RectangleF? prismRectangle;
int dlibLocationWholePercentages;
RectangleF? dlibPercentagesRectangle;
Models.OutputResolution? outputResolution = null;
foreach (Models.Face face in faces)
{
@ -226,7 +266,7 @@ internal abstract class Location
outputResolution ??= face.OutputResolution;
}
int before = results.Count;
foreach (LocationContainer<T> locationContainer in containers)
foreach (LocationContainer<T> locationContainer in locationContainers)
{
if (locationContainer.Location is null)
continue;
@ -242,23 +282,24 @@ internal abstract class Location
foreach (Marker marker in mappingFromPhotoPrism.Markers)
{
any = false;
prismRectangle = GetRectangle(mappingFromPhotoPrism.DatabaseFile, marker, outputResolution);
prismRectangle = GetPercentagesRectangle(mappingFromPhotoPrism.DatabaseFile, marker, outputResolution);
if (prismRectangle is null)
break;
prismArea = prismRectangle.Value.Width * prismRectangle.Value.Height;
location = GetLocation(mappingFromPhotoPrism.DatabaseFile, marker, prismRectangle.Value);
if (location is null)
break;
foreach (LocationContainer<T> locationContainer in containers)
foreach (LocationContainer<T> locationContainer in locationContainers)
{
if (any)
continue;
if (locationContainer.Location is null)
if (locationContainer.Rectangle is null)
continue;
dlibRectangle = new(locationContainer.Location.Left, locationContainer.Location.Top, locationContainer.Location.Right - locationContainer.Location.Left, locationContainer.Location.Bottom - locationContainer.Location.Top);
intersectRectangle = Rectangle.Intersect(prismRectangle.Value, dlibRectangle);
if (intersectRectangle.Width == 0 && intersectRectangle.Height == 0)
percent = GetIntersectPercent(prismRectangle.Value, prismArea, locationContainer.Rectangle.Value);
if (percent is null || percent < rectangleIntersectMinimum)
continue;
any = true;
if (!any)
any = true;
break;
}
foreach (Models.Face face in faces)
@ -267,11 +308,16 @@ internal abstract class Location
continue;
if (face.Location is null || face.OutputResolution is null)
continue;
dlibRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
intersectRectangle = Rectangle.Intersect(prismRectangle.Value, dlibRectangle);
if (intersectRectangle.Width == 0 && intersectRectangle.Height == 0)
(width, height) = OutputResolution.Get(face.OutputResolution);
dlibLocationWholePercentages = GetWholePercentages(height, face.Location, Stateless.ILocation.Digits, width);
dlibPercentagesRectangle = GetPercentagesRectangle(Stateless.ILocation.Digits, dlibLocationWholePercentages.ToString());
if (dlibPercentagesRectangle is null)
continue;
any = true;
percent = GetIntersectPercent(prismRectangle.Value, prismArea, dlibPercentagesRectangle.Value);
if (percent is null || percent < rectangleIntersectMinimum)
continue;
if (!any)
any = true;
break;
}
if (!any)
@ -283,31 +329,28 @@ internal abstract class Location
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)
{
List<Models.Face> results = new();
double? percent;
Rectangle checkRectangle;
Rectangle? sourceRectangle;
Rectangle intersectRectangle;
float? percent;
int width, height;
int faceLocationWholePercentages;
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)
{
if (sourceRectangle is null || sourceArea is null)
continue;
if (face.Location is null || face.OutputResolution is null)
continue;
checkRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
sourceRectangle = GetRectangle(Stateless.ILocation.Digits, face.OutputResolution, wholePercentages.ToString());
if (sourceRectangle is null)
(width, height) = OutputResolution.Get(face.OutputResolution);
faceLocationWholePercentages = GetWholePercentages(height, face.Location, Stateless.ILocation.Digits, width);
facePercentagesRectangle = GetPercentagesRectangle(Stateless.ILocation.Digits, faceLocationWholePercentages.ToString());
if (facePercentagesRectangle is null)
continue;
intersectRectangle = Rectangle.Intersect(checkRectangle, sourceRectangle.Value);
if (intersectRectangle.Width == 0 || intersectRectangle.Height == 0)
continue;
percent = (double)intersectRectangle.Width * intersectRectangle.Height / (checkRectangle.Width * checkRectangle.Height);
if (percent < rectangleIntersectMinimum)
percent = GetIntersectPercent(sourceRectangle.Value, sourceArea.Value, facePercentagesRectangle.Value);
if (percent is null || percent < rectangleIntersectMinimum)
continue;
results.Add(face);
}