Project 2: Fun with Filters and Frequencies!

NITYA SRI ADAPALA

Introduction

This project focusses on building the intuition needed for 2D convolutions and filtering and then learning how to use frequencies to sharpen images, combine two images into one and blend two images using multiresolution blending.


Finite Difference Operator


First, I showed the partial derivative in x and y of the cameraman image by convolving the image with finite difference operators D_x = [[1, -1]] and D_y = [[1],[-1]]. To compute the partial derivatives d_x and d_y, I used convolve2d from the scipy.signal library. Then, I computed and showed the gradient magnitude image using this formula: np.sqrt(d_x ** 2 + d_y ** 2). Essentially, I computed the square root of the sum of the squares of the partial derivatives. To turn this into an edge image, I binarized the gradient magnitude image by choosing an appropriate threshold of 0.33 and setting every value above the threshold to be 1 and every value below or equal to the threshold to be 0.

cameraman original image
Cameraman Original Image
partial derivative of cameraman along x
Partial derivative of x
partial derivative of cameraman along y
Partial derivative of y
gradient magnitude image of cameraman
Gradient Magnitude Image of Cameraman
binarized gradient magnitude image of cameraman
Binarized Gradient Magnitude Image of Cameraman

Derivative of Gaussian (DoG) Filter


I noticed that the results with just the finite difference operators D_x and D_y were quite noisy so I used a smoothing operator called the Gaussian filter. I created the Gaussian filter by first creating a 1D Gaussian Kernel using cv2.getGaussianKernel(ksize, sigma) with ksize = 10 and sigma = 2. Then, I took the outer product with its transpose to get a 2D gaussian kernel. I then created a blurred version of the original image by convolving it with this gaussian kernel. Once I have the blurred image, I repeat the procedure in the previous part with threshold = 0.055 to create the gradient magnitude image and the binarized gradient magnitude image.

cameraman blurred image
Cameraman Blurred Image
partial derivative of blurred cameraman along x
Partial derivative of x
partial derivative of blurred cameraman along y
Partial derivative of y
gradient magnitude image of blurred cameraman
Gradient Magnitude Image of Blurred Cameraman
binarized gradient magnitude image of blurred cameraman
Binarized Gradient Magnitude Image of Blurred Cameraman

I see the following differences:

To help me build intuition that convolutions are associative, I now do the same thing with a single convolution instead of two by creating a derivative of Gaussian filters. First, I convolve the Gaussian with D_x and D_y. Then, I display the resulting DoG filters as images. As can be seen, I verify that I get the same results as in the previous step, therefore proving that convolutions are associative.

cameraman blurred image
Cameraman Blurred Image
partial derivative of blurred cameraman along x in single convolution
Partial derivative of x
partial derivative of blurredcameraman along y in single convolution
Partial derivative of y
gradient magnitude image of blurred cameraman in a single convolution
Gradient Magnitude Image of Blurred Cameraman
in a Single Convolution
binarized gradient magnitude image of blurred cameraman in a single convolution
Binarized Gradient Magnitude Image of Blurred Cameraman
in a Single Convolution

Image "Sharpening"


In this part, we will derive the unsharp masking technique. The Gaussian filter is a low pass filter that retains only the low frequencies. Therefore, if we subtract the blurred version from the original image, we can get the high frequencies of the image. We combine this all into a single convolution operation which is called the unsharp mask filter. To construct this filter, I first created a 2D Gaussian kernel using kernel size 10 and sigma value 2 and convolved it with the original image to produce a blurry image that contains the low frequencies of the image. Then, I subtract the blurry image from the original image to produce an image that contains the high frequencies of the image. To create the sharpened image, I uses the following formula: original image + (alpha * high frequency image) where increasing alpha increases the number of high frequency images added to the original image, which makes the image sharper.

Taj Mahal
Taj Mahal Original Image
Blurred Taj Mahal
Blurred Taj Mahal
High Frequencies of Taj Mahal Image
High Frequency Image of Taj Mahal
Sharpened Taj Mahal with Alpha = 1.0
Sharpened Taj Mahal with Alpha = 1.0
Sharpened Taj Mahal with Alpha = 2.0
Sharpened Taj Mahal with Alpha = 2.0
Sharpened Taj Mahal with Alpha = 4.0
Sharpened Taj Mahal with Alpha = 4.0

