Fun with Filters and Frequencies

Part 1.1: Convolutions from Scratch

In this part, we test out different convolution approaches: one using 4 for-loops, one using 2 for-loops (slightly vectorized), and convolve2d from scipy. Overall, convolve2d was much faster than the naive implementations above. Convolving a box filter with an image of my friend's dog took well over a minute with the 4 for-loop implementation (~1 min 15 sec), 10 seconds with the vectorized convolution, and was nearly instantaneous with convolve2d (< 1 sec). By inspection, the results also looked identical as the boundaries and edges were pretty much the same.

Ozzie
Original Ozzie
Ozzie_boxed
Boxed Ozzie
Ozzie_Dx
Dx-ed Ozzie
Ozzie_Dy
Dy-ed Ozzie

Part 1.2: Finite Difference Operator

In this part, we test out the finite difference operators and try to find an optimal threshold value that detects edges in our images while ideally minimizing noise. After trying out different threshold values, I decided to go with a 0.25 threshold as the image was still noisy when using a 0.2 threshold whereas at 0.3, the edges started to disconnect.

Cameraman
Original Cameraman
Cameraman_Dx
Dx-ed Cameraman
Cameraman_Dy
Dy-ed Cameraman
Cameraman_mag
Cameraman Gradient Magnitude
Cameraman_binarize
Cameraman Gradient Binarized

Part 1.3: Derivative of Gaussian (DoG) Filter

In this part, we try a different approach to edge detection by convolving with a Gaussian filter instead of applying finite of difference operators directly, allowing us to produce much smoother edges albeit with a higher threshold value (I used a threshold of 40 here). We tried two different approaches: (1) we apply a Gaussian filter on images before taking their derivative and convolving, (2) we convolve Gaussian filters with derivatives then apply on images. Both produced the same, smoother result compared to part 1.2. A kernel size of 9 was applied on these images.

gaus_kernel
Gaussian Kernel
DoG_dx
DoG Dx
DoG_dy
DoG Dy
gaus_dx
Approach 1 Dx on Cameraman
gaus_dy
Approach 1 Dy on Cameraman
gaus_mag
Approach 1 Magnitude on Cameraman
camera-imgx
Approach 2 Dx on Cameraman
camera-imgy
Approach 2 Dy on Cameraman
gaus_mag
Approach 2 Magnitude on Cameraman
cameraman-final
Final Edge Image

Part 2.1: Image "Sharpening"

Next, we use a masking technique to "sharpen" an image. This is done by getting the high frequences of the image (subtracting the blurred image from the original), scaling it by some alpha value, and adding it back to our original image. I tested the technique on an image of the Taj Mahal as well as a super blurry image of Oski along with different alpha values.

taj
Original Taj
taj-blur
Blurred Taj (Low Frequency)
taj-details
Taj Details (High Frequency)
taj-sharpen
Taj Sharpened (alpha=1.5)
taj-sharpen-3
Taj Sharpened (alpha=3)
oski
Original Oski
taj-blur
Blurred Oski
taj-details
Oski Details
oski-sharpen-3
Oski Sharpened (alpha=3)
oski-sharpen-6
Oski Sharpened (alpha=6)

I also tried blurring then re-sharpening a sharp image and it looked comparable to the original one, although the colors were slightly less vibrant in the sharpened version.

cq
Original Bridge
cq-blur
Blurred Bridge
cq-details
Bridge Details
cq-sharpen-3
Bridge Sharpened (alpha=3)

Part 2.2: Hybrid Images

Then in this next part, we combine the low frequencies of one image with the high frequencies of another image to get a hybrid image effect. Aside from testing it out on Derek and Nutmeg, I tried to create a hybrid between an Eiffel-looking tower and the Campanile. For the tower hybrid, I used a low-pass cutoff of 15 and high pass cutoff of 25.

derek-hybrid
Derek Nutmeg Hybrid
tower
Original Tower
campanile
Original Campanile
tower-hybrid
Tower Campanile Hybrid
fourier
FFTs of Tower Hybrid

Part 2.3: Gaussian and Laplacian Stacks

This part uses Gaussian and Laplacian stacks to prepare us for the next part where we attempt to combine two images seamlessly. Here are the stacks on the provided apple and orange images.

apple-gaus
Apple Gaussian Stack
orange-gaus
Orange Gaussian Stack
apple-lap
Apple Laplacian Stack
orange-lap
Orange Laplacian Stack

Part 2.4: Multiresolution Blending (aka. Oraple)

And finally we can visualize the oraple result as well as some other fun blends!

oraple
Oraple Result
sun_night_blend
Sun Night Blend
food_blend
Food Blend