Abhilash7 commited on
Commit
d985525
·
verified ·
1 Parent(s): 3b543bc

Create overlay.py

Browse files
Files changed (1) hide show
  1. overlay.py +52 -0
overlay.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+
4
+ def _read_png_rgba(path):
5
+ png = cv2.imread(path, cv2.IMREAD_UNCHANGED)
6
+ if png is None or png.shape[2] != 4:
7
+ raise ValueError("Hairstyle PNG must be RGBA with transparency.")
8
+ return png
9
+
10
+ def auto_align(png_rgba, mask, landmarks=None):
11
+ """Scale & position the hairstyle PNG to cover the mask area, using landmarks if available."""
12
+ mh, mw = mask.shape[:2]
13
+ ys, xs = np.where(mask > 0)
14
+ if len(xs) == 0 or len(ys) == 0:
15
+ return cv2.resize(png_rgba, (mw, mh))
16
+
17
+ x0, x1 = xs.min(), xs.max()
18
+ y0, y1 = ys.min(), ys.max()
19
+ tw, th = int((x1 - x0) * 1.2), int((y1 - y0) * 1.1) # Slightly larger for better coverage
20
+ tw = max(1, min(tw, mw))
21
+ th = max(1, min(th, mh))
22
+ aligned = cv2.resize(png_rgba, (tw, th))
23
+
24
+ canvas = np.zeros((mh, mw, 4), dtype=np.uint8)
25
+
26
+ # Position: Use landmarks if available, else center on mask
27
+ if landmarks and "forehead_anchor" in landmarks:
28
+ fx, fy = landmarks["forehead_anchor"]
29
+ y = max(0, fy - int(0.8 * th)) # Anchor near forehead, offset up for hair
30
+ x = max(0, fx - int(tw / 2))
31
+ else:
32
+ y = max(0, y0 - int(0.25 * th))
33
+ x = max(0, x0 - int(0.05 * tw))
34
+
35
+ y2 = min(mh, y + th)
36
+ x2 = min(mw, x + tw)
37
+ crop_h, crop_w = y2 - y, x2 - x
38
+ canvas[y:y2, x:x2] = aligned[:crop_h, :crop_w]
39
+ return canvas
40
+
41
+ def _alpha_blend(base_bgr, overlay_rgba):
42
+ bgr = base_bgr.copy()
43
+ alpha = overlay_rgba[:, :, 3:4] / 255.0
44
+ rgb = overlay_rgba[:, :, :3]
45
+ bgr = (alpha * rgb + (1 - alpha) * bgr).astype(np.uint8)
46
+ return bgr
47
+
48
+ def apply_hairstyle(img_bgr, style_path, mask, landmarks=None):
49
+ png = _read_png_rgba(style_path)
50
+ aligned = auto_align(png, mask, landmarks)
51
+ out = _alpha_blend(img_bgr, aligned)
52
+ return out