当前位置: 首页 > news >正文

c++ opencv调用yolo onnx文件

网上找了一段代码,测试c++ opencv调用yolo onnx文件

yolov8n.onnx   opencv版本是4.12 ,另外测试了4.4和4.6版本的opencv运行有问题,可能对opencv版本有要求,有待研究,都在编译了contrib库的情况下测试的

#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <iostream>
#include <chrono>int main()
{// 加载 ONNX 模型std::string modelPath = "yolov8n.onnx";cv::dnn::Net net = cv::dnn::readNetFromONNX(modelPath);net.setPreferableBackend(cv::dnn::DNN_BACKEND_DEFAULT);net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);// 定义完整的COCO数据集类别名称std::vector<std::string> classes = {"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light","fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow","elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee","skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard","tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple","sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch","potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone","microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear","hair drier", "toothbrush"};// 打开视频文件或摄像头// 0 表示默认摄像头,也可以替换为视频文件路径如 "video.mp4"cv::VideoCapture cap("nfs.mp4");// 检查视频是否成功打开if (!cap.isOpened()) {std::cerr << "Error: Unable to open video source" << std::endl;return -1;}// 获取视频的帧率double fps = cap.get(cv::CAP_PROP_FPS);if (fps == 0) fps = 30.0; // 默认帧率// 用于计算FPS的变量auto lastTime = std::chrono::high_resolution_clock::now();int frameCount = 0;double currentFps = 0.0;cv::Mat frame;while (true) {// 读取帧cap >> frame;// 检查是否成功读取帧if (frame.empty()) {std::cout << "End of video or error reading frame" << std::endl;break;}// 计算FPSframeCount++;auto currentTime = std::chrono::high_resolution_clock::now();auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastTime).count();if (elapsedTime >= 1000) { // 每秒更新一次FPScurrentFps = frameCount / (elapsedTime / 1000.0);frameCount = 0;lastTime = currentTime;}// 将图像转换为blob格式cv::Mat blob = cv::dnn::blobFromImage(frame, 1 / 255.0, cv::Size(640, 640), cv::Scalar(0, 0, 0), true, false);net.setInput(blob);// 前向传播, 获取检测结果std::vector <cv::Mat> outputs;net.forward(outputs, net.getUnconnectedOutLayersNames());// output.size [ 1, 84, 8400]int rows = outputs[0].size[2];// 每个目标存储了多少个值(x,y,w,h+类别数)int length = outputs[0].size[1];// 转成单通道outputs[0] = outputs[0].reshape(1, length);// 按对角线翻转cv::transpose(outputs[0], outputs[0]);float* data = (float*)outputs[0].data;float xFactor = (float)frame.cols / 640;float yFactor = (float)frame.rows / 640;// 解析检测结果std::vector<int> classIds;std::vector<float> confidences;std::vector<cv::Rect> boxes;for (int i = 0; i < rows; i++){// 存储每个类别的置信度cv::Mat scores(1, classes.size(), CV_32FC1, data + 4);cv::Point classId;double maxClassScore;// 读取最大置信度并获得它的索引cv::minMaxLoc(scores, 0, &maxClassScore, 0, &classId);if (maxClassScore > 0.1){confidences.push_back(maxClassScore);classIds.push_back(classId.x);float x = data[0];float y = data[1];float w = data[2];float h = data[3];int left = int((x - 0.5 * w) * xFactor);int top = int((y - 0.5 * h) * yFactor);int width = int(w * xFactor);int height = int(h * yFactor);boxes.push_back(cv::Rect(left, top, width, height));}data += length;}// 执行非最大抑制,以消除具有较低置信度的冗余重叠框(NMS)std::vector<int> nmsResult;cv::dnn::NMSBoxes(boxes, confidences, 0.25, 0.7, nmsResult);for (int i = 0; i < nmsResult.size(); i++){int idx = nmsResult[i];int classId = classIds[idx];float confidence = confidences[idx];cv::Rect box = boxes[idx];// 绘制检测框并显示类别名称cv::rectangle(frame, box, cv::Scalar(0, 0, 255), 2);cv::putText(frame, classes[classId] + ": " + std::to_string(confidence).substr(0, 4),cv::Point(box.x, box.y - 10), cv::FONT_HERSHEY_DUPLEX, 1, cv::Scalar(0, 0, 255));}// 在图像上显示FPSstd::string fpsText = "FPS: " + std::to_string(static_cast<int>(currentFps));cv::putText(frame, fpsText, cv::Point(10, 30), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0), 2);// 显示结果cv::imshow("YOLO Detection", frame);// 按ESC键退出if (cv::waitKey(1) == 27) {break;}}// 释放资源cap.release();cv::destroyAllWindows();return 0;
}

http://www.lryc.cn/news/615015.html

相关文章:

  • 2025-08-09通过授权码的方式给exe程序充值
  • jQuery 零基础学习第一天
  • 计算BERT-BASE参数量
  • 【数据分享】各省农业土地流转率(2010-2023)
  • 安全合规3--防火墙
  • 光伏面板损伤检出率↑91%!陌讯多模态识别算法在无人机巡检的落地实践
  • 建筑物实例分割数据集-9,700 张图片 城市规划与发展 灾害评估与应急响应 房地产市场分析 智慧城市管理 地理信息系统(GIS) 环境影响评估
  • Android MVP架构详解:从理论到实践
  • leetcode2090:半径为K的子数组平均值(定长滑动窗口)
  • C# 使用iText获取PDF的trailer数据
  • 【lucene】HitsThresholdChecker命中阈值检测器
  • 【Datawhale AI夏令营第三期】多模态RAG
  • 《Learning To Count Everything》论文阅读
  • 论文阅读-ZeroDCE和ZeroDCE++
  • OpenCV图像裁剪与 ROI 操作
  • Kubernetes 集群密钥与机密管理方案对比分析:Vault、Sealed Secrets 与 AWS KMS
  • vue+flask山西非遗文化遗产图谱可视化系统
  • 【Linux】Tomcat
  • C# 异步编程(使用异步Lambda表达式)
  • 100-基于Python的智联招聘数据可视化分析推荐系统
  • 基于Dify实现对Excel的数据分析--动态配置图表
  • 篮球运动(动态规划)
  • Vue3子组件向父组件传值(defineEmits())
  • 年轻新标杆!东方心绣脸韧带年轻技术升级发布
  • 【线程池】压测确定线程池合适的参数
  • Qt/C++开发监控GB28181系统/实时监测设备在线离线/视频预览自动重连/重新点播取流/低延迟
  • 模板方法模式:优雅封装算法骨架
  • MX 播放器:安卓设备上的全能视频播放器
  • 浅谈 VM 桥接模式:让虚拟机像真实电脑一样接入网络
  • SimBA算法实现过程