Rotation with FFT
Via shear it is possible to rotate an image. Shearing is basically a shift operation but with different shift distance in each row.
Examples
For full interactivity, have a look at this Pluto notebook.
using Revise, FourierTools, Plots, TestImages, PlutoUI, ImageShow
begin
img = Float32.(testimage("fabio_512_gray"))
z = zeros(Float32, (768, 768))
FourierTools.center_set!(z, img)
end
Gray.(FourierTools.shear(z, -305))
Function references
FourierTools.shear — Functionshear(arr, Δ, shear_dir_dim=1, shear_dim=2; fix_nyquist=false, adapt_size=false::Bool, pad_value=zero(eltype(arr)))Shears an array by the amount of Δ pixels via an FFT approach. Δ is the relative shift between the top and bottom row shifted with respect to each other. shear_dir_dim decides the direction of the shear and shear_dim is the second dimension where the shear happens. There is also shear! available.
#Arguments
arr: array to shearshear_dir_dim: dimension of the shift during shearshear_dim: dimension along which to progress and apply variing shears alongshear_dir_dimfix_nyquist: apply a fix to the highest frequency during the Fourier-space application of the exponential factoradapt_size: if true, pad the data prior to the shear. The result array will be largerpad_value: the value to pad with (only applies ifadapt_size=true)assign_wrap=assign_wrap: replaces wrap-around areas bypad_value(only ofadapt_sizeisfalse)
For complex arrays we use fft, for real array we use rfft.
FourierTools.shear! — Functionshear!(arr, Δ, shear_dir_dim=1, shear_dim=2; fix_nyquist=false, assign_wrap=false, pad_value=zero(eltype(arr)))For more details see shear.
Extra Arguments
assign_wrap: if true wrap-around areas are replaced by pad_value pad_value: the value to replace wrap-around areas with
For complex arrays we can completely avoid large memory allocations. For real arrays, we need at least allocate on array in the fourier space.