下面是一个完整的动态目标跟踪项目,使用OpenCV的CSRT跟踪器实现,包含以下功能:
• 视频文件或摄像头输入
• 目标选择界面
• 跟踪结果显示
• 跟踪失败处理
• 性能评估指标
项目结构
target_tracking/
├── main.py # 主程序
├── requirements.txt # 依赖库
├── utils/
│ ├── init.py
│ ├── evaluation.py # 评估指标计算
│ └── visualization.py # 可视化工具
└── README.md # 项目说明
代码实现
main.py
【python】
import cv2
import time
import argparse
from utils.evaluation import TrackingResult
from utils.visualization import draw_tracking_results
class TargetTracker:
def init(self, tracker_type=‘csrt’):
“”“初始化跟踪器”""
self.tracker_types = {
‘csrt’: cv2.TrackerCSRT_create,
‘kcf’: cv2.TrackerKCF_create,
‘mosse’: cv2.TrackerMOSSE_create,
‘medianflow’: cv2.TrackerMedianFlow_create
}
if tracker_type not in self.tracker_types:
raise ValueError(f"不支持的跟踪器类型: {tracker_type}")
self.tracker = self.tracker_types[tracker_type]()
self.tracking_results = []
self.frame_count = 0
self.total_time = 0
def initialize(self, frame, bbox):
"""初始化跟踪器"""
self.tracker.init(frame, bbox)
self.tracking_results = []
self.frame_count = 0
self.total_time = 0
def update(self, frame):
"""更新跟踪器并返回结果"""
start_time = time.time()
success, bbox = self.tracker.update(frame)
elapsed_time = time.time() - start_time
self.frame_count += 1
self.total_time += elapsed_time
result = {
'frame': self.frame_count,
'success': success,
'bbox': bbox if success else None,
'time': elapsed_time
}
self.tracking_results.append(result)
return success, bbox
def get_stats(self):
"""获取跟踪统计信息"""
if self.frame_count == 0:
return {}
avg_fps = self.frame_count / self.total_time
return {
'frame_count': self.frame_count,
'total_time': self.total_time,
'avg_fps': avg_fps
}
def main():
parser = argparse.ArgumentParser(description=‘动态目标跟踪系统’)
parser.add_argument(’–input’, type=str, default=‘0’,
help=‘输入视频路径或摄像头索引 (默认: 0)’)
parser.add_argument(’–tracker’, type=str, default=‘csrt’,
choices=[‘csrt’, ‘kcf’, ‘mosse’, ‘medianflow’],
help=‘跟踪器类型 (默认: csrt)’)
parser.add_argument(’–output’, type=str, default=None,
help=‘输出视频路径’)
args = parser.parse_args()
# 初始化视频捕获
cap = cv2.VideoCapture(args.input)
if not cap.isOpened():
print(f"无法打开视频源: {args.input}")
return
# 初始化视频写入器
output_video = None
if args.output:
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
output_video = cv2.VideoWriter(args.output,
cv2.VideoWriter_fourcc(*'XVID'),
fps,
(frame_width, frame_height))
# 初始化跟踪器
tracker = TargetTracker(args.tracker)
# 读取第一帧
ret, frame = cap.read()
if not ret:
print("无法读取视频")
return
# 选择ROI
print("请用鼠标选择要跟踪的目标区域,然后按Enter确认")
bbox = cv2.selectROI("目标选择", frame, False)
cv2.destroyWindow("目标选择")
# 初始化跟踪器
tracker.initialize(frame, bbox)
# 跟踪循环
while True:
ret, frame = cap.read()
if not ret:
break
# 更新跟踪器
success, bbox = tracker.update(frame)
# 绘制结果
frame_with_results = draw_tracking_results(frame, bbox, success, tracker.get_stats())
# 显示结果
cv2.imshow("目标跟踪", frame_with_results)
# 写入输出视频
if args.output:
output_video.write(frame_with_results)
# 按q退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
cap.release()
if args.output:
output_video.release()
cv2.destroyAllWindows()
# 打印统计信息
stats = tracker.get_stats()
print("\n跟踪统计信息:")
print(f"总帧数: {stats.get('frame_count', 0)}")
print(f"总耗时: {stats.get('total_time', 0):.2f}秒")
print(f"平均FPS: {stats.get('avg_fps', 0):.2f}")
if name == “main”:
main()
utils/evaluation.py
【python】
class TrackingResult:
“”“跟踪结果评估类”""
def init(self):
self.results = []
def add_result(self, frame, success, bbox, time):
"""添加跟踪结果"""
self.results.append({
'frame': frame,
'success': success,
'bbox': bbox,
'time': time
})
def get_success_rate(self):
"""计算跟踪成功率"""
if not self.results:
return 0.0
success_count = sum(1 for r in self.results if r['success'])
return success_count / len(self.results)
def get_average_speed(self):
"""计算平均处理速度"""
if not self.results:
return 0.0
total_time = sum(r['time'] for r in self.results)
return total_time / len(self.results)
def get_stats(self):
"""获取所有统计信息"""
return {
'success_rate': self.get_success_rate(),
'avg_speed': self.get_average_speed(),
'total_frames': len(self.results)
}
utils/visualization.py
【python】
import cv2
import numpy as np
def draw_tracking_results(frame, bbox, success, stats):
“”“绘制跟踪结果”""
if success and bbox is not None:
x, y, w, h = [int(v) for v in bbox]
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 绘制中心点
center = (x + w // 2, y + h // 2)
cv2.circle(frame, center, 3, (255, 0, 0), -1)
# 显示状态信息
status_text = "跟踪中" if success else "跟踪失败"
fps_text = f"FPS: {stats.get('avg_fps', 0):.1f}" if stats else ""
cv2.putText(frame, status_text, (20, 4))