Part 1.1 - Warmup
To sharpen images, I used the unsharp masking technique where Sharpened image = f + α(f − f * g).
f * g is the image convoluted with a gaussian filter using some sigma value. I used an α = 4 and sigma = 0.2
Before sharpening
|
After sharpening
|
Part 1.2 - Hybrid Images
Overview
To create hybrid images, I combined one image consisting of its low frequencies with another image consisting of its high frequencies. This method hybradizes an image because at a distance, only the low frequencies are perceived (showing image 1), and up close, the high frequencies are seen (image 2). For my favorite image (hotdog-dachshund), I used a gaussian filter with a sigma value of 3 to create a low pass filter of my first image. For the high pass filter, I used a sigma value of 3, and just subtracted from image 2 its low pass filter. Then I add the low frequency and high frequency images together.
Favorite - Hot dog and Dachshund
Hot dog
|
Dachshund
|
Hybrid
|
Frequency analysis of Favorite images
Hot dog original image
|
Dachshund low frequency
|
Hot dog high pass
|
Dachshund low pass
|
Hybrid
|
More Hybrids
The Rock
|
John Cena
|
Hybrid
|
Happy face
|
Sad face
|
Hybrid
|
Failed attempts
Fox
|
Wolf
|
Hybrid
|
The last set of images did not align very well since there are some differences between the skeletal structures in the head (the nose of the wolf is much longer than the fox's), so even though the eyes are aligned, the rest of the head did not hybridize well.
Part 1.3 - Gaussian and Laplacian Stacks
Overview
To create the gaussian stacks, I recursively apply the gaussian filter, starting with sigma = 1, at each level of the stack, and double the sigma at each layer without downsizing the images to create a blurring effect. I created the laplacian stack by taking the difference between the current and previous layers of the gaussian stack. I also used 4 layers instead of 5, since for my favorite hybrid image, once it went to 5 layers the image was so blurry that you couldn't see anything.
Gaussian and Laplacian stack for Lincoln and Gala painting
Gaussian Layer 1
|
Gaussian Layer 2
|
Gaussian Layer 3
|
Gaussian Layer 4
|
Laplacian Lincoln Layer 1
|
Laplacian Lincoln Layer 2
|
Laplacian Lincoln Layer 3
|
Laplacian Lincoln Layer 4
|
Gaussian and Laplacian stack for Hotdog-Dachshund Hybrid
Gaussian Layer 1
|
Gaussian Layer 2
|
Gaussian Layer 3
|
Gaussian Layer 4
|
Laplacian Layer 1
|
Laplacian Layer 2
|
Laplacian Layer 3
|
Laplacian Layer 4
|
Part 1.4 - Multiresolution Blending
Overview
This goal of this section was to blend together two images by creating Laplacian stacks for both input images, and a Gaussian stack of the mask. For a regular blend, such as the Apple and Orange example from the paper, the mask is of the same size as the aligned images, with half of the matrix filled with 1's and the other half 0's. One of the images will appear where the 1's are while the other image appears where the 0's are. By applying a Gaussian stack of the mask, the blending becomes smoother. To combine the images, at each layer we weight each Laplacian layer with the corresponding Gaussian layer and the results like so: LS = GR*LA + (1-GR)*LB. "LS" is the combined layers, "GR" is the Gaussian mask layer, and "LA" and "LB" are the Laplacian layers for image A and B respectively. The final image is created by summing up the LS's obtained at each layer.
Split Mask
Apple
|
Orange
|
OrApple
|
Oreo
|
Chocolate chip cookie
|
Chocolate chip oreo
|
For the irregular mask, I did the same calculations as the split mask (half 1's and 0's), except I provided my own mask with the 1's and 0's at the coordinates I wanted the images to show up.
Irregular Mask
Hand
|
Eye
|
Mask for eye
|
Hand-Eye
|
Part 2 - Gradient Domain Fusion
Description
Part 2 of the project explores gradient-domain processing using Poisson Blending to blend objects/textures from a source image to a target image. This insight is that gradients of an image are more noticeable to people than the overall intensity of the image, so the goal becomes finding values for the target pixels that maximally preserve the gradient of the source region without changing the pixels in the background region. We use least squares to solve for new intensity values "v" to solve the blending constraint: .
That is, we want to find values "v" that minimize the gradient differences within the source image, and for pixels on the boundary of the source image, we want to minimize the gradient differences between the result and the target and the source image. This allows for a much smoother seem, while stil preserving the relationship between pixel intensities of the source image. The pixels lying outside of the source image boundary just inherit the intensity of the target image, so the background is left untouched.
Part 2.1 - Toy Problem
Overview
In the toy problem, we try to solve the constraints that the x gradients of the target should match the x gradients of the source (toy image), the y gradients of the target should match the y gradients of the source, and the top left corners of the two images should be the same color. We use least squares to solve for values "v" of the reconstructed image. The output comes out to resemble the source image quite closely, since we try to match gradients (preserve the image content) and intensity of the first pixel (preserves the overall intensity of the image).
Original Image
|
Reconstructed Image
|
Part 2.2 - Poisson Blending
Overview
Similarly to the toy problem, I used the previously mentioned equation to find values "v" that minimized gradients, but in this case I tried to minimize gradients in the 4 NSEW directions. And since these are color images, I just computed least squares on all the color channels of the source and target, and then stacked the results to form the final picture. I supplied my own source and mask images using similar techniques to the irregular mask for 1.4. Below, I've shown my favorite blending of a bathtub and a shark. For comparison, I've also shown a naive copy-paste of the source pixels onto the target pixels. In the naive case, the seam is very apparent since we do nothing to match the gradients, and the intensity of both images are unaltered. However, with poisson blending, we minimize the gradient between the blended image and target image, and we also try to preserve the gradient within the source image. This causes the overall intensity of the source to match with the target, so the water from the shark image matches more with the water in the bathtub, and the color of the shark is lightened to reflect the new water image.
Favorite Blending Result
Bathtub Target Image
|
Shark Source Image
|
Source Pixels Copied onto Target
|
Poisson Blending of Source and Target
|
Other Blending Results
Snowy Mountain Target Image
|
Penguin Source Image
|
Poisson Blend
|
Rabbit Target Image
|
Party Hat Source Image
|
Poisson Blend
|
Mountain Target Image
|
Nicholas Cage Source Image
|
Poisson Blend
|
After computing least squares, I tried to normalize the result vector to be within values of (0, 255). This is because after computing least squares, the values might lie outside of this range, causing some awkward coloring (like the below failed image).
Failed Attempt
Desert Target Image
|
Island Source Image
|
Poisson Blend
|
There were a couple of issues that made the poisson blending of the desert and the island a little difficult. One was that the source image has a very irregular shape, so a naive mask that just surrounds the overall island didn't work very well since it captured clouds in between the trees that transferred onto the sand on the desert. Another was that some areas of the source image were overly dark or overly bright, causing some irregular coloration.
Poisson Blending vs Laplacian Blending
Hand Original
|
Eye Original
|
Mask for eye
|
Source pixels copied over
|
Laplacian Pyramid Blend
|
Poisson Blend
|
Here, we have 3 different blending techniques used on the Hand-Eye example from part 1.4. The Laplacian blend was done in grayscale, but it still provides a good comparison. While the Laplacian blend did blend the two images together without a noticeable seam, there are still some differences between the skin color on the hand and on the eye, as well as some textural differences. Meanwhile, the Poisson blend did a much better job in matching the skin color and textural differences between the eye and the hand (albeit there's some bright blue pixels where the highlight on the eye picture is). This shows that when it comes to overall blending of colors and textures, the Poisson works better than the Laplacian. However, if we were just trying to preserve more of the textures of the source, and just blending the seams of the two images, the Laplacian seems to do a better job of that.
Important Things Learned
The most important thing I learned from this project are the mathematical theories behind each blending technique, as well as some of the general assumptions about image perception that we leverage to develop these blending techniques.