I've been playing around with taking Fourier transforms of images, screwing around in frequency-space, and doing the inverse transform. Here are some of the results.
The first one is a video where I just set all the phase information to a constant angle, sweeping through a full circle over the course of the video. Source and commands here: https://github.com/timmc/fimg/commit/2da3e37309eeee762adedbbb793678b9ba45bd08
In the second I largely preserve the phase information, but rotate the angle by 1/10 of a circle. Source: https://github.com/timmc/fimg/blob/c1231029/fimg.py#L59
I've also played with "rolling" the amplitude and phase arrays along one or both axes (independently or together), "blurring" the arrays (adding neighboring pixels), and swapping them. Some of the effects are interesting, others aren't.
The typical thing people do here is to mask out (set to zero) regions with higher frequencies, creating a blurring effect, or lower frequencies, creating an edge-highlighting effect. I haven't added code to do masks, but I can recommend this JS demo: http://bigwww.epfl.ch/demo/ip/demos/FFT-filtering/
For a refresher on Fourier transforms, I can recommend <https://www.youtube.com/watch?v=Y9FZ4igNxNA>, which then goes into *optical* Fourier transforms using... a simple glass lens. Pretty wild stuff.
Here's the result of throwing away frequency amplitude information, and just preserving phase. Specifically, I ran with `const_amp 10000` (it has a sort of CLI now!) to set the amplitudes all to an arbitrary 10k. This gives an image made mostly of graininess, I guess because high frequencies such as sensor noise are normally low-amplitude, and have been boosted here.
I can now plot phase, too! https://github.com/timmc/fimg/blob/30f0bb0a/fimg.py#L116
...which is mostly a speckly streaky mess, even harder to interpret than the amplitude plot. However, it does have some structure if you look at it in full 1:1 pixel view, so I decided to throw the *phase plot* back in as a source image and extract an amplitude plot of *that*.
And... it appears to have, to some degree, reconstructed the source image!
(It's all quartered-up because the plot outputs are rolled by 1/2 along both axes.)
Here's a weird photo from NYC of a giant crowd of fire extinguishers behind a hotel.
There are a *ton* of geometric patterns in this image, so it's great for FFT. (Not just the extinguishers—we got bricks, fence, pipes, etc. It's also different in X and Y directions.)
Did I mention I've got color working now? (Version 098feaac.) I run the FFT on each RGB channel separately and then recompose. It's not very colorful is it, though? Well, no reason it should be! Most of the FFT output is high-frequency stuff like sensor noise. Those big color blocks in the input are probably represented in a relatively small number of low-frequency pixels in the output.
(Note: This FFT is on a scaled-down version of the image.)
If I just blast the bejeezus out of the saturation and contrast on that last FFT, the first image shows the result. Note the concentric rings of red and cyan around the origin—that's probably the fire extinguishers! The orangey cast farther out is probably due to the bricks and the weird red haze over the upper left of the input image.
For comparison, the second image is when I took the FFT of the full-resolution image, *then* downscaled that. Notice how it appears to be zoomed out? That's because there's a broader range of frequencies to represent in a larger image. (It was also about 7x larger in file size, ~15 MB, which is why I downscaled it before uploading.) Now there's a greenish cast to the high frequency areas, and I don't know why!
I've published all of the above as a blog post: https://www.brainonfire.net/blog/2022/04/28/fourier-image-experiments/
I might come back later and add more to the post as I figure out new transforms, ways to avoid clipping, and interesting types of input images.
These two are very pretty as thumbnails. I feel mixed about the small grain texture of the full size images, but the small ones look sparkly and fun.