当前位置:首页>python>OpenCV 目标跟踪算法介绍与python和C++版本代码实现

OpenCV 目标跟踪算法介绍与python和C++版本代码实现

  • 2026-10-21 13:28:48
OpenCV 目标跟踪算法介绍与python和C++版本代码实现

OpenCV 目标跟踪算法介绍与实现

本文总结OpenCV中常见的目标跟踪算法,并提供Python和C++的双版本实现。

一、OpenCV中目标跟踪算法介绍

OpenCV提供了多种目标跟踪算法,主要分为两类:

1. 传统跟踪算法

  • • BOOSTING: 基于Haar级联的AdaBoost算法
  • • MIL: 多实例学习算法
  • • KCF: 核相关滤波算法
  • • TLD: 跟踪-学习-检测算法
  • • MedianFlow: 中值流跟踪算法
  • • MOSSE: 最小输出平方误差和算法
  • • CSRT: 通道和空间可靠性算法

2. 深度学习算法

  • • GOTURN: 基于深度学习的通用目标跟踪器

二、代码实现

Python版本

环境要求:(亲测,opencv版本不能大于3)

opencv-python=3.4.15.55opencv-contrib-python=3.4.15.55numpy=1.24.4

import cv2import sysimport timeclass OpenCVTracker:def __init__(self, tracker_type="KCF"):"""        初始化跟踪器        Args:            tracker_type: 跟踪算法类型                "BOOSTING", "MIL", "KCF", "TLD",                "MEDIANFLOW", "GOTURN", "MOSSE", "CSRT"        """self.tracker_type = tracker_typeself.tracker = self._create_tracker()self.bbox = Noneself.frame_count = 0self.fps = 0def _create_tracker(self):"""根据类型创建跟踪器"""        tracker_map = {"BOOSTING": cv2.TrackerBoosting_create,"MIL": cv2.TrackerMIL_create,"KCF": cv2.TrackerKCF_create,"TLD": cv2.TrackerTLD_create,"MEDIANFLOW": cv2.TrackerMedianFlow_create,"GOTURN": cv2.TrackerGOTURN_create,"MOSSE": cv2.TrackerMOSSE_create,"CSRT": cv2.TrackerCSRT_create        }if self.tracker_type in tracker_map:try:return tracker_map[self.tracker_type]()except AttributeError:print(f"警告: OpenCV版本可能不支持{self.tracker_type}算法")print("尝试使用KCF作为替代...")return cv2.TrackerKCF_create()else:print(f"错误: 不支持的跟踪器类型: {self.tracker_type}")print("使用默认的KCF算法")return cv2.TrackerKCF_create()def initialize(self, frame, bbox):"""        初始化跟踪器        Args:            frame: 初始帧图像            bbox: 边界框 (x, y, width, height)        """self.bbox = bbox        success = self.tracker.init(frame, bbox)self.frame_count = 0self.start_time = time.time()return successdef update(self, frame):"""        更新跟踪器        Args:            frame: 当前帧图像        Returns:            success: 是否跟踪成功            bbox: 更新后的边界框        """self.frame_count += 1# 更新跟踪器        success, bbox = self.tracker.update(frame)# 计算FPSif success:            current_time = time.time()            elapsed_time = current_time - self.start_timeif elapsed_time > 0:self.fps = self.frame_count / elapsed_timereturn success, bboxdef draw_bbox(self, frame, bbox, color=(0, 0, 255), thickness=1):"""在图像上绘制边界框"""        x, y, w, h = [int(v) for v in bbox]        cv2.rectangle(frame, (x, y), (x + w, y + h), color, thickness)# 显示跟踪器类型和FPS        info = f"{self.tracker_type}  FPS: {self.fps:.1f}"        cv2.putText(frame, info, (60, 60),                    cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 4)return framedef run_tracker(video_source=0, tracker_type="KCF"):"""    运行目标跟踪器    Args:        video_source: 视频源 (0-摄像头,或视频文件路径)        tracker_type: 跟踪算法类型    """# 创建视频捕获对象    cap = cv2.VideoCapture(video_source)if not cap.isOpened():print("错误: 无法打开视频源")return# 读取第一帧    ret, frame = cap.read()if not ret:print("错误: 无法读取视频")        cap.release()return# 选择ROI(感兴趣区域)print("请选择跟踪目标区域,然后按SPACE或ENTER键确认,按ESC取消")    cv2.namedWindow("Select ROI", cv2.WINDOW_NORMAL)    cv2.imshow("Select ROI", frame)    bbox = cv2.selectROI("Select ROI", frame, False)    cv2.destroyWindow("Select ROI")if bbox == (0, 0, 0, 0):print("未选择区域,退出程序")        cap.release()return# 创建跟踪器    tracker = OpenCVTracker(tracker_type)# 初始化跟踪器if not tracker.initialize(frame, bbox):print("错误: 跟踪器初始化失败")        cap.release()returnprint(f"开始跟踪,使用算法: {tracker_type}")print("按ESC键退出")while True:        ret, frame = cap.read()if not ret:break# 更新跟踪器        success, bbox = tracker.update(frame)# 绘制结果if success:            frame = tracker.draw_bbox(frame, bbox)else:            cv2.putText(frame, "Track Failed", (60, 60),                        cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)# 显示结果        cv2.namedWindow("Select ROI", cv2.WINDOW_NORMAL)        cv2.imshow("Select ROI", frame)# 按键处理        key = cv2.waitKey(1) & 0xFFif key == 27:  # ESC键break# 清理资源    cap.release()    cv2.destroyAllWindows()if __name__ == "__main__":run_tracker("../WIN_20221029_16_49_19_Pro.mp4", "KCF")

