|
|
|
|
|
|
|
import os |
|
from PIL import Image, ImageEnhance, ImageFilter |
|
from enum import Enum |
|
from segmentation import extract_person |
|
|
|
|
|
class Background(Enum): |
|
NATURE = os.path.join('background', 'spatial_sbs_2024-10-10_21-57-07-266Z.jpg') |
|
NEU = os.path.join('background', 'sbs_neu.jpg') |
|
GASTOWN = os.path.join('background', 'side_by_side_steam_clock.jpg') |
|
|
|
def get_background(self): |
|
return Image.open(self.value) |
|
|
|
|
|
|
|
class Disparity(Enum): |
|
CLOSE = 30 |
|
MED = 50 |
|
FAR = 100 |
|
|
|
|
|
|
|
def overlay_person(background, person, x_pos, y_pos): |
|
background = background.convert("RGBA") |
|
person = person.convert("RGBA") |
|
|
|
|
|
match_lighting_and_color(background, person) |
|
|
|
|
|
background.paste(person, (x_pos, y_pos), person) |
|
|
|
return background |
|
|
|
|
|
|
|
def scale_person(person, disparity): |
|
|
|
if disparity == Disparity.FAR: |
|
scaling_factor = 0.75 |
|
elif disparity == Disparity.MED: |
|
scaling_factor = 0.9 |
|
else: |
|
scaling_factor = 1 |
|
|
|
new_width = int(person.size[0] * scaling_factor) |
|
new_height = int(person.size[1] * scaling_factor) |
|
scaled_person = person.resize((new_width, new_height)) |
|
return scaled_person |
|
|
|
|
|
|
|
def match_lighting_and_color(background, person): |
|
|
|
brightness_factor = get_brightness_factor(background, person) |
|
person = ImageEnhance.Brightness(person).enhance(brightness_factor) |
|
|
|
|
|
contrast_factor = get_contrast_factor(background, person) |
|
person = ImageEnhance.Contrast(person).enhance(contrast_factor) |
|
|
|
return person |
|
|
|
|
|
|
|
def get_brightness_factor(background, person): |
|
|
|
background_avg_brightness = calculate_avg_brightness(background) |
|
person_avg_brightness = calculate_avg_brightness(person) |
|
|
|
|
|
return background_avg_brightness / person_avg_brightness |
|
|
|
|
|
|
|
def get_contrast_factor(background, person): |
|
|
|
background_avg_contrast = calculate_avg_contrast(background) |
|
person_avg_contrast = calculate_avg_contrast(person) |
|
|
|
|
|
return background_avg_contrast / person_avg_contrast |
|
|
|
|
|
def calculate_avg_brightness(image): |
|
grayscale_image = image.convert('L') |
|
pixels = list(grayscale_image.getdata()) |
|
return sum(pixels) / len(pixels) |
|
|
|
|
|
def calculate_avg_contrast(image): |
|
grayscale_image = image.convert('L') |
|
contrast_image = grayscale_image.filter(ImageFilter.FIND_EDGES) |
|
pixels = list(contrast_image.getdata()) |
|
return sum(pixels) / len(pixels) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def insert_person_in_pair(background: Background, person, disparity: Disparity): |
|
|
|
background_image = background.get_background() |
|
|
|
width, height = background_image.size |
|
left_image = background_image.crop((0, 0, width // 2, height)) |
|
right_image = background_image.crop((width // 2, 0, width, height)) |
|
person_height = person.size[1] |
|
|
|
|
|
|
|
y_pos = height - person_height |
|
if background == Background.NATURE: |
|
x_pos = 1750 |
|
if disparity == Disparity.MED: |
|
x_pos += 200 |
|
y_pos -= 25 |
|
elif disparity == Disparity.FAR: |
|
x_pos += 300 |
|
y_pos -= 200 |
|
elif background == Background.NEU: |
|
x_pos = 1500 |
|
if disparity == Disparity.MED: |
|
x_pos += 200 |
|
y_pos += 50 |
|
elif disparity == Disparity.FAR: |
|
x_pos += 300 |
|
y_pos += 100 |
|
else: |
|
x_pos = 350 |
|
if disparity == Disparity.MED: |
|
x_pos += 300 |
|
y_pos -= 25 |
|
elif disparity == Disparity.FAR: |
|
x_pos += 400 |
|
y_pos -= 50 |
|
|
|
|
|
person = scale_person(person, disparity) |
|
|
|
|
|
x_pos_right = x_pos - disparity.value |
|
|
|
|
|
left_with_person = overlay_person(left_image.copy(), person, x_pos, y_pos) |
|
right_with_person = overlay_person(right_image.copy(), person, x_pos_right, y_pos) |
|
|
|
return left_with_person, right_with_person |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|