nnibras commited on
Commit
1db9c1a
·
verified ·
1 Parent(s): 6aab31e

Upload trial_insert.py

Browse files
Files changed (1) hide show
  1. src/trial_insert.py +101 -0
src/trial_insert.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+
4
+
5
+ def insert_person_V2(
6
+ left_image_path, right_image_path, person_image_path, depth="medium"
7
+ ):
8
+ # Load left and right stereoscopic images
9
+ left_image = cv2.imread(left_image_path)
10
+ right_image = cv2.imread(right_image_path)
11
+
12
+ # Load the segmented person image with alpha channel (transparency)
13
+ person = cv2.imread(person_image_path, cv2.IMREAD_UNCHANGED)
14
+
15
+ # Define scaling and disparity values for each depth level
16
+ depth_settings = {
17
+ "close": {"scale": 1.2, "disparity": 15},
18
+ "medium": {"scale": 1.0, "disparity": 10},
19
+ "far": {"scale": 0.7, "disparity": 5},
20
+ }
21
+ scale_factor = depth_settings[depth]["scale"]
22
+ disparity = depth_settings[depth]["disparity"]
23
+
24
+ # Resize person image according to the scale factor
25
+ person_resized = cv2.resize(
26
+ person, None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_AREA
27
+ )
28
+ (ph, pw) = person_resized.shape[:2]
29
+
30
+ # Extract color and alpha channels from person image
31
+ person_rgb = person_resized[:, :, :3]
32
+ person_alpha = person_resized[:, :, 3] / 255.0 # Normalize alpha channel to [0, 1]
33
+
34
+ # Match brightness and contrast of the person to the background
35
+ person_rgb = match_brightness_contrast(left_image, person_rgb, person_alpha)
36
+
37
+ # Color match person to the background
38
+ person_rgb = match_color_tone(left_image, person_rgb, person_alpha)
39
+
40
+ # Create a blended version of the person with soft edges
41
+ person_blended = soft_edge_blending(person_rgb, person_alpha)
42
+
43
+ # Determine insertion position in the left image
44
+ x_offset, y_offset = 100, left_image.shape[0] - ph - 20
45
+ left_image[y_offset : y_offset + ph, x_offset : x_offset + pw] = blend_images(
46
+ left_image[y_offset : y_offset + ph, x_offset : x_offset + pw],
47
+ person_blended,
48
+ person_alpha,
49
+ )
50
+
51
+ # Create stereoscopic effect by shifting the person image in the right image
52
+ x_offset_right = x_offset + disparity
53
+ right_image[y_offset : y_offset + ph, x_offset_right : x_offset_right + pw] = (
54
+ blend_images(
55
+ right_image[y_offset : y_offset + ph, x_offset_right : x_offset_right + pw],
56
+ person_blended,
57
+ person_alpha,
58
+ )
59
+ )
60
+
61
+ return left_image, right_image
62
+
63
+
64
+ def match_brightness_contrast(background, person, alpha):
65
+ # Calculate the mean brightness of the background where the person will be placed
66
+ background_mean = np.mean(background, axis=(0, 1))
67
+ person_mean = np.mean(person, axis=(0, 1))
68
+ adjustment = background_mean / (person_mean + 1e-6)
69
+ return cv2.convertScaleAbs(person, alpha=adjustment[0], beta=adjustment[1])
70
+
71
+
72
+ def match_color_tone(background, person, alpha):
73
+ # Adjust color tone to match background
74
+ bg_mean, bg_std = cv2.meanStdDev(background)
75
+ person_mean, person_std = cv2.meanStdDev(person)
76
+ scale = (bg_std + 1e-6) / (person_std + 1e-6)
77
+ person = cv2.convertScaleAbs(
78
+ person, alpha=scale[0][0], beta=(bg_mean - person_mean)[0][0]
79
+ )
80
+ return person
81
+
82
+
83
+ def soft_edge_blending(person, alpha):
84
+ # Apply Gaussian blur to soften the edges for better blending
85
+ blurred_alpha = cv2.GaussianBlur(alpha, (15, 15), 0)
86
+ person = cv2.merge(
87
+ (
88
+ person[:, :, 0] * blurred_alpha,
89
+ person[:, :, 1] * blurred_alpha,
90
+ person[:, :, 2] * blurred_alpha,
91
+ )
92
+ )
93
+ return person
94
+
95
+
96
+ def blend_images(background, person, alpha):
97
+ # Blend person into background using the alpha mask
98
+ blended = (alpha[..., None] * person + (1 - alpha[..., None]) * background).astype(
99
+ np.uint8
100
+ )
101
+ return blended