Replace hardcoded config and directory scan with YAML config and explicit clip list
- config.py constants -> config/config.yaml (user-editable, git-ignored) - Questions and defaults now defined in the YAML, including per-question defaults - ClipSelector no longer scans the data dir; reads a user-provided clips.txt instead - Removed --daily / --time / --skip-existing-day args - video_loader now samples frames evenly across the full clip - pyyaml added as a dependency Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@ from PySide6.QtWidgets import (
|
||||
)
|
||||
|
||||
from .clip_selector import ClipSelector
|
||||
from .config import DEFAULTS, QUESTIONS, Config
|
||||
from .config import AppConfig
|
||||
from .mask_canvas import MaskCanvas
|
||||
from .video_loader import load_frames
|
||||
|
||||
@@ -26,25 +26,20 @@ from .video_loader import load_frames
|
||||
class Annotator(QMainWindow):
|
||||
def __init__(
|
||||
self,
|
||||
data_dir: Path,
|
||||
out_dir: Path,
|
||||
config: AppConfig,
|
||||
clip: str = None,
|
||||
target_time: str = None,
|
||||
daily: bool = False,
|
||||
extras: bool = False,
|
||||
skip_existing_day: bool = False,
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.out_dir = Path(out_dir)
|
||||
self.cfg = config
|
||||
self.out_dir = Path(config.out_dir)
|
||||
self.extras = extras
|
||||
|
||||
self.selector = ClipSelector(
|
||||
data_dir=Path(data_dir),
|
||||
data_dir=Path(config.data_dir),
|
||||
out_dir=self.out_dir,
|
||||
target_time=target_time,
|
||||
daily=daily,
|
||||
skip_existing_day=skip_existing_day,
|
||||
clips_file=Path(config.clips_file),
|
||||
)
|
||||
|
||||
self.setWindowTitle("River Annotator")
|
||||
@@ -53,10 +48,13 @@ class Annotator(QMainWindow):
|
||||
self._init_timer()
|
||||
|
||||
# ── clip loading ───────────────────────────────────────────────
|
||||
def _load_clip(self, specific: str = None, next_day: bool = False):
|
||||
self.filename = self.selector.next(specific=specific, next_day=next_day)
|
||||
def _load_clip(self, specific: str = None):
|
||||
self.filename = self.selector.next(specific=specific)
|
||||
self.frames, self.fps, self.dh, self.dw, self.h, self.w = load_frames(
|
||||
self.filename, Config.MAX_FRAMES
|
||||
self.filename,
|
||||
self.cfg.max_frames,
|
||||
self.cfg.display_max,
|
||||
self.cfg.fps_fallback,
|
||||
)
|
||||
self._pending_answers = self._read_saved_answers()
|
||||
|
||||
@@ -135,23 +133,22 @@ class Annotator(QMainWindow):
|
||||
|
||||
def _build_question_panel(self) -> QVBoxLayout:
|
||||
vbox = QVBoxLayout()
|
||||
for section, qs in QUESTIONS:
|
||||
for section, qs in self.cfg.get_questions():
|
||||
group = QGroupBox(section)
|
||||
gvbox = QVBoxLayout()
|
||||
for key, label, options in qs:
|
||||
for key, label, options, default in qs:
|
||||
gvbox.addWidget(QLabel(label))
|
||||
btn_group = QButtonGroup(self)
|
||||
row = QHBoxLayout()
|
||||
buttons = []
|
||||
default_value = DEFAULTS.get(key)
|
||||
for opt in options:
|
||||
btn = QRadioButton(opt)
|
||||
btn_group.addButton(btn)
|
||||
row.addWidget(btn)
|
||||
buttons.append(btn)
|
||||
if default_value == opt:
|
||||
if default == opt:
|
||||
btn.setChecked(True)
|
||||
if default_value is None and buttons:
|
||||
if default is None and buttons:
|
||||
buttons[-1].setChecked(True)
|
||||
self.q_widgets[key] = (btn_group, buttons, options)
|
||||
gvbox.addLayout(row)
|
||||
@@ -246,8 +243,8 @@ class Annotator(QMainWindow):
|
||||
if answers:
|
||||
self._set_answers(answers)
|
||||
|
||||
def _advance_clip(self, next_day: bool):
|
||||
self._load_clip(next_day=next_day)
|
||||
def _advance_clip(self):
|
||||
self._load_clip()
|
||||
self.frame_i = 0
|
||||
self.mc.load_clip(
|
||||
self.frames,
|
||||
@@ -262,7 +259,7 @@ class Annotator(QMainWindow):
|
||||
|
||||
def next_clip(self):
|
||||
self.save()
|
||||
self._advance_clip(next_day=self.selector.daily)
|
||||
self._advance_clip()
|
||||
|
||||
def skip_clip(self):
|
||||
self._advance_clip(next_day=self.selector.daily)
|
||||
self._advance_clip()
|
||||
|
||||
Reference in New Issue
Block a user