Refactor HVideoTool's configuration and project management: updated project handling in core/project.py, streamlined restoration settings in config.py, and improved documentation in CLAUDE.md. Removed unused parameters and enhanced type hints for better clarity.
This commit is contained in:
@@ -1,20 +1,22 @@
|
||||
"""DeepMosaics restorer — real generative mosaic removal, in-process.
|
||||
"""DeepMosaics restorers — real generative mosaic removal, in-process.
|
||||
|
||||
The DeepMosaics network code (GPL-3.0) is vendored under ``_deepmosaics/`` (see
|
||||
its NOTICE/LICENSE). We load the models **once** and run the per-frame clean path
|
||||
in-process — far faster than spawning a subprocess per frame (which reloaded the
|
||||
models every time). Only the model *weights* are user-supplied.
|
||||
The DeepMosaics network code (GPL-3.0) is vendored under ``_deepmosaics/`` (see its
|
||||
NOTICE/LICENSE). We load the models **once** and run in-process — far faster than
|
||||
spawning a subprocess per frame (which reloaded the models every time). Only the model
|
||||
*weights* are user-supplied. Both engines locate the mosaic themselves (BiSeNet
|
||||
``mosaic_position.pth``); detections are not passed to them.
|
||||
|
||||
Per-frame clean = DeepMosaics' ``cleanmosaic_img_server`` logic, reimplemented
|
||||
here (so we don't pull in their video/ffmpeg modules):
|
||||
locate mosaic (BiSeNet ``mosaic_position.pth``) → run the clean generator on the
|
||||
crop → feather it back. DeepMosaics finds the mosaic itself; our detections are
|
||||
used for navigation, not passed to it.
|
||||
Two engines:
|
||||
- :class:`DeepMosaicsRestorer` (per-frame): reproduces ``cleanmosaic_img_server`` —
|
||||
locate mosaic → run the image generator on the crop → feather it back. Image weights
|
||||
``clean_youknow_resnet_9blocks.pth``.
|
||||
- :class:`DeepMosaicsVideoRestorer` (temporal/BVDNet): reproduces
|
||||
``cleanmosaic_video_fusion`` — a window of neighbouring frames + recurrence, for
|
||||
temporal coherence. Video weights ``clean_youknow_video.pth``; needs a contiguous
|
||||
sequence (see :meth:`Restorer.restore_sequence`).
|
||||
|
||||
Setup (see README → Восстановление): download the **image** clean weights
|
||||
``clean_youknow_resnet_9blocks.pth`` + ``mosaic_position.pth`` into one folder and
|
||||
point the app at the clean-model file. The video model ``clean_youknow_video.pth``
|
||||
(BVDNet) needs neighbour frames and does NOT work per-frame.
|
||||
Setup (see README → Восстановление): drop the chosen ``clean_*.pth`` + ``mosaic_position.pth``
|
||||
into one folder (``models/deepmosaics``) and pick it in the restore dialog.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -31,8 +33,8 @@ from .base import (
|
||||
Cancelled,
|
||||
DetGetter,
|
||||
FrameGetter,
|
||||
ResultSink,
|
||||
Restorer,
|
||||
ResultSink,
|
||||
)
|
||||
|
||||
_VENDOR = Path(__file__).parent / "_deepmosaics"
|
||||
@@ -94,9 +96,8 @@ def _netg_kind(model_name: str) -> str:
|
||||
class DeepMosaicsRestorer(Restorer):
|
||||
def __init__(
|
||||
self,
|
||||
deepmosaics_dir: str | None, # kept for factory/config compatibility (weights hint)
|
||||
deepmosaics_dir: str | None, # optional extra dir to find mosaic_position.pth
|
||||
model_path: str | None,
|
||||
python_exe: str | None = None, # unused now (in-process)
|
||||
gpu_id: str = "0",
|
||||
) -> None:
|
||||
if not model_path or not Path(model_path).is_file():
|
||||
@@ -136,12 +137,13 @@ class DeepMosaicsRestorer(Restorer):
|
||||
# Fall back to CPU when CUDA isn't available: DeepMosaics calls `.cuda()`
|
||||
# whenever gpu_id != "-1", which raises "Torch not compiled with CUDA enabled"
|
||||
# on a CPU-only torch build.
|
||||
import torch # noqa: E402
|
||||
import torch
|
||||
if self._gpu != "-1" and not torch.cuda.is_available():
|
||||
self._gpu = "-1"
|
||||
|
||||
from models import loadmodel, runmodel # type: ignore # noqa: E402
|
||||
import util.image_processing as impro # type: ignore # noqa: E402
|
||||
import util.image_processing as impro # type: ignore
|
||||
|
||||
from models import loadmodel, runmodel # type: ignore
|
||||
|
||||
self._runmodel = runmodel
|
||||
self._impro = impro
|
||||
@@ -206,7 +208,6 @@ class DeepMosaicsVideoRestorer(Restorer):
|
||||
self,
|
||||
deepmosaics_dir: str | None,
|
||||
model_path: str | None,
|
||||
python_exe: str | None = None, # unused (in-process); kept for factory parity
|
||||
gpu_id: str = "0",
|
||||
) -> None:
|
||||
chosen: Path | None = None
|
||||
@@ -244,13 +245,14 @@ class DeepMosaicsVideoRestorer(Restorer):
|
||||
if str(_VENDOR) not in sys.path:
|
||||
sys.path.insert(0, str(_VENDOR))
|
||||
|
||||
import torch # noqa: E402
|
||||
import torch
|
||||
if self._gpu != "-1" and not torch.cuda.is_available():
|
||||
self._gpu = "-1" # CPU fallback (see DeepMosaicsRestorer for why)
|
||||
|
||||
from models import loadmodel, runmodel # type: ignore # noqa: E402
|
||||
import util.data as data # type: ignore # noqa: E402
|
||||
import util.image_processing as impro # type: ignore # noqa: E402
|
||||
import util.data as data # type: ignore
|
||||
import util.image_processing as impro # type: ignore
|
||||
|
||||
from models import loadmodel, runmodel # type: ignore
|
||||
|
||||
self._torch = torch
|
||||
self._runmodel = runmodel
|
||||
|
||||
Reference in New Issue
Block a user