LAB4 / src /trial_insert.py
nnibras's picture
Upload trial_insert.py
1db9c1a verified
import cv2
import numpy as np
def insert_person_V2(
left_image_path, right_image_path, person_image_path, depth="medium"
):
# Load left and right stereoscopic images
left_image = cv2.imread(left_image_path)
right_image = cv2.imread(right_image_path)
# Load the segmented person image with alpha channel (transparency)
person = cv2.imread(person_image_path, cv2.IMREAD_UNCHANGED)
# Define scaling and disparity values for each depth level
depth_settings = {
"close": {"scale": 1.2, "disparity": 15},
"medium": {"scale": 1.0, "disparity": 10},
"far": {"scale": 0.7, "disparity": 5},
}
scale_factor = depth_settings[depth]["scale"]
disparity = depth_settings[depth]["disparity"]
# Resize person image according to the scale factor
person_resized = cv2.resize(
person, None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_AREA
)
(ph, pw) = person_resized.shape[:2]
# Extract color and alpha channels from person image
person_rgb = person_resized[:, :, :3]
person_alpha = person_resized[:, :, 3] / 255.0 # Normalize alpha channel to [0, 1]
# Match brightness and contrast of the person to the background
person_rgb = match_brightness_contrast(left_image, person_rgb, person_alpha)
# Color match person to the background
person_rgb = match_color_tone(left_image, person_rgb, person_alpha)
# Create a blended version of the person with soft edges
person_blended = soft_edge_blending(person_rgb, person_alpha)
# Determine insertion position in the left image
x_offset, y_offset = 100, left_image.shape[0] - ph - 20
left_image[y_offset : y_offset + ph, x_offset : x_offset + pw] = blend_images(
left_image[y_offset : y_offset + ph, x_offset : x_offset + pw],
person_blended,
person_alpha,
)
# Create stereoscopic effect by shifting the person image in the right image
x_offset_right = x_offset + disparity
right_image[y_offset : y_offset + ph, x_offset_right : x_offset_right + pw] = (
blend_images(
right_image[y_offset : y_offset + ph, x_offset_right : x_offset_right + pw],
person_blended,
person_alpha,
)
)
return left_image, right_image
def match_brightness_contrast(background, person, alpha):
# Calculate the mean brightness of the background where the person will be placed
background_mean = np.mean(background, axis=(0, 1))
person_mean = np.mean(person, axis=(0, 1))
adjustment = background_mean / (person_mean + 1e-6)
return cv2.convertScaleAbs(person, alpha=adjustment[0], beta=adjustment[1])
def match_color_tone(background, person, alpha):
# Adjust color tone to match background
bg_mean, bg_std = cv2.meanStdDev(background)
person_mean, person_std = cv2.meanStdDev(person)
scale = (bg_std + 1e-6) / (person_std + 1e-6)
person = cv2.convertScaleAbs(
person, alpha=scale[0][0], beta=(bg_mean - person_mean)[0][0]
)
return person
def soft_edge_blending(person, alpha):
# Apply Gaussian blur to soften the edges for better blending
blurred_alpha = cv2.GaussianBlur(alpha, (15, 15), 0)
person = cv2.merge(
(
person[:, :, 0] * blurred_alpha,
person[:, :, 1] * blurred_alpha,
person[:, :, 2] * blurred_alpha,
)
)
return person
def blend_images(background, person, alpha):
# Blend person into background using the alpha mask
blended = (alpha[..., None] * person + (1 - alpha[..., None]) * background).astype(
np.uint8
)
return blended