ORB特征追踪

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

// 使用ORB特征检测器和描述符提取器
Ptr<ORB> detector = ORB::create();

// 特征匹配器
BFMatcher matcher(NORM_HAMMING);

int main()
{
    // 打开视频文件
    VideoCapture cap("video0.mp4");
    if (!cap.isOpened())
    {
        cerr << "无法打开视频文件" << endl;
        return -1;
    }

    // 存储前一帧的特征点和描述符
    Mat prevFrame, prevDescriptors;
    vector<KeyPoint> prevKeypoints;

    // 读取第一帧
    if (!cap.read(prevFrame))
    {
        cerr << "无法读取视频帧" << endl;
        return -1;
    }

    // 调整帧大小
    resize(prevFrame, prevFrame, Size(1280, 960));

    // 提取第一帧的特征
    detector->detectAndCompute(prevFrame, noArray(), prevKeypoints, prevDescriptors);

    namedWindow("Video", WINDOW_NORMAL);
    resizeWindow("Video", 1280, 960);
    int i = 0;

    while (true)
    {
        Mat frame, descriptors;
        vector<KeyPoint> keypoints;

        // 读取下一帧
        if (!cap.read(frame))
            break;

        // 提取当前帧的特征
        detector->detectAndCompute(frame, noArray(), keypoints, descriptors);

        // 进行特征匹配
        vector<DMatch> matches;
        matcher.match(prevDescriptors, descriptors, matches);

        // 筛选好的匹配点
        double max_dist = 0;
        double min_dist = 100;
        for (int i = 0; i < prevDescriptors.rows; i++)
        {
            double dist = matches[i].distance;
            if (dist < min_dist)
                min_dist = dist;
            if (dist > max_dist)
                max_dist = dist;
        }

        vector<DMatch> good_matches;
        for (int i = 0; i < prevDescriptors.rows; i++)
        {
            if (matches[i].distance <= max(2 * min_dist, 30.0))
            {
                good_matches.push_back(matches[i]);
            }
        }

        // 统计提取的特征数量和正确追踪的特征数量
        int extractedFeatures = keypoints.size();
        int trackedFeatures = good_matches.size();

        cout << "第" << ++i << "次提取的特征数量: " << extractedFeatures << endl;
        cout << "正确追踪的特征数量: " << trackedFeatures << endl;
        cout << "--------------------------------------------------" << endl;

        // 可视化匹配结果
        Mat img_matches;
        drawMatches(prevFrame, prevKeypoints, frame, keypoints, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
        // 在图像上显示特征数量信息
        stringstream ss;
        ss << "提取的特征数量: " << extractedFeatures << " 正确追踪的特征数量: " << trackedFeatures;
        putText(img_matches, ss.str(), Point(10, img_matches.rows - 10), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1, LINE_AA);

        imshow("Video", img_matches);

        // 更新上一帧的数据
        prevFrame = frame.clone();
        prevKeypoints = keypoints;
        prevDescriptors = descriptors;

        // 等待30ms,按下任意键退出
        char c = (char)waitKey(30);
        if (c == 27)
            break; // 按下ESC键退出
    }

    return 0;
}

读取视频前后帧特征追踪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值