From ce8b5aaa73b12470c632739760027640988c8507 Mon Sep 17 00:00:00 2001
From: Mathieu Beligon <mathieu@feedly.com>
Date: Sat, 28 Mar 2020 22:29:14 -0400
Subject: [PATCH] [runes] (blender) Add back rotation and scaling, with respect
 of labels

---
 .../research/dataset/blend/image_blender.py   |  5 ++-
 .../labeled_image_rotator.py                  | 32 +++++++++++++++++++
 .../labeled_image_scaler.py                   | 28 ++++++++++++++++
 3 files changed, 64 insertions(+), 1 deletion(-)
 create mode 100644 robots-at-runes/research/dataset/blend/labeled_image_modifiers/labeled_image_rotator.py
 create mode 100644 robots-at-runes/research/dataset/blend/labeled_image_modifiers/labeled_image_scaler.py

diff --git a/robots-at-runes/research/dataset/blend/image_blender.py b/robots-at-runes/research/dataset/blend/image_blender.py
index 57452da..4136200 100644
--- a/robots-at-runes/research/dataset/blend/image_blender.py
+++ b/robots-at-runes/research/dataset/blend/image_blender.py
@@ -62,6 +62,9 @@ if __name__ == "__main__":
 
     import matplotlib.pyplot as plt
 
+    from research.dataset.blend.labeled_image_modifiers.labeled_image_rotator import LabeledImageRotator
+    from research.dataset.blend.labeled_image_modifiers.labeled_image_scaler import LabeledImageScaler
+
     EXAMPLES_DIR = Path(__file__).parent / "examples"
 
     _obj = LabeledImage(
@@ -70,7 +73,7 @@ if __name__ == "__main__":
     )
     _bg = cv2.cvtColor(cv2.imread(str(EXAMPLES_DIR / "back1.jpg")), cv2.COLOR_BGR2RGB)
 
-    _blender = ImageBlender([])
+    _blender = ImageBlender([LabeledImageScaler(1.5), LabeledImageRotator(180)])
     for i in range(10):
         res = _blender.blend(_bg, _obj)
 
diff --git a/robots-at-runes/research/dataset/blend/labeled_image_modifiers/labeled_image_rotator.py b/robots-at-runes/research/dataset/blend/labeled_image_modifiers/labeled_image_rotator.py
new file mode 100644
index 0000000..b73c1eb
--- /dev/null
+++ b/robots-at-runes/research/dataset/blend/labeled_image_modifiers/labeled_image_rotator.py
@@ -0,0 +1,32 @@
+from dataclasses import dataclass
+
+import cv2
+import numpy as np
+from imutils import rotate_bound
+
+from polystar.common.models.image import Image
+from research.dataset.blend.labeled_image_modifiers.labeled_image_modifier_abc import LabeledImageModifierABC
+from research.dataset.labeled_image import PointOfInterest
+
+
+@dataclass
+class LabeledImageRotator(LabeledImageModifierABC):
+    max_angle_degrees: float
+
+    def _generate_modified_image(self, image: Image, angle: float) -> Image:
+        return rotate_bound(image, angle)
+
+    def _generate_modified_poi(
+        self, poi: PointOfInterest, original_image: Image, new_image: Image, angle_degrees: float
+    ) -> PointOfInterest:
+        angle_rads = np.deg2rad(angle_degrees)
+        sin, cos = np.sin(angle_rads), np.cos(angle_rads)
+        rotation_matrix = np.array([[cos, -sin], [sin, cos]])
+        prev_vector_to_center = np.array((poi.x - original_image.shape[1] / 2, poi.y - original_image.shape[0] / 2))
+        new_vector_to_center = np.dot(rotation_matrix, prev_vector_to_center)
+        return PointOfInterest(
+            int(new_vector_to_center[0] + new_image.shape[1] / 2), int(new_vector_to_center[1] + new_image.shape[0] / 2)
+        )
+
+    def _get_value_from_factor(self, factor: float) -> float:
+        return self.max_angle_degrees * factor
diff --git a/robots-at-runes/research/dataset/blend/labeled_image_modifiers/labeled_image_scaler.py b/robots-at-runes/research/dataset/blend/labeled_image_modifiers/labeled_image_scaler.py
new file mode 100644
index 0000000..73f9255
--- /dev/null
+++ b/robots-at-runes/research/dataset/blend/labeled_image_modifiers/labeled_image_scaler.py
@@ -0,0 +1,28 @@
+from dataclasses import dataclass
+
+import cv2
+
+from polystar.common.models.image import Image
+from research.dataset.blend.labeled_image_modifiers.labeled_image_modifier_abc import LabeledImageModifierABC
+from research.dataset.labeled_image import LabeledImage, PointOfInterest
+
+
+@dataclass
+class LabeledImageScaler(LabeledImageModifierABC):
+    max_scale: float
+
+    def _generate_modified_image(self, image: Image, scale: float) -> Image:
+        return cv2.resize(
+            image, (int(image.shape[1] * scale), int(image.shape[0] * scale)), interpolation=cv2.INTER_AREA
+        )
+
+    def _generate_modified_poi(
+        self, poi: PointOfInterest, original_image: Image, new_image: Image, scale: float
+    ) -> PointOfInterest:
+        return PointOfInterest(int(poi.x * scale), int(poi.y * scale))
+
+    def _get_value_from_factor(self, factor: float) -> float:
+        intensity = (self.max_scale - 1) * abs(factor) + 1
+        if factor > 0:
+            return intensity
+        return 1 / intensity
-- 
GitLab