PrashanthB461 commited on
Commit
15feb42
·
verified ·
1 Parent(s): 1741c1d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -47
app.py CHANGED
@@ -40,20 +40,48 @@ FFMPEG_AVAILABLE = check_ffmpeg()
40
 
41
  # ========================== # ByteTrack Implementation # ==========================
42
  class BYTETracker:
43
- def __init__(self, track_thresh=0.3, track_buffer=90, match_thresh=0.4, frame_rate=30):
44
  self.track_thresh = track_thresh
45
  self.track_buffer = track_buffer
46
- self.match_thresh = match_thresh # Lowered to 0.4 to improve tracking sensitivity
47
  self.frame_rate = frame_rate
48
  self.next_id = 1
49
  self.tracks = {}
50
  self.worker_history = {}
51
  self.last_positions = {}
 
52
 
53
  def update(self, dets, scores, cls):
54
  tracks = []
55
  current_time = time.time()
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  for i, (det, score, cl) in enumerate(zip(dets, scores, cls)):
58
  if score < self.track_thresh:
59
  continue
@@ -63,10 +91,8 @@ class BYTETracker:
63
  best_iou = 0
64
  best_track_id = None
65
 
 
66
  for track_id, track_info in self.tracks.items():
67
- if current_time - track_info['last_seen'] > self.track_buffer / self.frame_rate:
68
- continue
69
-
70
  tx, ty, tw, th = track_info['bbox']
71
  iou = self._calculate_iou([x, y, w, h], [tx, ty, tw, th])
72
 
@@ -94,54 +120,65 @@ class BYTETracker:
94
  'cls': cl
95
  })
96
  else:
97
- same_worker = False
98
- for worker_id, last_pos in self.last_positions.items():
99
- if self._is_same_worker([x, y], last_pos):
100
- self.tracks[worker_id] = {
 
101
  'bbox': [x, y, w, h],
102
  'score': score,
103
  'cls': cl,
104
  'last_seen': current_time
105
  }
 
 
106
  tracks.append({
107
- 'id': worker_id,
108
  'bbox': [x, y, w, h],
109
  'score': score,
110
  'cls': cl
111
  })
112
- same_worker = True
 
113
  break
114
 
