mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
People: Remove face embeddings and landmarks from JSON response #22
Improves performance by reducing response size.
This commit is contained in:
@@ -15,16 +15,16 @@ type Faces []Face
|
|||||||
|
|
||||||
// Face represents the face of a Subject.
|
// Face represents the face of a Subject.
|
||||||
type Face struct {
|
type Face struct {
|
||||||
ID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false;" json:"ID" yaml:"ID"`
|
ID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false;" json:"ID" yaml:"ID"`
|
||||||
FaceSrc string `gorm:"type:VARBINARY(8);" json:"Src" yaml:"Src,omitempty"`
|
FaceSrc string `gorm:"type:VARBINARY(8);" json:"Src" yaml:"Src,omitempty"`
|
||||||
SubjectUID string `gorm:"type:VARBINARY(42);index;" json:"SubjectUID" yaml:"SubjectUID,omitempty"`
|
SubjectUID string `gorm:"type:VARBINARY(42);index;" json:"SubjectUID" yaml:"SubjectUID,omitempty"`
|
||||||
Collisions int `json:"Collisions" yaml:"Collisions,omitempty"`
|
Collisions int `json:"Collisions" yaml:"Collisions,omitempty"`
|
||||||
Samples int `json:"Samples" yaml:"Samples,omitempty"`
|
Samples int `json:"Samples" yaml:"Samples,omitempty"`
|
||||||
Radius float64 `json:"Radius" yaml:"Radius,omitempty"`
|
Radius float64 `json:"Radius" yaml:"Radius,omitempty"`
|
||||||
EmbeddingJSON []byte `gorm:"type:MEDIUMBLOB;" json:"EmbeddingJSON" yaml:"EmbeddingJSON,omitempty"`
|
EmbeddingJSON json.RawMessage `gorm:"type:MEDIUMBLOB;" json:"-" yaml:"EmbeddingJSON,omitempty"`
|
||||||
CreatedAt time.Time `json:"CreatedAt" yaml:"CreatedAt,omitempty"`
|
CreatedAt time.Time `json:"CreatedAt" yaml:"CreatedAt,omitempty"`
|
||||||
UpdatedAt time.Time `json:"UpdatedAt" yaml:"UpdatedAt,omitempty"`
|
UpdatedAt time.Time `json:"UpdatedAt" yaml:"UpdatedAt,omitempty"`
|
||||||
embedding Embedding `gorm:"-"`
|
embedding Embedding `gorm:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnknownFace can be used as a placeholder for unknown faces.
|
// UnknownFace can be used as a placeholder for unknown faces.
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ func (m *File) AddFace(f face.Face, refUID string) {
|
|||||||
|
|
||||||
// FaceCount returns the current number of valid faces detected.
|
// FaceCount returns the current number of valid faces detected.
|
||||||
func (m *File) FaceCount() (c int) {
|
func (m *File) FaceCount() (c int) {
|
||||||
if err := Db().Model(Marker{}).Where("marker_invalid = 0 AND file_id = ?", m.ID).
|
if err := Db().Model(Marker{}).Where("file_id = ? AND marker_invalid = 0", m.ID).
|
||||||
Count(&c).Error; err != nil {
|
Count(&c).Error; err != nil {
|
||||||
log.Errorf("file: %s (count faces)", err)
|
log.Errorf("file: %s (count faces)", err)
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -20,26 +20,26 @@ const (
|
|||||||
|
|
||||||
// Marker represents an image marker point.
|
// Marker represents an image marker point.
|
||||||
type Marker struct {
|
type Marker struct {
|
||||||
ID uint `gorm:"primary_key" json:"ID" yaml:"-"`
|
ID uint `gorm:"primary_key" json:"ID" yaml:"-"`
|
||||||
FileID uint `gorm:"index;" json:"-" yaml:"-"`
|
FileID uint `gorm:"index;" json:"-" yaml:"-"`
|
||||||
MarkerType string `gorm:"type:VARBINARY(8);index:idx_markers_subject;default:'';" json:"Type" yaml:"Type"`
|
MarkerType string `gorm:"type:VARBINARY(8);index:idx_markers_subject;default:'';" json:"Type" yaml:"Type"`
|
||||||
MarkerSrc string `gorm:"type:VARBINARY(8);default:'';" json:"Src" yaml:"Src,omitempty"`
|
MarkerSrc string `gorm:"type:VARBINARY(8);default:'';" json:"Src" yaml:"Src,omitempty"`
|
||||||
MarkerName string `gorm:"type:VARCHAR(255);" json:"Name" yaml:"Name,omitempty"`
|
MarkerName string `gorm:"type:VARCHAR(255);" json:"Name" yaml:"Name,omitempty"`
|
||||||
SubjectUID string `gorm:"type:VARBINARY(42);index:idx_markers_subject;" json:"SubjectUID" yaml:"SubjectUID,omitempty"`
|
SubjectUID string `gorm:"type:VARBINARY(42);index:idx_markers_subject;" json:"SubjectUID" yaml:"SubjectUID,omitempty"`
|
||||||
SubjectSrc string `gorm:"type:VARBINARY(8);default:'';" json:"SubjectSrc" yaml:"SubjectSrc,omitempty"`
|
SubjectSrc string `gorm:"type:VARBINARY(8);default:'';" json:"SubjectSrc" yaml:"SubjectSrc,omitempty"`
|
||||||
FaceID string `gorm:"type:VARBINARY(42);index;" json:"FaceID" yaml:"FaceID,omitempty"`
|
Subject *Subject `gorm:"foreignkey:SubjectUID;association_foreignkey:SubjectUID;association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Subject,omitempty" yaml:"-"`
|
||||||
EmbeddingsJSON []byte `gorm:"type:MEDIUMBLOB;" json:"EmbeddingsJSON" yaml:"EmbeddingsJSON,omitempty"`
|
FaceID string `gorm:"type:VARBINARY(42);index;" json:"FaceID" yaml:"FaceID,omitempty"`
|
||||||
MarkerScore int `gorm:"type:SMALLINT" json:"Score" yaml:"Score,omitempty"`
|
EmbeddingsJSON json.RawMessage `gorm:"type:MEDIUMBLOB;" json:"-" yaml:"EmbeddingsJSON,omitempty"`
|
||||||
MarkerInvalid bool `json:"Invalid" yaml:"Invalid,omitempty"`
|
embeddings Embeddings `gorm:"-"`
|
||||||
MarkerJSON []byte `gorm:"type:MEDIUMBLOB;" json:"MarkerJSON" yaml:"MarkerJSON,omitempty"`
|
LandmarksJSON json.RawMessage `gorm:"type:MEDIUMBLOB;" json:"-" yaml:"LandmarksJSON,omitempty"`
|
||||||
X float32 `gorm:"type:FLOAT;" json:"X" yaml:"X,omitempty"`
|
X float32 `gorm:"type:FLOAT;" json:"X" yaml:"X,omitempty"`
|
||||||
Y float32 `gorm:"type:FLOAT;" json:"Y" yaml:"Y,omitempty"`
|
Y float32 `gorm:"type:FLOAT;" json:"Y" yaml:"Y,omitempty"`
|
||||||
W float32 `gorm:"type:FLOAT;" json:"W" yaml:"W,omitempty"`
|
W float32 `gorm:"type:FLOAT;" json:"W" yaml:"W,omitempty"`
|
||||||
H float32 `gorm:"type:FLOAT;" json:"H" yaml:"H,omitempty"`
|
H float32 `gorm:"type:FLOAT;" json:"H" yaml:"H,omitempty"`
|
||||||
|
Score int `gorm:"type:SMALLINT" json:"Score" yaml:"Score,omitempty"`
|
||||||
|
MarkerInvalid bool `json:"Invalid" yaml:"Invalid,omitempty"`
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
Subject *Subject `gorm:"foreignkey:SubjectUID;association_foreignkey:SubjectUID;association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Subject,omitempty" yaml:"-"`
|
|
||||||
embeddings Embeddings `gorm:"-"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnknownMarker can be used as a default for unknown markers.
|
// UnknownMarker can be used as a default for unknown markers.
|
||||||
@@ -51,10 +51,10 @@ func (Marker) TableName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewMarker creates a new entity.
|
// NewMarker creates a new entity.
|
||||||
func NewMarker(fileUID uint, refUID, markerSrc, markerType string, x, y, w, h float32) *Marker {
|
func NewMarker(fileID uint, subjectUID, markerSrc, markerType string, x, y, w, h float32) *Marker {
|
||||||
m := &Marker{
|
m := &Marker{
|
||||||
FileID: fileUID,
|
FileID: fileID,
|
||||||
SubjectUID: refUID,
|
SubjectUID: subjectUID,
|
||||||
MarkerSrc: markerSrc,
|
MarkerSrc: markerSrc,
|
||||||
MarkerType: markerType,
|
MarkerType: markerType,
|
||||||
X: x,
|
X: x,
|
||||||
@@ -72,9 +72,9 @@ func NewFaceMarker(f face.Face, fileID uint, refUID string) *Marker {
|
|||||||
|
|
||||||
m := NewMarker(fileID, refUID, SrcImage, MarkerFace, pos.X, pos.Y, pos.W, pos.H)
|
m := NewMarker(fileID, refUID, SrcImage, MarkerFace, pos.X, pos.Y, pos.W, pos.H)
|
||||||
|
|
||||||
m.MarkerScore = f.Score
|
|
||||||
m.MarkerJSON = f.RelativeLandmarksJSON()
|
|
||||||
m.EmbeddingsJSON = f.EmbeddingsJSON()
|
m.EmbeddingsJSON = f.EmbeddingsJSON()
|
||||||
|
m.LandmarksJSON = f.RelativeLandmarksJSON()
|
||||||
|
m.Score = f.Score
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
@@ -208,8 +208,8 @@ func UpdateOrCreateMarker(m *Marker) (*Marker, error) {
|
|||||||
"Y": m.Y,
|
"Y": m.Y,
|
||||||
"W": m.W,
|
"W": m.W,
|
||||||
"H": m.H,
|
"H": m.H,
|
||||||
"MarkerScore": m.MarkerScore,
|
"Score": m.Score,
|
||||||
"MarkerJSON": m.MarkerJSON,
|
"LandmarksJSON": m.LandmarksJSON,
|
||||||
"EmbeddingsJSON": m.EmbeddingsJSON,
|
"EmbeddingsJSON": m.EmbeddingsJSON,
|
||||||
"SubjectUID": m.SubjectUID,
|
"SubjectUID": m.SubjectUID,
|
||||||
})
|
})
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,7 @@
|
|||||||
package entity
|
package entity
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -22,26 +23,26 @@ type Subjects []Subject
|
|||||||
|
|
||||||
// Subject represents a named photo subject, typically a person.
|
// Subject represents a named photo subject, typically a person.
|
||||||
type Subject struct {
|
type Subject struct {
|
||||||
ID uint `gorm:"primary_key" json:"ID" yaml:"-"`
|
ID uint `gorm:"primary_key" json:"ID" yaml:"-"`
|
||||||
SubjectUID string `gorm:"type:VARBINARY(42);unique_index;" json:"UID" yaml:"UID"`
|
SubjectUID string `gorm:"type:VARBINARY(42);unique_index;" json:"UID" yaml:"UID"`
|
||||||
SubjectType string `gorm:"type:VARBINARY(8);" json:"Type" yaml:"Type"`
|
SubjectType string `gorm:"type:VARBINARY(8);" json:"Type" yaml:"Type"`
|
||||||
SubjectSrc string `gorm:"type:VARBINARY(8);" json:"Src" yaml:"Src"`
|
SubjectSrc string `gorm:"type:VARBINARY(8);" json:"Src" yaml:"Src"`
|
||||||
SubjectSlug string `gorm:"type:VARBINARY(255);index;" json:"Slug" yaml:"-"`
|
SubjectSlug string `gorm:"type:VARBINARY(255);index;" json:"Slug" yaml:"-"`
|
||||||
SubjectName string `gorm:"type:VARCHAR(255);index;" json:"Name" yaml:"Name"`
|
SubjectName string `gorm:"type:VARCHAR(255);index;" json:"Name" yaml:"Name"`
|
||||||
SubjectDescription string `gorm:"type:TEXT;" json:"Description" yaml:"Description,omitempty"`
|
SubjectDescription string `gorm:"type:TEXT;" json:"Description" yaml:"Description,omitempty"`
|
||||||
SubjectNotes string `gorm:"type:TEXT;" json:"Notes,omitempty" yaml:"Notes,omitempty"`
|
SubjectNotes string `gorm:"type:TEXT;" json:"Notes,omitempty" yaml:"Notes,omitempty"`
|
||||||
SubjectJSON []byte `gorm:"type:MEDIUMBLOB;" json:"JSON,omitempty" yaml:"JSON,omitempty"`
|
MetadataJSON json.RawMessage `gorm:"type:MEDIUMBLOB;" json:"Metadata,omitempty" yaml:"Metadata,omitempty"`
|
||||||
Favorite bool `json:"Favorite" yaml:"Favorite,omitempty"`
|
Favorite bool `json:"Favorite" yaml:"Favorite,omitempty"`
|
||||||
Hidden bool `json:"Hidden" yaml:"Hidden,omitempty"`
|
Hidden bool `json:"Hidden" yaml:"Hidden,omitempty"`
|
||||||
Private bool `json:"Private" yaml:"Private,omitempty"`
|
Private bool `json:"Private" yaml:"Private,omitempty"`
|
||||||
PhotoCount int `gorm:"default:0" json:"PhotoCount" yaml:"-"`
|
PhotoCount int `gorm:"default:0" json:"PhotoCount" yaml:"-"`
|
||||||
BirthYear int `json:"BirthYear" yaml:"BirthYear,omitempty"`
|
BirthYear int `json:"BirthYear" yaml:"BirthYear,omitempty"`
|
||||||
BirthMonth int `json:"BirthMonth" yaml:"BirthMonth,omitempty"`
|
BirthMonth int `json:"BirthMonth" yaml:"BirthMonth,omitempty"`
|
||||||
BirthDay int `json:"BirthDay" yaml:"BirthDay,omitempty"`
|
BirthDay int `json:"BirthDay" yaml:"BirthDay,omitempty"`
|
||||||
PassedAway *time.Time `json:"PassedAway,omitempty" yaml:"PassedAway,omitempty"`
|
PassedAway *time.Time `json:"PassedAway,omitempty" yaml:"PassedAway,omitempty"`
|
||||||
CreatedAt time.Time `json:"CreatedAt" yaml:"-"`
|
CreatedAt time.Time `json:"CreatedAt" yaml:"-"`
|
||||||
UpdatedAt time.Time `json:"UpdatedAt" yaml:"-"`
|
UpdatedAt time.Time `json:"UpdatedAt" yaml:"-"`
|
||||||
DeletedAt *time.Time `sql:"index" json:"DeletedAt,omitempty" yaml:"-"`
|
DeletedAt *time.Time `sql:"index" json:"DeletedAt,omitempty" yaml:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnknownPerson can be used as a placeholder for unknown people.
|
// UnknownPerson can be used as a placeholder for unknown people.
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ var SubjectFixtures = SubjectMap{
|
|||||||
Hidden: false,
|
Hidden: false,
|
||||||
SubjectDescription: "Subject Description",
|
SubjectDescription: "Subject Description",
|
||||||
SubjectNotes: "Short Note",
|
SubjectNotes: "Short Note",
|
||||||
SubjectJSON: []byte(""),
|
MetadataJSON: []byte(""),
|
||||||
PhotoCount: 1,
|
PhotoCount: 1,
|
||||||
BirthYear: 2000,
|
BirthYear: 2000,
|
||||||
BirthMonth: 5,
|
BirthMonth: 5,
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import "github.com/ulule/deepcopier"
|
|||||||
|
|
||||||
// Marker represents an image marker edit form.
|
// Marker represents an image marker edit form.
|
||||||
type Marker struct {
|
type Marker struct {
|
||||||
MarkerType string `json:"Type"`
|
MarkerType string `json:"Type"`
|
||||||
SubjectUID string `json:"SubjectUID"`
|
MarkerSrc string `json:"Src"`
|
||||||
SubjectSrc string `json:"SubjectSrc"`
|
MarkerName string `json:"Name"`
|
||||||
MarkerName string `json:"Name"`
|
SubjectUID string `json:"SubjectUID"`
|
||||||
MarkerSrc string `json:"Src"`
|
SubjectSrc string `json:"SubjectSrc"`
|
||||||
MarkerScore int `json:"Score"`
|
Score int `json:"Score"`
|
||||||
MarkerInvalid bool `json:"Invalid"`
|
Invalid bool `json:"Invalid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMarker(m interface{}) (f Marker, err error) {
|
func NewMarker(m interface{}) (f Marker, err error) {
|
||||||
|
|||||||
@@ -9,21 +9,21 @@ import (
|
|||||||
func TestNewMarker(t *testing.T) {
|
func TestNewMarker(t *testing.T) {
|
||||||
t.Run("success", func(t *testing.T) {
|
t.Run("success", func(t *testing.T) {
|
||||||
var m = struct {
|
var m = struct {
|
||||||
MarkerType string
|
MarkerType string
|
||||||
MarkerSrc string
|
MarkerSrc string
|
||||||
MarkerName string
|
MarkerName string
|
||||||
SubjectUID string
|
SubjectUID string
|
||||||
SubjectSrc string
|
SubjectSrc string
|
||||||
MarkerScore int
|
Score int
|
||||||
MarkerInvalid bool
|
Invalid bool
|
||||||
}{
|
}{
|
||||||
MarkerType: "face",
|
MarkerType: "face",
|
||||||
MarkerSrc: "image",
|
MarkerSrc: "image",
|
||||||
MarkerName: "Foo",
|
MarkerName: "Foo",
|
||||||
SubjectUID: "3h59wvth837b5vyiub35",
|
SubjectUID: "3h59wvth837b5vyiub35",
|
||||||
SubjectSrc: "meta",
|
SubjectSrc: "meta",
|
||||||
MarkerScore: 100,
|
Score: 100,
|
||||||
MarkerInvalid: true,
|
Invalid: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := NewMarker(m)
|
f, err := NewMarker(m)
|
||||||
@@ -37,7 +37,7 @@ func TestNewMarker(t *testing.T) {
|
|||||||
assert.Equal(t, "Foo", f.MarkerName)
|
assert.Equal(t, "Foo", f.MarkerName)
|
||||||
assert.Equal(t, "3h59wvth837b5vyiub35", f.SubjectUID)
|
assert.Equal(t, "3h59wvth837b5vyiub35", f.SubjectUID)
|
||||||
assert.Equal(t, "meta", f.SubjectSrc)
|
assert.Equal(t, "meta", f.SubjectSrc)
|
||||||
assert.Equal(t, 100, f.MarkerScore)
|
assert.Equal(t, 100, f.Score)
|
||||||
assert.Equal(t, true, f.MarkerInvalid)
|
assert.Equal(t, true, f.Invalid)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user