[C++]基于C++opencv结合vibe和sort tracker实现高空抛物实时检测

【vibe算法介绍】

ViBe算法是一种高效的像素级视频背景建模和前景检测算法。以下是对该算法的详细介绍:

一、算法原理

ViBe算法的核心思想是通过为每个像素点存储一个样本集,利用该样本集与当前像素值进行比较,从而判断该像素是否属于背景。算法的主要步骤包括背景模型的初始化、前景检测过程和背景模型的更新方法。

  1. 背景模型的初始化
    • 在初始时刻(如第一帧图像),为每个像素点随机选择其邻域像素的像素值作为背景模型的样本值。这样可以确保背景模型在开始时即具有一定的鲁棒性。
  2. 前景检测过程
    • 对于后续的图像序列,算法会将每个新的像素值与背景模型中的样本进行比较。
    • 如果新像素值与背景模型中的样本值差异小于预设的阈值,则该像素被判定为背景;否则,被判定为前景。
  3. 背景模型的更新方法
    • ViBe算法的更新策略具有时间和空间上的随机性。
    • 在时间随机性方面,算法会随机选择一个背景模型进行更新,以模拟像素值随时间变化的不确定性。
    • 在空间随机性方面,算法会在被判定为背景的像素点的邻域中随机选择一个像素值来更新背景模型,以模拟像素值在空间上的变化。

二、算法优点

  1. 内存占用少:由于每个像素只需存储一个样本集,因此内存占用较少。
  2. 性能优越:算法的性能优于混合高斯、参数化方法等传统方法,尤其在处理动态背景时表现出色。
  3. 无参数法:算法无需手动调整参数,可以直接应用于各种场景。
  4. 抗噪能力强:由于采用随机更新策略,算法对噪声具有较强的鲁棒性。

三、算法挑战与限制

  1. Ghost区域:在某些情况下,算法可能会出现误检,将前景物体误判为背景,形成所谓的“Ghost”区域。
  2. 环境变化适应性:算法需要能够适应环境的变化,如光照变化、相机抖动等。
  3. 密集物体检测:对于图像中密集出现的物体(如树叶、树干等),算法的检测效果可能受到一定影响。

综上所述,ViBe算法是一种高效、鲁棒的像素级视频背景建模和前景检测算法,具有广泛的应用前景。然而,在实际应用中仍需注意其挑战与限制,并进行相应的优化和改进。

【sort track算法介绍】

SORT(Simple Online and Realtime Tracking)算法是一种简单、高效且实用的多目标跟踪算法。以下是对SORT算法的介绍,内容将按照清晰的格式分点表示,并尽可能参考文章中的相关数字和信息:

一、算法概述

  • 全称:Simple Online and Realtime Tracking(SORT)
  • 特点:简单、高效、实时性强
  • 应用领域:适用于各种需要实时多目标跟踪的场景,如监控视频分析、自动驾驶汽车感知、无人机追踪等

二、算法原理

1. 核心组件
  • 卡尔曼滤波:用于预测目标在下一帧中的位置。卡尔曼滤波基于前一帧的目标位置和速度来预测当前帧的目标位置,并基于测量值(即检测到的目标位置)来更新预测值,以达到更精确的估计。
  • 匈牙利算法:用于解决数据关联问题,即确定前后两帧中真正匹配的目标。匈牙利算法通过计算前后两帧目标之间的相似度矩阵,并求解该矩阵来找到最佳匹配。
2. 工作流程
  1. 目标检测:使用目标检测器(如Faster R-CNN)在每一帧中检测目标,得到目标框(Detections)。
  2. 预测:使用卡尔曼滤波器预测当前帧的轨迹(Tracks)。
  3. 匹配:将目标框(Detections)和轨迹(Tracks)进行IOU(Intersection over Union)匹配。匹配结果分为三种:
    • Matched Track:成功匹配的目标和轨迹。
    • Unmatched Tracks:未能成功匹配的目标轨迹,被认为是失配。如果失配持续了T次(T是一个预设的阈值),该目标ID将从待跟踪目标中删除。
    • Unmatched Detections:未能成功匹配到轨迹的目标框,需要为其分配一个新的轨迹。
  4. 更新:卡尔曼滤波根据匹配的轨迹状态预测下一帧的目标框状态,并更新所有轨迹的状态。

三、算法特点

  • 实时性强:由于算法复杂度低,SORT算法可以实现高速跟踪,据参考文章所述,追踪器可以实现260Hz的速度。
  • 简单易用:代码结构清晰,依赖库少,便于理解和集成到其他项目中。
  • 兼容性强:可在Windows和Linux环境下运行,适用范围广。
  • 灵活性:提供参数调整,适应不同场景的需求。

