OpenCV版本兼容问题致目标跟踪代码无法运行求助
OpenCV目标跟踪代码版本兼容问题修复与全跟踪器对比方案
问题概述
手上有一套基于旧版OpenCV编写的目标跟踪代码,运行时报错:AttributeError: module 'cv2' has no attribute 'TrackerCSRT_create',查阅官方文档和网络资料后仍未解决,需要适配新版OpenCV并获取所有可用目标跟踪技术进行对比测试。
错误原因
从OpenCV 4.x版本开始,大部分传统目标跟踪器被迁移至cv2.legacy模块下,旧版直接调用cv2.TrackerXX_create的方式不再生效,这是导致报错的核心原因。
修复与适配方案
- 调整跟踪器初始化路径:将原代码中
cv2.TrackerXX_create的调用改为从cv2.legacy模块获取 - 兼容多版本(可选):添加版本判断逻辑,让代码同时支持OpenCV 3.x和4.x+环境
- 扩充跟踪器范围:加入OpenCV 4.x新增的跟踪器(如GOTURN、DaSiamRPN),覆盖所有官方支持的跟踪技术
适配后的全跟踪器对比代码
import cv2 import numpy as np import matplotlib.pyplot as plt import time import pandas as pd # 适配OpenCV多版本的跟踪器映射,包含所有官方支持的跟踪器 OPENCV_OBJECT_TRACKERS = { "csrt": cv2.legacy.TrackerCSRT_create if hasattr(cv2.legacy, 'TrackerCSRT_create') else cv2.TrackerCSRT_create, "kcf": cv2.legacy.TrackerKCF_create if hasattr(cv2.legacy, 'TrackerKCF_create') else cv2.TrackerKCF_create, "boosting": cv2.legacy.TrackerBoosting_create, "mil": cv2.legacy.TrackerMIL_create, "tld": cv2.legacy.TrackerTLD_create, "medianflow": cv2.legacy.TrackerMedianFlow_create, "mosse": cv2.legacy.TrackerMOSSE_create, # OpenCV 4.x新增跟踪器 "goturn": cv2.TrackerGOTURN_create if hasattr(cv2, 'TrackerGOTURN_create') else None, "dasiamrpn": cv2.TrackerDaSiamRPN_create if hasattr(cv2, 'TrackerDaSiamRPN_create') else None } # 过滤当前环境不支持的跟踪器 available_trackers = {k:v for k,v in OPENCV_OBJECT_TRACKERS.items() if v is not None} print("可用跟踪器列表:", list(available_trackers.keys())) # 选择单个跟踪器测试(可替换为循环实现批量测试) tracker_name = "mil" tracker = available_trackers[tracker_name]() print("当前使用跟踪器:", tracker_name) gt = pd.read_csv("gt_new.txt") video_path = "MOT17-13-SDP.mp4" cap = cv2.VideoCapture(video_path) # 通用参数初始化 initBB = None fps = 25 frame_number = [] f = 0 success_track_count = 0 track_list = [] start_time = time.time() while True: time.sleep(0.01) ret, frame = cap.read() if ret: frame = cv2.resize(frame, dsize=(960, 540)) (H, W) = frame.shape[:2] # 绘制真实标注框(GT) car_gt = gt[gt.frame_no == f] if len(car_gt) != 0: x, y, w, h = car_gt.x.values[0], car_gt.y.values[0], car_gt.w.values[0], car_gt.h.values[0] center_x, center_y = car_gt.center_x.values[0], car_gt.center_y.values[0] cv2.rectangle(frame, (x, y), (x+w, y+h), (0,255,0), 2) cv2.circle(frame, (center_x, center_y), 2, (0,0,255), -1) # 跟踪逻辑执行 if initBB is not None: success, box = tracker.update(frame) if f <= np.max(gt.frame_no): x, y, w, h = [int(i) for i in box] cv2.rectangle(frame, (x, y), (x+w, y+h), (0,0,255), 2) success_track_count += 1 track_center_x = int(x + w/2) track_center_y = int(y + h/2) track_list.append([f, track_center_x, track_center_y]) # 显示跟踪状态信息 info = [("跟踪器", tracker_name), ("跟踪成功", "是" if success else "否")] for i, (label, value) in enumerate(info): text = f"{label}: {value}" cv2.putText(frame, text, (10, H - (i*20) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,255), 2) # 显示当前帧号 cv2.putText(frame, f"帧号: {f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2) cv2.imshow("跟踪画面", frame) # 按键控制 key = cv2.waitKey(1) & 0xFF if key == ord("t"): initBB = cv2.selectROI("跟踪画面", frame, fromCenter=False) tracker.init(frame, initBB) elif key == ord("q"): break frame_number.append(f) f += 1 else: break cap.release() cv2.destroyAllWindows() # 计算跟踪耗时 stop_time = time.time() total_time = stop_time - start_time # 跟踪结果评估 track_df = pd.DataFrame(track_list, columns=["frame_no", "center_x", "center_y"]) if len(track_df) != 0: print("跟踪方法: ", tracker) print("总耗时: ", total_time) print("GT总帧数: ", len(gt)) print("跟踪成功帧数: ", success_track_count) # 计算GT与跟踪结果的欧氏误差 track_frames = track_df.frame_no gt_center_x = gt.center_x[track_frames].values gt_center_y = gt.center_y[track_frames].values track_center_x = track_df.center_x.values track_center_y = track_df.center_y.values error_per_frame = np.sqrt((gt_center_x - track_center_x)**2 + (gt_center_y - track_center_y)**2 ) plt.plot(error_per_frame) plt.xlabel("帧号") plt.ylabel("GT与跟踪结果的欧氏距离") plt.title(f"{tracker_name}跟踪误差曲线") plt.show() total_error = np.sum(error_per_frame) print("总误差: ", total_error)
批量对比测试实现
若要批量测试所有可用跟踪器,可将单个跟踪器选择逻辑替换为循环遍历:
for tracker_name in available_trackers.keys(): print(f"\n===== 测试跟踪器: {tracker_name} =====") tracker = available_trackers[tracker_name]() # 重置跟踪相关变量 initBB = None success_track_count = 0 track_list = [] start_time = time.time() f = 0 # 后续执行原代码中的视频读取、跟踪、评估逻辑(需将循环内的帧计数等变量重置)
内容的提问来源于stack exchange,提问作者Eren Yanic
相关产品推荐
相关产品推荐

