2 releases

0.1.1 Apr 29, 2023
0.1.0 Dec 9, 2021

#818 in Algorithms

Download history 28/week @ 2024-06-08 39/week @ 2024-06-15 30/week @ 2024-06-22 13/week @ 2024-06-29 23/week @ 2024-07-06 20/week @ 2024-07-13 33/week @ 2024-07-20 63/week @ 2024-07-27 43/week @ 2024-08-03 39/week @ 2024-08-10 33/week @ 2024-08-17 26/week @ 2024-08-24 30/week @ 2024-08-31 270/week @ 2024-09-07 40/week @ 2024-09-14 55/week @ 2024-09-21

399 downloads per month
Used in butter2d

MPL-2.0 license

39KB
429 lines

2D Fourier transform for images

This crate aims to provide easy to use 2D spectral transforms for images, such as Fourier (FFT) and cosine (DCT) transforms. By default, only the Fourier transforms are availables. The cosine transform is available with the rustdct feature, named after the corresponding optional dependency.

By default, only implementations on mutable slices &mut [f64] are available, inside the fft2d::slice module of this crate. Implementations of the transforms are also available for nalgebra matrices in the fft2d::nalgebra module, if the nalgebra feature is activated.

Here is a partial extract of code for the low_pass filtering example with the input and output images, just to get a sense of the API.

fft2d_low_pass_mandrill

// Compute the 2D fft of the complex image data (beware of the transposition).
fft_2d(width, height, &mut img_buffer);

// Shift opposite quadrants of the fft (like matlab fftshift).
img_buffer = fftshift(height, width, &img_buffer);

// Apply a low-pass filter.
let low_pass = low_pass_filter(height, width);
let fft_low_pass: Vec<Complex<f64>> =
    low_pass.iter().zip(&img_buffer)
    .map(|(l, b)| l * b).collect();

// Invert the FFT back to the spatial domain of the image.
img_buffer = ifftshift(height, width, &fft_low_pass);
ifft_2d(height, width, &mut img_buffer);

// Normalize the data after FFT and IFFT.
let fft_coef = 1.0 / (width * height) as f64;
for x in img_buffer.iter_mut() { *x *= fft_coef; }

Examples

There are a few examples showing how to use the API, located in the examples/ folder.

Low pass filter via Fourier transform

This example shows how to apply a low pass filter on images. It is present both for the mutable slice API at examples/low_pass.rs and for the nalgebra API at examples/low_pass_nalgebra.rs. Example results are visible in the figure above in the readme. You can compile and run the example with the following command:

cargo run --release --example low_pass

Image resizing via 2D cosine transform

This example shows how to use a 2D cosine transform to resize an image. It consists in performing a DCT, then truncating (or expanding) the image buffer, and performing and inverse DCT. You can compile and run the example with the following command:

cargo run --release --features rustdct --example dct_resize

Normal integration to generate a depth map (or a 3D mesh)

In this example, we start from a normal map, which is an image encoding the (x,y,z) components of a surface normals into the RGB components of an image, and we integrate that normal map to get a depth map containing an estimated depth Z at each pixel. One algorithm to integrate those normals consists in writing a Poisson solver (as in Poisson equation) based on a 2D DCT. The relevant code is located in the dct_poisson function of the examples/normal_integration.rs file. You can compile and run the example with the following command:

cargo run --release --features rustdct,nalgebra --example normal_integration

fft2d_normal_integration

The cat normal map used in this example comes from Harvard's photometric stereo dataset.

The code for the normal integration is a Rust implementation of the method presented in the following paper. Big thanks to Yvain Quéau (@yqueau) for the help in setting up this port of his matlab code.

Normal Integration: a Survey - Queau et al., 2017

Dependencies

~3–4MB
~78K SLoC