From 41b6d06ca38c705522b7fa87f1200cb80294166e Mon Sep 17 00:00:00 2001 From: asreva Date: Fri, 8 May 2026 08:48:43 +0200 Subject: [PATCH] Gifs are now optionally save (--extras) --- .claude/settings.local.json | 8 +++++++ .../annotation_script.py | 24 ++++++++++--------- 2 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 .claude/settings.local.json diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..e52b9a5 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,8 @@ +{ + "permissions": { + "allow": [ + "Bash(Get-ChildItem -Recurse -Depth 2)", + "Bash(Select-Object FullName)" + ] + } +} diff --git a/src/river_annotation_tool/annotation_script.py b/src/river_annotation_tool/annotation_script.py index 3f9c6b1..c8200e0 100644 --- a/src/river_annotation_tool/annotation_script.py +++ b/src/river_annotation_tool/annotation_script.py @@ -128,13 +128,14 @@ def load_frames(zip_path: Path, max_frames: int): # MAIN APP # ───────────────────────────────────────────── class Annotator(QMainWindow): - def __init__(self, data_dir: Path, out_dir: Path, clip: str = None, target_time: str = None, daily: bool = False): + def __init__(self, data_dir: Path, out_dir: Path, clip: str = None, target_time: str = None, daily: bool = False, extras: bool = False): super().__init__() self.data_dir = Path(data_dir) self.out_dir = Path(out_dir) self.target_time = target_time self.daily = daily + self.extras = extras self.current_date = None self.history = [] @@ -531,20 +532,20 @@ class Annotator(QMainWindow): with open(out / "metadata.json", "w") as f: json.dump(self.get_answers(), f, indent=2) - # images mid = len(self.frames) // 2 frame = self.frames[mid] overlay_frame = self._make_overlay(frame) Image.fromarray(frame).save(out / "frame.png") - Image.fromarray((self.mask * 255).astype(np.uint8)).save(out / "mask_vis.png") Image.fromarray(overlay_frame).save(out / "overlay.png") - # GIFs — original and overlay, high-res (display size) and low-res (half) - overlay_frames = [self._make_overlay(f) for f in self.frames] - self._save_gif(self.frames, out / "video_original_hires.gif", scale=1.0) - self._save_gif(self.frames, out / "video_original_lowres.gif", scale=0.5) - self._save_gif(overlay_frames, out / "video_overlay_hires.gif", scale=1.0) - self._save_gif(overlay_frames, out / "video_overlay_lowres.gif", scale=0.5) + if self.extras: + Image.fromarray((self.mask * 255).astype(np.uint8)).save(out / "mask_vis.png") + + overlay_frames = [self._make_overlay(f) for f in self.frames] + self._save_gif(self.frames, out / "video_original_hires.gif", scale=1.0) + self._save_gif(self.frames, out / "video_original_lowres.gif", scale=0.5) + self._save_gif(overlay_frames, out / "video_overlay_hires.gif", scale=1.0) + self._save_gif(overlay_frames, out / "video_overlay_lowres.gif", scale=0.5) print("Saved:", out) @@ -579,11 +580,12 @@ class Annotator(QMainWindow): # ───────────────────────────────────────────── def parse_args(): parser = argparse.ArgumentParser() - parser.add_argument("--data", default="C:\\Users\\BONVALOT\\Documents\\Hydroscan\\data\\filtered_s3\\all_filtered_data") + parser.add_argument("--data", default=r"C:\Users\sieverin\HydroScan\Code\river-annotation-tool\data\filtered_data") parser.add_argument("--out", default="data/annotation_results/") parser.add_argument("--clip", default=None, help="Stem name of a specific clip to load (e.g. 'left_20230501')") parser.add_argument("--time", default=None, help="Target time to filter clips by day (format: HH:MM, e.g. '14:30'). Selects the closest clip to this time for each day.") parser.add_argument("--daily", action="store_true", help="Load only 1 clip per day at the specified time (requires --time).") + parser.add_argument("--extras", action="store_true", help="Also save GIFs, frame PNG, overlay PNG, and mask_vis PNG alongside the mask.") return parser.parse_args() @@ -592,7 +594,7 @@ if __name__ == "__main__": app = QApplication([]) - win = Annotator(Path(args.data), Path(args.out), clip=args.clip, target_time=args.time, daily=args.daily) + win = Annotator(Path(args.data), Path(args.out), clip=args.clip, target_time=args.time, daily=args.daily, extras=args.extras) win.show() app.exec()