【opencv】dnn示例-vit_tracker.cpp 使用OpenCV库和ViTTrack模型实现的视频追踪程序

65e0bcc15f7c222f50af0787fdd9b984.png

这段代码是一个使用OpenCV库和ViTTrack模型实现的视频追踪程序。程序通过摄像头或视频文件获取图像序列,并对选定的目标对象进行实时追踪。

代码主要分为以下几个部分:

导入必要的库:程序开始时先导入了iostream,cmath以及相关OpenCV的库。

参数解析:通过定义一个参数字典keys来解析命令行输入的参数,这些参数包括输入的视频源、模型的路径以及计算后端等。

追踪器的创建与设置:使用给定的模型文件以及命令行参数中的后端和目标设备选项,创建一个ViT追踪器对象。

视频捕获:程序尝试打开摄像头或读取视频文件。如果指定了摄像头或视频文件但不能成功打开,程序将输出错误信息。

目标对象的选择:获取视频的第一帧,并让用户选择一个区域作为追踪的初始目标。

追踪循环:程序进入一个循环,不断从视频源获取新的帧,并使用追踪器更新目标位置。每一次追踪完成后,都会输出框架的计数、预测分数、目标位置方框以及每帧追踪耗时。

追踪结果展示:将追踪的结果(目标位置的矩形框及其分数)覆盖在原图像上,并在窗口中展示出来。

退出处理:程序会在按下ESC键后退出追踪循环,并关闭程序。

整体而言,代码实现了一个基于ViT追踪模型的视频目标追踪系统,包含了从视频源获取图像、初始化追踪目标、连续追踪目标以及展示追踪结果等功能。程序使用OpenCV的DNN模块加载ONNX格式的深度学习模型,并通过选择合适的后端(例如CUDA)和目标设备来加速计算过程。

