Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/release-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ jobs:
--icon assets/app_icon.ico `
--paths src `
--hidden-import core.build_info `
--hidden-import mediapipe `
--add-data "src/ui/dark_theme.qss;." `
--add-data "assets/app_icon.ico;." `
--add-data "assets/app_icon.png;." `
Expand All @@ -161,6 +162,8 @@ jobs:
--hidden-import torch `
--hidden-import sklearn `
--hidden-import sentence_transformers `
--collect-data mediapipe `
--collect-data pyiqa `
--add-data "models;models" `
--runtime-hook runtime_hook.py `
src/main.py
Expand Down Expand Up @@ -214,6 +217,7 @@ jobs:
--icon assets/photosort.icns \
--paths src \
--hidden-import core.build_info \
--hidden-import mediapipe \
--add-data src/ui/dark_theme.qss:. \
--add-data assets/app_icon.ico:. \
--add-data assets/app_icon.png:. \
Expand All @@ -236,6 +240,8 @@ jobs:
--hidden-import torch \
--hidden-import sklearn \
--hidden-import sentence_transformers \
--collect-data mediapipe \
--collect-data pyiqa \
--add-data models:models \
src/main.py

Expand Down
27 changes: 8 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ PhotoSort is a powerful desktop application focused on speed designed to streaml
* **Fast Processing**: Intensive operations (scanning, thumbnailing, analysis) run once in batch to ensure fast image scrolling.
* **Optimized Image Handling**: Supports a wide range of formats, including various RAW types, with efficient caching.
* **Intelligent Image Rotation**: Smart rotation system that automatically tries lossless metadata rotation first, with optional fallback to pixel rotation when needed.
* **AI Best-Shot Ranking**: Compare stacks with either the bundled multi-model pipeline or an OpenAI-compatible vision model (e.g. Qwen3-VL).
* **AI Best-Shot Ranking**: Compare stacks with either the bundled MUSIQ/MANIQA/LIQE pipeline or an OpenAI-compatible vision model (e.g. Qwen3-VL).
* **AI Star Ratings**: Ask the configured AI engine to score individual photos with 1–5 stars.

- **Update Notifications**: Automatically checks for new releases and notifies users when updates are available, with direct download links.
Expand Down Expand Up @@ -102,25 +102,15 @@ The application will automatically detect and load the model when you use the ro

### AI Best Shot Ranking & Engines

PhotoSort can rank similar shots and assign AI ratings using either a local
multi-model pipeline or an OpenAI-compatible vision model; switch engines in
PhotoSort can rank similar shots and assign AI ratings using either the local
MUSIQ/MANIQA/LIQE pipeline or an OpenAI-compatible vision model; switch engines in
**Preferences → AI Rating Engine** (`F10`). Settings persist between sessions.

**Local pipeline (default)**
Runs entirely offline with three Hugging Face checkpoints:
BlazeFace face detector (`qualcomm/MediaPipe-Face-Detection`), eye-state classifier
(`MichalMlodawski/open-closed-eye-classification-mobilev2`), and the aesthetic predictor
(`shunk031/aesthetics-predictor-v2-sac-logos-ava1-l14-linearMSE`). Place each bundle
under `models/` and choose **Local Pipeline** in preferences.

Required downloads (install into `models/`):

1. **Face detector** – [`qualcomm/MediaPipe-Face-Detection`](https://huggingface.co/qualcomm/MediaPipe-Face-Detection)
Extract `model.onnx` to `models/job_*/model.onnx` (or e.g. `models/MediaPipe-Face-Detection_FaceDetector_float/model.onnx`).
2. **Eye-state classifier** – [`MichalMlodawski/open-closed-eye-classification-mobilev2`](https://huggingface.co/MichalMlodawski/open-closed-eye-classification-mobilev2)
Copy all files into `models/open-closed-eye-classification-mobilev2/`.
3. **Aesthetic predictor** – [`shunk031/aesthetics-predictor-v2-sac-logos-ava1-l14-linearMSE`](https://huggingface.co/shunk031/aesthetics-predictor-v2-sac-logos-ava1-l14-linearMSE)
Copy all files into `models/aesthetic_predictor/` (includes the CLIP backbone plus regression head).
Runs entirely offline by blending three state-of-the-art no-reference IQA models:
**MUSIQ**, **MANIQA**, and **LIQE**. These metrics are loaded
through [`pyiqa`](https://github.com/chaofengc/IQA-PyTorch); no manual model
downloads are required.

**LLM engine**
Connect PhotoSort to any OpenAI-compatible endpoint that accepts images
Expand All @@ -138,8 +128,7 @@ the API key blank.
- **AI star ratings**: To score every visible image, run **View → AI Rate Images**
(`Ctrl+A`). The ratings are stored in your XMP sidecars/metadata cache so
they survive reloads, and you can filter the library using the standard rating
controls. (Detailed breakdowns from the AI response are kept internally for future
UI integrations.)
controls.

### Exporting Logs

Expand Down
4 changes: 2 additions & 2 deletions assets/keyboard-layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ <h3 style="float: left;" class="editable">Photosort Shortcuts (ctrl/cmd)</h3>
<div data-key="KeyX" class="key">X<span class="userText"></span></div>
<div data-key="KeyC" class="key">C<span class="userText"></span></div>
<div data-key="KeyV" class="key">V<span class="userText"></span></div>
<div data-key="KeyB" class="key key--colour--navy">B<span class="userText">Analyze Best Shots (Ctrl+B)</span></div>
<div data-key="KeyB" class="key key--colour--navy">B<span class="userText">Analyze Best Shots</span></div>
<div data-key="KeyN" class="key">N<span class="userText"></span></div>
<div data-key="KeyM" class="key">M<span class="userText"></span></div>
<div data-key="Comma" class="key">, &lt;<span class="userText"></span></div>
Expand Down Expand Up @@ -946,7 +946,7 @@ <h3 style="float: left;" class="editable">Photosort Shortcuts (shift)</h3>
<div data-key="KeyX" class="key">X<span class="userText"></span></div>
<div data-key="KeyC" class="key">C<span class="userText"></span></div>
<div data-key="KeyV" class="key">V<span class="userText"></span></div>
<div data-key="KeyB" class="key key--colour--navy">B<span class="userText">Analyze Best Shots (Selected)</span></div>
<div data-key="KeyB" class="key key--colour--navy">B<span class="userText">Analyze Best Shots (Images Selected)</span></div>
<div data-key="KeyN" class="key key--colour--orange">N<span class="userText">Decline Rotation Suggestions</span></div>
<div data-key="KeyM" class="key">M<span class="userText"></span></div>
<div data-key="Comma" class="key">, &lt;<span class="userText"></span></div>
Expand Down
Binary file modified assets/keyboard-layout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion requirements-cuda.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ opencv-python
pyexiv2
piexif
onnxruntime-gpu
torchvision
torchvision
pyiqa
mediapipe
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ pyexiv2
piexif
onnxruntime
torchvision
pyiqa
mediapipe
14 changes: 6 additions & 8 deletions src/core/ai/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""
AI helper utilities for advanced ranking/scoring pipelines.
"""AI helper utilities for best-shot ranking and scoring."""

Currently exposes the experimental best-photo selector which chains together
multiple pre-trained models (face detection, eye-state classification, and
image quality scoring) to rank similar shots.
"""

from .best_photo_selector import BestPhotoSelector, BestShotResult # noqa: F401
from .best_photo_selector import ( # noqa: F401
BestPhotoSelector,
BestShotResult,
MetricSpec,
)
Loading
Loading