You are on page 1of 4

COMPUTER VISION

HOMEWORK – 1
Laplacian Blending:

We begin by dividing the two input images, the apple and the orange, into separate channels
using a mask. Next, we apply blending techniques to each channel individually. To enhance the
blending effect, we create a Gaussian pyramid for the mask and a Laplacian pyramid for the
images. These pyramids are then combined and downsized to generate the final blended
image. The fundamental idea is that in order to create pyramids and then seamlessly combine
two separate images into one, we must employ Gaussian (low pass) and Laplacian (high pass)
filters.

By utilizing the provided Apple, Orange, and Mask images and applying the algorithm, I have
obtained the blended image.

OUTPUT:

 After implementing the algorithm, I understood that in order to blend/combine images


they must have same dimensions in order to apply the algorithm and get the results. In
Most cases it performed well.

 Also, I have tried on some images with two different colors where the results are pretty
inconsistent in most cases. As colors in the image are completely different in each other.
Code used for implementation:
#install and import the libraries
import numpy as np
import scipy.signal as sig
from scipy import misc
import matplotlib.pyplot as plt
from scipy import ndimage
import cv2
import imageio
from google.colab.patches import cv2_imshow

# up-sampling the images


def upsample_image(image):
# Create a new image with twice the dimensions of the input image
image_upscale = np.zeros((2 * image.shape[0], 2 * image.shape[1]))

# Copy the pixels from the original image to alternate pixels in the new
image
image_upscale[::2, ::2] = image

# Bi-linear interpolation kernel


kernel = (1.0 / 256) * np.array(
[[1, 4, 6, 4, 1], [4, 16, 24, 16, 4], [6, 24, 36, 24, 6], [4, 16, 24,
16, 4], [1, 4, 6, 4, 1]])

# Convolve the up-sampled image with the kernel


return ndimage.filters.convolve(image_upscale, 4 * kernel,
mode='constant')

# down-sampling the image


def downsample_image(image):
# Down-sample the image by a factor of 2 using Gaussian blurring
kernel = (1.0 / 256) * np.array(
[[1, 4, 6, 4, 1], [4, 16, 24, 16, 4], [6, 24, 36, 24, 6], [4, 16, 24,
16, 4], [1, 4, 6, 4, 1]])
# Apply Gaussian blur to the image
image_downscale = ndimage.filters.convolve(image, kernel, mode='constant')
# Down-sample the blurred image by selecting every alternate pixel
return image_downscale[::2, ::2]

# Constructing image pyramids for the given images


def build_pyramids(image):

# Build Gaussian and Laplacian pyramids for the given image


G = [image] # Gaussian pyramid
L = [] # Laplacian pyramid

# Downsample the image


while image.shape[0] >= 2 and image.shape[1] >= 2:
image = downsample_image(image)
# Add the downsampled image to the Gaussian pyramid
G.append(image)
# Upsample the next level of the Gaussian pyramid
for i in range(len(G) - 1):
interpolated = upsample_image(G[i + 1])
# Calculate the Laplacian by subtracting the upsampled image from the
current level
L.append(G[i] - interpolated[:G[i].shape[0], :G[i].shape[1]])
return G[:-1], L

# Performing pyramid blending of two images using a mask


def pyramid_blending(A, B, mask):

# Build Gaussian and Laplacian pyramids for images A and B


[GA, LA] = build_pyramids(A)
[GB, LB] = build_pyramids(B)
[Gmask, LMask] = build_pyramids(mask)
blend = []
for i in range(len(LA)):
# Blend the Laplacian layers based on the mask
LS = Gmask[i] / 255 * LA[i] + (1 - Gmask[i] / 255) * LB[i]
blend.append(LS)
return blend

# Reconstruct the pyramids as well as upsampling and adding up with each level
def reconstruct_image(pyramid):
# Reconstruct the image from the Laplacian pyramid
rows, cols = pyramid[0].shape
res = np.zeros((rows, cols + cols // 2), dtype=np.double)
reversed_pyramid = pyramid[::-1]
stack = reversed_pyramid[0]
for i in range(1, len(reversed_pyramid)):
# Upsample the previous level and add it to the current level
stack_upsampled = upsample_image(stack)
stack_upsampled_cropped =
stack_upsampled[:reversed_pyramid[i].shape[0], :reversed_pyramid[i].shape[1]]
stack = stack_upsampled_cropped + reversed_pyramid[i]
return stack

# Perform color blending of two images based on a mask


def perform_color_blending(img1, img2, mask):

# Split the input images into their RGB channels


img1_r, img1_g, img1_b = cv2.split(img1)
img2_r, img2_g, img2_b = cv2.split(img2)

# Check if any image dimensions mismatch and throw value error


if mask.ndim == 2: # Grayscale mask
mask_r = mask_g = mask_b = mask
elif mask.ndim == 3: # Color mask
mask_r, mask_g, mask_b = cv2.split(mask)
else:
raise ValueError("Invalid mask dimensions.")

# Check dimensions
if img1_r.shape != img2_r.shape or img1_r.shape != mask_r.shape:
raise ValueError("Input image and mask dimensions do not match.")
# Perform pyramid blending on each color channel
R = reconstruct_image(pyramid_blending(img1_r, img2_r, mask))
G = reconstruct_image(pyramid_blending(img1_g, img2_g, mask))
B = reconstruct_image(pyramid_blending(img1_b, img2_b, mask))

# Merge the color channels back into an RGB image


output = cv2.merge((R, G, B))

# Save and display the output image


imageio.imsave("blended image.png", output)
img = cv2.imread("blended image.png")
cv2_imshow(img)

# Load input images and mask


apple = imageio.imread('apple.png')
orange = imageio.imread('orange.png')
mask = cv2.imread('mask.png', 0)

# Perform color blending and display the output


perform_color_blending(apple, orange, mask)

References:

 https://www.w3schools.com/python/
 https://docs.opencv.org/4.x/dc/dff/tutorial_py_pyramids.html
 http://persci.mit.edu/pub_pdfs/RCA84.pdf
 http://graphics.cs.cmu.edu/courses/15463/2005_fall/www/Lectures/
Pyramids.pdf

You might also like