C++版本

CmakeList.txt:

cmake_minimum_required(VERSION 3.10)project(OpenCVTracker)set(CMAKE_CXX_STANDARD 11)set(CMAKE_CXX_STANDARD_REQUIRED ON)# 查找OpenCVfind_package(OpenCV REQUIRED)# 包含目录include_directories(${OpenCV_INCLUDE_DIRS})# 可执行文件add_executable(tracker_comparison tracker_main.cpp)# 链接库target_link_libraries(tracker_comparison ${OpenCV_LIBS})

Code:(opencv版本依然使用4以下版本)

#include<opencv2/opencv.hpp>#include<opencv2/tracking.hpp>#include<iostream>#include<chrono>#include<map>#include<string>using namespace cv;using namespace std;using namespace std::chrono;class OpenCVTracker{private:    Ptr<Tracker> tracker;    string trackerType;    Rect2d bbox;int frameCount;double fps;    steady_clock::time_point startTime;public:OpenCVTracker(const string& type = "CSRT")         : trackerType(type), frameCount(0), fps(0) {createTracker();    }boolcreateTracker(){// 创建跟踪器if (trackerType == "BOOSTING") {            tracker = TrackerBoosting::create();        } else if (trackerType == "MIL") {            tracker = TrackerMIL::create();        } else if (trackerType == "KCF") {            tracker = TrackerKCF::create();        } else if (trackerType == "TLD") {            tracker = TrackerTLD::create();        } else if (trackerType == "MEDIANFLOW") {            tracker = TrackerMedianFlow::create();        } else if (trackerType == "GOTURN") {            tracker = TrackerGOTURN::create();        } else if (trackerType == "MOSSE") {            tracker = TrackerMOSSE::create();        } else if (trackerType == "CSRT") {            tracker = TrackerCSRT::create();        } else {            cerr << "错误: 不支持的跟踪器类型: " << trackerType << endl;            cerr << "使用默认的CSRT算法" << endl;            trackerType = "CSRT";            tracker = TrackerCSRT::create();return false;        }if (tracker.empty()) {            cerr << "错误: 无法创建跟踪器" << endl;return false;        }        cout << "创建跟踪器: " << trackerType << endl;return true;    }boolinitialize(const Mat& frame, const Rect2d& boundingBox){        bbox = boundingBox;        frameCount = 0;        startTime = steady_clock::now();return tracker->init(frame, bbox);    }boolupdate(const Mat& frame, Rect2d& updatedBox){        frameCount++;bool success = tracker->update(frame, bbox);        updatedBox = bbox;// 计算FPSif (success) {auto currentTime = steady_clock::now();auto elapsedTime = duration_cast<milliseconds>(currentTime - startTime);if (elapsedTime.count() > 0) {                fps = frameCount * 1000.0 / elapsedTime.count();            }        }return success;    }voiddrawBoundingBox(Mat& frame, const Rect2d& box, const Scalar& color = Scalar(0, 255, 0), int thickness = 2){rectangle(frame, box, color, thickness);// 显示跟踪器类型和FPS        string info = trackerType + " | FPS: " + to_string(fps).substr(0, 4);putText(frame, info, Point(10, 30),                FONT_HERSHEY_SIMPLEX, 0.8, color, 2);    }string getTrackerType()const{return trackerType;    }doublegetFPS()const{return fps;    }};voidrunTracker(int videoSource = 0, const string& trackerType = "CSRT"){// 打开视频源VideoCapture cap(videoSource);if (!cap.isOpened()) {        cerr << "错误: 无法打开视频源" << endl;return;    }// 读取第一帧    Mat frame;if (!cap.read(frame)) {        cerr << "错误: 无法读取视频" << endl;        cap.release();return;    }// 选择ROI    Rect2d bbox = selectROI("选择跟踪区域", frame, false);if (bbox.width == 0 || bbox.height == 0) {        cout << "未选择区域,退出程序" << endl;        cap.release();destroyAllWindows();return;    }// 创建跟踪器OpenCVTracker tracker(trackerType);// 初始化跟踪器if (!tracker.initialize(frame, bbox)) {        cerr << "错误: 跟踪器初始化失败" << endl;        cap.release();destroyAllWindows();return;    }    cout << "开始跟踪,使用算法: " << trackerType << endl;    cout << "按ESC键退出,按R键重新选择区域" << endl;namedWindow("目标跟踪", WINDOW_AUTOSIZE);while (cap.read(frame)) {        Rect2d updatedBox;// 更新跟踪器bool success = tracker.update(frame, updatedBox);// 绘制结果if (success) {            tracker.drawBoundingBox(frame, updatedBox);        } else {putText(frame, "跟踪失败", Point(10, 60),                    FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2);        }// 显示结果imshow("目标跟踪", frame);// 按键处理char key = (char)waitKey(30);if (key == 27) {  // ESC键break;        } else if (key == 'r' || key == 'R') {  // R键重置            cout << "重新选择跟踪区域..." << endl;            bbox = selectROI("选择跟踪区域", frame, false);if (bbox.width > 0 && bbox.height > 0) {                tracker.initialize(frame, bbox);            }        }    }// 清理资源    cap.release();destroyAllWindows();}intmain(int argc, char** argv){runTracker(0, "CSRT");  // 使用摄像头,CSRT算法return 0;}

