diff --git a/common/polystar/common/models/image.py b/common/polystar/common/models/image.py
index 61af256e9c096f11347a3d419421ea7f20626b5e..fcc4faafdfded5bf1558b237dab685132bff813f 100644
--- a/common/polystar/common/models/image.py
+++ b/common/polystar/common/models/image.py
@@ -4,19 +4,20 @@ from typing import Iterable
 import cv2
 from nptyping import Array
 
+Image = Array[int, ..., ..., 3]
 
-class Image(Array[int, ..., ..., 3]):
-    @staticmethod
-    def from_path(image_path: Path, conversion: int = cv2.COLOR_BGR2RGB) -> "Image":
-        return cv2.cvtColor(cv2.imread(str(image_path), cv2.IMREAD_UNCHANGED), conversion)
 
-    def save(self, image_path: Path, conversion: int = cv2.COLOR_RGB2BGR):
-        image_path.parent.mkdir(exist_ok=True, parents=True)
-        cv2.imwrite(str(image_path), cv2.cvtColor(self, conversion))
+def load_image(image_path: Path, conversion: int = cv2.COLOR_BGR2RGB) -> Image:
+    return cv2.cvtColor(cv2.imread(str(image_path), cv2.IMREAD_UNCHANGED), conversion)
+
+
+def save_image(image: Image, image_path: Path, conversion: int = cv2.COLOR_RGB2BGR):
+    image_path.parent.mkdir(exist_ok=True, parents=True)
+    cv2.imwrite(str(image_path), cv2.cvtColor(image, conversion))
 
 
 def load_images_in_directory(
     directory: Path, pattern: str = "*", conversion: int = cv2.COLOR_BGR2RGB
 ) -> Iterable[Image]:
     for image_path in directory.glob(pattern):
-        yield Image.from_path(image_path, conversion)
+        yield load_image(image_path, conversion)
diff --git a/common/polystar/common/models/image_annotation.py b/common/polystar/common/models/image_annotation.py
index b34e4116626ba1be75bb26c7e3ac62045b50d087..36707b94e2e83f7eb923044cab184229072cabdb 100644
--- a/common/polystar/common/models/image_annotation.py
+++ b/common/polystar/common/models/image_annotation.py
@@ -6,7 +6,7 @@ from xml.dom.minidom import parseString
 
 import xmltodict
 from dicttoxml import dicttoxml
-from polystar.common.models.image import Image
+from polystar.common.models.image import Image, load_image, save_image
 from polystar.common.models.object import Object, ObjectFactory
 
 
@@ -28,7 +28,7 @@ class ImageAnnotation:
     @property
     def image(self) -> Image:
         if self._image is None:
-            self._image = Image.from_path(self.image_path)
+            self._image = load_image(self.image_path)
         return self._image
 
     @staticmethod
@@ -78,5 +78,5 @@ class ImageAnnotation:
         self.image_path.parent.mkdir(exist_ok=True, parents=True)
         self.xml_path.parent.mkdir(exist_ok=True, parents=True)
 
-        Image.save(self.image, self.image_path)
+        save_image(self.image, self.image_path)
         self.xml_path.write_text(self.to_xml())
diff --git a/common/research/common/dataset/perturbations/perturbator.py b/common/research/common/dataset/perturbations/perturbator.py
index 986aa8a91fa6b80575f7ca3b9d48159b544e9cbe..4391fe969ce49d6deff254f7c6f7e7b8060d2170 100644
--- a/common/research/common/dataset/perturbations/perturbator.py
+++ b/common/research/common/dataset/perturbations/perturbator.py
@@ -6,15 +6,21 @@ from typing import List
 import cv2
 import matplotlib.pyplot as plt
 import numpy as np
-
-from polystar.common.models.image import Image
-from research.common.dataset.perturbations.image_modifiers.brightness import BrightnessModifier
-from research.common.dataset.perturbations.image_modifiers.contrast import ContrastModifier
-from research.common.dataset.perturbations.image_modifiers.gaussian_blur import GaussianBlurrer
-from research.common.dataset.perturbations.image_modifiers.gaussian_noise import GaussianNoiser
-from research.common.dataset.perturbations.image_modifiers.horizontal_blur import HorizontalBlurrer
-from research.common.dataset.perturbations.image_modifiers.image_modifier_abc import ImageModifierABC
-from research.common.dataset.perturbations.image_modifiers.saturation import SaturationModifier
+from polystar.common.models.image import Image, load_image
+from research.common.dataset.perturbations.image_modifiers.brightness import \
+    BrightnessModifier
+from research.common.dataset.perturbations.image_modifiers.contrast import \
+    ContrastModifier
+from research.common.dataset.perturbations.image_modifiers.gaussian_blur import \
+    GaussianBlurrer
+from research.common.dataset.perturbations.image_modifiers.gaussian_noise import \
+    GaussianNoiser
+from research.common.dataset.perturbations.image_modifiers.horizontal_blur import \
+    HorizontalBlurrer
+from research.common.dataset.perturbations.image_modifiers.image_modifier_abc import \
+    ImageModifierABC
+from research.common.dataset.perturbations.image_modifiers.saturation import \
+    SaturationModifier
 
 
 @dataclass
