From 5c506faef25e3a0d90635463602b938a6f20811b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Bo=C5=99il?= <519192@mail.muni.cz> Date: Wed, 25 Mar 2026 13:51:13 +0000 Subject: [PATCH 1/3] chore: JSONMultiClassMask --- ratiopath/parsers/json_multi_class_mask.py | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 ratiopath/parsers/json_multi_class_mask.py diff --git a/ratiopath/parsers/json_multi_class_mask.py b/ratiopath/parsers/json_multi_class_mask.py new file mode 100644 index 0000000..9eb07ff --- /dev/null +++ b/ratiopath/parsers/json_multi_class_mask.py @@ -0,0 +1,45 @@ +import json +from pathlib import Path + +import numpy as np +from PIL import Image, ImageDraw + + +class JSONMultiClassMask: + """Parses JSON annotations and renders them into a multi-class mask array. + + Expects class to value mapping on input. + """ + + def __init__( + self, + json_path: Path, + mask_size: tuple[int, int], + scale_factor: float, + target_groups: dict[str, int], + ): + self.json_path = json_path + self.mask_size = mask_size # (width, height) + self.scale = scale_factor + self.target_groups = target_groups + + def __call__(self) -> np.ndarray: + mask_img = Image.new("L", self.mask_size, 0) + draw = ImageDraw.Draw(mask_img) + + with open(self.json_path) as f: + data = json.load(f) + + for item in data.get("items", []): + class_name = item.get("name") + + if class_name in self.target_groups: + coords = item.get("coordinates", []) + if not coords: + continue + + fill_value = self.target_groups[class_name] + scaled_coords = [(c[0] * self.scale, c[1] * self.scale) for c in coords] + draw.polygon(scaled_coords, fill=fill_value) + + return np.array(mask_img) From b1b0ef28ffc3b8c16b68cdd6eb52778adaa67e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Bo=C5=99il?= <519192@mail.muni.cz> Date: Wed, 25 Mar 2026 13:53:33 +0000 Subject: [PATCH 2/3] fix: fix init --- ratiopath/parsers/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ratiopath/parsers/__init__.py b/ratiopath/parsers/__init__.py index 9aa5761..99ff7e0 100644 --- a/ratiopath/parsers/__init__.py +++ b/ratiopath/parsers/__init__.py @@ -1,6 +1,7 @@ from ratiopath.parsers.asap_parser import ASAPParser from ratiopath.parsers.darwin7_json_parser import Darwin7JSONParser from ratiopath.parsers.geojson_parser import GeoJSONParser +from ratiopath.parsers.json_multi_class_mask import JSONMultiClassMask -__all__ = ["ASAPParser", "Darwin7JSONParser", "GeoJSONParser"] +__all__ = ["ASAPParser", "Darwin7JSONParser", "GeoJSONParser", "JSONMultiClassMask"] From f888896027f1e7609d55dc7f553801b3f31f1889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Bo=C5=99il?= <519192@mail.muni.cz> Date: Wed, 25 Mar 2026 13:55:23 +0000 Subject: [PATCH 3/3] fix: mypy --- ratiopath/parsers/json_multi_class_mask.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ratiopath/parsers/json_multi_class_mask.py b/ratiopath/parsers/json_multi_class_mask.py index 9eb07ff..86dc484 100644 --- a/ratiopath/parsers/json_multi_class_mask.py +++ b/ratiopath/parsers/json_multi_class_mask.py @@ -7,7 +7,7 @@ class JSONMultiClassMask: """Parses JSON annotations and renders them into a multi-class mask array. - + Expects class to value mapping on input. """