Fork facesaver -> anime-facesaver: real anime face detector instead of COCO 'person' proxy
Original saved any frame with a big COCO person box (heads, hands, shoes). Switches to yolov8x6_animeface (HF: Fuyucchi), keeps the scene-change gate, adds --gpu pinning via CUDA_VISIBLE_DEVICES before torch init, --download-model, --preview-dir QC mode, optional edge margin and min face-area fraction.
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# anime-facesaver
|
||||
|
||||
Scene-gated still extractor for building anime training datasets from
|
||||
video. Fork of `facesaver`, created Oct 2026.
|
||||
|
||||
## Why this fork exists
|
||||
|
||||
The original facesaver ran stock COCO `yolov11l.pt` and accepted
|
||||
class 0 — **`person`** — as a "proxy for face" (their comment, not ours).
|
||||
COCO has no face class, so every frame containing a large enough person
|
||||
passed: full-body shots, headless crops, a hand at 75% confidence. That
|
||||
is why the old Gabriel Dropout output contained stills of shoes.
|
||||
|
||||
anime-facesaver uses a dedicated anime-face detector instead:
|
||||
[`yolov8x6_animeface`](https://huggingface.co/Fuyucchi/yolov8_animeface)
|
||||
— yolov8x6 fine-tuned at 1280px on 10k manually annotated anime images
|
||||
(P=0.957 R=0.924 mAP50=0.955 on its test set). It detects faces. Only
|
||||
faces. The scene-change gate from the original is preserved: at most one
|
||||
still is saved per detected scene, which keeps near-duplicates out of
|
||||
the dataset.
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
uv venv --python 3.12 .venv # or: python3.12 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt # add --index-url for your CUDA ver
|
||||
python anime_facesaver.py --download-model ... # fetches weights once
|
||||
```
|
||||
|
||||
Weights land in `models/yolov8x6_animeface.pt` (~195 MB, AGPL-3.0).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
python anime_facesaver.py \
|
||||
-I /home/alex/Documents/image-training-datasets/gabriel-dropout-show \
|
||||
-O /home/alex/Documents/image-training-datasets/gabriel-dropout-v2 \
|
||||
--gpu 1 \
|
||||
--preview-dir /home/alex/Documents/image-training-datasets/gabriel-dropout-v2-preview
|
||||
```
|
||||
|
||||
### GPU pinning (important on the shared .80 box)
|
||||
|
||||
`--gpu` sets `CUDA_VISIBLE_DEVICES` **before** torch initializes, so no
|
||||
context leaks onto the wrong card:
|
||||
|
||||
| flag | effect |
|
||||
|-----------|-----------------------------------------------|
|
||||
| `--gpu 1` | pin to physical GPU 1 (recommended on .80) |
|
||||
| `--gpu 0` | pin to GPU 0 — OOMs while Strata holds it |
|
||||
| `--gpu cpu` | force CPU |
|
||||
| `--gpu auto` | let torch pick |
|
||||
|
||||
### Key options
|
||||
|
||||
| flag | default | meaning |
|
||||
|------|---------|---------|
|
||||
| `--conf` | 0.3 | detector confidence (model's own recommendation; it is high-precision) |
|
||||
| `--min-width` / `--min-height` | 100 | minimum face box size in px |
|
||||
| `--min-face-fraction` | 0.005 | face box area as fraction of frame — kills distant background extras; `0` disables |
|
||||
| `--edge-margin` | 0 | require faces this far inside frame edges; `0` accepts edge-touching faces (original hard-rejected them) |
|
||||
| `--scene-threshold` | 30.0 | PySceneDetect ContentDetector threshold (same as original) |
|
||||
| `--imgsz` | 1280 | inference size; model was trained at 1280, `640` is faster at some recall cost |
|
||||
| `--preview-dir` | off | also write annotated copies (green boxes) of every saved frame for eyeball QC |
|
||||
|
||||
## Notes
|
||||
|
||||
- Runs every frame of every scene until a face qualifies, then waits
|
||||
for the next scene start. That is the original behavior and it is why
|
||||
dense scenes don't flood the output.
|
||||
- The detector ships as `yolov8x6` — big and a little slow (it was
|
||||
trained to be precise, not cheap). On a 3090 at 1280px expect roughly
|
||||
8-12 fps; an hour of 24fps anime is ~15 min of inference per GPU.
|
||||
- **License**: the model weights are AGPL-3.0 (Fuyucchi); ultralytics is
|
||||
AGPL-3.0 too. Fine for personal/research dataset building; if this
|
||||
ever ships in a product, revisit.
|
||||
|
||||
## Verification
|
||||
|
||||
Run `--preview-dir` and eyeball the `_ann.png` files: every saved frame
|
||||
should show a green box on a real face. Compare against the original
|
||||
facesaver output to quantify how many old saves had no face at all.
|
||||
Reference in New Issue
Block a user