CS 180

Fun with Filters and Frequencies

By Evan Chang ยท CS 180 Project 2

Tech: Python, NumPy, SciPy, Matplotlib, OpenCV

Part 1: Fun with Filters

Finite Difference Operator

A common task in image processing is finding the edges in an image along both the horizontal and vertical directions. This is often done by computing the gradients of the image along the x and y directions. This can be simply done by convolving the image with simple kernels that approximate the derivative of the image using finite differences. These kernels are simply taking the difference between two consecutive pixels in the image as an approximation of the true derivative.

\[\text{Gradient in x direction: } \matrix{D_x} = \begin{bmatrix} 1 -1 \end{bmatrix}\] \[\text{Gradient in y direction: } \matrix{D_y} = \begin{bmatrix} 1 \ -1 \end{bmatrix}\]

Image Gradient (dx)
Image Gradient (dx)
Image Gradient (dy)
Image Gradient (dy)

We can also compute the magnitude of the gradient by taking the square root of the sum of the squares of the gradients in the x and y directions to visualize the edges in the image. In order to remove some of the noise, we also can threshold the gradient magnitude to get a clearer picture of the edges in the image.

Image Gradient Magnitude
Image Gradient Magnitude
Thresholded Image Gradient Magnitude
Thresholded Image Gradient Magnitude (threshold=0.27)

Derivative of Gaussian (DoG Filter)

We can also smooth out our gradient magnitude edges by smoothing image first using a Gaussian filter. Convolving our image with a Gaussian filter gives us a cleaner picture of the edges. When we thresholded, we could tell we were only displaying the stronger edges and there was less noise in the image. However, there were also some gaps in the edges that we did have due to this thresholding. We can see in the smoothed version that the edges are more continuous and there are less gaps in the edges.

Thresholded Image Gradient Magnitude
Thresholded Image Gradient Magnitude (non-smoothed)
Thresholded Image Gradient Magnitude (smoothed)
Thresholded Image Gradient Magnitude (smoothed)

Due to the linear nature of convolutions, we can also compute this smoothed gradient magnitude using only one filter instead of two. This filter is known as the Derivative of Gaussian (DoG) filter and works by convolving the Gaussian with the finite difference operators first. Since these are much smaller than the image, we can convolve the Gaussian with the finite difference operators first and then convolve the result with the image to get the same result in less time.

Image Gradient with Two Convolutions
Two Convolutions
Image Gradient (DoG)
Single Convolution (DoG filter)

Part 2: Fun with Frequencies

Image Sharpening

Another common task in image processing is image sharpening. A simple way we can accomplish this is by adding high-frequency components back into the image.

We can get the high-frequency portions by subtracting the blurred image from the original image. This gives us high-frequency components that we can add back with an enhancement factor to sharpen the image.

Combining these operations into one filter gives us the unsharp mask filter. The process is outlined below for two example images:

Image sharpening process
Image sharpening process
Costco sharpening process
Costco sharpening process

Here are some results from testing this filter on several blurry images.

Original Taj image
Original image
Sharpened Taj image
Sharpened image
Blurry Costco entrance
Blurry Costco
Sharpened Costco entrance
Sharpened Costco
Blurry concert stage
Blurry concert image
Sharpened concert stage
Sharpened concert image
Blurry IVE concert image
Blurry IVE concert image
Sharpened IVE concert image
Sharpened IVE concert image
Cedar waxwing in a tree
(Not so blurry) bird picture
Sharpened bird image
Sharpened bird picture

From these examples, we can see that the unsharp mask filter does a good job of enhancing some higher-frequency components. It does particularly well with lines in building structures.

However, it is far from perfect as an unblurring filter since it only enhances edges already present in the image and cannot recover lost details.

For fun, this is what happens when we apply the unsharp mask filter to a blurred and re-sharpened image:

Original Oski image
Oski
Sharpened Oski image
Sharpened Oski

This image was already decently sharp. I then blurred and re-sharpened it. The result is an image of Oski with even sharper edges than the original.

Hybrid Images

In this section, I created hybrid images by combining low-frequency components of one image with high-frequency components of another image.

Since humans perceive low frequency much better than high frequency, up close we see mostly the low-pass image. From farther away, we can see elements of the high-pass image.

As before, I get low-pass components by Gaussian blurring. I get high-pass components by subtracting the low-pass filtered image from the original image. Then I average the two filtered images to produce the hybrid image.

We can control the amount of high-frequency content by adjusting the Gaussian sigma. Higher sigma changes how much frequency content is retained.

Before hybridizing, I aligned the two images by matching points and resizing to the same dimensions.

Nutmeg the cat
Nutmeg the cat
Derek
Derek the human
Nutmeg-Derek hybrid image
Hybrid image

We can visualize frequency response by taking the Fourier transform and plotting its magnitude.

As shown below, the hybrid keeps low-frequency portions of image 1 and high-frequency portions of image 2.

Hybrid image Fourier transform
Hybrid image Fourier transform (Miles-Monkey hybrid)

Here are other hybrid-image examples:

Miles portrait
roommate
Monkey image
Monkey
Miles-monkey hybrid
Miles-Monkey hybrid image
Dominic portrait
cool man
Wizard monkey image
Wizard Monkey
Dom-wizard hybrid
Cool-Wizard hybrid image

This last image did not turn out great, likely because shapes and color schemes of the two source images were too different. It mostly looked like one image with a slight ghost of the other.

Multi-resolution Blending

Another common task in image processing is blending two images together. If we simply splice images, we get a harsh seam between them.

Multiresolution blending smooths this seam by blending at multiple resolutions and recombining.

Gaussian and Laplacian Stacks

To separate images into resolutions, I used Gaussian and Laplacian stacks. These decompose images into different frequency bands for later combination.

Unlike the Gaussian pyramid from project 1, here I built Gaussian stacks by applying Gaussian kernels with increasing sigma values. I then got Laplacian stacks by subtracting adjacent Gaussian levels.

Gaussian and Laplacian stacks of an apple
Gaussian and Laplacian stacks of an apple

Implementing Multi-resolution Blending

Following Burt and Adelson, I blended two images by creating Gaussian and Laplacian stacks for both images, plus a Gaussian stack for the mask to smooth jagged edges from a simple spline blend.

Multiresolution blending process
Multiresolution blending process

Here are my blending results:

Oraple blending process
Oraple blending process
Oraple final
Oraple
Lance-Kenny blending process
Lance-Kenny blending process
Lance-Kenny final
Lance-Kenny
Costco-Glade blending process
Costco-Glade blending process
Costco-Glade final
Costco-Glade
Dark Wellman bright sky blending process
Dark Wellman bright sky blending process
Dark Wellman bright sky final
Dark Wellman bright sky
Dark Wellman dark sky blending process
Dark Wellman dark sky blending process
Dark Wellman dark sky final
Dark Wellman dark sky
Bright Wellman fantasy sky blending process
Bright Wellman fantasy sky blending process
Bright Wellman fantasy sky final
Bright Wellman fantasy sky

Takeaways

After blending with a basic vertical mask, I first tried inserting an object into an image with an irregular mask. That did not work well due to color mismatch and different fields of view.

I then tried blending just the sky, which still looked slightly irregular due to color differences and scene shadows. Finally, I used skies with closer shading and got better blends with the building.

I drew irregular masks by hand in Photoshop. Jagged mask edges became unnoticeable in the final output because the Gaussian stack blurred the mask boundaries.

My main takeaway is how much simple operations can improve and manipulate images. More advanced methods would likely do better, but I was happy with the results from this pipeline and found it very interesting how far Gaussian-based filtering can go.