Files
HVideoTool/README.md
T

333 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HVideoTool
Десктопная утилита с графическим интерфейсом для **обнаружения уже наложенной
цензуры** (мозаика, пикселизация, размытие, чёрные плашки) на **картинках**.
Работа организована в **проекты**: создаёте проект (или раскадровываете ролик кнопкой
«Создать из ролика…») — приложение прогоняет каждый кадр через детектор, **обводит
найденные области** и показывает **подробный список** того, что нашлось на каждой
картинке. Отобранные кадры можно перемещать в **избранное** (для сбора датасета/
примеров).
### Проект
Проект — это папка со всем необходимым:
```
МойПроект/
├── project.json # настройки проекта (детектор, модель, порог, движок) + метаданные
├── frames/ # картинки проекта
├── detections.json # кэш детекций
└── collections/ # коллекции; «Избранное» — папка для отобранных кадров
```
Настройки (детектор / модель / порог / движок восстановления) хранятся **внутри
проекта** — каждый проект помнит, как его настраивали. Глобальные настройки
(`~/HVideoTool/settings.json`) задают лишь **значения по умолчанию для новых проектов**
и список недавних. При запуске без аргументов автоматически открывается последний
проект.
> Инструмент для просмотра, отладки детекции и отбора кадров. Видео раскадровывает
> через ffmpeg (ставится автоматически с пакетом `imageio-ffmpeg`; системный ffmpeg
> из PATH используется в приоритете), либо через OpenCV.
---
## Возможности
- **Проекты**: «Создать проект…», «Открыть проект…», «Импортировать папку как
проект…» (копирует картинки из обычной папки в `frames/` нового проекта) и подменю
**«Недавние проекты»**.
- **Создать из ролика…** — раскадровка видео в новый проект (кадры в `frames/`). Два
режима: **только ключевые кадры** (в разы быстрее — декодируются лишь I-кадры) и
**каждый N-й кадр**; опциональный даунскейл (меньше файлов и нагрузки на диск/АВ).
ffmpeg идёт в комплекте (`imageio-ffmpeg`); системный ffmpeg из PATH — в приоритете.
- **Избранное**: «★ В избранное» (Ctrl+M) перемещает выбранные кадры в папку
`collections/Избранное` внутри проекта — для отбора кадров (мультивыбор
поддерживается). Папка создаётся автоматически.
- Картинки проекта (`.jpg/.png/.bmp/.webp/.tif`) — список слева.
- Картинка с **обводкой контуром** найденных областей — по центру.
- **Подробная таблица детекций** справа: тип, уверенность, bbox, число точек
полигона. Выбор строки **подсвечивает** конкретную область на картинке.
- **Ленивая детекция**: картинка прогоняется по двойному клику / кнопке «Рассчитать
кадр», результат кэшируется.
- **Кэш детекций сохраняется в проект** (см. [ниже](#кэш-детекций)) — при повторном
открытии проекта результаты подхватываются, не нужно считать заново.
- **Три режима пересчёта**:
- **«Детектировать все»** — *дозапуск*: считает только ещё не посчитанные кадры
(можно прерывать и продолжать);
- **«Все заново»** — полная регенерация: очищает кэш и пересчитывает весь проект;
- **«Рассчитать кадр»** (Space / двойной клик) — всегда пересчитывает текущий кадр.
- **Кнопка «■ Стоп» (Esc)** отменяет любую текущую длинную операцию (детекция всего
проекта, раскадровка ролика, импорт папки, восстановление DeepMosaics). Уже
посчитанное при отмене сохраняется в кэш.
- **Навигация под картинкой**: ◀ ▶ (`,`/`.`), ползунок-перемотка и переходы к
кадрам с детекцией ◀/▶ (`[`/`]`). На ползунке **бирюзовыми метками** отмечены кадры
с найденной цензурой; строки списка **подсвечиваются цветом** (🔴 цензура найдена,
🟢 проверено и чисто).
- Детекция — через **YOLO**, **несколько моделей сразу** (как ADetailer): сложите веса
в `models/yolo/<категория>/` (например `models/yolo/mosaic/`, `models/yolo/face/`) и
отметьте нужные галочками в меню **«Модели»** тулбара. При расчёте кадра прогоняются
все выбранные модели, их детекции попадают в общую таблицу и рисуются оверлеем —
**цвет по категории-папке**. Порог уверенности — в тулбаре.
- **Индикатор устройства** в строке состояния: «⚡ CUDA» или «🖥 CPU». Клик по «CPU»
показывает диагностику (почему GPU не задействован) и команды установки PyTorch с
CUDA. Если CUDA недоступна, YOLO и DeepMosaics автоматически работают на CPU
(медленнее, но без ошибок).
## Кэш детекций
Результаты детекции сохраняются в корне проекта в файл `detections.json`. Это даёт:
- **возобновление между сессиями** — открыли проект повторно, готовые детекции сразу
на месте (метки на ползунке и подсветка строк восстанавливаются);
- **дозапуск** — «Детектировать все» пропускает уже посчитанные кадры;
- **отказоустойчивость** — при отмене/закрытии посчитанное не теряется.
Кэш помечен «удостоверением» — **набором выбранных моделей** + `conf`/`imgsz`. Если
открыть проект с **другим набором моделей**, чужой кэш не загружается (чтобы не выдавать
старые результаты за текущие). Полностью пересчитать — кнопка **«Все заново»**.
> Ключи внутри файла — **имена файлов**, поэтому кэш переживает перемещение/
> переименование проекта. Хранится результат **одного** детектора за раз: посчитали
> одним, переключились на другой и посчитали — кэш перезапишется.
## Восстановление (расцензуривание)
Кнопка **«Расцензурить кадр»** восстанавливает найденные области на текущем кадре,
**«Показать оригинал/результат»** переключает вид, **«Сохранить результат»** пишет
`<имя>_restored.jpg` рядом с кадром. Движок выбирается в
меню **Файл → Движок восстановления…**.
**Пакетный прогон по диапазону.** Кнопки **«Расцензурить все»** (дозапуск — пропускает
уже сделанные) и **«Все заново»** обрабатывают **все кадры проекта** в фоне и пишут
результаты в папку **`restored/`** проекта (имена кадров сохраняются; папка держится
отдельно от `frames/`, чтобы результаты не попадали обратно в список кадров). Прогресс,
отмена (**«■ Стоп»**) и предпросмотр текущего кадра работают как при детекции.
Доступны два **семейства** движков: **DeepMosaics** (восстанавливает мозаику) и
**diffusion-inpaint (SwarmUI)** (перерисовывает область заново). DeepMosaics — по
умолчанию; код **встроен** (vendored, GPL-3.0; ставить отдельно не нужно — нужны только
**веса** и желательно **GPU NVIDIA/CUDA**). Три движка в списке:
- **DeepMosaics — картинка** — реальное генеративное удаление мозаики **покадрово**.
- **DeepMosaics — видео (BVDNet)** — **временно́й** движок: использует **соседние кадры**
(окно ±2 кадра с шагом 3) и собственный предыдущий результат для когерентности на
роликах. Из-за рекуррентности обрабатывает **непрерывный диапазон по порядку** — т.е.
запускайте его через **«Расцензурить все»** (одиночный «Расцензурить кадр» сведётся к
окну из одного кадра). Нужна **видеомодель** `clean_youknow_video.pth`.
- **Diffusion-inpaint (SwarmUI)** — **перерисовывает** область цензуры заново диффузионной
inpaint-моделью по **маске из YOLO-детекций** и промпту (не восстанавливает оригинал!).
Лучше всего для **чёрных плашек / сплошной заливки**, где DeepMosaics бессилен. Покадрово
→ на роликах будет **мерцание**. См. «Настройка SwarmUI» ниже.
На аниме качество DeepMosaics ограничено (модели обучены на реальном видео).
### Настройка DeepMosaics
Нужны только **веса** — положите их в **`models/deepmosaics/`** (папка в `.gitignore`,
веса большие, ~92 МБ). Скачать: официальная папка
([Google Drive](https://drive.google.com/drive/folders/1LTERcN33McoiztYEwBxMuRjjgxh4DEPs),
Baidu код `1x0a`):
- **`clean_youknow_resnet_9blocks.pth`** — картиночная clean-модель (движок «картинка»);
- **`clean_youknow_video.pth`** — видеомодель BVDNet (движок «видео», соседние кадры);
- **`mosaic_position.pth`** — локатор мозаики (должен лежать рядом, нужен обоим).
Затем в приложении: **Файл → Движок восстановления…**, выберите движок (**DeepMosaics —
картинка** или **видео**) и **модель из выпадающего списка** (наполняется из
`models/deepmosaics` — для видеодвижка показываются только `clean_*_video.pth`; есть
«Обзор…» для файла в другом месте) и GPU id (`-1` = CPU). Если веса в `models/deepmosaics`
— работает сразу; модель грузится один раз, дальше кадры считаются быстро.
> **Какую модель брать:** для покадрового движка — **картиночную**
> `clean_youknow_resnet_9blocks.pth`; для временно́го — **видео** `clean_youknow_video.pth`
> (она запускается только пакетно, «Расцензурить все», т.к. ей нужны соседние кадры). Если
> на кадре нет мозаики, результат = исходный кадр.
>
> Код DeepMosaics (GPL-3.0) лежит в `core/restore/_deepmosaics/` и поэтому **весь
> проект распространяется под GPL-3.0**. Запускается на современных `torch 2.x`/
> `numpy 2.x` (проверено). [LADA](https://github.com/ladaapp/lada) (видеомодель,
> лучшее качество на реальном видео) пока не подключён.
### Настройка Diffusion-inpaint (SwarmUI)
Этот движок перерисовывает область **по маске из детекций YOLO**, поэтому **сначала
посчитайте детекцию** («Детектировать все» или «Рассчитать кадр»), а затем запускайте
расцензуривание — кадры без детекций остаются без изменений. Диффузионная модель крутится
в **отдельном сервере SwarmUI**, приложение лишь шлёт ему по HTTP картинку + маску + промпт
(никаких `torch`/`diffusers` в самом приложении на этом пути).
1. Установите и запустите [SwarmUI](https://github.com/mcmonkeyprojects/SwarmUI), загрузите
в нём inpaint-чекпойнт (SD/SDXL). По умолчанию сервер слушает `http://localhost:7801`.
2. В приложении: **Файл → Движок восстановления…** → выберите **Diffusion-inpaint
(SwarmUI)** и задайте:
- **SwarmUI URL** (по умолчанию `http://localhost:7801`);
- **Чекпойнт** — имя модели как её знает SwarmUI (пусто = текущая в сервере);
- **Промпт / Negative** — что нарисовать в области под цензурой / чего избегать;
- **Шаги / CFG / Denoise / Seed** — параметры генерации (`Denoise` 0..1, 1 = полностью
перерисовать; `Seed` `-1` = случайный);
- **Маска: расширить / размытие** (px) — расширение и мягкость края маски.
- Кнопка **«Проверить соединение»** дёргает SwarmUI и сразу показывает ✓ (сервер
отвечает) или ✗ с текстом ошибки — удобно убедиться в адресе до расцензуривания.
3. Запустите **«Расцензурить кадр»** или **«Расцензурить все»** — движок прогонит только
кадры с детекциями.
> Diffusion **выдумывает** правдоподобное содержимое, а не восстанавливает оригинал. Это
> сознательно второй движок (не замена DeepMosaics) под случаи, где под цензурой не
> осталось данных (чёрные плашки). Бэкенд абстрактный — позже можно добавить ComfyUI/A1111
> как ещё одну реализацию `DiffusionBackend`.
## Что НЕ делает (осознанно вне области задачи)
- Не **генерирует** изображения через диффузию (никакого ControlNet/SDXL).
- Не детектирует «контент, который следовало бы зацензурить» (NSFW) — ищем
именно **уже наложенную** цензуру.
- Полноценное генеративное восстановление пока не подключено (см. выше).
---
## Требования
- **ОС:** Windows 11 x64 (основная целевая платформа).
- **Python:** 3.11+.
- **GPU (опционально):** NVIDIA + CUDA для YOLO-детектора и DeepMosaics. CPU-режим
работает, но медленный (особенно DeepMosaics / временно́й BVDNet).
## Установка
```powershell
git clone https://github.com/mrleo1nid/HVideoTool.git
cd HVideoTool
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[yolo]"
```
Детекция (YOLO) и расцензуривание (DeepMosaics) требуют **PyTorch** — установите его
отдельно под вашу CUDA (см. [Модель детектора](#модель-детектора)).
## Запуск
```powershell
# Без аргументов — открывается последний проект (или создайте/откройте новый в тулбаре)
python -m hvideotool
# Необязательно: сразу открыть проект и указать модель YOLO
python -m hvideotool "C:\path\to\МойПроект" --model models\lada_mosaic_detection_model_v4_accurate.pt
```
Путь к модели и порог сохраняются в `~/HVideoTool/settings.json` и применяются при
следующем запуске.
---
## Модели детекции (мульти-YOLO)
Детекция — **только YOLO**, но можно держать и включать **несколько моделей сразу**
(как ADetailer). Структура папок:
```
models/yolo/
├── mosaic/ # модель(и) детекции мозаики (LADA) — категория "mosaic", красный цвет
├── face/ # напр. yolov8-face — категория "face", зелёный цвет
└── <своё>/ # любая категория = имя папки = ярлык + цвет
```
Каждая модель — **сегментационная** YOLO ([Ultralytics](https://github.com/ultralytics/ultralytics),
`core/detection/yolo.py`), маски превращаются в контуры. Включайте модели галочками в
меню **«Модели»** тулбара (там же «Добавить модель…» — скопирует `.pt` в нужную
категорию). При расчёте кадра прогоняются **все включённые** модели, детекции
объединяются (`core/detection/multi.py`), **цвет и ярлык — по категории-папке**.
Рекомендуемые веса для мозаики — [**LADA mosaic detection**](https://huggingface.co/ladaapp/lada).
(Старый эвристический classic-CV детектор и комбинированный режим удалены — давали
много ложных срабатываний.)
> **⚠️ Берите правильную модель для мозаики.** В `models/yolo/mosaic/` нужна модель
> **детекции цензуры** (LADA `lada_mosaic_detection_model_v4_accurate.pt`). Обычная
> COCO-модель (`yolo11n-seg.pt`) детектит людей/предметы — это «шум».
> **Домен важен.** Модель LADA обучена на **реальном видео** (JAV); на части
> рисованного/аниме контента работает, на части — плохо. Хорошего публичного
> YOLO-детектора цензуры для аниме нет — это потребовало бы обучения своей модели.
**Своя модель мозаики для аниме.** Можно обучить **YOLO11-seg** на синтетике
(накладываем мозаику на чистые кадры → авторазметка) и подключить `.pt` в наш
`YoloDetector` **без изменений кода**. Инструменты — в
[`scripts/training/`](scripts/training/README.md):
```powershell
python scripts\training\gen_mosaic_dataset.py --input C:\clean_frames --output dataset_mosaic
python scripts\training\train_mosaic.py --data dataset_mosaic\data.yaml --epochs 100
# затем скопируйте runs\segment\mosaic\weights\best.pt в models\yolo\mosaic\ и включите галочкой
```
Установка YOLO-детектора:
```powershell
pip install -e ".[yolo]"
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121
New-Item -ItemType Directory -Force models\yolo\mosaic | Out-Null
curl.exe -L -o models\yolo\mosaic\lada_mosaic_detection_model_v4_accurate.pt `
"https://huggingface.co/ladaapp/lada/resolve/main/lada_mosaic_detection_model_v4_accurate.pt?download=true"
python -m hvideotool # модель из models\yolo\mosaic подхватится и включится автоматически
```
> **⚠️ Лицензия.** Ultralytics YOLO и веса LADA — **AGPL-3.0**; код DeepMosaics —
> **GPL-3.0**. Поэтому весь проект распространяется под **GPL-3.0**.
---
## Архитектура (кратко)
```
hvideotool/
├── __main__.py # точка входа + CLI (всё опционально)
├── app.py # инициализация QApplication
├── config.py # настройки: порог/оверлей, detector_models (мульти-YOLO), движок восстановления
├── settings_store.py # дефолты новых проектов + последний/недавние → settings.json
├── ui/
│ ├── main_window.py # окно: список файлов | картинка | таблица детекций
│ ├── image_view.py # отрисовка картинки + оверлей-контуры (QPainter)
│ └── marker_slider.py # ползунок-перемотка с метками кадров с детекцией
└── core/
├── imageio.py # unicode-safe чтение/запись картинок (Windows-пути)
├── project.py # Project: раскладка (project.json/frames/detections.json/collections) + настройки
├── video/frame.py # Frame (картинка BGR + индекс) — вход детектора
├── detection/ # только YOLO, мульти-модель
│ ├── base.py # Detector (ABC): detect(frame) -> list[Detection]
│ ├── factory.py # build_detector -> MultiYoloDetector по выбранным моделям
│ ├── registry.py # поиск моделей в models/yolo/<категория>/*.pt
│ ├── multi.py # MultiYoloDetector: прогон нескольких моделей + объединение
│ ├── types.py # Detection (+ label/категория, .display), CensorType
│ ├── cache.py # кэш детекций (ключ = набор моделей + conf/imgsz)
│ └── yolo.py # YOLO-детектор (Ultralytics, маски→полигоны, ярлык категории)
└── restore/ # DeepMosaics (восстановление) или diffusion-inpaint (перерисовка)
├── base.py # Restorer (ABC): restore() + restore_sequence() + .temporal/.needs_detections
├── factory.py # build_restorer -> deepmosaics | deepmosaics_video | diffusion
├── deepmosaics.py # движки «картинка» (покадрово) и «видео» (BVDNet)
├── _deepmosaics/ # встроенный код DeepMosaics (GPL-3.0)
├── mask.py # маска из детекций (для diffusion inpaint)
├── diffusion.py # DiffusionRestorer + DiffusionBackend (ABC) + InpaintParams
└── swarmui.py # бэкенд SwarmUI (HTTP, stdlib urllib — без torch)
```
Детекция синхронная (по клику/по кнопке «Детектировать все»); тяжёлый YOLO на CPU
заметно медленнее, чем на CUDA. Длинные операции можно прервать кнопкой «■ Стоп»
(Esc), а результаты кэшируются на диск — см. [Кэш детекций](#кэш-детекций).
## Технологический стек
| Компонент | Выбор |
|----------------------|--------------------------------------------------|
| Язык | Python ≥ 3.11 |
| GUI | PySide6 (Qt 6) |
| Обработка картинок | OpenCV / NumPy |
| Детектор | Ultralytics YOLO, мульти-модель (models/yolo/<кат>) |
| Расцензуривание | DeepMosaics (встроен) + PyTorch/CUDA, или diffusion-inpaint через SwarmUI (HTTP) |
## Лицензия
**GPL-3.0** — из-за встроенного кода DeepMosaics (GPL-3.0); веса/код YOLO LADA — AGPL-3.0.