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;
}
相关文章:
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> #inc…...
oracle创建管理用户并授权
oracle创建管理用户并授权 创建用户 create user test identified by test;修改密码 alter user test identified by 123456;删除用户 drop user test;删除拥有对象的用户 若用户拥有对象,则不能直接删除,否则将返回一个错误值。指定关键字cascade,…...
三江学院图书馆藏八一新书《乡村振兴战略下传统村落文化旅游设计》
三江学院图书馆藏八一新书《乡村振兴战略下传统村落文化旅游设计》...
机器学习笔记 - 基于PyTorch + 类似ResNet的单目标检测
一、获取并了解数据 我们将处理年龄相关性黄斑变性 (AMD) 患者的眼部图像。 数据集下载地址,从下面的地址中,找到iChallenge-AMD,然后下载。 Baidu Research Open-Access Dataset - DownloadDownload Baidu Research Open-Access Datasethttps://ai.baidu.com/bro…...
系列二、Redis简介
一、概述 # 官网 https://redis.io/ 总结:redis是一个内存型的数据库。 二、特点 Redis是一个高性能key/value内存型数据库。Redis支持丰富的数据类型。Redis支持持久化 。Redis单线程,单进程。...
基于TF-IDF+TensorFlow+词云+LDA 新闻自动文摘推荐系统—深度学习算法应用(含ipynb源码)+训练数据集
目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境TensorFlow环境方法一方法二 模块实现1. 数据预处理1)导入数据2)数据清洗3)统计词频 2. 词云构建3. 关键词提取4. 语音播报5. LDA主题模型6. 模型构建 系统测试工程源代码下载…...
尼科彻斯定理-C语言/Java
描述 验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。 例如: 1^31 2^335 3^37911 4^313151719 输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。&…...
C++学习笔记——从面试题出发学习C++
C学习笔记——从面试题出发学习C C学习笔记——从面试题出发学习C1. 成员函数的重写、重载和隐藏的区别?2. 构造函数可以是虚函数吗?内联函数可以是虚函数吗?析构函数为什么一定要是虚函数?3. 解释左值/右值、左值/右值引用、std:…...
WebAPIs 第二天
DOM事件基础 事件监听事件类型事件对象 一.事件监听 ① 概念:就是让程序检测是否有事件发生,一旦有事件触发,就立即调用一个函数做出响应,也成为绑定事件或者注册事件 ② 语法:元素对象.addEventListener(事件类型&…...
解决macOS执行fastboot找不到设备的问题
背景 最近准备给我的备用机Redmi Note 11 5G刷个类原生的三方ROM,MIUI实在是用腻了。搜罗了一番,在XDA上找到了一个基于Pixel Experience开发的ROM:PixelExperience Plus for Redmi Note 11T/11S 5G/11 5G/POCO M4 Pro 5G (everpal)…...
Linux命令 -- chmod
Linux命令 -- chmod 参数含义权限说明修改文件权限修改目录权限 参数含义 文件用户 u 文件所有者g 文件所有者同组的用户o 其它用户a 所有用户 文件权限 r 读权限(对应数值4)w 写权限(对应数值2)x 执行权限(对应数…...
国产超低功耗32位MCU的应用
随着物联网技术的不断发展,超低功耗MCU已经成为了物联网方案中主要的芯片处理技术。超低功耗MCU具有众多的优点,其中一大所用就是能够大大提高物联网设备的续航能力,保证设备在长时间内不掉电不断电。那么,超低功耗MCU在物联网方案…...
将数组(矩阵)旋转根据指定的旋转角度scipy库的rotate方法
【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将数组(矩阵)旋转 根据指定的旋转角度 scipy库的rotate方法 关于下列代码说法正确的是? import numpy as np from scipy.ndimage import rotate a np.array([[1,2,3,4], …...
MFC创建和使用OCX控件
文章目录 MFC建立OCX控件注册OCX控件与反注册使用Internet Explorer测试ocx控件OCX控件添加方法OCX控件添加事件Web使用OCX控件MFC使用OCX控件使用OCX控件调用ocx的功能函数对ocx的事件响应OCX控件调试工具tstcon32.exe加载ocx控件使用tstcon32.exe调试ocxMFC建立OCX控件 新建…...
【设计模式】抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在抽象工厂模式中,接口是负责创建一个相关对象…...
小白带你学习linux的Redis3.2集群(三十三)
目录 一、Redis主从复制 1、概念 2、作用 3、缺点 4、流程 5、搭建 6、验证 二、Reids哨兵模式 1、概念 2、作用 3、缺点 4、结构 5、搭建 6、验证 三、Redis集群 1、概述 2、原理 3、架构细节 4、选举过程 四、搭建 1、第一步现在外部使用finalshell 9.9…...
嵌入式技术,就在你的手边!
嵌入式技术,听起来多么高大上的名词,同时它也确实是当今信息技术的前沿领域,但这并不意味着它就距离我们很遥远。 事实恰恰相反,在当今科技发展迅猛的时代,嵌入式技术成为了人们生活中不可或缺的一部分。它以其小巧、高…...
nodejs+vue+elementui健康饮食美食菜谱分享网站系统
本系统采用了nodejs语言的vue框架,数据采用MySQL数据库进行存储。结合B/S结构进行开发设计,功能强大,界面化操作便于上手。本系统具有良好的易用性和安全性,系统功能齐全,可以满足饮食分享管理的相关工作。 语言 node.…...
input 设置type=“number“,鼠标悬停关闭提示语
一、问题 最近刚发现input 设置type"number"之后,鼠标悬停会出现提示语:请输入有效值。两个最接近的有效值分别为xx和xx。想要输入的值确实为number格式,又可以输入小数,不限制小数位,所以要把这讨厌的提示去…...
CSDN互利共赢玩法实战!!!
csdn项目第一波基本都顺利跑了起来,我们总计找来了一两千个新的项目源码,来让大家变现。 在实战中,主要两个玩法,一个引流,一个付费资源。付费资源门槛越来越高,所以我们这一波升级完成的号,就非…...
蓝桥杯单片机 | 实战解析【进阶04】基于24C02的按键次数掉电存储与动态显示系统
1. 项目背景与需求分析 在蓝桥杯单片机竞赛中,数据持久化存储是一个非常重要的考点。24C02作为一款经典的EEPROM芯片,经常被用来实现掉电不丢失的数据存储功能。这次我们要实现的功能是记录三个独立按键的触发次数,并且在系统断电后依然能够保…...
Halcon 实战指南:基于局部形变的模板匹配在柔性物体检测中的应用与参数调优
1. 柔性物体检测的挑战与局部形变匹配的价值 在工业视觉检测中,软包装、纺织品、橡胶件等柔性物体的检测一直是个难题。这些材料在传送带或机械臂抓取过程中,难免会发生拉伸、褶皱等轻微形变。传统的刚性模板匹配方法在这里往往会失效——因为哪怕1%的形…...
别再只输密码了!手把手带你用Wireshark抓包,亲手‘看见’WPA2的四次握手过程(含过滤技巧)
无线网络安全实战:用Wireshark解析WPA2四次握手全流程 家里WiFi突然连不上?明明密码正确却反复提示认证失败?作为网络工程师,我遇到过太多次同事抱怨"路由器抽风",而真相往往藏在那些看不见的数据帧里。今天…...
【Python基础20讲】第01章:Python 环境搭建与第一个程序
博主智算菩萨,专注于人工智能、Python编程、音视频处理及UI窗体程序设计等方向。致力于以通俗易懂的方式拆解前沿技术,从零基础入门到高阶实战,陪伴开发者共同成长。目前已开设五大技术专栏,累计发布多篇原创技术文章,…...
终极指南:如何快速部署本地AI大语言模型服务
终极指南:如何快速部署本地AI大语言模型服务 【免费下载链接】llama-cpp-python Python bindings for llama.cpp 项目地址: https://gitcode.com/gh_mirrors/ll/llama-cpp-python llama-cpp-python 是一个为 llama.cpp 提供Python绑定的开源库,让…...
MIT App Inventor完整指南:无需代码的移动应用开发利器
MIT App Inventor完整指南:无需代码的移动应用开发利器 【免费下载链接】appinventor-sources MIT App Inventor Public Open Source 项目地址: https://gitcode.com/gh_mirrors/ap/appinventor-sources MIT App Inventor是一个强大的开源移动应用开发平台&a…...
【NLP实战】基于NLTK词性标注的英语缩写消歧:以he‘s/she‘s为例
1. 为什么需要英语缩写消歧? 第一次处理英文文本数据时,我就被hes/shes这类缩写搞得晕头转向。明明都是s结尾,有时候表示"is",有时候又表示"has"。比如"Shes finished"和"Shes happy"&a…...
告别蓝绿滤镜:用WaterGAN和Python实战,5分钟搞定水下照片色彩还原
水下照片色彩还原实战:5分钟用WaterGAN让蓝绿世界重焕生机 每次潜水归来,看着相机里那些被蓝绿色调吞噬的照片,总有种说不出的遗憾。珊瑚本该是绚丽的橙红,热带鱼身上的花纹应当鲜艳夺目,但在水下摄影中,这…...
YOLOv8模型部署实战:从PyTorch到TensorRT的高效转换与性能调优
1. 环境准备:搭建TensorRT转换的基石 第一次尝试将YOLOv8模型部署到生产环境时,我花了整整三天时间在环境配置上。这种痛苦经历让我明白,稳定的基础环境是后续所有工作的前提。TensorRT对环境的要求极为严格,CUDA、cuDNN、Python版…...
告别VGA驱动困惑:用Verilog在Cyclone IV FPGA上实现800x60彩条与字符显示(附完整代码)
FPGA实战:用Verilog在Cyclone IV上实现VGA彩条与字符显示系统 第一次接触FPGA驱动VGA显示时,我被那些复杂的时序参数和硬件连接弄得晕头转向。屏幕要么一片漆黑,要么显示错位的彩色条纹,调试过程简直是一场噩梦。直到真正理解了从…...