四、优缺点

  • 优点
    • 速度快:处理速度快,适用于实时应用。
    • 准确性高:在没有遮挡的情况下,准确性较高。
  • 缺点
    • 对遮挡处理不足:当目标被遮挡时,ID切换次数较高,可能导致跟踪不准确。
    • 未考虑目标外观特征:仅使用检测框的位置和大小进行目标匹配,未考虑目标的外观特征。

五、总结

SORT算法以其简单、高效和实时性强的特点,在多目标跟踪领域具有广泛的应用前景。然而,在实际应用中仍需注意其处理遮挡和目标外观特征方面的限制,并根据具体需求进行相应的优化和改进。

【测试环境】

vs2019

opencv==4.8.0

x64 release(Debug暂时没测试通过)

【部分实现源码】

#define _CRT_SECURE_NO_WARNINGS
#include "tracker.hpp"
#include "trajectory.hpp"
#include "utils.hpp"
#include "vibe_sequential.hpp"
#include <array>
#include <chrono>
#include <cmath>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <stdexcept>
#include <string>
#include <string_view>
#include <thread>
using namespace std;
using namespace cv;
int main(int argc, char* argv[]) {
   

  
    int maxNumBlobs = 64;
    VideoCapture capture("test.mp4");
    if (!capture.isOpened())
        return -1;
    double fps = capture.get(cv::CAP_PROP_FPS);          // 帧率
    int width = capture.get(cv::CAP_PROP_FRAME_WIDTH);   // 视频帧宽度
    int height = capture.get(cv::CAP_PROP_FRAME_HEIGHT); // 视频帧高度
      // Create vibe algorithm instance
    auto vibe = std::make_unique<ViBeSequential>(height, width, 14, 20, 2, 5);
    // Create tracker instance
    auto tracker = std::make_unique<SortTracker>(3, 3);

    auto detections = std::vector<cv::Rect2f>(8);
    cv::Mat fgMask(height, width, CV_8U);
    cv::Mat updateMask(height, width, CV_8U);
    cv::Mat fgBlobLabels(height, width, CV_32S);
    cv::Mat fgBlobCentroids(64, 2, CV_64F);
    cv::Mat fgBlobStats(64, 5, CV_32S);

    // Prepare structure elements for morphological filtering
    cv::Mat se3x3 = cv::getStructuringElement(cv::MORPH_ELLIPSE, { 3, 3 });
    cv::Mat se5x5 = cv::getStructuringElement(cv::MORPH_ELLIPSE, { 5, 5 });
    cv::Mat se7x7 = cv::getStructuringElement(cv::MORPH_ELLIPSE, { 7, 7 });

    // Prepare runtime measurement
    auto tm = cv::TickMeter();



    while (true)
    {
        Mat frame;
        capture >> frame; // 从相机读取新一帧
        if (frame.empty())
        {
            break;
        }

        /* Segmentation and update. */
        tm.reset();
        tm.start();
        // Run background segmentation with ViBe
        vibe->segment(frame, fgMask);

        // Process update mask
        cv::morphologyEx(fgMask, updateMask, cv::MORPH_OPEN, se3x3);

        // Update ViBe
        vibe->update(frame, updateMask);

        // Post-processing on foreground mask
        cv::morphologyEx(fgMask, fgMask, cv::MORPH_OPEN, se3x3);
        cv::morphologyEx(fgMask, fgMask, cv::MORPH_CLOSE, se5x5);

        tm.stop();

        double vibeProcessTimeMs = tm.getTimeMilli();

        // Find all connected components
        int numFgBlobs = cv::connectedComponentsWithStats(
            fgMask, fgBlobLabels, fgBlobStats, fgBlobCentroids);

        if (numFgBlobs > maxNumBlobs) {
            // Too many blobs, consider this frame invalid

            tracker->clear();
            continue;
        }

        detections.clear();
        for (int i = 1; i < numFgBlobs; i++) {
            auto* blobStat = fgBlobStats.ptr<int>(i);

            int x = blobStat[cv::CC_STAT_LEFT] - 6;
            int y = blobStat[cv::CC_STAT_TOP] - 6;
            int w = blobStat[cv::CC_STAT_WIDTH] + 12;
            int h = blobStat[cv::CC_STAT_HEIGHT] + 12;
            // int a = blobStat[cv::CC_STAT_AREA];

            // Add new bbox
            detections.emplace_back(x, y, w, h);

            // auto color = colors.row(i % colors.rows);
            cv::rectangle(frame, { x, y, w, h }, { 255, 50, 0 }, 1);
        }

        tm.reset();
        tm.start();

        // Update tracker with newly detected bboxes
        tracker->update(detections, frame);

        tm.stop();
        double trackingTimeMs = tm.getTimeMilli();

        std::array<char, 64> str;
        std::sprintf(str.data(),
            "[PROCESS TIME] ViBe: %.2f ms, Tracking: %.2f",
            vibeProcessTimeMs,
            trackingTimeMs);

        // Draw process time measurement result on current frame
        cv::putText(frame,
            str.data(),
            { 12, 30 },
            cv::FONT_HERSHEY_SIMPLEX,
            0.5,
            { 0, 0, 255 },
            1,
            cv::LINE_AA);


        cv::imshow("frame", frame);
        cv::imshow("fgmask", fgMask);
        cv::imshow("update mask", updateMask);

        if (char(waitKey(2)) == 'q')
        {

            break;
        }
    }
    
    capture.release();
    cv::destroyAllWindows();


}