// VitTracker
// model: https://github.com/opencv/opencv_zoo/tree/main/models/object_tracking_vittrack#include <iostream> // 引入输入输出流库
#include <cmath> // 引入数学运算库#include <opencv2/dnn.hpp> // 引入OpenCV深度神经网络模块
#include <opencv2/imgproc.hpp> // 引入OpenCV图像处理模块
#include <opencv2/highgui.hpp> // 引入OpenCV高级用户界面模块
#include <opencv2/video.hpp> // 引入OpenCV视频处理模块using namespace cv; // 使用cv命名空间简化代码
using namespace cv::dnn; // 使用cv::dnn命名空间简化代码const char *keys = // 定义命令行参数"{ help     h  |   | Print help message }" // 打印帮助信息"{ input    i  |   | Full path to input video folder, the specific camera index. (empty for camera 0) }" // 输入视频路径或摄像头索引(默认为0)"{ net    | object_tracking_vittrack_2023sep.onnx | Path to onnx model of vitTracker.onnx}" // vitTracker.onnx模型的路径"{ backend     | 5 | Choose one of computation backends: " // 选择计算后端"0: automatically (by default), " // 自动选择"1: Halide language (http://halide-lang.org/), " // Halide语言"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), " // 英特尔深度学习推理引擎"3: OpenCV implementation, " // OpenCV实现"4: VKCOM, " // VKCOM"5: CUDA }," // CUDA"{ target      | 6 | Choose one of target computation devices: " // 选择目标计算设备"0: CPU target (by default), " // CPU"1: OpenCL, " // OpenCL"2: OpenCL fp16 (half-float precision), " // OpenCL fp16 (半精度浮点)"3: VPU, " // VPU"4: Vulkan, " // Vulkan"6: CUDA, " // CUDA"7: CUDA fp16 (half-float preprocess) }" // CUDA fp16 (半精度预处理)
;static
int run(int argc, char** argv) // 定义主要运行函数
{// Parse command line arguments.CommandLineParser parser(argc, argv, keys); // 命令行参数解析if (parser.has("help")) // 如果存在帮助参数{parser.printMessage(); // 打印帮助信息return 0;}std::string inputName = parser.get<String>("input"); // 获取输入源std::string net = parser.get<String>("net"); // 获取模型路径int backend = parser.get<int>("backend"); // 获取后端参数int target = parser.get<int>("target"); // 获取目标计算设备参数Ptr<TrackerVit> tracker; // 声明一个ViT跟踪器的智能指针try // 尝试加载跟踪器和模型{TrackerVit::Params params; // 创建跟踪器参数结构params.net = samples::findFile(net); // 找到或保持模型文件路径params.backend = backend; // 设置后端参数params.target = target; // 设置目标计算设备参数tracker = TrackerVit::create(params); // 创建跟踪器实例}catch (const cv::Exception& ee) // 如果捕获到异常{std::cerr << "Exception: " << ee.what() << std::endl; // 打印异常信息std::cout << "Can't load the network by using the following files:" << std::endl; // 说明无法加载网络std::cout << "net : " << net << std::endl; // 打印网络路径return 2;}const std::string winName = "vitTracker"; // 窗口名称namedWindow(winName, WINDOW_AUTOSIZE); // 创建具有自动大小的窗口// Open a video file or an image file or a camera stream.VideoCapture cap; // 创建视频捕获对象if (inputName.empty() || (isdigit(inputName[0]) && inputName.size() == 1)) // 如果输入为空或仅有单个数字(表示摄像头索引){int c = inputName.empty() ? 0 : inputName[0] - '0'; // 默认为0或转换数字为摄像头索引std::cout << "Trying to open camera #" << c << " ..." << std::endl;if (!cap.open(c)) // 尝试打开摄像头{std::cout << "Capture from camera #" << c << " didn't work. Specify -i=<video> parameter to read from video file" << std::endl; // 打开失败提示return 2;}}else if (inputName.size()) // 如果输入非空{inputName = samples::findFileOrKeep(inputName); // 查找或保持文件路径if (!cap.open(inputName)) // 尝试打开视频文件{std::cout << "Could not open: " << inputName << std::endl; // 打开失败提示return 2;}}// Read the first image.Mat image; // 创建一个Mat对象用于存放图像cap >> image; // 捕获一帧图像if (image.empty()) // 如果图像为空{std::cerr << "Can't capture frame!" << std::endl; // 抓取图像失败提示return 2;}Mat image_select = image.clone(); // 克隆捕获的图像以便用户选择跟踪区域putText(image_select, "Select initial bounding box you want to track.", Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); // 在图像上添加文字指导用户选择跟踪区域putText(image_select, "And Press the ENTER key.", Point(0, 35), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); // 提示用户按下回车键确认选择Rect selectRect = selectROI(winName, image_select); // 让用户选择一个区域并返回矩形坐标std::cout << "ROI=" << selectRect << std::endl; // 输出用户选择的区域tracker->init(image, selectRect); // 初始化跟踪器并使用用户选择的区域TickMeter tickMeter; // 创建一个时钟计时器对象for (int count = 0; ; ++count) // 循环处理视频帧{cap >> image; // 捕获一帧图像if (image.empty()) // 如果图像为空{std::cerr << "Can't capture frame " << count << ". End of video stream?" << std::endl; // 抓取图像失败提示break;}Rect rect; // 创建一个矩形对象tickMeter.start(); // 开始计时bool ok = tracker->update(image, rect); // 更新跟踪器状态并返回跟踪框的位置tickMeter.stop(); // 停止计时float score = tracker->getTrackingScore(); // 获取跟踪评分std::cout << "frame " << count << // 输出当前帧数": predicted score=" << score << // 输出预测评分"  rect=" << rect << // 输出跟踪框位置"  time=" << tickMeter.getTimeMilli() << "ms" << // 输出计时时间std::endl;Mat render_image = image.clone(); // 克隆当前帧以便绘制跟踪结果if (ok) // 如果跟踪成功{rectangle(render_image, rect, Scalar(0, 255, 0), 2); // 在渲染图像上绘制跟踪框std::string timeLabel = format("Inference time: %.2f ms", tickMeter.getTimeMilli()); // 格式化输出计时标签std::string scoreLabel = format("Score: %f", score); // 格式化输出评分标签putText(render_image, timeLabel, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); // 将计时标签绘制在图像上putText(render_image, scoreLabel, Point(0, 35), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); // 将评分标签绘制在图像上}imshow(winName, render_image); // 显示渲染后图像tickMeter.reset(); // 重置计时器int c = waitKey(1); // 等待按键if (c == 27 /*ESC*/) // 如果按下ESC键break; // 退出循环}std::cout << "Exit" << std::endl; // 输出退出提示return 0; // 返回成功
}int main(int argc, char **argv) // 主程序入口函数
{try // 尝试运行主功能函数{return run(argc, argv); // 调用run函数并返回结果}catch (const std::exception& e) // 捕获任何抛出的异常{std::cerr << "FATAL: C++ exception: " << e.what() << std::endl; // 输出异常信息return 1; // 返回失败}
}

