Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 30746ff

Browse files
committed
add checking to valid bbox, handling disapare tracker and refactor code to more oop
1 parent 06caf13 commit 30746ff

File tree

1 file changed

+83
-15
lines changed

1 file changed

+83
-15
lines changed

‎custom_paralel_threade_refactored.py

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,12 @@ def detect_objects(self, frame):
8686
for result in results:
8787
for box in result.boxes:
8888
x1, y1, x2, y2 = box.xyxy[0]
89-
bboxes.append((int(x1), int(y1), int(x2 - x1), int(y2 - y1)))
89+
w = int(x2 - x1)
90+
h = int(y2 - y1)
91+
if w > 0 and h > 0:
92+
bboxes.append((int(x1), int(y1), w, h))
93+
else:
94+
logging.warning(f"Detected invalid bounding box with zero area: {(x1, y1, w, h)}")
9095
logging.debug(f"Detected {len(bboxes)} bounding boxes.")
9196
return bboxes
9297
except Exception as e:
@@ -114,6 +119,12 @@ def create_tracker(self, image, bbox, algorithm):
114119
Returns:
115120
dict or None: A dictionary containing tracker info or None if initialization fails.
116121
"""
122+
# Validate the bounding box
123+
x, y, w, h = bbox
124+
if w <= 0 or h <= 0:
125+
logging.error(f"Invalid bounding box with zero area: {bbox}. Cannot initialize tracker.")
126+
return None
127+
117128
tracker = None
118129
logging.debug(f"Initializing tracker '{algorithm}' with bbox: {bbox}")
119130

@@ -200,9 +211,11 @@ def update_single_tracker(tracker_info):
200211
elif algorithm == 'Nano' and area >= upper_threshold:
201212
logging.info(f"Switching tracker {idx} from Nano to KCF due to size increase.")
202213
self.switch_tracker(tracker_info, scaled_image, 'KCF')
214+
203215
except Exception as e:
204216
logging.error(f"Exception in tracker {idx} ({algorithm}): {e}")
205217
tracker_info['ok'] = False
218+
self.trackers.remove(tracker_info)
206219

207220
for idx, tracker_info in enumerate(self.trackers):
208221
tracker_info['index'] = idx
@@ -228,8 +241,10 @@ def switch_tracker(self, tracker_info, scaled_image, new_algorithm):
228241
})
229242
logging.info(f"Tracker {idx} switched to {new_algorithm}.")
230243
else:
231-
logging.error(f"Failed to switch tracker {idx} to {new_algorithm}.")
244+
logging.error(f"Failed to switch tracker {idx} to {new_algorithm} due to invalid bbox. Removing tracker.")
245+
# Remove the tracker since it cannot be initialized
232246
tracker_info['ok'] = False
247+
self.trackers.remove(tracker_info)
233248

234249
def reset_trackers(self):
235250
"""Reset all trackers."""
@@ -290,6 +305,51 @@ def draw_fps(frame, prev_time, prev_fps):
290305
return prev_time, fps
291306

292307

308+
def is_bbox_touches_frame(bbox, frame_width, frame_height):
309+
"""
310+
Check if any part of the bounding box is touches the frame boundaries.
311+
312+
Args:
313+
bbox (list or tuple): Bounding box in the format [x, y, w, h].
314+
frame_width (int): Width of the frame.
315+
frame_height (int): Height of the frame.
316+
317+
Returns:
318+
bool: True if any part of the bounding box is touches the frame, False otherwise.
319+
"""
320+
x, y, w, h = bbox
321+
322+
# Check if bounding box is within frame boundaries
323+
if x < 0 or y < 0 or x + w > frame_width or y + h > frame_height:
324+
return True # Bounding box touches or crosses the frame boundary
325+
else:
326+
return False # Bounding box is completely inside the frame
327+
328+
329+
def display_tracker_info(debug_image, index, algorithm, elapsed_time_ms, score, color_list):
330+
"""
331+
Display tracker information on the debug image.
332+
333+
Args:
334+
debug_image (numpy.ndarray): Image on which to draw.
335+
index (int): Index of the tracker.
336+
algorithm (str): Name of the tracking algorithm.
337+
elapsed_time_ms (float): Elapsed time in milliseconds.
338+
score (str or float): Tracking score.
339+
color_list (list): List of colors for drawing.
340+
"""
341+
if score != '-':
342+
text = f"{algorithm} : {elapsed_time_ms:.1f}ms Score:{score:.2f}"
343+
else:
344+
text = f"{algorithm} : {elapsed_time_ms:.1f}ms"
345+
cv.putText(debug_image, text,
346+
(10, int(25 * (index + 1))),
347+
cv.FONT_HERSHEY_SIMPLEX,
348+
0.7,
349+
color_list[index % len(color_list)],
350+
2, cv.LINE_AA)
351+
352+
293353
def process_tracking_results(trackers, debug_image, tracker_manager, color_list, scale_factor):
294354
"""
295355
Process tracking results, draw bounding boxes, and handle tracking failures.
@@ -301,6 +361,10 @@ def process_tracking_results(trackers, debug_image, tracker_manager, color_list,
301361
color_list (list): List of colors for drawing.
302362
scale_factor (float): The scaling factor used for resizing images.
303363
"""
364+
frame_height, frame_width = debug_image.shape[:2] # Get frame dimensions
365+
366+
trackers_to_reset = [] # List to keep track of trackers that need to be reset
367+
304368
for tracker_info in trackers:
305369
index = tracker_info['index']
306370
ok = tracker_info['ok']
@@ -318,10 +382,17 @@ def process_tracking_results(trackers, debug_image, tracker_manager, color_list,
318382
h = int(h / scale_factor)
319383
new_bbox = [x, y, w, h]
320384

385+
# Use the separate function to check boundary crossing
386+
if is_bbox_touches_frame(new_bbox, frame_width, frame_height):
387+
logging.info(f"Tracker {index} ({algorithm}) bounding box crossed frame boundary. Resetting tracker.")
388+
trackers_to_reset.append(index)
389+
continue # Skip drawing and processing this tracker
390+
321391
# Draw bounding box
322392
cv.rectangle(debug_image,
323-
(new_bbox[0], new_bbox[1]),
324-
(new_bbox[0] + new_bbox[2], new_bbox[1] + new_bbox[3]),
393+
(max(new_bbox[0], 0), max(new_bbox[1], 0)),
394+
(min(new_bbox[0] + new_bbox[2], frame_width - 1),
395+
min(new_bbox[1] + new_bbox[3], frame_height - 1)),
325396
color_list[index % len(color_list)],
326397
thickness=2)
327398
logging.debug(f"Tracker {index} ({algorithm}) updated successfully with bbox: {new_bbox}")
@@ -331,18 +402,15 @@ def process_tracking_results(trackers, debug_image, tracker_manager, color_list,
331402
tracker_manager.reset_trackers()
332403
break
333404

334-
# Display tracker info
405+
# Display tracker info using the new function
335406
elapsed_time_ms = elapsed_time * 1000
336-
if score != '-':
337-
text = f"{algorithm} : {elapsed_time_ms:.1f}ms Score:{score:.2f}"
338-
else:
339-
text = f"{algorithm} : {elapsed_time_ms:.1f}ms"
340-
cv.putText(debug_image, text,
341-
(10, int(25 * (index + 1))),
342-
cv.FONT_HERSHEY_SIMPLEX,
343-
0.7,
344-
color_list[index % len(color_list)],
345-
2, cv.LINE_AA)
407+
display_tracker_info(debug_image, index, algorithm, elapsed_time_ms, score, color_list)
408+
409+
# Reset trackers that are marked for reset
410+
if trackers_to_reset:
411+
for idx in sorted(trackers_to_reset, reverse=True):
412+
logging.info(f"Removing tracker {idx} due to boundary crossing.")
413+
del tracker_manager.trackers[idx]
346414

347415

348416
def main():

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /