File size: 2,312 Bytes
e7a5a81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import cv2
import numpy as np


def draw_landmarks(
    image: np.ndarray,
    landmarks: np.ndarray,
    color: tuple = (0, 255, 0),
    radius: int = 1
) -> np.ndarray:
    """Draw facial landmark points on a copy of the image."""
    out = image.copy()
    if landmarks is None:
        return out
    for (x, y) in landmarks.astype(int):
        if 0 <= x < image.shape[1] and 0 <= y < image.shape[0]:
            cv2.circle(out, (x, y), radius, color, -1)
    return out


def draw_bounding_boxes(
    image: np.ndarray,
    bboxes: list,
    color: tuple = (0, 255, 0),
    thickness: int = 2
) -> np.ndarray:
    """Draw bounding boxes on a copy of the image. Accepts (x1,y1,x2,y2) tuples."""
    out = image.copy()
    for bbox in bboxes:
        if hasattr(bbox, 'bbox'):
            # InsightFace face object
            x1, y1, x2, y2 = bbox.bbox.astype(int)
        else:
            x1, y1, x2, y2 = [int(v) for v in bbox]
        cv2.rectangle(out, (x1, y1), (x2, y2), color, thickness)
    return out


def draw_mask_overlay(
    image: np.ndarray,
    mask: np.ndarray,
    color: tuple = (0, 120, 255),
    alpha: float = 0.35
) -> np.ndarray:
    """Overlay a coloured semi-transparent mask on the image."""
    out = image.copy().astype(np.float32)
    overlay = np.zeros_like(image, dtype=np.float32)
    m = mask.astype(np.float32) / 255.0 if mask.max() > 1 else mask.astype(np.float32)
    overlay[:] = color[::-1]  # BGR
    mask_3 = np.stack([m] * 3, axis=-1)
    out = out * (1 - mask_3 * alpha) + overlay * mask_3 * alpha
    return np.clip(out, 0, 255).astype(np.uint8)


def draw_quality_metrics(
    image: np.ndarray,
    metrics: dict
) -> np.ndarray:
    """Draw quality metric text overlay on the image."""
    out = image.copy()
    lines = [
        f"Align: {metrics.get('alignment', 0):.1f}/100",
        f"Blend: {metrics.get('blend', 0):.1f}/100",
        f"dE:    {metrics.get('delta_e', 0):.2f}",
        f"Natural: {metrics.get('naturalness', 0):.1f}/100",
    ]
    y = 20
    for line in lines:
        cv2.putText(out, line, (10, y), cv2.FONT_HERSHEY_SIMPLEX,
                    0.5, (0, 0, 0), 2, cv2.LINE_AA)
        cv2.putText(out, line, (10, y), cv2.FONT_HERSHEY_SIMPLEX,
                    0.5, (255, 255, 255), 1, cv2.LINE_AA)
        y += 20
    return out