【效果展示】

【视频演示】

基于C++opencv结合vibe和sort tracker实现高空抛物实时检测_哔哩哔哩_bilibili【测试环境】vs2019opencv==4.8.0x64 release(Debug暂时没测试通过)更多信息参考博文:blog.csdn.net/FL1623863129/article/details/139493227, 视频播放量 6、弹幕量 0、点赞数 0、投硬币枚数 0、收藏人数 0、转发人数 0, 视频作者 未来自主研究中心, 作者简介 未来自主研究中心,相关视频:基于onnx模型加密与解密深度学习模型保护方法介绍,使用纯opencv部署yolov8目标检测模型onnx,C++版本yolov8的onnx模型加密方法保护自己模型和版权,将yolov8封装成一个类几行代码完成语义分割任务,使用C#的winform部署yolov8的onnx实例分割模型,使用C#调用libotrch-yolov5模型实现全网最快winform目标检测,Python自动答题脚本刷题,100%正确率,附源码!可刷课!期末再也不用担心挂科了!Python教程Python入门编程入门爬虫代码Python基础安装,C#调用yolov7进行目标检测winform开发,基于yolov8官方目标追踪botsort和bytetrack源码开发视频演示,使用C#部署openvino-yolov5s模型icon-default.png?t=N7T8https://www.bilibili.com/video/BV1zD421g7zR/?vd_source=989ae2b903ea1b5acebbe2c4c4a635ee

【源码下载地址】https://download.csdn.net/download/FL1623863129/89403409

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/694686.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot的学习要点

目录 SpringBoot 创建项目 配置文件 注解 命名规范 SpringBoot整合第三方技术 …… 中文文档&#xff1a;Spring Boot 中文文档 SpringBoot Spring Boot 是基于 Spring 框架的一种快速构建微服务应用的方式它主要提供了自动配置、简化配置、运行时应用监控等功能它…

vue2中的插槽使用以及Vuex的使用

插槽分为默认插槽&#xff0c;定名插槽还有作用域插槽 一.默认插槽&#xff0c;定名插槽 //app.vue <template> <div class"container"><CategoryTest title"美食" :listData"foods"><img slot"center" src&qu…

NotebookLM全新升级:Gemini 1.5 Pro助力全球研究与写作

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Python第二语言(九、Python第一阶段实操)

目录 1. json数据格式 2. Python与json之间的数据转换 3. pyecharts模块官网 4. pyecharts快速入门&#xff08;折线图&#xff09; 5. pyecharts全局配置选项 5.1 set_global_ops使用 5.1.1. title_opts 5.1.2 legend_opts 5.1.3 toolbox_opts 5.1.4 visualmap_opts…

L47---2706. 购买两块巧克力(排序)---Java版

1.题目描述 2.思路 &#xff08;1&#xff09;排序&#xff1a;从最便宜的巧克力开始组合 &#xff08;2&#xff09;双循环遍历所有可能的两块巧克力组合&#xff0c;计算其总花费。如果总花费小于等于 money&#xff0c;则更新最大剩余金额 &#xff08;3&#xff09;由于价…

度小满金融大模型的应用创新

XuanYuan/README.md at main Duxiaoman-DI/XuanYuan GitHub

jmeter性能优化之mysql监控sql慢查询语句分析

接上次博客&#xff1a;基础配置 多用户登录并退出jmx文件&#xff1a;百度网盘 提取码&#xff1a;0000 一、练习jmeter脚本检测mysql慢查询 随意找一个脚本(多用户登录并退出)&#xff0c;并发数设置300、500后分别查看mysql监控平台 启动后查看&#xff0c;主要查看mysql…