Here is a sharp image that I blurred and then sharpened again:

Campanile
Campanile Original Image
Sharpened Campanile with Alpha = 1.0
Sharpened Campanile with Alpha = 1.0
Sharpened Campanile with Alpha = 2.0
Sharpened Campanile with Alpha = 2.0
Sharpened Campanile with Alpha = 4.0
Sharpened Campanile with Alpha = 4.0

Hybrid Images


The goal of this part of the assignment is to create hybrid images using the approach described in the SIGGRAPH 2006 paper by Oliva, Torralba, and Schyns. Hybrid images are static images that change in interpretation as a function of the viewing distance. The basic idea is that high frequency tends to dominate perception when it is available, but, at a distance, only the low frequency (smooth) part of the signal can be seen. By blending the high frequency portion of one image with the low-frequency portion of another, you get a hybrid image that leads to different interpretations at different distances.

Here are the sample images I used for debugging and the hybrid image produced from them:

Picture of Derek
Image of human Derek
Nutmeg the cat
Image of cat Nutmeg
Hybrid image of Derek and Nutmeg
Hybrid image of Derek and Nutmeg

In order to create this hybrid image, I wrote code to low-pass filter one image by using a Gaussian filter, high-pass filter the second image by subtracting the blurred image from the original image, and then averaged the two images to produce the final hybrid image. For a low-pass filter, Oliva et al. suggested using a standard 2D Gaussian filter. For a high-pass filter, they suggest using the impulse filter minus the Gaussian filter (which can be computed by subtracting the Gaussian-filtered image from the original). I chose the cutoff-frequency of each filter by doing some experimentation.

Here, I combine Nadal and Federer into a hybrid image. At closer distances, you see Nadal but at further distances you see Federer.

Picture of Federer
Image of Roger Federer
Picture of Nadal
Image of Rafael Nadal
Hybrid image of Federer and Nadal
Hybrid image of Federer and Nadal

My favorite result is this hybrid image of Nadal and Federer so I also illustrated the process through frequency analysis. I showed the log magnitude of the Fourier transform of the two input images, the filtered images, and the hybrid image using: plt.imshow(np.log(np.abs(np.fft.fftshift(np.fft.fft2(gray_image)))))

Frequency analysis of Federer original image
Frequency Analysis of Original Federer Image
Frequency analysis of Nadal original image
Frequency Analysis of Original Nadal Image
Frequency analysis of Federer filtered image
Frequency Analysis of Filtered Federer Image
Frequency analysis of Nadal filtered image
Frequency Analysis of Filtered Nadal Image
Frequency analysis of Hybrid image of Federer and Nadal
Frequency analysis of hybrid image of Federer and Nadal

Here is an example of a failure case. I tried to combine a koala and a tiger but it is quite difficult to see the tiger at close distances since the koala dominates the image. Maybe I could try using color to enhance the effect and instead of choosing a tiger, maybe I should've chosen something that is more similar in shape to a koala.

Picture of Koala
Image of Koala
Picture of tiger
Image of Tiger
Hybrid image of Koala and Tiger
Hybrid image of Koala and Tiger

Gaussian and Laplacian Stacks


The goal of this part of the assignment is to blend two images seamlessly using multi resolution blending as described in the 1983 paper by Burt and Adelson. An image spline is a smooth seam joining two image together by gently distorting them. Multiresolution blending computes a gentle seam between the two images seperately at each band of image frequencies, resulting in a much smoother seam. First, I need to create and visualize the Gaussian and Laplacian stacks and then using the stacks, I need to blend together images. Firstly, for this part I need to implement the Gaussian and Laplacian stacks, which are similar to pyramids but without the downsampling. In order to build the Gaussian stack, I use a for loop to iterate through each level and produce an image that is blurrier than the previous level using a 2D Gaussian filter. As a result, the higher the level, the more blurry the image is. In order to build the Laplacian stack, I use a for loop to iterate (levels - 1) times, each time producing an image that is equaivalent to subtracting the blurrier image at the next level from the image at the current level. The last level of the Laplacian stack is the same as the last level of the Gaussian stack. Constructing the Gaussian and Laplacian stacks will prepare me for the next step of Multi-resolution blending in the next section.

