def rotate(img: np.ndarray, ann: Annotation, degrees: float, mode: str=RotationModes.KEEP) ->\ (np.ndarray, Annotation): # @TODO: add "preserve_size" mode """ Rotates the image by random angle. Args: img: Input image array. ann: Input annotation. degrees: Rotation angle, counter-clockwise. mode: parameter: "keep" - keep original image data, then new regions will be filled with black color; "crop" - crop rotated result to exclude black regions; Returns: A tuple containing rotated image array and annotation. """ _validate_image_annotation_shape(img, ann) rotator = ImageRotator(img.shape[:2], degrees) if mode == RotationModes.KEEP: rect_to_crop = None elif mode == RotationModes.CROP: rect_to_crop = rotator.inner_crop else: raise NotImplementedError('Wrong black_regions mode.') res_img = rotator.rotate_img(img, use_inter_nearest=False) res_ann = ann.rotate(rotator) if rect_to_crop is not None: res_img = sly_image.crop(res_img, rect_to_crop) res_ann = res_ann.relative_crop(rect_to_crop) return res_img, res_ann
def rotate(img: np.ndarray, degrees_angle: float, mode=RotateMode.KEEP_BLACK) -> np.ndarray: """ Rotate given a NumPy / OpenCV image on selected angle and Extend/Crop by chosen mode. :param img: image for rotation :param degrees_angle: angle in degrees :param mode: one of RotateMode enum values :return: rotated and processed image """ rotator = ImageRotator(imsize=img.shape[:2], angle_degrees_ccw=degrees_angle) if mode == RotateMode.KEEP_BLACK: return rotator.rotate_img( img, use_inter_nearest=False) # @TODO: order = ??? elif mode == RotateMode.CROP_BLACK: img_rotated = rotator.rotate_img(img, use_inter_nearest=False) return rotator.inner_crop.get_cropped_numpy_slice(img_rotated) elif mode == RotateMode.SAVE_ORIGINAL_SIZE: # TODO Implement this in rotator instead. return skimage.transform.rotate(img, degrees_angle, resize=False) else: raise NotImplementedError('Rotate mode "{0}" not supported!'.format( str(mode)))
def test_rotate(self): imsize = (101, 101) rotator = ImageRotator(imsize=imsize, angle_degrees_ccw=-90) res_poly = self.poly.rotate(rotator) self.assertPolyEquals(res_poly, [[90, 10], [90, 40], [60, 30], [70, 10]], [[[80, 20], [80, 30], [70, 30], [70, 20]]])
def test_rotate(self): in_size = (15, 15) rotator = ImageRotator(imsize=in_size, angle_degrees_ccw=90) res_bitmap = self.bitmap.rotate(rotator) expected_data = np.array([[[0.4, 0.5], [1.0, 1.1]], [[0.2, 0.3], [0.8, 0.9]], [[0.0, 0.1], [0.6, 0.7]]], dtype=np.float64) # TODO origin self.assertListEqual(res_bitmap.data.tolist(), expected_data.tolist())
def test_rotate(self): in_size = (15, 15) rotator = ImageRotator(imsize=in_size, angle_degrees_ccw=90) res_bitmap = self.bitmap.rotate(rotator) expected_mask = np.array([[0, 0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1], [0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0]], dtype=np.bool) self.assertListEqual(res_bitmap.data.tolist(), expected_mask.tolist())
def test_rotate(self): rotator = ImageRotator((21, 21), 90) # Center pixel is (10, 10) rot_point = self.point.rotate(rotator) self.assertPointEquals(rot_point, 15, 10)
def test_rotate(self): imsize = (101, 101) rotator = ImageRotator(imsize=imsize, angle_degrees_ccw=90) res_rect = self.rect.rotate(rotator) self.assertRectEquals(res_rect, 70, 5, 90, 30)