Fixed assumed center of rotation in the case of even-size inputs for vip-fft and skimage imlib
@@ -242,8 +242,8 @@ def frame_rotate(array, angle, imlib='vip-fft', interpolation='lanczos4',
max_val = np.max(im_temp)
im_temp /= max_val
- array_out = rotate(im_temp, angle, order=order, center=cxy, cval=np.nan,
- mode=border_mode)
+ array_out = rotate(im_temp, angle, order=order, center=(cx, cy),
+ cval=np.nan, mode=border_mode)
array_out *= max_val
array_out += min_val
@@ -539,18 +539,23 @@ def rotate_fft(array, angle):
while angle>360:
angle-=360
+ # first convert to odd size before multiple 90deg rotations
+ if not y_ori%2 or not x_ori%2:
+ array_in = np.zeros([array.shape[0]+1,array.shape[1]+1])
+ array_in[:-1,:-1] = array.copy()
+ else:
+ array_in = array.copy()
+
if angle>45:
dangle = angle%90
if dangle>45:
dangle = -(90-dangle)
nangle = np.rint(angle/90)
- array_in = np.rot90(array, nangle)
+ array_in = np.rot90(array_in, nangle)
else:
dangle = angle
- array_in = array.copy()
- if y_ori%2 or x_ori%2:
- # NO NEED TO SHIFT BY 0.5px: FFT assumes rot. center on cx+0.5, cy+0.5!
+ # remove last row and column to make it even size before FFT
array_in = array_in[:-1,:-1]
a = np.tan(np.deg2rad(dangle)/2)
@@ -569,9 +574,8 @@ def rotate_fft(array, angle):
s_xyx = _fft_shear(s_xy, arr_x, a, ax=1, pad=0)
if y_ori%2 or x_ori%2:
- # shift + crop back to odd dimensions , using FFT
+ # set it back to original dimensions
array_out = np.zeros([s_xyx.shape[0]+1,s_xyx.shape[1]+1])
- # NO NEED TO SHIFT BY 0.5px: FFT assumes rot. center on cx+0.5, cy+0.5!
array_out[:-1,:-1] = np.real(s_xyx)
else:
array_out = np.real(s_xyx)
