opencv4.8 c++ 新版本使用TrackerMOSSE追踪功能
【代码】opencv4.8 c++ 新版本使用TrackerMOSSE追踪功能。
·
#include <opencv2/opencv.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/tracking/tracking_legacy.hpp>
#include <iostream>
int main() {
// 打开视频或摄像头
cv::VideoCapture cap(0); // 使用摄像头,或者替换为视频文件路径
if (!cap.isOpened()) {
std::cout << "无法打开视频源" << std::endl;
return -1;
}
// 创建 MOSSE 跟踪器
cv::Ptr<cv::legacy::TrackerMOSSE> tracker = cv::legacy::TrackerMOSSE::create();
// 读取第一帧
cv::Mat frame;
cap >> frame;
if (frame.empty()) {
std::cout << "无法读取视频帧" << std::endl;
return -1;
}
// 选择要跟踪的目标区域,使用 Rect2d
cv::Rect2d bbox = cv::selectROI("跟踪", frame, false);
// 初始化跟踪器
tracker->init(frame, bbox);
while (true) {
// 读取新的一帧
cap >> frame;
if (frame.empty())
break;
// 更新跟踪器,使用 Rect2d
bool ok = tracker->update(frame, bbox);
if (ok) {
// 绘制跟踪框
cv::rectangle(frame, bbox, cv::Scalar(255, 0, 0), 2, 1);
}
else {
// 跟踪失败
cv::putText(frame, "Tracking failure", cv::Point(100, 80),
cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(0, 0, 255), 2);
}
// 显示结果
cv::imshow("跟踪", frame);
// 按 ESC 键退出
char c = (char)cv::waitKey(1);
if (c == 27)
break;
}
cap.release();
cv::destroyAllWindows();
return 0;
}
另外python版本的opencv也有追踪功能
4.x版本的话
import cv2
import sys
def main():
# 1. 设置视频源:0 代表默认摄像头,也可以换成视频文件路径,例如 'video.mp4'
video_path = "vtest.avi"
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
print("无法打开视频源")
sys.exit()
# 2. 创建追踪器
# OpenCV 4.x 推荐使用 CSRT,精度高;如果追求速度可以使用 KCF
tracker = cv2.TrackerCSRT_create()
# 状态标记
is_tracking = False
print("操作说明:")
print("1. 视频正在播放...")
print("2. 按下【空格键】暂停视频并开始框选对象")
print("3. 鼠标框选后,再次按下【空格键】或【回车键】确认框选并开始追踪")
print("4. 按下【ESC】退出程序")
while True:
# 读取一帧
ret, frame = cap.read()
if not ret:
print("视频结束或无法读取")
break
# 如果正在追踪状态,更新追踪器
if is_tracking:
success, box = tracker.update(frame)
if success:
# box 返回的是 (x, y, w, h)
(x, y, w, h) = [int(v) for v in box]
# 画出矩形框
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame, "Tracking", (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
else:
cv2.putText(frame, "Lost", (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
# 显示当前帧
cv2.imshow("Object Tracker (Space to Select)", frame)
# 键盘监听
key = cv2.waitKey(30) & 0xFF
# 按下 ESC 退出
if key == 27:
break
# 按下 空格键 (ASCII 32) 进入选择模式
elif key == 32:
print("--- 已暂停,请用鼠标框选对象 ---")
print("--- 框选完成后,按 空格 或 回车 开始追踪 ---")
# selectROI 是 OpenCV 自带的工具
# 它会暂停画面,允许用户画框
# 参数:窗口名,图像帧,是否从中心开始画(False),是否显示十字准星(False)
bbox = cv2.selectROI("Object Tracker (Space to Select)", frame, fromCenter=False, showCrosshair=True)
# bbox 返回 (x, y, w, h),如果用户取消选择通常返回全是0
if bbox[2] > 0 and bbox[3] > 0: # 宽度高度大于0
# 重新创建追踪器(为了支持多次重新框选,每次都新建一个)
tracker = cv2.TrackerCSRT_create()
# 初始化追踪器
tracker.init(frame, bbox)
is_tracking = True
print("--- 开始追踪 ---")
else:
print("--- 未选择对象,继续播放 ---")
is_tracking = False
# 释放资源
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
或者有模式选择的
import cv2
import sys
# ================= 配置区域 =================
# 可选模式: "csrt", "kcf", "mil", "boosting", "tld", "medianflow", "mosse"
# 推荐: "csrt" (最准), "kcf" (速度快), "mosse" (速度极快但不如kcf准)
TRACKER_TYPE = "csrt"
# ===========================================
def create_tracker(tracker_type):
"""
根据名称创建追踪器工厂函数
注意:在 OpenCV 4.x 中,部分老旧追踪器被移到了 cv2.legacy 包中
"""
tracker_type = tracker_type.lower()
# 核心追踪器 (直接可用)
if tracker_type == 'csrt':
return cv2.TrackerCSRT_create()
elif tracker_type == 'kcf':
return cv2.TrackerKCF_create()
elif tracker_type == 'mil':
return cv2.TrackerMIL_create()
# Legacy 追踪器 (位于 opencv-contrib 的 legacy 模块中)
# 如果报错 AttributeError,说明你可能没装 opencv-contrib-python 或者版本差异
try:
if tracker_type == 'boosting':
return cv2.legacy.TrackerBoosting_create()
elif tracker_type == 'tld':
return cv2.legacy.TrackerTLD_create()
elif tracker_type == 'medianflow':
return cv2.legacy.TrackerMedianFlow_create()
elif tracker_type == 'mosse':
return cv2.legacy.TrackerMOSSE_create()
except AttributeError:
print(f"错误: 你的 OpenCV 版本似乎不支持 {tracker_type},请尝试 csrt 或 kcf")
sys.exit()
print(f"不支持的追踪器类型: {tracker_type}")
sys.exit()
def main():
# 1. 设置视频源
video_path = "vtest.avi"
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
print("无法打开视频源")
sys.exit()
# 初始化追踪器变量
tracker = create_tracker(TRACKER_TYPE)
is_tracking = False
print(f"当前使用追踪器算法: 【{TRACKER_TYPE.upper()}】")
print("-" * 40)
print("操作说明:")
print(" [空格键] : 暂停视频 -> 鼠标框选 -> 再次按空格/回车开始追踪")
print(" [ESC键] : 退出程序")
print(" [C 键] : 清除当前追踪目标 (不暂停)")
print("-" * 40)
while True:
ret, frame = cap.read()
if not ret:
print("视频结束")
break
# 如果正在追踪
if is_tracking:
success, box = tracker.update(frame)
if success:
(x, y, w, h) = [int(v) for v in box]
# 绘制追踪框
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 显示算法名称
cv2.putText(frame, f"{TRACKER_TYPE.upper()} Tracker", (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
else:
cv2.putText(frame, "Tracking Failed", (50, 80),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
# 显示帮助信息
info_text = "Tracking: ON" if is_tracking else "Tracking: OFF (Press Space)"
color = (0, 255, 0) if is_tracking else (0, 255, 255)
cv2.putText(frame, info_text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2)
cv2.imshow("Multi-Tracker Object Tracking", frame)
# 键盘监听
key = cv2.waitKey(30) & 0xFF
# ESC 退出
if key == 27:
break
# C 键清除追踪
elif key == ord('c'):
is_tracking = False
print("--- 追踪已清除 ---")
# 空格键:暂停并选择
elif key == 32:
print("\n--- 进入选择模式 ---")
# 必须重新创建追踪器,否则旧的历史数据会干扰新的追踪
tracker = create_tracker(TRACKER_TYPE)
# 弹出选择框
bbox = cv2.selectROI("Multi-Tracker Object Tracking", frame, fromCenter=False, showCrosshair=True)
# 如果框选了区域 (宽和高 > 0)
if bbox[2] > 0 and bbox[3] > 0:
tracker.init(frame, bbox)
is_tracking = True
print(f"--- 目标已锁定,使用 {TRACKER_TYPE} 开始追踪 ---")
else:
is_tracking = False
print("--- 未选择区域,取消追踪 ---")
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
老版本的opencv例如3.4.2.17可参考以下代码
如果需要更高的准确率,并且可以容忍延迟的话,使用CSRT
如果需要更快的FPS,并且可以容许稍低一点的准确率的话,使用KCF
如果纯粹的需要速度的话,用MOSSE。

import cv2
import sys
(major_ver, minor_ver, subminor_ver) = (cv2.__version__).split('.')
if __name__ == '__main__':
# Set up tracker.
# Instead of MIL, you can also use
tracker_types = ['BOOSTING', 'MIL', 'KCF', 'TLD', 'MEDIANFLOW', 'GOTURN', 'MOSSE', 'CSRT']
tracker_type = tracker_types[2]
if int(minor_ver) < 3:
tracker = cv2.Tracker_create(tracker_type)
else:
if tracker_type == 'BOOSTING':
tracker = cv2.TrackerBoosting_create()
if tracker_type == 'MIL':
tracker = cv2.TrackerMIL_create()
if tracker_type == 'KCF':
tracker = cv2.TrackerKCF_create()
if tracker_type == 'TLD':
tracker = cv2.TrackerTLD_create()
if tracker_type == 'MEDIANFLOW':
tracker = cv2.TrackerMedianFlow_create()
if tracker_type == 'GOTURN':
tracker = cv2.TrackerGOTURN_create()
if tracker_type == 'MOSSE':
tracker = cv2.TrackerMOSSE_create()
if tracker_type == "CSRT":
tracker = cv2.TrackerCSRT_create()
# Read video
video = cv2.VideoCapture("1.mp4")
# Exit if video not opened.
if not video.isOpened():
print
"Could not open video"
sys.exit()
# Read first frame.
ok, frame = video.read()
if not ok:
print
'Cannot read video file'
sys.exit()
# Define an initial bounding box
bbox = (287, 23, 86, 320)
# Uncomment the line below to select a different bounding box
bbox = cv2.selectROI(frame, False)
# Initialize tracker with first frame and bounding box
ok = tracker.init(frame, bbox)
while True:
# Read a new frame
ok, frame = video.read()
if not ok:
break
# Start timer
timer = cv2.getTickCount()
# Update tracker
ok, bbox = tracker.update(frame)
# Calculate Frames per second (FPS)
fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer);
# Draw bounding box
if ok:
# Tracking success
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:
# Tracking failure
cv2.putText(frame, "Tracking failure detected", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
# Display tracker type on frame
cv2.putText(frame, tracker_type + " Tracker", (100, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2);
# Display FPS on frame
cv2.putText(frame, "FPS : " + str(int(fps)), (100, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2);
# Display result
cv2.imshow("Tracking", frame)
# Exit if ESC pressed
k = cv2.waitKey(1) & 0xff
if k == 27: break
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)