115
- if not same_worker:
116
- self.tracks[self.next_id] = {
117
- 'bbox': [x, y, w, h],
118
- 'score': score,
119
- 'cls': cl,
120
- 'last_seen': current_time
121
- }
122
- self.worker_history[self.next_id] = [[x, y]]
123
- self.last_positions[self.next_id] = [x, y]
124
- tracks.append({
125
- 'id': self.next_id,
126
- 'bbox': [x, y, w, h],
127
- 'score': score,
128
- 'cls': cl
129
- })
130
- self.next_id += 1
131
-
132
- current_time = time.time()
133
- stale_ids = []
134
- for track_id, track_info in self.tracks.items():
135
- if current_time - track_info['last_seen'] > self.track_buffer / self.frame_rate:
136
- stale_ids.append(track_id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
- for track_id in stale_ids:
139
- del self.tracks[track_id]
140
- if track_id in self.worker_history:
141
- del self.worker_history[track_id]
142
- if track_id in self.last_positions:
143
- del self.last_positions[track_id]
144
-
145
  return tracks
146
 
147
  def _calculate_iou(self, box1, box2):
@@ -159,7 +196,7 @@ class BYTETracker:
159
  iou = intersection_area / (box1_area + box2_area - intersection_area)
160
  return iou
161
 
162
- def _is_same_worker(self, pos1, pos2, threshold=100): # Reduced threshold for 384x384 frames
163
  x1, y1 = pos1
164
  x2, y2 = pos2
165
  distance = np.sqrt((x1 - x2)**2 + (y1 - y2)**2)
@@ -197,7 +234,7 @@ CONFIG = {
197
  "domain": "login"
198
  },
199
  "PUBLIC_URL_BASE": "https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo2/resolve/main/static/output/",
200
- "CONFIDENCE_THRESHOLDS": { # Lowered thresholds to improve detection
201
  "no_helmet": 0.4,
202
  "no_harness": 0.25,
203
  "unsafe_posture": 0.25,
@@ -206,16 +243,16 @@ CONFIG = {
206
  },
207
  "MIN_VIOLATION_FRAMES": 1,
208
  "VIOLATION_COOLDOWN": 30.0,
209
- "WORKER_TRACKING_DURATION": 30.0,
210
  "MAX_PROCESSING_TIME": 60,
211
  "FRAME_SKIP": 1,
212
  "BATCH_SIZE": 4,
213
  "PARALLEL_WORKERS": max(1, cpu_count() - 1),
214
- "TRACK_BUFFER": 90,
215
  "TRACK_THRESH": 0.3,
216
- "MATCH_THRESH": 0.4,
217
  "SNAPSHOT_QUALITY": 95,
218
- "MAX_WORKER_DISTANCE": 100, # Adjusted to match BYTETracker threshold
219
  "TARGET_RESOLUTION": (384, 384)
220
  }
221
 
@@ -553,7 +590,7 @@ def process_video(video_data, temp_dir):
553
  frame_skip = CONFIG["FRAME_SKIP"]
554
  processed_frames = 0
555
  last_yield_time = start_time
556
- worker_counter = 1 # For assigning unique worker IDs
557
 
558
  while processed_frames < total_frames:
559
  batch_frames = []
 
40
 
41
  # ========================== # ByteTrack Implementation # ==========================
42
  class BYTETracker:
43
+ def __init__(self, track_thresh=0.3, track_buffer=90, match_thresh=0.5, frame_rate=30):
44
  self.track_thresh = track_thresh
45
  self.track_buffer = track_buffer
46
+ self.match_thresh = match_thresh # Increased to 0.5 for better matching
47
  self.frame_rate = frame_rate
48
  self.next_id = 1
49
  self.tracks = {}
50
  self.worker_history = {}
51
  self.last_positions = {}
52
+ self.recently_removed = {} # Store recently removed tracks for re-identification
53
 
54
  def update(self, dets, scores, cls):
55
  tracks = []
56
  current_time = time.time()
57
 
58
+ # Prune stale tracks
59
+ stale_ids = []
60
+ for track_id, track_info in self.tracks.items():
61
+ if current_time - track_info['last_seen'] > self.track_buffer / self.frame_rate:
62
+ stale_ids.append(track_id)
63
+
64
+ for track_id in stale_ids:
65
+ # Store recently removed tracks for re-identification (for 1 second)
66
+ self.recently_removed[track_id] = {
67
+ 'bbox': self.tracks[track_id]['bbox'],
68
+ 'last_seen': current_time,
69
+ 'last_position': self.last_positions.get(track_id, [0, 0])
70
+ }
71
+ del self.tracks[track_id]
72
+ if track_id in self.worker_history:
73
+ del self.worker_history[track_id]
74
+ if track_id in self.last_positions:
75
+ del self.last_positions[track_id]
76
+
77
+ # Clean up recently_removed tracks older than 1 second
78
+ to_remove = []
79
+ for track_id, info in self.recently_removed.items():
80
+ if current_time - info['last_seen'] > 1.0:
81
+ to_remove.append(track_id)
82
+ for track_id in to_remove:
83
+ del self.recently_removed[track_id]
84
+
85
  for i, (det, score, cl) in enumerate(zip(dets, scores, cls)):
86
  if score < self.track_thresh:
87
  continue
 
91
  best_iou = 0
92
  best_track_id = None
93
 
94
+ # Try to match with active tracks
95
  for track_id, track_info in self.tracks.items():
 
 
 
96
  tx, ty, tw, th = track_info['bbox']
97
  iou = self._calculate_iou([x, y, w, h], [tx, ty, tw, th])
98
 
 
120
  'cls': cl
121
  })
122
  else:
