omar-ah commited on
Commit
4e8b763
·
verified ·
1 Parent(s): 99c5702

Upload vil_tracker/evaluation/evaluate.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. vil_tracker/evaluation/evaluate.py +139 -0
vil_tracker/evaluation/evaluate.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Benchmark evaluator for tracking datasets.
3
+
4
+ Supports:
5
+ - LaSOT: Large-scale Single Object Tracking
6
+ - UAV123: UAV tracking at 123 fps
7
+ - DTB70: Drone Tracking Benchmark
8
+ - VisDrone-SOT: Vision meets Drone SOT
9
+
10
+ Metrics: AUC (Success), Precision, Normalized Precision
11
+ """
12
+
13
+ import os
14
+ import json
15
+ import numpy as np
16
+ from collections import defaultdict
17
+
18
+
19
+ def compute_iou(box_a, box_b):
20
+ """Compute IoU between two boxes in [x, y, w, h] format."""
21
+ xa1, ya1 = box_a[0], box_a[1]
22
+ xa2, ya2 = xa1 + box_a[2], ya1 + box_a[3]
23
+ xb1, yb1 = box_b[0], box_b[1]
24
+ xb2, yb2 = xb1 + box_b[2], yb1 + box_b[3]
25
+
26
+ inter_x1 = max(xa1, xb1)
27
+ inter_y1 = max(ya1, yb1)
28
+ inter_x2 = min(xa2, xb2)
29
+ inter_y2 = min(ya2, yb2)
30
+
31
+ inter_area = max(0, inter_x2 - inter_x1) * max(0, inter_y2 - inter_y1)
32
+ area_a = box_a[2] * box_a[3]
33
+ area_b = box_b[2] * box_b[3]
34
+ union_area = area_a + area_b - inter_area
35
+
36
+ return inter_area / max(union_area, 1e-6)
37
+
38
+
39
+ def compute_center_distance(box_a, box_b):
40
+ """Compute center distance between two boxes in [x, y, w, h] format."""
41
+ ca = np.array([box_a[0] + box_a[2] / 2, box_a[1] + box_a[3] / 2])
42
+ cb = np.array([box_b[0] + box_b[2] / 2, box_b[1] + box_b[3] / 2])
43
+ return np.linalg.norm(ca - cb)
44
+
45
+
46
+ def compute_success_curve(ious, thresholds=None):
47
+ """Compute success curve (fraction of frames with IoU > threshold)."""
48
+ if thresholds is None:
49
+ thresholds = np.arange(0, 1.05, 0.05)
50
+
51
+ ious = np.array(ious)
52
+ success = np.array([np.mean(ious >= t) for t in thresholds])
53
+ return thresholds, success
54
+
55
+
56
+ def compute_auc(ious):
57
+ """Compute AUC from IoU values."""
58
+ thresholds, success = compute_success_curve(ious)
59
+ return np.trapz(success, thresholds) / (thresholds[-1] - thresholds[0])
60
+
61
+
62
+ class BenchmarkEvaluator:
63
+ """Evaluate tracker on standard benchmarks."""
64
+
65
+ def __init__(self, tracker, device='cuda'):
66
+ self.tracker = tracker
67
+ self.device = device
68
+
69
+ def evaluate_sequence(self, frames, gt_boxes):
70
+ """Evaluate on a single sequence.
71
+
72
+ Args:
73
+ frames: list of (H, W, 3) numpy arrays
74
+ gt_boxes: list of [x, y, w, h] ground truth boxes
75
+ Returns:
76
+ dict with per-frame IoUs and metrics
77
+ """
78
+ # Initialize with first frame
79
+ self.tracker.initialize(frames[0], gt_boxes[0])
80
+
81
+ pred_boxes = [gt_boxes[0]] # First frame is given
82
+ ious = [1.0]
83
+
84
+ for i in range(1, len(frames)):
85
+ pred_box = self.tracker.track(frames[i])
86
+ pred_boxes.append(pred_box)
87
+
88
+ if gt_boxes[i] is not None and gt_boxes[i][2] > 0 and gt_boxes[i][3] > 0:
89
+ iou = compute_iou(pred_box, gt_boxes[i])
90
+ ious.append(iou)
91
+ else:
92
+ ious.append(0.0)
93
+
94
+ auc = compute_auc(ious)
95
+
96
+ return {
97
+ 'pred_boxes': pred_boxes,
98
+ 'ious': ious,
99
+ 'auc': auc,
100
+ 'mean_iou': np.mean(ious),
101
+ }
102
+
103
+ def evaluate_dataset(self, dataset_path, dataset_type='lasot'):
104
+ """Evaluate on a full dataset.
105
+
106
+ Args:
107
+ dataset_path: path to dataset root
108
+ dataset_type: 'lasot', 'uav123', 'dtb70', or 'visdrone'
109
+ Returns:
110
+ dict with overall metrics and per-sequence results
111
+ """
112
+ sequences = self._load_dataset(dataset_path, dataset_type)
113
+
114
+ results = {}
115
+ all_ious = []
116
+
117
+ for seq_name, (frames, gt_boxes) in sequences.items():
118
+ print(f"Evaluating {seq_name}...")
119
+ seq_result = self.evaluate_sequence(frames, gt_boxes)
120
+ results[seq_name] = seq_result
121
+ all_ious.extend(seq_result['ious'])
122
+
123
+ overall_auc = compute_auc(all_ious)
124
+ per_seq_auc = {name: r['auc'] for name, r in results.items()}
125
+ mean_seq_auc = np.mean(list(per_seq_auc.values())) if per_seq_auc else 0.0
126
+
127
+ return {
128
+ 'overall_auc': overall_auc,
129
+ 'mean_seq_auc': mean_seq_auc,
130
+ 'per_sequence': per_seq_auc,
131
+ 'num_sequences': len(sequences),
132
+ 'num_frames': len(all_ious),
133
+ }
134
+
135
+ def _load_dataset(self, dataset_path, dataset_type):
136
+ """Load dataset sequences. Returns dict of {name: (frames, gt_boxes)}."""
137
+ # Placeholder - real implementation would load actual dataset files
138
+ print(f"Loading {dataset_type} from {dataset_path}")
139
+ return {}