File size: 3,997 Bytes
f3d0a26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# demo/visualizer.py
import numpy as np
import cv2
from typing import Optional

def draw_box_on_frame(
    frame: np.ndarray,   # [H, W, 3] uint8 RGB
    box: list,           # [x1, y1, x2, y2]
    color: tuple = (255, 255, 0),
    label: str = "",
    thickness: int = 2,
    dashed: bool = False
) -> np.ndarray:
    """Draw a single bounding box on a frame"""
    frame = frame.copy()
    x1, y1, x2, y2 = [int(v) for v in box]

    if dashed:
        # Draw dashed rectangle manually
        dash_len = 10
        gap_len  = 5
        pts = [
            ((x1, y1), (x2, y1)),  # top
            ((x2, y1), (x2, y2)),  # right
            ((x2, y2), (x1, y2)),  # bottom
            ((x1, y2), (x1, y1)),  # left
        ]
        for (px1, py1), (px2, py2) in pts:
            dx = px2 - px1
            dy = py2 - py1
            dist = max(abs(dx), abs(dy))
            if dist == 0:
                continue
            for i in range(0, dist, dash_len + gap_len):
                s = i / dist
                e = min(i + dash_len, dist) / dist
                sx = int(px1 + s * dx)
                sy = int(py1 + s * dy)
                ex = int(px1 + e * dx)
                ey = int(py1 + e * dy)
                cv2.line(frame, (sx, sy), (ex, ey), color, thickness)
    else:
        cv2.rectangle(frame, (x1, y1), (x2, y2), color, thickness)

    if label:
        cv2.putText(
            frame, label,
            (x1, max(y1 - 8, 12)),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.6, color, 2
        )

    return frame


def draw_trajectory_on_frame(
    frame: np.ndarray,
    boxes: np.ndarray,    # [T, 4] — full trajectory
    current_t: int,
    color: tuple = (255, 200, 0)
) -> np.ndarray:
    """
    Draw the motion path (center points) up to current frame.
    Gives a visual "trail" showing where the object came from.
    """
    frame = frame.copy()
    centers = np.stack([
        (boxes[:, 0] + boxes[:, 2]) / 2,
        (boxes[:, 1] + boxes[:, 3]) / 2
    ], axis=1).astype(int)

    # Draw path line
    for i in range(1, current_t + 1):
        alpha = i / (current_t + 1)  # fade older points
        c = tuple(int(v * alpha) for v in color)
        cv2.line(
            frame,
            tuple(centers[i-1]),
            tuple(centers[i]),
            c, 2
        )

    # Draw current center dot
    cv2.circle(frame, tuple(centers[current_t]), 5, color, -1)

    return frame


def create_comparison_strip(
    original: np.ndarray,   # [T, H, W, 3]
    result:   np.ndarray,   # [T, H, W, 3]
    pred_boxes: np.ndarray, # [T, 4]
    sample_ts: list = None  # which frames to show
) -> np.ndarray:
    """
    Creates a horizontal strip for visual comparison.
    Shows: Original | Result | Diff for N sampled frames.
    """
    T = len(original)
    if sample_ts is None:
        sample_ts = [0, T//4, T//2, 3*T//4, T-1]

    rows = []
    for t in sample_ts:
        orig_t = original[t].copy()
        res_t  = result[t].copy()

        # Draw box on result
        res_t = draw_box_on_frame(
            res_t, pred_boxes[t],
            color=(0, 255, 0),
            label=f"t={t}"
        )

        # Amplified diff
        diff_t = np.abs(
            orig_t.astype(np.int32) - result[t].astype(np.int32)
        )
        diff_t = (diff_t * 4).clip(0, 255).astype(np.uint8)

        # Add labels
        def add_label(img, text):
            img = img.copy()
            cv2.putText(img, text, (10, 25),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.7,
                        (255, 255, 255), 2)
            cv2.putText(img, text, (10, 25),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.7,
                        (0, 0, 0), 1)
            return img

        orig_t = add_label(orig_t, "Original")
        res_t  = add_label(res_t,  "Result")
        diff_t = add_label(diff_t, "Diff x4")

        row = np.concatenate([orig_t, res_t, diff_t], axis=1)
        rows.append(row)

    return np.concatenate(rows, axis=0)