VS+QT+Opencv使用YOLOv4对视频流进行目标检测

对单张图像的检测,请参考:https://blog.csdn.net/qq_45445740/article/details/109659938

#include <fstream>
#include <sstream>
#include <iostream>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>using namespace cv;
using namespace dnn;
using namespace std;// 初始化参数
float confThreshold = 0.5; // 置信度
float nmsThreshold = 0.4;  // NMS
int inpWidth = 416;  // 网络输入图像的宽度
int inpHeight = 416; // 网络输入图像的高度
vector<string> classes;// 使用非最大值抑制去除低置信度的边界框
void postprocess(Mat& frame, const vector<Mat>& out);// 绘制预测的边界框
void drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat& frame);// 获取输出层的名称
vector<String> getOutputsNames(const Net& net);
void detect_image(string image_path, string modelWeights, string modelConfiguration, string classesFile);
void detect_video(string video_path, string modelWeights, string modelConfiguration, string classesFile);int main(int argc, char** argv)
{// 给出模型的配置和权重文件String modelConfiguration = "E:/00000000E/QT/pracitce/PcbDetectv2/01图像识别/model/yolo-obj.cfg";String modelWeights = "E:/00000000E/QT/pracitce/PcbDetectv2/01图像识别/model/yolo-obj_4000.weights";string image_path = "E:/00000000E/QT/pracitce/PcbDetectv2/01图像识别/image/01.jpg";string classesFile = "E:/00000000E/QT/pracitce/PcbDetectv2/01图像识别/model/classes.names";// "coco.names";// detect_image(image_path, modelWeights, modelConfiguration, classesFile);string video_path = "E:/00000000E/QT/pracitce/PcbDetectv2/02视频检测/video/test.mp4";detect_video(video_path, modelWeights, modelConfiguration, classesFile);cv::waitKey(0);return 0;
}void detect_image(string image_path, string modelWeights, string modelConfiguration, string classesFile) 
{// 加载分类类别ifstream ifs(classesFile.c_str());string line;while (getline(ifs, line)) classes.push_back(line);// 加载网络Net net = readNetFromDarknet(modelConfiguration, modelWeights);net.setPreferableBackend(DNN_BACKEND_OPENCV);net.setPreferableTarget(DNN_TARGET_OPENCL);// 打开视频文件或图像文件或摄像机流string str, outputFile;cv::Mat frame = cv::imread(image_path);// Create a windowstatic const string kWinName = "Deep learning object detection in OpenCV";namedWindow(kWinName, WINDOW_NORMAL);Mat blob;blobFromImage(frame, blob, 1 / 255.0, Size(inpWidth, inpHeight), Scalar(0, 0, 0), true, false);// 设置网络输入net.setInput(blob);// 运行前向传递以获得输出层的输出vector<Mat> outs;net.forward(outs, getOutputsNames(net));// 移除低置信度的边界框postprocess(frame, outs);// 返回推断的总时间(t)和每个层的计时(以layersTimes表示)vector<double> layersTimes;double freq = getTickFrequency() / 1000;double t = net.getPerfProfile(layersTimes) / freq;string label = format("Inference time for a frame : %.2f ms", t);putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255));// 写入带有检测框的帧imshow(kWinName, frame);cv::waitKey(30);
}void detect_video(string video_path, string modelWeights, string modelConfiguration, string classesFile) 
{string outputFile = "./yolo_out_cpp.avi";;ifstream ifs(classesFile.c_str());string line;while (getline(ifs, line)) classes.push_back(line);Net net = readNetFromDarknet(modelConfiguration, modelWeights);net.setPreferableBackend(DNN_BACKEND_OPENCV);net.setPreferableTarget(DNN_TARGET_CPU);VideoCapture cap;Mat frame, blob;try {// 打开视频文件ifstream ifile(video_path);if (!ifile) throw("error");cap.open(video_path);}catch (...) {cout << "Could not open the input image/video stream" << endl;return;}// Get the video writer initialized to save the output video//  video.open(outputFile, //	VideoWriter::fourcc('M', 'J', 'P', 'G'), 28, Size(cap.get(CAP_PROP_FRAME_WIDTH), cap.get(CAP_PROP_FRAME_HEIGHT)));static const string kWinName = "Deep learning object detection in OpenCV";namedWindow(kWinName, WINDOW_NORMAL);while (waitKey(1) < 0){cap >> frame;if (frame.empty()) {cout << "Done processing !!!" << endl;cout << "Output file is stored as " << outputFile << endl;waitKey(3000);break;}blobFromImage(frame, blob, 1 / 255.0, Size(inpWidth, inpHeight), Scalar(0, 0, 0), true, false);net.setInput(blob);vector<Mat> outs;net.forward(outs, getOutputsNames(net));postprocess(frame, outs);vector<double> layersTimes;double freq = getTickFrequency() / 1000;double t = net.getPerfProfile(layersTimes) / freq;string label = format("Inference time for a frame : %.2f ms", t);putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255));Mat detectedFrame;frame.convertTo(detectedFrame, CV_8U);imshow(kWinName, frame);}cap.release();
}void postprocess(Mat& frame, const vector<Mat>& outs)
{vector<int> classIds;vector<float> confidences;vector<Rect> boxes;for (size_t i = 0; i < outs.size(); ++i){// 扫描网络输出的所有边界框,只保留置信度高的边界框。将盒子的类标签指定为盒子得分最高的类float* data = (float*)outs[i].data;for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols){Mat scores = outs[i].row(j).colRange(5, outs[i].cols);Point classIdPoint;double confidence;// 获取最高分的值和位置minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);if (confidence > confThreshold){int centerX = (int)(data[0] * frame.cols);int centerY = (int)(data[1] * frame.rows);int width = (int)(data[2] * frame.cols);int height = (int)(data[3] * frame.rows);int left = centerX - width / 2;int top = centerY - height / 2;classIds.push_back(classIdPoint.x);confidences.push_back((float)confidence);boxes.push_back(Rect(left, top, width, height));}}}// 执行非最大抑制以消除置信度较低的冗余重叠框vector<int> indices;NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, indices);for (size_t i = 0; i < indices.size(); ++i){int idx = indices[i];Rect box = boxes[idx];drawPred(classIds[idx], confidences[idx], box.x, box.y,box.x + box.width, box.y + box.height, frame);}}// 绘制预测框
void drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat& frame)
{// 绘制显示边界框的矩形rectangle(frame, Point(left, top), Point(right, bottom), Scalar(255, 178, 50), 3);// 获取类名及其置信度的标签string label = format("%.2f", conf);if (!classes.empty()){CV_Assert(classId < (int)classes.size());label = classes[classId] + ":" + label;}// 在边界框的顶部显示标签int baseLine;Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);top = max(top, labelSize.height);rectangle(frame, Point(left, top - round(1.5 * labelSize.height)), Point(left + round(1.5 * labelSize.width), top + baseLine), Scalar(255, 255, 255), FILLED);putText(frame, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 0), 1);
}vector<String> getOutputsNames(const Net& net)
{static vector<String> names;if (names.empty()){// 获取输出层的索引,即输出不相连的层vector<int> outLayers = net.getUnconnectedOutLayers();vector<String> layersNames = net.getLayerNames();names.resize(outLayers.size());for (size_t i = 0; i < outLayers.size(); ++i)names[i] = layersNames[outLayers[i] - 1];}return names;
}

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

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

相关文章

支付整体架构

5.4 支付的技术架构 架构即未来&#xff0c;只有建立在技术架构设计良好的体系上&#xff0c;支付机构才能有美好的未来。如果支付的技术体系在架构上存在问题&#xff0c;那么就没有办法实现高可用性、高安全性、高效率和水平可扩展性。 总结多年来在海内外支付机构主持和参与…

C语言之位运算

一、什么是位运算 所谓位运算是指进行二进制位的运算 在系统软件中&#xff0c;常要处理二进位的问题 例如&#xff0c;将一个存储单元中的各二进位左移或右移一位&#xff0c;两个数按位相加等 二、位运算符和位运算 1、按位与 运算符(&) 参加运算的两个数据&#xff…

php 常用调试方式

要在PHP命令行中配置Xdebug&#xff0c;您需要完成以下步骤&#xff1a; 安装Xdebug扩展&#xff1a;首先&#xff0c;确保已经安装了Xdebug扩展。您可以通过在终端中运行php -m来检查是否安装了Xdebug扩展。如果没有安装&#xff0c;您可以按照官方文档或适用于您所使用的操作…

python正则表达式详解笔记,python正则表达式教学

正则表达式 正则表达式是一个特殊的字符序列&#xff0c;计算机科学的一个概念。通常被用来检索、替换那些符合某个模式(规则)的文本。 许多程序设计语言都支持利用正则表达式进行字符串操作。在Python中需要通过正则表达式对字符串进行匹配的时候&#xff0c;可以使用re模块…

Exploiting Proximity-Aware Tasks for Embodied Social Navigation 论文阅读

论文信息 题目&#xff1a;Exploiting Proximity-Aware Tasks for Embodied Social Navigation 作者&#xff1a;Enrico Cancelli&#xff0c; Tommaso Campari 来源&#xff1a;arXiv 时间&#xff1a;2023 Abstract 学习如何在封闭且空间受限的室内环境中在人类之间导航&a…

uniapp 获取 view 的宽度、高度以及上下左右左边界位置

<view class"cont-box"></view> /* 获取节点信息的对象 */ getElementRect() {const query uni.createSelectorQuery().in(this);query.select(".cont-box").boundingClientRect(res > {console.log(res);console.log(res.height); // 10…

Taro UI中的AtTabs

TaroUI 中的 AtTabs 是一个用于创建标签页(tab)组件的组件。它提供了一种简单的方式来切换显示不同的内容。 AtTabs 的使用方式如下&#xff1a; 首先&#xff0c;引入 AtTabs 组件和必要的样式&#xff1a; import { AtTabs, AtTabsPane } from taro-ui import taro-ui/dis…

Kubernetes系列-删除deployment和pod

通过deployment创建的pod直接执行delete是不会正常被删除的&#xff0c;因为deployment中设置了pod的数量&#xff0c;deployment会动态维护pod的数量&#xff0c;倘若pod数量少于约定数量&#xff0c;deployment会创建pod&#xff0c;直到pod数量达到约定数量才会停止。 如若…

mysql数据库第十二课------mysql语句的拔高2------飞高高

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

研发工程师玩转Kubernetes——通过PV的节点亲和性影响Pod部署

在《研发工程师玩转Kubernetes——PVC通过storageClassName进行延迟绑定》一文中&#xff0c;我们利用Node亲和性&#xff0c;让Pod部署在节点ubuntud上。因为Pod使用的PVC可以部署在节点ubuntuc或者ubuntud上&#xff0c;而系统为了让Pod可以部署成功&#xff0c;则让PVC与Pod…

Spring-Cloud-Loadblancer详细分析_2

LoadBalancerClients 终于分析到了此注解的作用&#xff0c;它是实现不同服务之间的配置隔离的关键 Configuration(proxyBeanMethods false) Retention(RetentionPolicy.RUNTIME) Target({ ElementType.TYPE }) Documented Import(LoadBalancerClientConfigurationRegistrar…

Mongodb:业务应用(1)

环境搭建参考&#xff1a;mongodb&#xff1a;环境搭建_Success___的博客-CSDN博客 需求&#xff1a; 在文章搜索服务中实现保存搜索记录到mongdb 并在搜索时查询出mongdb保存的数据 1、安装mongodb依赖 <dependency><groupId>org.springframework.data</groupI…

Intellij IDEA 导入 eclipse web 项目详细操作

Eclipse当中的web项目都会有这两个文件。但是idea当中应该是没有的&#xff0c;所以导入会出现兼容问题。但是本篇文章会教大家如何导入&#xff0c;并且导入过后还能使用tomcat运行。文章尽可能以图片的形式进行演示。我的idea使用的版本是2022.3.3版本。当然按正常来说版本之…

查询树形目录(内存遍历成树返回)

实体 Data TableName("dtp_sm_servicetype") ApiModel(value "SmServicetype对象", description "服务类型") EqualsAndHashCode(callSuper true) public class SmServicetype extends BaseEntity {ApiModelProperty("服务类型名称&quo…

C++ ModBUS TCP客户端工具 qModMaster 介绍及使用

qModMaster工具介绍 QModMaster是一个基于Qt的Modbus主站&#xff08;Master&#xff09;模拟器&#xff0c;用于模拟和测试Modbus TCP和RTU通信。它提供了一个直观的图形界面&#xff0c;使用户能够轻松设置和发送Modbus请求&#xff0c;并查看和分析响应数据。 以下是QModM…

图论——最短路算法

引入&#xff1a; 如上图&#xff0c;已知图G。 问节点1到节点3的最短距离。 可心算而出为d[1,2]d[2,3]112,比d[1,3]要小。 求最短路径算法&#xff1a; 1.Floyd(弗洛伊德) 是一种基于三角形不等式的多源最短路径算法。边权可以为负数 表现为a[i,j]a[j,k]<a[i,k]。 …

vue3 使用 element-china-area-data 实现地区选择器

官方地址&#xff1a;https://www.npmjs.com/package/element-china-area-data?activeTabreadme 在线示例&#xff1a;https://plortinus.github.io/element-china-area-data/index.html 实际使用 <el-col :span"12"><el-form-item label"所处城市&…

什么是响应式设计?列举几种实现响应式设计的方法。

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是响应式设计&#xff1f;⭐ 实现响应式设计的方法⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏…

Docker安装ElasticSearch/ES 7.4.0

目录 前言安装ElasticSearch/ES安装步骤1&#xff1a;准备1. 安装docker2. 搜索可以使用的镜像。3. 也可从docker hub上搜索镜像。4. 选择合适的redis镜像。 安装步骤2&#xff1a;拉取ElasticSearch镜像1 拉取镜像2 查看已拉取的镜像 安装步骤3&#xff1a;创建容器创建容器方…

android 如何分析应用的内存(十八)终章——使用Perfetto查看内存与调用栈之间的泄露

android 如何分析应用的内存&#xff08;十八&#xff09; 在前面两篇文章中&#xff0c;先是介绍了如何用AS查看Android的堆内存&#xff0c;然后介绍了使用MAT查看 Android的堆内存。AS能够满足基本的内存分析需求&#xff0c;但是无法进行多个堆的综合比较&#xff0c;因此…