Web server and application to view photos organized in directories.
Features:
Using the docker image:
docker run \
-v /path/to/originals:/data:rw \
-v /path/to/store:/app/store:rw \
--user $(stat -c '%u:%g' ~) \
gpajot/photon:latest
The easiest way to serve is to use this Caddy configuration:
localhost:8000 {
encode
handle /api/* {
reverse_proxy <HOST>
}
handle /originals/* {
header Cache-Control "max-age=31536000, immutable"
root <PATH_TO_ORIGINALS>
file_server
}
handle /thumbs/* {
header Cache-Control "max-age=31536000, immutable"
root <PATH_TO_THUMBNAILS>
file_server
}
handle {
root <PATH_TO_FRONT>
route {
try_files {path} /index.html
header Cache-Control "max-age=31536000, immutable"
header /index.html Cache-Control "no-cache"
header /favicon.png Cache-Control "no-cache"
header /manifest.json Cache-Control "no-cache"
}
file_server
}
}
Tip
To add authentication, see adding [forward auth](https://caddyserver.com/docs/caddyfile/directives/forward_auth) on the `handle /api/*` block
Caution
Originals stay untouched by default apart from being renamed, **unless** you specify an option for video conversion. Passing a value other than `none` (the default) to `--orig.video.convert-preset` will **replace** the videos with converted ones. This also implies that all original formats must be supported by your browser.
Reverse geocoding is done using a kDTree in 2 dimension to find the closest city. Cities are downloaded from Geonames on first use and cached in the database.
Face detection and recognition is made using ONNX models.
Both pretrained models correspond to buffalo_l
of deepinsight/insightface:
Pretrained models are downloaded from Immich at Hugging Face and cached
in /app/store/models-cache.
Clustering is done with an adapted, incremental DBSCAN algorithm. 4 passes are made, the first 3 are very close to the original DBSCAN algorithm.
Simple caching of closest neighbors with distances to avoid recomputing in each phase.
Identify core faces. A core face is defined by having at least K neighbors within EPS distance.
Here we suppose that EPS is conservative (low) to only create meaningful clusters.
In addition to that, 2 conditions are added:
--core.faces.clustering.core-min-confidence)--core.faces.clustering.core-front-facing-threhold)These conditions are added to avoid creating big clusters of unclear faces that would swallow other clusters.
Incremental support.
When adding new faces to already clustered faces (as the library grows), we first try to assign new core faces to
existing clusters. We assign a face to the cluster of the closest clustered core face within EPS distance.
After adding points, we must check if clusters should be merged as new points might have bridged the gap.
Assign each core face to a cluster. This is done by selecting a non-clustered core face, adding it to a
cluster and recursively adding all core faces within EPS distance. When no more faces can be added a new cluster is
created, and this is repeated until all core faces are assigned to a cluster.
Assign non-core faces to clusters. This is done by assigning to the cluster of the closest core face within a certain
distance, if any. Here we deviate from the original algorithm by using EPS * R (because EPS is conservative).
R is controlled via the --core.faces.clustering.non-core-multiplier.
This pass is an addition to the original algorithm. We add even more non-core faces to clusters by adding all
unclustered faces that have at least K neighbors (core and non-core) in the same cluster within EPS * R distance.
This pass should help to compensate differences in density inside clusters, and the fact that we are conservative with
core faces.
The most important parameter to tune is the number of neighbors K (--core.faces.clustering.min-neighbors), as it
will
depend on the number of faces and their density:
The clustering logs should help with that by checking how many core faces there are, how many clusters are created and how many are merged.
After face embeddings have been computed and clustered, identification is done by assigning each cluster to a person (admin page).
Content type
Image
Digest
sha256:712351634…
Size
232 MB
Last updated
4 days ago
docker pull gpajot/photon