by Ziran Zhou
In this project, I followed the instructions and the background introduction of the spec and explored how to use of convolution of finite different operators and a Gaussian filter to detect edges, also sharpening of images and how to use Gaussian and Laplacian stacks to blend images with masking.
I calculated the partial derivatives in both the x and y axes directions and use them as the finite difference operators to the cameraman image through convolution, and with the gradient magnitude which represents the edges's intnsities. I then binarized the gradient magnitude by applying a threshold by applying a threshold previously been fine-tuned to balance the noises supression and edge clarity and I received a gradient magnitude map and a binarized edge detection image.
1.1-edge_image.png
1.1-gradient_magnitude.png
There were noises observed in part 1.1 and Gaussian filter is used to smooth teh original image before calculating the gradient and the 2D Gaussian kernel uses a 1D kernel and its outer product together, capable of blurring and smoothing the image. I used this for convolution process in partial derivative computation in x and y axes directions and I computed the Derivatice of Gaussian (DoG) filters for those directions and combine the smoothing together reducing the noise captured.
1.2-smoothed_image.png
1.2-edge_X_image.png
1.2-edge_Y_image.png
There are many differences between the results from part 1.1 and part 1.2, specifically, in terms of noise reduction, the DoG approach substantially reduces the noises and the use of Gaussian filter smooths the image before differentiation and helps with removing high-frequency noise, which makes the edges smoother, clearer and more continuous, whereas that of the finite difference operator are noisier and more fragmented, so the approach of part 1.2 leads to fewer spurious edges that arises from noises, having higher precision and better at retaining of meaningful edges.
Also, we can compare the results from 1.2 and 1.1 to see the gradient magnitude and binarized results are similar, even with different implementations, those of 1.2 are as shown below:
1.2-gradient_magnitude.png
1.2-edge_image.png
I used Unsharp Masking Technique to sharpen a blurry image, by first applying a Gaussian filter smooth the image, then I isolated the High-Frequency edge details by subtracting the smoothed image from the original, i.e., removing the areas that are too smoothed, retaining sharp edges, and then I amplified these high-frequency sharp edge details which will be added back to the convolution operation.
2.1-taj_original_image.png
Like part 1.2, I used a Gaussian filter that acts as a lowpass filter to smooth the original image by averaging the pixel values and preserving low-frequency information while reducing the high-frequency details like noises and edges.
2.1-taj_smoothed_image.png
Then, I subtract the smoothed image from the original image to enhances the high-frequency edges and other sharp features by retaining the difference between the smoothed version and the original image.
2.1-taj_sharp_edges_image.png
I then combined the original smoothed image with the enhanced high intensity edges image, which created a scaled version of the sharpened result.
I did have to clip the image due to saving using skimage methods resulting in saved
image being rendered with grey coloring, and clipping help retains the value to 0~255.
2.1-taj_processed_image.png
Petra, Jordan
2.1-petra_original_image.png
2.1-petra_smoothed_image.png
2.1-petra_sharp_edges_image.png
2.1-petra_processed_image.png
Fanjingshan, China
2.1-fanjingshan_original_image.png
2.1-fanjingshan_smoothed_image.png
2.1-fanjingshan_sharp_edges_image.png
2.1-fanjingshan_processed_image.png
In this part, I followed the specifications and blends a low-frequency result of one image with the high-frequency of another image and then i created a low-pass filter using a 2D Gaussian filter like that of part 1.2 from the 1st image from the input, and a high-pass one from the 2nd subtracting its Gaussian filter.
For hybridization, I aligned the images first to ensure a consistent blending, and this is achieved
using the helper function align_images provided in the project spec,
(align_image_code.py), where an
interative window would pop up to
allow me select 2 points of alignment of each image aiming to blend together. After, I would
select the sigma values used for the Gaussian filter, which is referred to as the filter cutoff
frequencities, and I experimented with the value to find the values that achieved the optimal
result (to my interpretation).
2.2-Derek_aligned.png
2.2-Nutmeg_aligned.png
2.2-Derek_Nutmeg_blended_gray.png
I also used Fourier transoform on the images and the hybrid image were computed and visualized to analyze the frequency components for the Derek-Numeg-blending. It is noticeable that Fourier transform retains low frequencies for low-pass filtered image, and high for high-pass one.
2.2-Frequency_Analysis.png
Joker & Iracebeth
2.2-Joker_aligned.png
2.2-Iracebeth_aligned.png
2.2-Joker_Iracebeth_blended_gray.png
Rhaenyra Targaryen & Ru Paul
2.2-Rhaenyra_aligned.png
2.2-Rupaul_aligned.png
2.2-Rhaenyra_Rupaul_blended_gray.png
Following the instructions, I implemented the Gaussian and Laplacian stacks without downsampling as you would if using Pyramid method, i.e., the image dimensions were retained instead of changed at each level of the stack, and the Gaussian stack was created by successively applying a Gaussian filter with increasing standard deviation at each level. I also added in the improvement that the sigma is increased as the levels deepen, which makes the effect stronger with fewer levels needed. The Laplacian stack was created by subtracting consecutive levels of the Gaussian stack so that I can get the high-frequency details at each level.
I then applied these stacks to 2 images in the sample, i.e. apple & orange, and visualized the different levels of the effects of the Gaussian and the Laplacian stacks, and the results look similar to those of pyramid method.
2.3-gaussian_stack_apple.png
2.3-gaussian_stack_orange.png
2.3-laplacian_stack_apple.png
2.3-laplacian_stack_orange.png
Following the instructions, I implemented Multiresolution Blending to "seamlessly" combine to images using teh Gaussian and Laplacian stacks from part 2.3. I accomplished this by using a mask to control the blending region, which is cutsmoly designed, and for Orange-Apple-blending problem, vertical blending seam mask is used. The Gaussian stack of the mask was used to smooth the transition b/w the 2 images, creating a smooth "oraple" then used the Laplacian stack to capture the high-frequency details and edges from both images and allowed for much more natural reconstruction of the final blended image.
2.4-oraple.png
Later, I also created my own custom irregular mask, which I define as an Ellipse with a center distanced awar from the Top Left Corner of the image able to adjust for the length of major-axis and minor-axis and the its angle orientated. This mask will retain the details of the 1st image within the ellipse while retaining that of the 2nd image in the other region.
2.4-gaussian_stack_giraffe.png
2.4-gaussian_stack_orange.png
2.4-laplacian_stack_giraffe.png
2.4-laplacian_stack_seaturtle.png
2.4-turiraffle.png
2.4-gaussian_stack_deathstar.png
2.4-gaussian_stack_arrakis.png
2.4-laplacian_stackdeathstar.png
2.4-laplacian_stack_seaarrakis.png
2.4-deatharrakis.png
The ellipse works reasonably well for the Giraffe-SeaTurtle-blending problem, but needed much more adjustment for the DeathStar-Arrakis-blending problem since I only want to show the "eye" of death star and not other parts.
With the help of starter code, and the methods of Gaussian and Laplacian and Fourier, I was able to find many important results being asked, including the edges, sharpened images, aligned and blended images, and mask-blended images.
Here are the input images attached just in case the GitHub image upload leads to image deprecations.
cameraman.png
taj.jpg
petra.jpg
DerekPicture.jpg
nutmeg.png
heathjoker.jpg
iracebeth.jpg
rhaenyra.jpg
rupaul.jpeg
apple.jpeg
orange.jpeg
giraffe.jpeg
seaturtle.jpeg
deathstar.jpeg
arrakis.jpeg