Picture of Apple
Image of Apple
Picture of Orange
Image of Orange
Picture of Gaussian Stack of Apple
Gaussian Stack of Apple
Picture of Laplacian Stack of Apple
Laplacian Stack of Apple
Picture of Gaussian Stack of Orange
Gaussian Stack of Orange
Picture of Laplacian Stack of Orange
Laplacian Stack of Orange

Multiresolution Blending


In this part, we will mainly focus on blending two images together. After constructing the Gaussian and Laplacian stacks for the two images, we need to construct the Gaussian stack for the mask which will help blur the seam between the two images. Then, in order to create the blended image, I use this formula: blended = (1 - gaussian_stack_mask) * laplacian_stack_apple + gaussian_stack_mask * laplacian_stack_orange. This creates a Laplacian stack for the hybrid image so then we need to add all the layers together to get the final blended image.

Here are the sample images I used for debugging:

Picture of Apple
Image of Apple
Picture of Orange
Image of Orange
Picture of Mask for Orapple
Regular Vertical Seam Mask
Gaussian stack of Mask
Gaussian Stack of Mask
Picture of Laplacian stack of Hybrid Image of Orange and Apple
Laplacian Stack of Hybrid Image Orapple
Orapple hybrid image
Orapple

Exploring my own examples of multiresolution blending


SUN + MOON

Picture of Sun
Image of Sun
Picture of Moon
Image of Moon
Picture of Gaussian Stack of Sun
Gaussian Stack of Sun
Picture of Laplacian Stack of Sun
Laplacian Stack of Sun
Picture of Gaussian Stack of Moon
Gaussian Stack of Moon
Picture of Laplacian Stack of Moon
Laplacian Stack of Moon
Picture of Blob mask
Regular Blob Mask
Gaussian stack of Blob Mask
Gaussian Stack of Blob Mask
Picture of Laplacian stack of Hybrid Image of Sun and Moon
Laplacian Stack of Hybrid Image Sun + Moon
Sun + Moon hybrid image
Sun + Moon

IRONMAN + CAPTAIN AMERICAN = CAPTAIN IRONMAN

Picture of IronMan
Image of IronMan
Picture of Captain America
Image of Captain America
Picture of Gaussian Stack of IronMan
Gaussian Stack of IronMan
Picture of Laplacian Stack of IronMan
Laplacian Stack of IronMan
Picture of Gaussian Stack of Captain America
Gaussian Stack of Cpatain America
Picture of Laplacian Stack of Captain America
Laplacian Stack of Captain America
Picture of Mask for Captain IronMan
Irregular Face Mask
Gaussian stack of Irregular Face Mask
Gaussian Stack of Irregular Face Mask
Picture of Laplacian stack of Hybrid Image of IronMan and Captain America
Laplacian Stack of Hybrid Image Captain IronMan
Captain IronMan hybrid image
Captain IronMan

ANGELINA JOLIE + ROBOT = JOBOT

Picture of Angelina Jolie
Image of Angelina Jolie
Picture of Robot
Image of Robot
Picture of Gaussian Stack of Jolie
Gaussian Stack of Angelina Jolie
Picture of Laplacian Stack of Jolie
Laplacian Stack of Angelina Jolie
Picture of Gaussian Stack of Robot
Gaussian Stack of Robot
Picture of Laplacian Stack of Robot
Laplacian Stack of Robot
Picture of Mask for Jobot
Regular Horizontal Seam Mask
Gaussian stack of Horizontal Seam Mask
Gaussian Stack of Horizontal Seam Mask
Picture of Laplacian stack of Hybrid Image of Jolie and Robot
Laplacian Stack of Hybrid Image Jobot
Jobot hybrid image
Jobot