AI-powered photo culling and organization for FRC competition photography
Download · Features · Screenshot · Getting Started · Tech Stack · Contributing · License
An open-source desktop application built by volunteers of Fikret Yuksel Foundation. Designed to help FRC (FIRST Robotics Competition) media teams quickly sort through hundreds of competition photos — keeping the best shots, detecting duplicates, and organizing everything automatically.
| Platform | File | Notes |
|---|---|---|
| macOS (Apple Silicon) | 📦 .dmg (ARM) | M1, M2, M3, M4 Macs |
| macOS (Intel) | 📦 .dmg (x64) | Pre-2020 Intel Macs |
| Windows | 📦 .exe Installer | Windows 10/11 (64-bit) |
| Linux (Debian/Ubuntu) | 📦 .deb | Ubuntu, Debian, Pop!_OS |
| Linux (Fedora/RHEL) | 📦 .rpm | Fedora, RHEL, openSUSE |
| Linux (Universal) | 📦 .AppImage | All Linux distros |
Auto-update: The app automatically checks for new versions. You'll get an in-app notification when an update is available.
- Technical Quality Analysis — Evaluates sharpness, exposure, contrast, and EXIF data to score each photo (0–100)
- Duplicate & Burst Detection — Finds exact duplicates (perceptual hashing + SSIM) and burst/similar shots (feature matching), keeps only the best from each group
- Smart Organization — Automatically categorizes photos into Keep / Maybe / Reject
- Manual Review & Override — Browse photos in a gallery view, drag between categories, batch operations with keyboard shortcuts
- Multi-folder Input — Select multiple folders, optionally merge into a single output
- Export — Copy organized photos to output folder with progress tracking
- Dark & Light Mode — Toggle between themes, glassmorphism UI with FYF brand colors
- Bilingual — Full Turkish and English language support (TR / EN)
- Cross-platform — Native desktop app for macOS (.dmg), Windows (.exe), and Linux (.deb / .AppImage)
# Clone the repo
git clone https://github.com/fikretyukselit/fyf-photo-culler.git
cd fyf-photo-culler
# Install Python dependencies
pip install fastapi "uvicorn[standard]" opencv-python-headless Pillow imagehash scikit-image tqdm numpy
# Start the Python backend (Terminal 1)
python3 -m backend.server
# Install frontend dependencies and start the app (Terminal 2)
cd ui
bun install
bun run tauri devThe backend will print BACKEND_PORT=9470 — the frontend connects to it automatically.
# Build Python sidecar binary
pyinstaller --onefile --name fyf-backend backend/server.py \
--hidden-import culling --add-data "culling:culling"
# Copy to Tauri binaries directory
cp dist/fyf-backend ui/src-tauri/binaries/fyf-backend-$(rustc -vV | grep host | awk '{print $2}')
# Build the app
cd ui && bun run tauri buildOutput: .dmg (macOS), .exe installer (Windows), or .deb / .AppImage (Linux) in ui/src-tauri/target/release/bundle/
| Layer | Technology |
|---|---|
| Desktop Shell | Tauri 2.0 |
| Frontend | React + TypeScript + Vite |
| UI Components | shadcn/ui + Tailwind CSS |
| State Management | Zustand |
| Backend | Python + FastAPI (localhost sidecar) |
| Image Analysis | OpenCV, Pillow, imagehash, scikit-image |
| Package Manager | Bun |
fyf-photo-culler/
├── backend/ # FastAPI server (Python sidecar)
│ ├── server.py # App entry + port discovery
│ ├── state.py # In-memory session state
│ ├── thumbnail.py # Thumbnail generation/caching
│ └── routes/ # REST API endpoints
│ ├── analysis.py # POST /analyze, GET /progress (SSE)
│ ├── photos.py # Photo listing, thumbnails, metadata
│ ├── review.py # Manual override endpoints
│ └── export.py # File export with progress
├── culling/ # Core analysis engine
│ ├── technical.py # Quality scoring (sharpness, exposure, contrast)
│ ├── duplicates.py # Duplicate & burst detection (pHash, SSIM, ORB)
│ ├── organizer.py # File organization & reporting
│ └── utils.py # Image loading, thumbnails, file utilities
├── ui/ # Tauri + React desktop app
│ ├── src/
│ │ ├── components/ # React components (Landing, Review, Export...)
│ │ └── lib/ # API client, stores, i18n
│ └── src-tauri/ # Rust config + sidecar management
└── pyproject.toml # Python project metadata
Data flow: Tauri launches Python sidecar → sidecar starts FastAPI on localhost → frontend calls REST API with SSE for real-time progress.
| Key | Action |
|---|---|
K |
Move selected to Keep |
M |
Move selected to Maybe |
R |
Move selected to Reject |
A |
Select all in current category |
Esc |
Clear selection |
Space |
Toggle selection |
Arrow keys |
Navigate photos |
This is an open-source project by FYF volunteers. Contributions are welcome!
- Fork the repo
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes
- Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Fikret Yuksel Foundation is a non-profit organization dedicated to inspiring and educating young students, enabling them to discover and develop their potential while fostering Turkey's growth. This tool was built to support our FRC robotics teams' media operations.