Linux安装MySQL教程【带图文命令巨详细】

巨详细Linux安装MySQL 1、查看是否有自带数据库或残留数据库信息1.1检查残留mysql1.2检查并删除残留mysql依赖1.3检查是否自带mariadb库 2、下载所需MySQL版本&#xff0c;上传至系统指定位置2.1创建目录2.2下载MySQL压缩包 3、安装MySQL3.1创建目录3.2解压mysql压缩包3.3安装解…

Ajax 快速入门

Ajax 概念&#xff1a;Ajax是一种Web开发技术&#xff0c;允许在不重新加载整个页面的情况下&#xff0c;与服务器交换数据并更新网页的部分内容。 作用&#xff1a; 数据交换&#xff1a;Ajax允许通过JavaScript向服务器发送请求&#xff0c;并能够接收服务器响应的数据。 异…

hustoj二开

目录 1、路径问题2、开发问题&#xff08;1&#xff09;、mysql&#xff08;2&#xff09;、php 啊啊啊啊&#xff01;&#xff01;&#xff01;难崩&#xff1a; 路径问题搞了好长时间才明白了该项目的路径如何设置的 >_< ,&#xff0c;本文就路径问题&#xff0c;前端页…

梯度提升决策树(GBDT)

GBDT&#xff08;Gradient Boosting Decision Tree&#xff09;&#xff0c;全名叫梯度提升决策树&#xff0c;是一种迭代的决策树算法&#xff0c;又叫 MART&#xff08;Multiple Additive Regression Tree&#xff09;&#xff0c;它通过构造一组弱的学习器&#xff08;树&am…

【C语言】轻松拿捏-联合体

谢谢观看&#xff01;希望以下内容帮助到了你&#xff0c;对你起到作用的话&#xff0c;可以一键三连加关注&#xff01;你们的支持是我更新地动力。 因作者水平有限&#xff0c;有错误还请指出&#xff0c;多多包涵&#xff0c;谢谢&#xff01; 联合体 一、联合体类型的声明二…

DDMA信号处理以及数据处理的流程---随机目标生成

Hello&#xff0c;大家好&#xff0c;我是Xiaojie&#xff0c;好久不见&#xff0c;欢迎大家能够和Xiaojie一起学习毫米波雷达知识&#xff0c;Xiaojie准备连载一个系列的文章—DDMA信号处理以及数据处理的流程&#xff0c;本系列文章将从目标生成、信号仿真、测距、测速、cfar…

RabbitMQ(五)集群配置、Management UI

文章目录 一、安装RabbitMQ1、前置要求2、安装docker版复制第一个节点的.erlang.cookie进入各节点命令行配置集群检查集群状态 3、三台组合集群安装版rabbitmq节点rabbitmq-node2节点rabbitmq-node3节点 二、负载均衡&#xff1a;Management UI1、说明2、安装HAProxy3、修改配置…

找出链表倒数第k个元素-链表题

LCR 140. 训练计划 II - 力扣&#xff08;LeetCode&#xff09; 快慢指针。快指针臂慢指针快cnt个元素到最后&#xff1b; class Solution { public:ListNode* trainingPlan(ListNode* head, int cnt) {struct ListNode* quick head;struct ListNode* slow head;for(int i …

Spring配置多数据库(采用数据连接池管理)

一&#xff0c;前言 大家在开发过程中&#xff0c;如果项目大一点就会遇到一种情况&#xff0c;同一个项目中可能会用到很多个数据源&#xff0c;那么这篇文章&#xff0c;博主为大家分享在spring应用中如何采用数据库连接池的方式配置配置多数据源。 本篇文章采用大家用的最…

音视频转为文字SuperVoiceToText

音视频转为文字SuperVoiceToText&#xff0c;它能够把视频或语音文件高效地转换为文字&#xff0c;它是基于最为先进的 AI 大模型&#xff0c;通过在海量语音资料上进行训练学习而造就&#xff0c;具备极为卓越的识别准确率。 不仅如此&#xff0c;它支持包括汉语、英语、日语…

Java Set系列集合的使用规则和场景(HashSet,LinkedHashSet,TreeSet)

Set集合 package SetDemo;import java.util.HashSet; import java.util.Iterator; import java.util.Set;public class SetDemo {public static void main(String[] args) {/*Set集合的特点&#xff1a;1.Set系列集合的特点&#xff1a;Set集合是一个存储元素不能重复的集合方…