PhotoPrism for more locations
This commit is contained in:
54
Shared/Models/DatabaseFile.cs
Normal file
54
Shared/Models/DatabaseFile.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record DatabaseFile(
|
||||
[property: JsonPropertyName("id")] int Id,
|
||||
[property: JsonPropertyName("photo_id")] int PhotoId,
|
||||
[property: JsonPropertyName("photo_uid")] string PhotoUid,
|
||||
[property: JsonPropertyName("photo_taken_at")] string PhotoTakenAt,
|
||||
[property: JsonPropertyName("time_index")] string TimeIndex,
|
||||
[property: JsonPropertyName("media_id")] string MediaId,
|
||||
[property: JsonPropertyName("media_utc")] object MediaUtc,
|
||||
[property: JsonPropertyName("instance_id")] string InstanceId,
|
||||
[property: JsonPropertyName("file_uid")] string FileUid,
|
||||
[property: JsonPropertyName("file_name")] string FileName,
|
||||
[property: JsonPropertyName("file_root")] string FileRoot,
|
||||
[property: JsonPropertyName("original_name")] string OriginalName,
|
||||
[property: JsonPropertyName("file_hash")] string FileHash,
|
||||
[property: JsonPropertyName("file_size")] int FileSize,
|
||||
[property: JsonPropertyName("file_codec")] string FileCodec,
|
||||
[property: JsonPropertyName("file_type")] string FileType,
|
||||
[property: JsonPropertyName("media_type")] string MediaType,
|
||||
[property: JsonPropertyName("file_mime")] string FileMime,
|
||||
[property: JsonPropertyName("file_primary")] long FilePrimary,
|
||||
[property: JsonPropertyName("file_sidecar")] long FileSidecar,
|
||||
[property: JsonPropertyName("file_missing")] long FileMissing,
|
||||
[property: JsonPropertyName("file_portrait")] long FilePortrait,
|
||||
[property: JsonPropertyName("file_video")] long FileVideo,
|
||||
[property: JsonPropertyName("file_duration")] long FileDuration,
|
||||
[property: JsonPropertyName("file_fps")] object FileFps,
|
||||
[property: JsonPropertyName("file_frames")] object FileFrames,
|
||||
[property: JsonPropertyName("file_width")] int FileWidth,
|
||||
[property: JsonPropertyName("file_height")] int FileHeight,
|
||||
[property: JsonPropertyName("file_orientation")] int FileOrientation,
|
||||
[property: JsonPropertyName("file_projection")] string FileProjection,
|
||||
[property: JsonPropertyName("file_aspect_ratio")] double FileAspectRatio,
|
||||
[property: JsonPropertyName("file_hdr")] long FileHdr,
|
||||
[property: JsonPropertyName("file_watermark")] long FileWatermark,
|
||||
[property: JsonPropertyName("file_color_profile")] string FileColorProfile,
|
||||
[property: JsonPropertyName("file_main_color")] string FileMainColor,
|
||||
[property: JsonPropertyName("file_colors")] string FileColors,
|
||||
[property: JsonPropertyName("file_luminance")] string FileLuminance,
|
||||
[property: JsonPropertyName("file_diff")] long FileDiff,
|
||||
[property: JsonPropertyName("file_chroma")] long FileChroma,
|
||||
[property: JsonPropertyName("file_software")] string FileSoftware,
|
||||
[property: JsonPropertyName("file_error")] string FileError,
|
||||
[property: JsonPropertyName("mod_time")] long ModTime,
|
||||
[property: JsonPropertyName("created_at")] string CreatedAt,
|
||||
[property: JsonPropertyName("created_in")] long CreatedIn,
|
||||
[property: JsonPropertyName("updated_at")] string UpdatedAt,
|
||||
[property: JsonPropertyName("updated_in")] long UpdatedIn,
|
||||
[property: JsonPropertyName("published_at")] object PublishedAt,
|
||||
[property: JsonPropertyName("deleted_at")] object DeletedAt
|
||||
);
|
@ -74,6 +74,21 @@ public class MappingFromLocation : Properties.IMappingFromLocation
|
||||
|
||||
}
|
||||
|
||||
public class MappingFromPhotoPrism : Properties.IMappingFromPhotoPrism
|
||||
{
|
||||
|
||||
public DatabaseFile DatabaseFile { init; get; }
|
||||
public List<Marker> Markers { init; get; }
|
||||
|
||||
[JsonConstructor]
|
||||
public MappingFromPhotoPrism(DatabaseFile databaseFile, List<Marker> markers)
|
||||
{
|
||||
DatabaseFile = databaseFile;
|
||||
Markers = markers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class MappingFromPerson : Properties.IMappingFromPerson
|
||||
{
|
||||
|
||||
@ -109,23 +124,25 @@ public class Mapping : Properties.IMapping
|
||||
public int? By => _By;
|
||||
public MappingFromItem MappingFromItem { init; get; }
|
||||
public MappingFromLocation MappingFromLocation { init; get; }
|
||||
public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; }
|
||||
public MappingFromPerson? MappingFromPerson => _MappingFromPerson;
|
||||
public string? SegmentC => _SegmentC;
|
||||
public SortingContainer? SortingContainer => _SortingContainer;
|
||||
|
||||
[JsonConstructor]
|
||||
public Mapping(int? by, MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation, MappingFromPerson? mappingFromPerson, string? segmentC, SortingContainer? sortingContainer)
|
||||
public Mapping(int? by, MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, MappingFromPerson? mappingFromPerson, string? segmentC, SortingContainer? sortingContainer)
|
||||
{
|
||||
_By = by;
|
||||
_SegmentC = segmentC;
|
||||
MappingFromItem = mappingFromItem;
|
||||
MappingFromLocation = mappingFromLocation;
|
||||
MappingFromPhotoPrismCollection = mappingFromPhotoPrismCollection;
|
||||
_MappingFromPerson = mappingFromPerson;
|
||||
_SortingContainer = sortingContainer;
|
||||
}
|
||||
|
||||
public Mapping(MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation) :
|
||||
this(null, mappingFromItem, mappingFromLocation, null, null, null)
|
||||
public Mapping(MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) :
|
||||
this(null, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection, null, null, null)
|
||||
{ }
|
||||
|
||||
public override string ToString()
|
||||
|
@ -14,8 +14,8 @@ public record Marker(
|
||||
[property: JsonPropertyName("subj_src")] string SubjSrc,
|
||||
[property: JsonPropertyName("face_id")] string FaceId,
|
||||
[property: JsonPropertyName("face_dist")] double FaceDist,
|
||||
[property: JsonPropertyName("embeddings_json")] string EmbeddingsJson,
|
||||
[property: JsonPropertyName("landmarks_json")] string LandmarksJson,
|
||||
// [property: JsonPropertyName("embeddings_json")] string EmbeddingsJson,
|
||||
// [property: JsonPropertyName("landmarks_json")] string LandmarksJson,
|
||||
[property: JsonPropertyName("x")] double X,
|
||||
[property: JsonPropertyName("y")] double Y,
|
||||
[property: JsonPropertyName("w")] double W,
|
||||
|
@ -1,36 +0,0 @@
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record MarkerWith(
|
||||
string MarkerUid,
|
||||
string FileUid,
|
||||
string MarkerType,
|
||||
string MarkerSrc,
|
||||
string MarkerName,
|
||||
int MarkerReview,
|
||||
int MarkerInvalid,
|
||||
string SubjUid,
|
||||
string SubjSrc,
|
||||
string FaceId,
|
||||
double FaceDist,
|
||||
string EmbeddingsJson,
|
||||
string LandmarksJson,
|
||||
double X,
|
||||
double Y,
|
||||
double W,
|
||||
double H,
|
||||
int Q,
|
||||
int Size,
|
||||
int Score,
|
||||
string Thumb,
|
||||
string MatchedAt,
|
||||
string CreatedAt,
|
||||
string UpdatedAt,
|
||||
int FileId,
|
||||
string FileName,
|
||||
int? DlibId,
|
||||
int? Count,
|
||||
double? Percent,
|
||||
int? NormalizedRectangle,
|
||||
long? PersonKey,
|
||||
string PersonKeyFormatted
|
||||
);
|
@ -23,6 +23,14 @@ public interface IMappingFromLocation
|
||||
|
||||
}
|
||||
|
||||
public interface IMappingFromPhotoPrism
|
||||
{
|
||||
|
||||
public DatabaseFile DatabaseFile { init; get; }
|
||||
public List<Marker> Markers { init; get; }
|
||||
|
||||
}
|
||||
|
||||
public interface IMappingFromPerson
|
||||
{
|
||||
|
||||
@ -40,6 +48,7 @@ public interface IMapping
|
||||
public string? SegmentC { get; }
|
||||
public MappingFromItem MappingFromItem { init; get; }
|
||||
public MappingFromLocation MappingFromLocation { init; get; }
|
||||
public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; }
|
||||
public MappingFromPerson? MappingFromPerson { get; }
|
||||
public SortingContainer? SortingContainer { get; }
|
||||
|
||||
|
@ -5,6 +5,21 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
public interface ILocation
|
||||
{ // ...
|
||||
|
||||
Rectangle? TestStatic_GetRectangle(Models.OutputResolution outputResolution, DatabaseFile databaseFile, Marker marker) =>
|
||||
GetRectangle(outputResolution, databaseFile, marker);
|
||||
static Rectangle? GetRectangle(Models.OutputResolution outputResolution, DatabaseFile databaseFile, Marker marker) =>
|
||||
Location.GetRectangle(outputResolution, databaseFile, marker);
|
||||
|
||||
Models.Location? TestStatic_GetLocation(Models.OutputResolution outputResolution, DatabaseFile databaseFile, Marker marker) =>
|
||||
GetLocation(outputResolution, databaseFile, marker);
|
||||
static Models.Location? GetLocation(Models.OutputResolution outputResolution, DatabaseFile databaseFile, Marker marker) =>
|
||||
Location.GetLocation(outputResolution, databaseFile, marker);
|
||||
|
||||
List<Models.Location> TestStatic_GetLocations(List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, List<Models.Face> faces) =>
|
||||
GetLocations(mappingFromPhotoPrismCollection, faces);
|
||||
static List<Models.Location> GetLocations(List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, List<Models.Face> faces) =>
|
||||
Location.GetLocations(mappingFromPhotoPrismCollection, faces);
|
||||
|
||||
Rectangle TestStatic_GetRectangle(Rectangle checkRectangle, int locationDigits, int locationFactor, int normalizedRectangle, Models.OutputResolution outputResolution, bool useOldWay) =>
|
||||
GetRectangle(checkRectangle, locationDigits, locationFactor, normalizedRectangle, outputResolution, useOldWay);
|
||||
static Rectangle GetRectangle(Rectangle checkRectangle, int locationDigits, int locationFactor, int normalizedRectangle, Models.OutputResolution outputResolution, bool useOldWay) =>
|
||||
|
@ -17,6 +17,7 @@ public interface IPath
|
||||
DeleteEmptyDirectories(rootDirectory, deletedDirectories);
|
||||
static void DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories) =>
|
||||
XPath.DeleteEmptyDirectories(rootDirectory, deletedDirectories);
|
||||
// $dirs = gci "" -directory -recurse | Where { (gci $_.fullName).count -eq 0 } | select -expandproperty FullName $dirs | Foreach-Object { Remove-Item $_ }
|
||||
|
||||
string[] TestStatic_GetDirectoryNames(string directory) =>
|
||||
GetDirectoryNames(directory);
|
||||
|
@ -189,4 +189,81 @@ internal abstract class Location
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
private static bool Matches(Models.OutputResolution outputResolution, DatabaseFile databaseFile)
|
||||
{
|
||||
bool result = outputResolution.Height == databaseFile.FileHeight && outputResolution.Width == databaseFile.FileWidth;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static Rectangle? GetRectangle(Models.OutputResolution outputResolution, DatabaseFile databaseFile, Marker marker)
|
||||
{
|
||||
Rectangle? 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));
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static Models.Location? GetLocation(Marker marker, Rectangle rectangle)
|
||||
{
|
||||
Models.Location? result;
|
||||
bool verified = Check(rectangle.Bottom, rectangle.Height, rectangle.Left, rectangle.Right, rectangle.Top, rectangle.Width, zCount: 1, throwException: false);
|
||||
if (!verified)
|
||||
result = null;
|
||||
else
|
||||
result = new(rectangle.Bottom, marker.Score / 100, rectangle.Left, rectangle.Right, rectangle.Top);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static Models.Location? GetLocation(Models.OutputResolution outputResolution, DatabaseFile databaseFile, Marker marker)
|
||||
{
|
||||
Models.Location? result;
|
||||
Rectangle? rectangle = GetRectangle(outputResolution, databaseFile, marker);
|
||||
if (rectangle is null)
|
||||
result = null;
|
||||
else
|
||||
result = GetLocation(marker, rectangle.Value);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static List<Models.Location> GetLocations(List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, List<Models.Face> faces)
|
||||
{
|
||||
List<Models.Location> results = new();
|
||||
double percent;
|
||||
Rectangle dlibRectangle;
|
||||
Rectangle? prismRectangle;
|
||||
Models.Location? location;
|
||||
Rectangle intersectRectangle;
|
||||
foreach (Models.Face face in faces)
|
||||
{
|
||||
if (face.Location is null || face.OutputResolution is null)
|
||||
continue;
|
||||
foreach (MappingFromPhotoPrism mappingFromPhotoPrism in mappingFromPhotoPrismCollection)
|
||||
{
|
||||
dlibRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
|
||||
foreach (Marker marker in mappingFromPhotoPrism.Markers)
|
||||
{
|
||||
prismRectangle = GetRectangle(face.OutputResolution, mappingFromPhotoPrism.DatabaseFile, marker);
|
||||
if (prismRectangle is null)
|
||||
{
|
||||
location = new(1, 0, 0, 1, 0);
|
||||
results.Add(location);
|
||||
continue;
|
||||
}
|
||||
location = GetLocation(marker, prismRectangle.Value);
|
||||
if (location is null)
|
||||
continue;
|
||||
intersectRectangle = Rectangle.Intersect(dlibRectangle, prismRectangle.Value);
|
||||
percent = (double)intersectRectangle.Width * intersectRectangle.Height / (dlibRectangle.Width * dlibRectangle.Height);
|
||||
if (percent > 0.000001)
|
||||
continue;
|
||||
results.Add(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user