stashface / CLAUDE.md
cc1234
docs: add CLAUDE.md for project guidance and setup instructions
2e8f987

A newer version of the Gradio SDK is available: 5.35.0

Upgrade

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Stashface is a Python-based face recognition application that identifies performers in images using ensemble machine learning models. It provides a Gradio web interface for uploading images and searching for performer matches against a database of known performers.

Common Commands

Installation and Setup

uv install  # Install dependencies using uv package manager

Running the Application

python app.py  # Launch the Gradio web interface on localhost:7860

Testing

pytest tests/  # Run all tests
pytest tests/test_vtt_parser.py  # Run specific test file

Environment Variables

  • DEEPFACE_HOME: Set to "." (current directory) for DeepFace model storage
  • CUDA_VISIBLE_DEVICES: Set to "-1" to force CPU usage
  • VISAGE_KEY: Required for decrypting performer database in persons.zip

Architecture

Core Components

  1. DataManager (models/data_manager.py): Handles loading and querying face recognition data

    • Manages encrypted performer database (data/persons.zip)
    • Loads face embeddings from JSON (data/faces.json)
    • Handles Voyager vector indices for FaceNet and ArcFace models
  2. EnsembleFaceRecognition (models/face_recognition.py): Implements ensemble face recognition

    • Combines FaceNet512 and ArcFace models using weighted voting
    • Normalizes distances and computes confidence scores
    • Uses DeepFace backend for face detection and embedding extraction
  3. WebInterface (web/interface.py): Gradio-based web interface

    • Two main tabs: Multiple Face Search and Faces in Sprite
    • Handles image uploads and displays JSON results
    • Integrates with image processing pipeline
  4. Image Processing (models/image_processor.py): Core image processing logic

    • Extracts faces using YOLOv8 and MediaPipe detectors
    • Generates embeddings for original and horizontally flipped images
    • Returns performer information with confidence scores

Data Flow

  1. User uploads image through Gradio interface
  2. Face detection extracts individual faces from image
  3. Face embeddings generated using ensemble models (FaceNet + ArcFace)
  4. Embeddings queried against Voyager vector indices
  5. Results ranked by confidence and returned with performer metadata

Key Dependencies

  • DeepFace: Face recognition and embedding extraction
  • Gradio: Web interface framework
  • Voyager: Vector similarity search indices
  • MediaPipe: Alternative face detection backend
  • PyZipper: Encrypted ZIP file handling for performer database
  • UV: Modern Python package manager

File Structure

stashface/
β”œβ”€β”€ app.py                  # Main application entry point
β”œβ”€β”€ data/                   # Face recognition data files
β”‚   β”œβ”€β”€ faces.json         # Face metadata
β”‚   β”œβ”€β”€ persons.zip        # Encrypted performer database
β”‚   └── *.voy              # Voyager vector indices
β”œβ”€β”€ models/                # Core ML models and data handling
β”‚   β”œβ”€β”€ data_manager.py    # Data loading and querying
β”‚   β”œβ”€β”€ face_recognition.py # Ensemble face recognition
β”‚   └── image_processor.py # Image processing pipeline
β”œβ”€β”€ web/                   # Web interface
β”‚   └── interface.py       # Gradio interface
β”œβ”€β”€ utils/                 # Utility functions
β”‚   └── vtt_parser.py      # VTT file parsing for video sprites
└── tests/                 # Test files

Development Notes

  • The application uses CPU-only inference (CUDA disabled via environment variable)
  • Face embeddings are averaged between original and horizontally flipped images for better accuracy
  • The performer database is encrypted and requires the VISAGE_KEY environment variable
  • Vector indices use E4M3 storage format for memory efficiency
  • The ensemble approach combines FaceNet512 and ArcFace models with equal weighting (1.0 each)