PhotoPrism for more locations

This commit is contained in:
2022-12-25 13:54:17 -07:00
parent a510019c1d
commit 37c7b6760d
31 changed files with 395 additions and 509 deletions

View 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
);

View File

@ -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()

View File

@ -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,

View File

@ -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
);

View File

@ -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; }

View File

@ -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) =>

View File

@ -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);

View File

@ -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;
}
}