123
+ # Try to re-identify with recently removed tracks
124
+ reidentified = False
125
+ for track_id, info in self.recently_removed.items():
126
+ if self._is_same_worker([x, y], info['last_position'], threshold=150): # Increased threshold
127
+ self.tracks[track_id] = {
128
  'bbox': [x, y, w, h],
129
  'score': score,
130
  'cls': cl,
131
  'last_seen': current_time
132
  }
133
+ self.worker_history[track_id] = [[x, y]]
134
+ self.last_positions[track_id] = [x, y]
135
  tracks.append({
136
+ 'id': track_id,
137
  'bbox': [x, y, w, h],
138
  'score': score,
139
  'cls': cl
140
  })
141
+ reidentified = True
142
+ del self.recently_removed[track_id]
143
  break
144
 
145
+ if not reidentified:
146
+ # Check if it matches an existing worker by position
147
+ same_worker = False
148
+ for worker_id, last_pos in self.last_positions.items():
149
+ if self._is_same_worker([x, y], last_pos, threshold=150): # Increased threshold
150
+ self.tracks[worker_id] = {
151
+ 'bbox': [x, y, w, h],
152
+ 'score': score,
153
+ 'cls': cl,
154
+ 'last_seen': current_time
155
+ }
156
+ tracks.append({
157
+ 'id': worker_id,
158
+ 'bbox': [x, y, w, h],
159
+ 'score': score,
160
+ 'cls': cl
161
+ })
162
+ same_worker = True
163
+ break
164
+
165
+ if not same_worker:
166
+ self.tracks[self.next_id] = {
167
+ 'bbox': [x, y, w, h],
168
+ 'score': score,
169
+ 'cls': cl,
170
+ 'last_seen': current_time
171
+ }
172
+ self.worker_history[self.next_id] = [[x, y]]
173
+ self.last_positions[self.next_id] = [x, y]
174
+ tracks.append({
175
+ 'id': self.next_id,
176
+ 'bbox': [x, y, w, h],
177
+ 'score': score,
178
+ 'cls': cl
179
+ })
180
+ self.next_id += 1
181
 
 
 
 
 
 
 
 
182
  return tracks
183
 
184
  def _calculate_iou(self, box1, box2):
 
196
  iou = intersection_area / (box1_area + box2_area - intersection_area)
197
  return iou
198
 
199
+ def _is_same_worker(self, pos1, pos2, threshold=150): # Increased threshold to 150
200
  x1, y1 = pos1
201
  x2, y2 = pos2
202
  distance = np.sqrt((x1 - x2)**2 + (y1 - y2)**2)
 
234
  "domain": "login"
235
  },
236
  "PUBLIC_URL_BASE": "https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo2/resolve/main/static/output/",
237
+ "CONFIDENCE_THRESHOLDS": {
238
  "no_helmet": 0.4,
239
  "no_harness": 0.25,
240
  "unsafe_posture": 0.25,
 
243
  },
244
  "MIN_VIOLATION_FRAMES": 1,
245
  "VIOLATION_COOLDOWN": 30.0,
246
+ "WORKER_TRACKING_DURATION": 5.0, # Reverted to 5.0 seconds
247
  "MAX_PROCESSING_TIME": 60,
248
  "FRAME_SKIP": 1,
249
  "BATCH_SIZE": 4,
250
  "PARALLEL_WORKERS": max(1, cpu_count() - 1),
251
+ "TRACK_BUFFER": 150, # 5.0 seconds at 30 fps
252
  "TRACK_THRESH": 0.3,
253
+ "MATCH_THRESH": 0.5, # Increased to 0.5
254
  "SNAPSHOT_QUALITY": 95,
255
+ "MAX_WORKER_DISTANCE": 150, # Increased to match _is_same_worker threshold
256
  "TARGET_RESOLUTION": (384, 384)
257
  }
258
 
 
590
  frame_skip = CONFIG["FRAME_SKIP"]
591
  processed_frames = 0
592
  last_yield_time = start_time
593
+ worker_counter = 1
594
 
595
  while processed_frames < total_frames:
596
  batch_frames = []