【opencv】教程代码 —features2D(1)AKAZE_tracking 追踪给定视频中的目标对象

本文介绍了一个基于OpenCV的视觉追踪系统,利用AKAZE和ORB算法进行目标对象的特征检测和匹配,通过RANSAC和统计信息来实时更新目标边界框,展示了追踪过程中的关键点匹配、内点检测和帧率计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用了OpenCV的AKAZE和ORB算法来追踪给定视频中的目标对象

b1655de6c03e86274eb9b18381619874.png

69335afdfdb130ec5ba300450c7da21c.png

这段代码是一个简单的视觉追踪系统,使用了OpenCV的AKAZE和ORB算法来追踪给定视频中的目标对象。主要包含一下几个部分:

  1. Tracker类:这是核心的追踪类,包括下面重要的方法;

  • setFirstFrame: 这个方法设置了第一帧图像及目标的边界包围框。它先根据给定的边界框,得到掩膜图像,然后提取特征点和特征描述符。

  • process: 这个方法处理每一帧图像,提取其特征点及描述符,并与第一帧进行匹配、模型拟合,得到当前帧的目标边界包围框。

main函数:主函数首先进行初始化工作,比如解析命令行参数,创建检测器(AKAZE和ORB)和匹配器,初始化两个Tracker。然后进入一个循环中,处理每一帧图像,每10帧更新一次统计信息,最后打印整体的统计信息。

#include <opencv2/features2d.hpp>       // 导入OpenCV特征检测库
#include <opencv2/videoio.hpp>          // 导入OpenCV视频输入输出库
#include <opencv2/imgproc.hpp>          // 导入OpenCV图像处理库
#include <opencv2/calib3d.hpp>          // 导入OpenCV相机标定和三维重建库
#include <opencv2/highgui.hpp>          // 导入OpenCV显示图像的库
#include <vector>                       // 导入标准模版库中的向量库
#include <iostream>                     // 导入输入输出流库
#include <iomanip>                      // 导入输入输出流操作库


#include "stats.h"                      // 导入统计结构体的定义
#include "utils.h"                      // 导入绘图和打印功能的工具库


using namespace std;                   // 使用标准命名空间
using namespace cv;                    // 使用OpenCV命名空间


// 定义一些常量参数
const double akaze_thresh = 3e-4;       // AKAZE检测阈值, 用于定位大约1000个关键点 控制AKAZE算法的特征点检测敏感度。
const double ransac_thresh = 2.5f;      // RANSAC内点阈值
const double nn_match_ratio = 0.8f;     // 最近邻匹配比率
const int bb_min_inliers = 100;         // 绘制边界框的最少内点数
const int stats_update_period = 10;     // 每10帧更新一次屏幕上的统计信息


// 定义example命名空间下的Tracker类
namespace example {
class Tracker
{
public:
    Tracker(Ptr<Feature2D> _detector, Ptr<DescriptorMatcher> _matcher) :
        detector(_detector),
        matcher(_matcher)
    {}


    // 设置视频的第一帧以及目标边界框
    void setFirstFrame(const Mat frame, vector<Point2f> bb, string title, Stats& stats);
    // 处理视频的每一帧
    Mat process(const Mat frame, Stats& stats);
    // 获取特征检测器
    Ptr<Feature2D> getDetector() {
        return detector;
    }


protected:
    Ptr<Feature2D> detector;               // 特征检测器指针
    Ptr<DescriptorMatcher> matcher;        // 描述子匹配器指针
    Mat first_frame, first_desc;           // 第一帧和它的描述子
    vector<KeyPoint> first_kp;             // 第一帧中的关键点
    vector<Point2f> object_bb;             // 目标的边界框
};


// setFirstFrame 函数实现
void Tracker::setFirstFrame(const Mat frame, vector<Point2f> bb, string title, Stats& stats)
{
    // 根据边界框创建掩码
    // 使用new关键字动态创建一个Point类型的数组,大小为bb容器的大小
    cv::Point *ptMask = new cv::Point[bb.size()];
    // 创建指向Point数组的指针数组,准备传递给绘图函数
    const Point* ptContain = { &ptMask[0] };
    // 计算bb容器大小,并转换为int类型
    int iSize = static_cast<int>(bb.size());
    // 遍历bb容器中的所有Point2f点
    for (size_t i=0; i<bb.size(); i++) {
        // 将每个Point2f点转换为Point,并赋值给前面创建的Point数组
        ptMask[i].x = static_cast<int>(bb[i].x);
        ptMask[i].y = static_cast<int>(bb[i].y);
    }
    first_frame = frame.clone();               // 克隆帧到first_frame
    cv::Mat matMask = cv::Mat::zeros(frame.size(), CV_8UC1); // 创建和第一帧同样大小的掩码Mat
    cv::fillPoly(matMask, &ptContain, &iSize, 1, cv::Scalar::all(255)); // 将所选区域填充为255
    // 用掩码检测特征点并计算描述子
    detector->detectAndCompute(first_frame, matMask, first_kp, first_desc);
    stats.keypoints = (int)first_kp.si
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值