@@ -37,7 +43,7 @@ class ImagePerturbator:
 
 if __name__ == "__main__":
     EXAMPLE_DIR = Path(__file__).parent / "examples"
-    rune_img = Image.from_path(EXAMPLE_DIR / "test.png")
+    rune_img = load_image(EXAMPLE_DIR / "test.png")
     perturbator = ImagePerturbator(
         [
             ContrastModifier(),
diff --git a/common/research/common/dataset/perturbations/utils.py b/common/research/common/dataset/perturbations/utils.py
index 551bc65023efc8983c09ec78dbdbbeb598a7dce7..fb90ebea203cece50b3439264561e125587e2b87 100644
--- a/common/research/common/dataset/perturbations/utils.py
+++ b/common/research/common/dataset/perturbations/utils.py
@@ -3,15 +3,15 @@ from pathlib import Path
 import cv2
 import matplotlib.pyplot as plt
 import numpy as np
-
-from polystar.common.models.image import Image
-from research.common.dataset.perturbations.image_modifiers.image_modifier_abc import ImageModifierABC
+from polystar.common.models.image import load_image
+from research.common.dataset.perturbations.image_modifiers.image_modifier_abc import \
+    ImageModifierABC
 
 EXAMPLE_DIR = Path(__file__).parent / "examples"
 
 
 def simple_modifier_demo(modifier: ImageModifierABC):
-    rune_img = Image.from_path(EXAMPLE_DIR / "test.png")
+    rune_img = load_image(EXAMPLE_DIR / "test.png")
     rune_perturbed = modifier.modify(rune_img, 1)
     cv2.imwrite(str(EXAMPLE_DIR / f"res_{modifier}.png"), cv2.cvtColor(rune_perturbed, cv2.COLOR_RGB2BGR))
     side_by_side_display = np.hstack((rune_img, rune_perturbed))
diff --git a/common/research/common/dataset/roco_dataset.py b/common/research/common/dataset/roco_dataset.py
index b90eefc0d2e772937dd576381a828725d22500d6..7c8b9e650862b2e311092129456b91da51a407ca 100644
--- a/common/research/common/dataset/roco_dataset.py
+++ b/common/research/common/dataset/roco_dataset.py
@@ -3,8 +3,7 @@ from pathlib import Path
 from typing import Iterable
 
 from more_itertools import ilen
-
-from polystar.common.models.image import Image
+from polystar.common.models.image import Image, load_image
 from polystar.common.models.image_annotation import ImageAnnotation
 
 
@@ -17,7 +16,7 @@ class ROCODataset:
     @property
     def images(self) -> Iterable[Image]:
         for image_path in self.image_paths:
-            yield Image.from_path(image_path)
+            yield load_image(image_path)
 
     @property
     def image_annotations(self) -> Iterable[ImageAnnotation]:
diff --git a/common/research/common/datasets/image_dataset.py b/common/research/common/datasets/image_dataset.py
index 9ede6326accbf19365c098f7f1f59b6fb6ed2a8f..047633689a5bcbccf2b6052a4fff0a3918f4a4f2 100644
--- a/common/research/common/datasets/image_dataset.py
+++ b/common/research/common/datasets/image_dataset.py
@@ -25,7 +25,7 @@ class ImageFileDataset(LazyDataset[Path, TargetT], ABC):
         pass
 
     def open(self) -> ImageDataset:
-        return self.transform_examples(Image.from_path)
+        return self.transform_examples(load_image)
 
     def __len__(self):
         return ilen(self.image_files)
diff --git a/common/research/common/datasets/roco/directory_roco_dataset.py b/common/research/common/datasets/roco/directory_roco_dataset.py
index 9857bea0b90228184f7517226ee6c6e199fc066a..5df40213d341fff85c3eadd42ac5fb0c688360d2 100644
--- a/common/research/common/datasets/roco/directory_roco_dataset.py
+++ b/common/research/common/datasets/roco/directory_roco_dataset.py
@@ -1,6 +1,6 @@
 from pathlib import Path
 
-from polystar.common.models.image import Image
+from polystar.common.models.image import Image, save_image
 from research.common.datasets.image_dataset import ImageDirectoryDataset
 from research.common.datasets.roco.roco_annotation import ROCOAnnotation
 
@@ -21,5 +21,5 @@ class DirectoryROCODataset(ImageDirectoryDataset[ROCOAnnotation]):
         self.annotations_dir.mkdir()
 
     def add(self, image: Image, annotation: ROCOAnnotation):
-        Image.save(image, self.images_dir / f"{annotation.name}.jpg")
+        save_image(image, self.images_dir / f"{annotation.name}.jpg")
         (self.annotations_dir / f"{annotation.name}.xml").write_text(annotation.to_xml())
diff --git a/common/research/common/image_pipeline_evaluation/image_dataset_generator.py b/common/research/common/image_pipeline_evaluation/image_dataset_generator.py
index 862b0492325578aa2391ed6afc85d098066d5aee..f9b321bbbd1ac05ebc001137efd6410382e32a44 100644
--- a/common/research/common/image_pipeline_evaluation/image_dataset_generator.py
+++ b/common/research/common/image_pipeline_evaluation/image_dataset_generator.py
@@ -2,7 +2,7 @@ from abc import abstractmethod
 from pathlib import Path
 from typing import Generic, Iterable, List, Tuple, TypeVar
 
-from polystar.common.models.image import Image
+from polystar.common.models.image import Image, load_image
 from research.common.dataset.directory_roco_dataset import DirectoryROCODataset
 
 T = TypeVar("T")
@@ -17,7 +17,7 @@ class ImageDatasetGenerator(Generic[T]):
             prev_total_size = len(images)
             for img_path, label in self.from_roco_dataset(dataset):
                 images_path.append(img_path)
-                images.append(Image.from_path(img_path))
+                images.append(load_image(img_path))
                 labels.append(label)
             dataset_sizes.append(len(images) - prev_total_size)
         return images_path, images, labels, dataset_sizes
diff --git a/common/tests/common/unittests/datasets/roco/test_directory_dataset_zoo.py b/common/tests/common/unittests/datasets/roco/test_directory_dataset_zoo.py
index 69ad22403d4d6acb5445a98506b42f829269da83..fbb37073dd6f19c8b17ecacd2e0ac7360ccf03c4 100644
--- a/common/tests/common/unittests/datasets/roco/test_directory_dataset_zoo.py
+++ b/common/tests/common/unittests/datasets/roco/test_directory_dataset_zoo.py
@@ -4,7 +4,7 @@ from unittest import TestCase
 
 from numpy import asarray, float32
 from numpy.testing import assert_array_almost_equal
-from polystar.common.models.image import Image
+from polystar.common.models.image import save_image
 from research.common.datasets.roco.directory_roco_dataset import \
     DirectoryROCODataset
 from research.common.datasets.roco.roco_annotation import ROCOAnnotation
@@ -35,7 +35,7 @@ class TestDirectoryROCODataset(TestCase):
             dataset.annotations_dir.mkdir()
             dataset.images_dir.mkdir()
             (dataset.annotations_dir / "frame_1.xml").write_text(annotation.to_xml())
-            Image.save(image, dataset.images_dir / "frame_1.jpg")
+            save_image(image, dataset.images_dir / "frame_1.jpg")
 
             image_dataset = dataset.open()
 
diff --git a/robots-at-runes/research/robots_at_runes/dataset/labeled_image.py b/robots-at-runes/research/robots_at_runes/dataset/labeled_image.py
index bc49b1cb35158127d3aeff40c0c2b8131db528dc..e6894d1cf51b4e3d64034e7db8a7684b05deac76 100644
--- a/robots-at-runes/research/robots_at_runes/dataset/labeled_image.py
+++ b/robots-at-runes/research/robots_at_runes/dataset/labeled_image.py
@@ -4,10 +4,9 @@ from typing import Any, Dict, Iterable, List
 from xml.dom.minidom import parseString
 
 import cv2
-
 import xmltodict
 from dicttoxml import dicttoxml
-from polystar.common.models.image import Image
+from polystar.common.models.image import Image, load_image, save_image
 
 
 @dataclass
@@ -35,7 +34,7 @@ class LabeledImage:
     point_of_interests: List[PointOfInterest] = field(default_factory=list)
 
     def save(self, directory_path: Path, name: str):
-        Image.save(self.image, directory_path / "image" / f"{name}.jpg")
+        save_image(self.image, directory_path / "image" / f"{name}.jpg")
         self._save_annotation(directory_path / "image_annotation" / f"{name}.xml")
 
     def _save_annotation(self, annotation_path: Path):
@@ -57,7 +56,7 @@ class LabeledImage:
         directory: Path, name: str, conversion: int = cv2.COLOR_BGR2RGB, ext: str = "jpg"
     ) -> "LabeledImage":
         return LabeledImage(
-            image=Image.from_path(directory / "image" / f"{name}.{ext}", conversion),
+            image=load_image(directory / "image" / f"{name}.{ext}", conversion),
             point_of_interests=PointOfInterest.from_annotation_file(directory / "image_annotation" / f"{name}.xml"),
         )