该代码是使用OpenCV库实现的一个简单的视频跟踪应用程序。它主要通过解析命令行输入不同的参数来调整视频输入源、选择神经网络模型、计算后端以及目标计算设备。代码首先尝试加载一个基于ViT(Vision Transformer)的目标跟踪器模型。接下来,它通过用户选择的图像区域初始化跟踪器并开始对视频流中的目标进行跟踪。每个循环中,都会更新跟踪器并计算其评分以及跟踪目标的位置,然后将跟踪结果绘制在每帧上并实时显示给用户。如果用户按下ESC键,则会退出循环结束程序。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TCP-IP详解卷一:协议 第2章 链路层——阅读总结——

该内容适合程序员查看 第2章 链路层 2.1 引言 链路层有三个目的&#xff1a; 1.为IP模块发送和接收IP数据报&#xff1b; 2.为ARP模块发送ARP请求和接收ARP应答&#xff1b; 3.为RARP发送RARP请求和接收RARP应答&#xff1b; 2.2 以太网和IEEE 802封装 以太网&#xff1a;带…

视频教程下载:用ChatGPT快速提升股票投资能力

学完此视频后可以获得&#xff1a; 学习如何使用人工智能/Chatgpt进行基础/快速/高级财务与研究分析 学习如何使用人工智能/Chatgpt对任何公司进行定性投资研究 学习如何使用人工智能/Chatgpt对任何公司进行定量投资研究 学习如何使用人工智能/Chatgpt创建、预测和分析财务…

OpenHarmony UI动画-recyclerview_animators

简介 带有添加删除动画效果以及整体动画效果的list组件库 下载安装 ohpm install ohos/recyclerview-animatorsOpenHarmony ohpm 环境配置等更多内容&#xff0c;请参考如何安装OpenHarmony ohpm 包 使用说明 引入组件库 import { RecyclerView } from "ohos/recycler…

SOLIDWORKS Composer如何使用3D工具实现更真实的动画效果

当我们使用SOLIDWORKS composer创建动画时&#xff0c;往往会涉及到产品的安装与拆解&#xff0c;现实生活中我们在拆卸组装产品的时候&#xff0c;我们往往需要一些工具的协助&#xff0c;比如扳手、螺丝刀等等&#xff0c;那么我们如何在虚拟动画中也将这一过程以逼真的形式展…

前端项目的导入和启动

安装依赖 前端安装依赖只需要在控制台执行“npm i”即可。Tips&#xff1a;当我们执行的时候&#xff0c;有时候会很慢。可以考虑使用yarn或者pnpm。然而使用yarn或者pnpm有时候有一些莫名其妙的问题。所以还是得使用npm&#xff0c; 这个时候可以通过更换镜像源为淘宝镜像源。…

安卓xml存储读取和sharedpreferences文件存储读取

起因今天有人问到我 xml文件存储读取和sharedpreferences读写该咋做&#xff0c;能不能帮忙写个案例&#xff0c;这里我简单写出一个案例&#xff0c;一下是全部的代码 一、首先引入 权限 <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE&q…

OpenHarmony UI开发-ohos-svg

简介 ohos-svg是一个SVG图片的解析器和渲染器&#xff0c;解析SVG图片并渲染到页面上。它支持大部分 SVG 1.1 规范&#xff0c;包括基本形状、路径、文本、样式和渐变,它能够渲染大多数标准的 SVG 图像。ohos-svg的优点是性能好、内存占用低。 效果展示 SVG图片解析并绘制: …

【网站项目】新生报到系统小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

RIP最短路实验(华为)

思科设备参考&#xff1a;RIP最短路实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是一种基于距离矢量的内部网关协议&#xff0c;工作原理是每个路由器周期性地向邻居路由器发…

C++笔记:类和对象(二)

对象和引用 代码演示&#xff1a; #include<iostream> using namespace std;class A { public :A() default;A(const A&) default; private :};class B { public :B(A &a) : a(a) {} private :A &a; };class C { public :C() default;C(const C &) …

深入解析Apache Hadoop YARN:工作原理与核心组件

什么是YARN&#xff1f; YARN&#xff08;Yet Another Resource Negotiator&#xff09;是Apache Hadoop生态系统中的一个重要组件&#xff0c;用于资源管理和作业调度。它是Hadoop 2.x版本中的一个关键特性&#xff0c;取代了旧版本中的JobTracker和TaskTracker。YARN的设计目…

VUE 弹框内容懒加载-真实项目

背景&#xff1a;VUE 页面&#xff0c;点击按钮&#xff0c;弹框&#xff0c;内容从接口获取&#xff0c;数据量比较大&#xff0c;鼠标滑到页面最底部&#xff0c;调取一次接口&#xff0c;分批加载&#xff1b; demo&#xff1a; <template><div><!-- 触发弹…