三、编译与运行说明

Python版本运行

# 安装依赖(使用清华镜像源,下载速度快一些)pip install opencv-python==3.4.15.55 opencv-contrib-python==3.4.15.55 numpy==1.24.4 -i https://pypi.tuna.tsinghua.edu.cn/simple/# 运行python tracker.py 

C++版本编译

# 使用CMake编译mkdir buildcd buildcmake ..make# 运行程序./tracker_demo test.mp4 KCF

四、总结和使用建议

算法
速度
准确性
抗遮挡
适用场景
BOOSTING
慢
中等
差
简单场景,实时性要求不高
MIL
中等
中等
中等
一般跟踪任务
KCF
快
高
中等
实时跟踪,无严重遮挡
TLD
慢
高
高
长时跟踪,目标可能消失重现
MedianFlow
快
中等
差
匀速直线运动目标
MOSSE
很快
中等
差
极速跟踪需求
CSRT
中等
高
高
高精度跟踪
GOTURN
中等
高
高
复杂场景,GPU加速
  1. 1. 实时性要求高:选择KCF或MOSSE
  2. 2. 精度要求高:选择CSRT或GOTURN
  3. 3. 抗遮挡需求:选择TLD或CSRT
  4. 4. 简单场景:选择MedianFlow或MOSSE
  5. 5. CPU环境:避免使用GOTURN
  6. 6. 长时跟踪:建议使用TLD

最新文章

随机文章