def test_slow_warp_nonint_oshape(): image = np.random.rand(5, 5) with pytest.raises(ValueError): warp(image, lambda xy: xy, output_shape=(13.1, 19.5)) warp(image, lambda xy: xy, output_shape=(13.0001, 19.9999))
def test_warp_tform(): x = np.zeros((5, 5), dtype=np.double) x[2, 2] = 1 theta = -np.pi / 2 tform = SimilarityTransform(scale=1, rotation=theta, translation=(0, 4)) x90 = warp(x, tform, order=1) assert_array_almost_equal(x90, np.rot90(x)) x90 = warp(x, tform.inverse, order=1) assert_array_almost_equal(x90, np.rot90(x))
def test_bool_nonzero_order_errors(order): img = np.zeros((10, 10), dtype=bool) with pytest.raises(ValueError): rescale(img, 0.5, order=order) with pytest.raises(ValueError): resize(img, (5, 5), order=order) with pytest.raises(ValueError): warp(img, np.eye(3), order=order)
def test_warp_identity(): img = img_as_float(rgb2gray(astronaut())) assert len(img.shape) == 2 assert np.allclose(img, warp(img, AffineTransform(rotation=0))) assert not np.allclose(img, warp(img, AffineTransform(rotation=0.1))) rgb_img = np.transpose(np.asarray([img, np.zeros_like(img), img]), (1, 2, 0)) warped_rgb_img = warp(rgb_img, AffineTransform(rotation=0.1)) assert np.allclose(rgb_img, warp(rgb_img, AffineTransform(rotation=0))) assert not np.allclose(rgb_img, warped_rgb_img) # assert no cross-talk between bands assert np.all(0 == warped_rgb_img[:, :, 1])
def test_warp_matrix(): x = np.zeros((5, 5), dtype=np.double) x[2, 2] = 1 refx = np.zeros((5, 5), dtype=np.double) refx[1, 1] = 1 matrix = np.array([[1, 0, 1], [0, 1, 1], [0, 0, 1]]) # _warp_fast outx = warp(x, matrix, order=1) assert_array_almost_equal(outx, refx) # check for ndimage.map_coordinates outx = warp(x, matrix, order=5)
def test_zero_image_size(): with pytest.raises(ValueError): warp(np.zeros(0), SimilarityTransform()) with pytest.raises(ValueError): warp(np.zeros((0, 10)), SimilarityTransform()) with pytest.raises(ValueError): warp(np.zeros((10, 0)), SimilarityTransform()) with pytest.raises(ValueError): warp(np.zeros((10, 10, 0)), SimilarityTransform())
def test_bool_array_warnings(): img = np.zeros((10, 10), dtype=bool) with expected_warnings(['Input image dtype is bool']): rescale(img, 0.5, anti_aliasing=True) with expected_warnings(['Input image dtype is bool']): resize(img, (5, 5), anti_aliasing=True) with expected_warnings(['Input image dtype is bool']): rescale(img, 0.5, order=1) with expected_warnings(['Input image dtype is bool']): resize(img, (5, 5), order=1) with expected_warnings(['Input image dtype is bool']): warp(img, np.eye(3), order=1)
def test_homography(): x = np.zeros((5, 5), dtype=np.double) x[1, 1] = 1 theta = -np.pi / 2 M = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 4], [0, 0, 1]]) x90 = warp(x, inverse_map=ProjectiveTransform(M).inverse, order=1) assert_array_almost_equal(x90, np.rot90(x))
def applyTransformationOnIma(self, ima2): if not self.transfMat: self._findTransformationMatrix() alignedIma = warp(ima2, ProjectiveTransform(matrix=self.transfMat), output_shape=ima2.shape, order=3, mode='constant', cval=np.median(ima2.data)) return CCDData(alignedIma, unit=ima2.unit)
def test_warp_callable(): x = np.zeros((5, 5), dtype=np.double) x[2, 2] = 1 refx = np.zeros((5, 5), dtype=np.double) refx[1, 1] = 1 def shift(xy): return xy + 1 outx = warp(x, shift, order=1) assert_array_almost_equal(outx, refx)
def test_warp_nd(): for dim in range(2, 8): shape = dim * (5, ) x = np.zeros(shape, dtype=np.double) x_c = dim * (2, ) x[x_c] = 1 refx = np.zeros(shape, dtype=np.double) refx_c = dim * (1, ) refx[refx_c] = 1 coord_grid = dim * (slice(0, 5, 1), ) coords = np.array(np.mgrid[coord_grid]) + 1 outx = warp(x, coords, order=0, cval=0) assert_array_almost_equal(outx, refx)
def test_warp_clip_cval_not_used(order): # Test that clipping does not consider cval part of the input range if it # is not used in the output image x = np.ones((15, 15), dtype=np.float64) x[5:-5, 5:-5] = 2 # Transform the image by stretching it out by one pixel on each side so # that cval will not actually be used transform = AffineTransform(scale=15/(15+2), translation=(1, 1)) with expected_warnings(['Bi-quadratic.*bug'] if order == 2 else None): outx = warp(x, transform, mode='constant', order=order, cval=0, clip=True) # At higher orders of interpolation, the transformed image has overshoots # beyond the input range that should be clipped to the range 1 to 2. Even # though cval=0, the minimum value of the clipped output image should be # 1 and not affected by the unused cval. assert_array_almost_equal(outx.min(), 1)
def test_inverse(): tform = SimilarityTransform(scale=0.5, rotation=0.1) inverse_tform = SimilarityTransform(matrix=np.linalg.inv(tform.params)) image = np.arange(10 * 10).reshape(10, 10).astype(np.double) assert_array_equal(warp(image, inverse_tform), warp(image, tform.inverse))
def test_invalid(): with pytest.raises(ValueError): warp(np.ones((4, 3, 3, 3)), SimilarityTransform())
def test_const_cval_out_of_range(): img = np.random.randn(100, 100) cval = -10 warped = warp(img, AffineTransform(translation=(10, 10)), cval=cval) assert np.sum(warped == cval) == (2 * 100 * 10 - 10 * 10)
def radon(image, theta=None): """ Calculates the radon transform of an image given specified projection angles. Parameters ---------- image : array_like Input image. The rotation axis will be located in the pixel with indices ``(image.shape[0] // 2, image.shape[1] // 2)``. theta : array_like, optional Projection angles (in degrees). If `None`, the value is set to np.arange(180). circle : boolean, optional Assume image is zero outside the inscribed circle, making the width of each projection (the first dimension of the sinogram) equal to ``min(image.shape)``. preserve_range : bool, optional Whether to keep the original range of values. Otherwise, the input image is converted according to the conventions of `img_as_float`. Also see https://scikit-image.org/docs/dev/user_guide/data_types.html Returns ------- radon_image : ndarray Radon transform (sinogram). The tomography rotation axis will lie at the pixel index ``radon_image.shape[0] // 2`` along the 0th dimension of ``radon_image``. References ---------- .. [1] AC Kak, M Slaney, "Principles of Computerized Tomographic Imaging", IEEE Press 1988. .. [2] B.R. Ramesh, N. Srinivasa, K. Rajgopal, "An Algorithm for Computing the Discrete Radon Transform With Some Applications", Proceedings of the Fourth IEEE Region 10 International Conference, TENCON '89, 1989 Notes ----- Based on code of Justin K. Romberg (https://www.clear.rice.edu/elec431/projects96/DSP/bpanalysis.html) """ image = convert_to_float(image, None) theta = np.linspace(0., 180., max(image.shape), endpoint=False) with tf.compat.v1.Session() as sess: diagonal = tf.sqrt(2.0) * max(image.shape) pad = [tf.dtypes.cast(tf.math.ceil(diagonal - s), tf.int32) for s in image.shape] new_center = [(s + p) // 2 for s, p in zip(image.shape, pad)] old_center = [s // 2 for s in image.shape] pad_before = [nc - oc for oc, nc in zip(old_center, new_center)] pad_width = [(pb, p - pb) for pb, p in zip(pad_before, pad)] padded_image = tf.pad(image, pad_width, mode='constant', constant_values=0) # padded_image is always square if padded_image.shape[0] != padded_image.shape[1]: raise ValueError('padded_image must be a square') center = padded_image.shape[0] // 2 radon_image = np.zeros((padded_image.shape[0], len(theta))) # convert degree to radian for i, angle in enumerate(np.deg2rad(theta)): cos_a, sin_a = tf.math.cos(angle), tf.math.sin(angle) R = tf.Variable(list([[cos_a, sin_a, -center * (cos_a + sin_a - 1)], [-sin_a, cos_a, -center * (cos_a - sin_a - 1)], [0, 0, 1]])) init_op = tf.compat.v1.global_variables_initializer() sess.run(init_op) rotated = wp.warp(padded_image.eval(), R.eval(), clip=False) # update transformed image radon_image[:, i] = rotated.sum(0) return radon_image