From 6f4c2ad2681e4c9b917a26dbe4305a4ef5ceedf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sun, 26 Aug 2012 18:46:13 +0200 Subject: [PATCH] Add function for image rotation --- skimage/transform/_warps.py | 62 +++++++++++++++++++++++++++ skimage/transform/tests/test_warps.py | 9 +++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/skimage/transform/_warps.py b/skimage/transform/_warps.py index e796b454..7b0fbeed 100644 --- a/skimage/transform/_warps.py +++ b/skimage/transform/_warps.py @@ -211,6 +211,68 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1, return clipped.squeeze() +def rotate(image, angle, preserve_shape=False, order=1, + mode='constant', cval=0.): + """Rotate image by a certain angle around its center. + + Parameters + ---------- + image : ndarray + Input image. + angle : float + Rotation angle in degrees in counter-clockwise direction. + preserve_shape : bool, optional + Determine whether the shape of the output image will be automatically + calculated, so the complete rotated image exactly fits. Default is + False. + + Returns + ------- + rotated : ndarray + Rotated version of the input. + + Other parameters + ---------------- + order : int + Order of splines used in interpolation. See + `scipy.ndimage.map_coordinates` for detail. + mode : string + How to handle values outside the image borders. See + `scipy.ndimage.map_coordinates` for detail. + cval : string + Used in conjunction with mode 'constant', the value outside + the image boundaries. + + """ + + rows, cols = image.shape[0], image.shape[1] + + # rotation around center + translation = np.array((cols, rows)) / 2. + tform1 = SimilarityTransform(translation=-translation) + tform2 = SimilarityTransform(rotation=np.deg2rad(angle)) + tform3 = SimilarityTransform(translation=translation) + tform = tform1 + tform2 + tform3 + + output_shape = None + if not preserve_shape: + # determine shape of output image + corners = tform([[0, 0], [0, rows], [cols, 0], [cols, rows]]) + corners = np.round(corners, 4) + minc = np.floor(corners[:, 0].min()) + minr = np.floor(corners[:, 1].min()) + maxc = np.ceil(corners[:, 0].max()) + maxr = np.ceil(corners[:, 1].max()) + output_shape = [maxr - minr, maxc - minc] + + # fit output image in new shape + tform4 = SimilarityTransform(translation=(minc, minr + 1)) + tform = tform4 + tform + + return warp(image, tform, output_shape=output_shape, order=order, + mode=mode, cval=cval) + + def _swirl_mapping(xy, center, rotation, strength, radius): x, y = xy.T x0, y0 = center diff --git a/skimage/transform/tests/test_warps.py b/skimage/transform/tests/test_warps.py index f896a452..d5ffff59 100644 --- a/skimage/transform/tests/test_warps.py +++ b/skimage/transform/tests/test_warps.py @@ -2,7 +2,7 @@ from numpy.testing import assert_array_almost_equal, run_module_suite import numpy as np from scipy.ndimage import map_coordinates -from skimage.transform import (warp, warp_coords, +from skimage.transform import (warp, warp_coords, rotate, AffineTransform, ProjectiveTransform, SimilarityTransform) @@ -74,6 +74,13 @@ def test_fast_homography(): assert d < 0.001 +def test_rotate(): + x = np.zeros((5, 5), dtype=np.double) + x[1, 1] = 1 + x90 = rotate(x, 90) + assert_array_almost_equal(x90, np.rot90(x)) + + def test_swirl(): image = img_as_float(data.checkerboard())