如何在OpenCV中实现多目标自动检测追踪,替代手动选择bbox
问题
我正在用OpenCV开发一个算法,用来追踪视频特定区域内的多个移动目标。现在的算法需要在第一帧手动选择bbox(边界框)才能开始追踪,我想改成自动检测所有目标,但不知道具体怎么实现。
当前手动选择bbox的代码片段:
# Select the bounding box in the first frame bbox = cv2.selectROI(frame, False) ret = tracker.init(frame, bbox)
完整原始代码:
tracker = cv2.TrackerKCF_create() # import the necessary packages # noinspection PyUnresolvedReferences from imutils.video import VideoStream import argparse # noinspection PyUnresolvedReferences import imutils import time import cv2 print("GeeksForGeeks") print("Your OpenCV version is: " + cv2.__version__) tracker_types = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'MOSSE', 'CSRT'] tracker_type = tracker_types[5] if tracker_type == 'BOOSTING': tracker = cv2.legacy.TrackerBoosting_create() if tracker_type == 'MIL': tracker = cv2.TrackerMIL_create() if tracker_type == 'KCF': tracker = cv2.TrackerKCF_create() if tracker_type == 'TLD': tracker = cv2.legacy.TrackerTLD_create() if tracker_type == 'MEDIANFLOW': tracker = cv2.legacy.TrackerMedianFlow_create() #if tracker_type == 'GOTURN': # tracker = cv2.TrackerGOTURN_create() if tracker_type == 'MOSSE': tracker = cv2.legacy.TrackerMOSSE_create() if tracker_type == "CSRT": tracker = cv2.TrackerCSRT_create() # Get the video file and read it vid_capture = cv2.VideoCapture('/Users/leonienelz/Downloads/capture_output60_countr02_1676545157.mp4') ret, frame = vid_capture.read() frame_height, frame_width = frame.shape[:2] # Resize the video for a more convinient view frame = cv2.resize(frame, [frame_width // 2, frame_height // 2]) # Initialize video writer to save the results output = cv2.VideoWriter(f'{tracker_type}.avi', cv2.VideoWriter_fourcc(*'XVID'), 60.0, (frame_width // 2, frame_height // 2), True) if not ret: print('cannot read the video') # Select the bounding box in the first frame bbox = cv2.selectROI(frame, False) ret = tracker.init(frame, bbox) # Start tracking while True: ret, frame = vid_capture.read() frame = cv2.resize(frame, [frame_width // 2, frame_height // 2]) if not ret: print('something went wrong') break timer = cv2.getTickCount() ret, bbox = tracker.update(frame) fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer) if ret: p1 = (int(bbox[0]), int(bbox[1])) p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3])) cv2.rectangle(frame, p1, p2, (255, 0, 0), 2, 1) else: cv2.putText(frame, "Tracking failure detected", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2) cv2.putText(frame, tracker_type + " Tracker", (100, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2) cv2.putText(frame, "FPS : " + str(int(fps)), (100, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2) cv2.imshow("Tracking", frame) output.write(frame) k = cv2.waitKey(1) & 0xff if k == 27: break vid_capture.release() output.release() #cv2.destroyAllWindows()
解决方案
核心思路
要实现自动检测+多目标追踪,分两步走:
- 目标自动检测:在第一帧用目标检测模型识别所有需要追踪的目标边界框
- 多目标追踪管理:为每个检测到的目标初始化独立追踪器,后续帧统一更新所有追踪器的位置
下面以HOG+SVM行人检测(适合行人追踪场景)和OpenCV多追踪器为例,修改代码实现需求:
修改后的完整代码
# 导入必要包 from imutils.video import VideoStream import argparse import imutils import time import cv2 print("GeeksForGeeks") print("Your OpenCV version is: " + cv2.__version__) tracker_types = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'MOSSE', 'CSRT'] tracker_type = tracker_types[5] # 选用MOSSE,速度快适合多目标场景 # 初始化多追踪器,用于管理多个目标的追踪器 multi_tracker = cv2.legacy.MultiTracker_create() # 初始化HOG行人检测器(如果追踪其他目标,替换为对应检测器即可) hog = cv2.HOGDescriptor() hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector()) # 读取视频文件 vid_capture = cv2.VideoCapture('/Users/leonienelz/Downloads/capture_output60_countr02_1676545157.mp4') ret, frame = vid_capture.read() frame_height, frame_width = frame.shape[:2] # 调整视频尺寸方便查看 frame = cv2.resize(frame, [frame_width // 2, frame_height // 2]) # 初始化视频写入器保存结果 output = cv2.VideoWriter(f'{tracker_type}_multi.avi', cv2.VideoWriter_fourcc(*'XVID'), 60.0, (frame_width // 2, frame_height // 2), True) if not ret: print('无法读取视频') # --------------------------- # 替换手动选框:自动检测目标 # --------------------------- # HOG检测行人,参数可根据场景调整 rects, weights = hog.detectMultiScale(frame, winStride=(4, 4), padding=(8, 8), scale=1.05) # 非极大值抑制,去除重叠框避免重复追踪 rects = imutils.non_max_suppression(rects, probs=None, overlapThresh=0.65) # 为每个检测到的目标初始化追踪器并添加到多追踪器 for (x, y, w, h) in rects: # 根据选择的追踪器类型创建实例 if tracker_type == 'BOOSTING': tracker = cv2.legacy.TrackerBoosting_create() elif tracker_type == 'MIL': tracker = cv2.TrackerMIL_create() elif tracker_type == 'KCF': tracker = cv2.TrackerKCF_create() elif tracker_type == 'TLD': tracker = cv2.legacy.TrackerTLD_create() elif tracker_type == 'MEDIANFLOW': tracker = cv2.legacy.TrackerMedianFlow_create() elif tracker_type == 'MOSSE': tracker = cv2.legacy.TrackerMOSSE_create() elif tracker_type == "CSRT": tracker = cv2.TrackerCSRT_create() # 将追踪器和对应目标框添加到多追踪器 multi_tracker.add(tracker, frame, (x, y, w, h)) # 开始追踪循环 while True: ret, frame = vid_capture.read() frame = cv2.resize(frame, [frame_width // 2, frame_height // 2]) if not ret: print('视频读取异常') break timer = cv2.getTickCount() # 更新所有追踪器的位置 ret, bboxes = multi_tracker.update(frame) fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer) # 绘制所有追踪框 if ret: for i, bbox in enumerate(bboxes): p1 = (int(bbox[0]), int(bbox[1])) p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3])) # 用不同颜色区分不同目标 color = (0, 255*(i%3), 255*(i%2)) cv2.rectangle(frame, p1, p2, color, 2, 1) else: cv2.putText(frame, "部分目标追踪失败", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2) # 添加文字信息 cv2.putText(frame, tracker_type + " 多目标追踪器", (100, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2) cv2.putText(frame, "FPS : " + str(int(fps)), (100, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2) cv2.imshow("多目标追踪", frame) output.write(frame) # 按ESC退出 k = cv2.waitKey(1) & 0xff if k == 27: break # 释放资源 vid_capture.release() output.release() cv2.destroyAllWindows()
关键修改说明
- 自动检测替换手动选框:用HOG+SVM实现行人自动检测,若需追踪其他目标,可替换为Haar级联分类器(如车辆检测)或YOLO系列模型(通用目标检测)
- 多追踪器管理:使用
cv2.legacy.MultiTracker_create()替代单个追踪器,支持同时追踪多个目标 - 目标去重:用
imutils.non_max_suppression去除重叠检测框,避免重复追踪同一目标 - 多目标可视化:为每个目标分配不同颜色的追踪框,方便区分
扩展优化建议
- 特定区域过滤:在检测后,可添加逻辑只保留位于指定区域内的目标框,实现"特定区域内追踪"的需求
- 高精度检测:如果需要更高精度,可使用YOLOv8的ONNX模型,OpenCV支持直接加载ONNX模型进行推理
- 失效重检测:添加追踪失效判断,当某个目标追踪失败时,重新运行检测找回目标
内容的提问来源于stack exchange,提问作者phytonnewbie
相关产品推荐
相关产品推荐

