diff --git a/CLAUDE.md b/CLAUDE.md index ccf65ba..b7f2afe 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -149,7 +149,9 @@ hvideotool/ paths and, if nothing is selected, default-ticks every discovered model. `build_detector` builds one `YoloDetector` per selected model (tagged `label=category`) wrapped in a `MultiYoloDetector` that concatenates their detections (no cross-model dedup). Each - `Detection` carries `label` (category); overlay colour + table group by `Detection.display` + `Detection` carries `label` (category) **and `model`** (the producing `.pt` stem, tagged in + `YoloDetector` — shown as its own "Модель" column in the detail table since a category folder + may hold several models); overlay colour + table group by `Detection.display` (label, else the CensorType) via `OverlayConfig.colors` + a stable `palette` fallback. - **Background jobs (`ui/workers.py`).** Detection and restoration are CPU-heavy and would freeze the GUI, so they run on a `QThreadPool` thread via `Job` (a `QRunnable` @@ -248,6 +250,12 @@ hvideotool/ `restore_sequence(count, get_frame, get_dets, emit, should_cancel)` (the batch run uses it; single-frame `restore` degrades to a window of the same frame). Needs the **video** weights `clean_youknow_video.pth` (+ `mosaic_position.pth` beside). `INPUT_SIZE=256`. + **`feed_restored`** (config `dm_feed_restored`, default on, checkbox in `RestoreDialog`): + when set, the **past** neighbours in the window (`ji`, not yet restored) stay original. Slightly out-of-distribution + for the BVDNet (trained on mosaic windows), so it's a toggle; off = faithful DeepMosaics. `restore_sequence` is on the `Restorer` ABC (default = independent per-frame loop); `_restore_all` dispatches on `restorer.temporal` (temporal → `restore_sequence` over the @@ -266,10 +274,15 @@ hvideotool/ `_step_hit` scans `_results` for the next non-empty frame). The slider and file list are kept in sync via `_update_nav` guarded by `_nav_sync` (avoids signal loops); all navigation ultimately drives `file_list.setCurrentRow`. The scrubber is a custom - `MarkerSlider` (`ui/marker_slider.py`) that paints cyan ticks at frames with - detections (`_refresh_marks` projects `_results` onto row indices; per-pixel deduped - so big folders stay cheap). File-list rows are tinted too (`_tag_file`): red = - censorship found, green = checked & clean. Both reset on `_invalidate_results`. + `MarkerSlider` (`ui/marker_slider.py`) that paints **two mark layers**: cyan ticks + (upper half) at frames with detections (`_refresh_marks` projects `_results`) and + **green ticks (lower half) at restored frames** (`_refresh_restored_marks` scans + `restored/` + in-memory `_restored`; called on load and after each restore op, not + per-frame); per-pixel deduped so big folders stay cheap. Under the scrubber a + **progress summary** `stats_label` reads "Кадров: N · детектировано: D/N (с цензурой: + H) · расцензурено: R/N" (`_update_counts_label`, cheap counts; `_restored_count` + cached by `_refresh_restored_marks`). File-list rows are tinted too (`_tag_file`): + red = censorship found, green = checked & clean. Both reset on `_invalidate_results`. - **Cancellation (cooperative).** A single "■ Стоп" toolbar action (Esc) cancels the running op. `_begin_busy(total)` / `_end_busy()` toggle `self._busy` + the Stop button + the progress bar (`total=None` → indeterminate). For **background jobs** (detection, diff --git a/hvideotool/config.py b/hvideotool/config.py index 223822d..72f3a12 100644 --- a/hvideotool/config.py +++ b/hvideotool/config.py @@ -62,3 +62,7 @@ class AppConfig: dm_dir: str | None = None # optional extra dir to search for mosaic_position.pth dm_model: str | None = None # DeepMosaics clean weights (clean_*.pth) dm_gpu: str = "0" # CUDA device id, "-1" for CPU + # Temporal engine only: feed already-restored PAST frames into the BVDNet window + # (instead of the original mosaic frames) for stronger temporal coherence. Slightly + # out-of-distribution for the net (trained on mosaic windows) — toggle in the dialog. + dm_feed_restored: bool = True diff --git a/hvideotool/core/detection/types.py b/hvideotool/core/detection/types.py index 4b3ca80..5b2adb6 100644 --- a/hvideotool/core/detection/types.py +++ b/hvideotool/core/detection/types.py @@ -24,6 +24,7 @@ class Detection: bbox: tuple[int, int, int, int] # x, y, w, h polygon: list[tuple[int, int]] = field(default_factory=list) # contour points label: str = "" # model category (models/yolo/