使用Openvino部署C++的Yolov5时类别信息混乱问题记录

使用Openvino部署C++的Yolov5时类别信息混乱问题记录

简单记录一下。

一、问题描述

问题描述:在使用Yolov5的onnx格式模型进行C++的Openvino进行模型部署时,通过读取classes.txt获得类别信息时,出现模型类别混乱,或者说根本就不给图像赋予类别标签的情况。
在这里插入图片描述

二、解决办法

通过debug程序,发现是读取txt文件时的问题,读入txt文件时,会读出几行空白的数据。
在这里插入图片描述
最终发现原因是classes.txt文件中,多了几个空白的换行。需要尽量留意,删除掉空白的换行

三、部署测试代码

三个部分,需要提取配置好opencv和openvino

1.main.cpp
#include <opencv2/opencv.hpp>  
#include <boost/filesystem.hpp>  
#include <iostream>  
#include <string>  
#include "yolov5vino.h"namespace fs = boost::filesystem;
YOLOv5VINO yolov5VINO;int main() {std::string sourceDir = "D:/work/C++Code/Yolov5Openvino/Test/testimgs";std::string destDir = "D:/work/C++Code/Yolov5Openvino/Test/output";std::string ModelPath = "D:/work/C++Code/Yolov5Openvino/Test/best.onnx";std::string ClassesPath = "D:/work/C++Code/Yolov5Openvino/Test/classes.txt";yolov5VINO.init(ModelPath, ClassesPath);// 确保目标目录存在  if (!fs::exists(destDir)) {fs::create_directories(destDir);}// 遍历源目录中的所有文件  for (fs::directory_iterator end, dir(sourceDir); dir != end; ++dir) {if (fs::is_regular_file(dir->status())) {std::string filePath = dir->path().string();std::string fileName = dir->path().filename().string();// 读取图片  cv::Mat img = cv::imread(filePath, cv::IMREAD_COLOR);if (img.empty()) {std::cerr << "Failed to load image: " << filePath << std::endl;continue;}std::vector<Detection> outputs;yolov5VINO.detect(img, outputs);yolov5VINO.drawRect(img, outputs);// 构造目标文件路径  std::string destFilePath = destDir + "/" + fileName;// 保存图  if (!cv::imwrite(destFilePath, img)) {std::cerr << "Failed to save image: " << destFilePath << std::endl;}else {std::cout << "Saved image: " << destFilePath << std::endl;}}}return 0;
}
2.Yolv5nivo.h
#pragma once
#ifndef YOLOV5VINO_H
#define YOLOV5VINO_H
#include <fstream>
#include <opencv2/opencv.hpp>
#include <inference_engine.hpp>
#define NOT_NCS2
using namespace std;
using namespace InferenceEngine;struct Detection
{int class_id;float confidence;cv::Rect box;
};class YOLOv5VINO
{
public:YOLOv5VINO();~YOLOv5VINO();void init(string modelPath, string classPath);cv::Mat formatYolov5(const cv::Mat& source);void detect(cv::Mat& image, vector<Detection>& outputs);void drawRect(cv::Mat& image, vector<Detection>& outputs);void loadClassList(string classPath);
private:float m_scoreThreshold = 0.5;float m_nmsThreshold = 0.6;float m_confThreshold = 0.5;//"CPU","GPU","MYRIAD"
#ifdef NCS2const std::string m_deviceName = "MYRIAD";const std::string m_modelFilename = "configFiles/yolov5sNCS2.xml";
#elseconst std::string m_deviceName = "CPU";const std::string m_modelFilename = "best.onnx";
#endif // NCS2const std::string m_classfile = "classes.txt";size_t m_numChannels = 3;size_t m_inputH = 416;size_t m_inputW = 416;size_t m_imageSize = 0;std::string m_inputName = "";std::string m_outputName = "";const vector<cv::Scalar> colors = { cv::Scalar(255, 255, 0), cv::Scalar(0, 255, 0), cv::Scalar(0, 255, 255), cv::Scalar(255, 0, 0) };InferRequest m_inferRequest;Blob::Ptr m_inputData;public:vector<std::string> m_classNames;//const vector<std::string> m_classNames = { "138A","8151","B1100","JH8161","RE85","S22","KA90","T105","TX2295" };// const vector<string> m_classNames = { "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light" };
};
#endif
3.yolov5vino.cpp
#include "yolov5vino.h"YOLOv5VINO::YOLOv5VINO()
{
}YOLOv5VINO::~YOLOv5VINO()
{
}void YOLOv5VINO::init(string modelPath, string classPath)
{InferenceEngine::Core ie;InferenceEngine::CNNNetwork network = ie.ReadNetwork(modelPath);InputsDataMap inputs = network.getInputsInfo();OutputsDataMap outputs = network.getOutputsInfo();for (auto item : inputs){m_inputName = item.first;auto input_data = item.second;input_data->setPrecision(Precision::FP32);input_data->setLayout(Layout::NCHW);input_data->getPreProcess().setColorFormat(ColorFormat::RGB);std::cout << "input name = " << m_inputName << std::endl;}for (auto item : outputs){auto output_data = item.second;output_data->setPrecision(Precision::FP32);m_outputName = item.first;std::cout << "output name = " << m_outputName << std::endl;}auto executable_network = ie.LoadNetwork(network, m_deviceName);m_inferRequest = executable_network.CreateInferRequest();m_inputData = m_inferRequest.GetBlob(m_inputName);m_numChannels = m_inputData->getTensorDesc().getDims()[1];m_inputH = m_inputData->getTensorDesc().getDims()[2];m_inputW = m_inputData->getTensorDesc().getDims()[3];m_imageSize = m_inputH * m_inputW;loadClassList(classPath);}void YOLOv5VINO::loadClassList(string classPath)
{std::ifstream ifs(classPath);std::string line;while (getline(ifs, line)){m_classNames.push_back(line);}ifs.close();
}cv::Mat YOLOv5VINO::formatYolov5(const cv::Mat& source)
{int col = source.cols;int row = source.rows;int max = MAX(col, row);cv::Mat result = cv::Mat::zeros(max, max, CV_8UC3);source.copyTo(result(cv::Rect(0, 0, col, row)));return result;
}void YOLOv5VINO::detect(cv::Mat& image, vector<Detection>& outputs)
{cv::Mat input_image = formatYolov5(image);cv::Mat blob_image;cv::resize(input_image, blob_image, cv::Size(m_inputW, m_inputH));cv::cvtColor(blob_image, blob_image, cv::COLOR_BGR2RGB);float* data = static_cast<float*>(m_inputData->buffer());for (size_t row = 0; row < m_inputH; row++) {for (size_t col = 0; col < m_inputW; col++) {for (size_t ch = 0; ch < m_numChannels; ch++) {
#ifdef NCS2data[m_imageSize * ch + row * m_inputW + col] = float(blob_image.at<cv::Vec3b>(row, col)[ch]);
#elsedata[m_imageSize * ch + row * m_inputW + col] = float(blob_image.at<cv::Vec3b>(row, col)[ch] / 255.0);
#endif // NCS2}}}auto start = std::chrono::high_resolution_clock::now();m_inferRequest.Infer();auto output = m_inferRequest.GetBlob(m_outputName);const float* detection_out = static_cast<PrecisionTrait<Precision::FP32>::value_type*>(output->buffer());//维度信息const SizeVector outputDims = output->getTensorDesc().getDims();//1,6300[25200],9float x_factor = float(input_image.cols) / m_inputW;float y_factor = float(input_image.rows) / m_inputH;float* dataout = (float*)detection_out;const int dimensions = outputDims[2];const int rows = outputDims[1];vector<int> class_ids;vector<float> confidences;vector<cv::Rect> boxes;for (int i = 0; i < rows; ++i){float confidence = dataout[4];if (confidence >= m_confThreshold){float* classes_scores = dataout + 5;cv::Mat scores(1, m_classNames.size(), CV_32FC1, classes_scores);cv::Point class_id;double max_class_score;minMaxLoc(scores, 0, &max_class_score, 0, &class_id);if (max_class_score > m_scoreThreshold){confidences.push_back(confidence);class_ids.push_back(class_id.x);float x = dataout[0];float y = dataout[1];float w = dataout[2];float h = dataout[3];int left = int((x - 0.5 * w) * x_factor);int top = int((y - 0.5 * h) * y_factor);int width = int(w * x_factor);int height = int(h * y_factor);boxes.push_back(cv::Rect(left, top, width, height));}}dataout += dimensions;}vector<int> nms_result;cv::dnn::NMSBoxes(boxes, confidences, m_scoreThreshold, m_nmsThreshold, nms_result);for (int i = 0; i < nms_result.size(); i++){int idx = nms_result[i];Detection result;result.class_id = class_ids[idx];result.confidence = confidences[idx];result.box = boxes[idx];outputs.push_back(result);}std::sort(outputs.begin(), outputs.end(), [](const Detection& a, const Detection& b) {return a.confidence > b.confidence; // 从大到小排序  });
}void YOLOv5VINO::drawRect(cv::Mat& image, vector<Detection>& outputs)
{int detections = outputs.size();for (int i = 0; i < detections; ++i){auto detection = outputs[i];auto box = detection.box;auto classId = detection.class_id;const auto color = colors[classId % colors.size()];rectangle(image, box, color, 3);rectangle(image, cv::Point(box.x, box.y - 40), cv::Point(box.x + box.width, box.y), color, cv::FILLED);putText(image, m_classNames[classId].c_str(), cv::Point(box.x, box.y - 5), cv::FONT_HERSHEY_SIMPLEX, 1.5, cv::Scalar(0, 0, 0), 2);}}

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

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

相关文章

如何将avi格式转换为flv格式呢?

FLV是随着FLASH MX的推出发展而来的一种视频格式&#xff0c;目前被众多新一代视频分享网站所采用&#xff0c;是目前增长较快&#xff0c;也较为广泛的视频传播格式。 FLV格式可以轻松导入FLASH播放器中&#xff0c;另外它还能起到保护版权的作用&#xff0c;非常受欢迎。那么…

在优化微信、支付宝小程序用户体验时有哪些关键指标

在优化小程序用户体验时&#xff0c;有几个关键指标需要特别关注&#xff0c;这些指标不仅能够帮助评估当前的用户体验状况&#xff0c;还能为后续的优化工作提供明确的方向。以下是一些关键指标及其解释&#xff1a; 1. 日活跃用户&#xff08;DAU&#xff09; 是指每天使用…

『 Linux 』网络基础

文章目录 协议分层OSI 七层模型TCP/IP 四层(五层)模型网络协议栈与操作系统的联系报文TCP/IP 通讯过程以太网通信的过程以太网的数据碰撞 协议分层 协议分层是计算机网络中奖网络协议进行组织和管理的方法; 通过将网络通信过程分成多个层次,每个层次负责特定的功能从而简化网络…

触屏交互设备的安全风险

现实中的绝大多数电子设备都具有交互性&#xff0c;而现在越来越多的公共场合有布置越来越多的带触屏的交互设备&#xff0c;功能有简单的&#xff0c;有复杂的&#xff0c;布置的场所和应用的场合也各有不同&#xff0c;几乎在任何一个大型公共场合都可以看到这样的设备&#…

【算法 03】雇佣问题

“雇用问题”及其算法优化 在日常生活和工作中&#xff0c;我们经常会遇到需要从多个选项中做出选择的情况&#xff0c;而“雇用问题”正是这样一个典型的例子。在这个问题中&#xff0c;我们不仅要考虑如何高效地找到最佳候选人&#xff0c;还要关注整个过程中的成本。今天&a…

提高工作效率: AWS Gen AI 在几秒钟内总结会议记录

欢迎来到雲闪世界。全面介绍如何利用 AWS Lambda、Bedrock 和 S3 创建总结会议记录的工作流程 免责声明&#xff1a;本文中使用的会议记录纯属虚构&#xff0c;仅用于作为本文说明和教育目的。它并不反映任何实际的对话、事件或个人。任何与实际人物或事件的相似之处纯属巧合。…

为什么网站要使用HTTPS访问

网站使用HTTPS访问的原因有很多&#xff0c;主要可以归纳为以下几个关键点&#xff1a; 1、数据安全性&#xff1a;HTTPS使用SSL/TLS协议对通信过程进行加密&#xff0c;确保信息在传输过程中不被窃取、篡改或冒充。对于涉及敏感信息&#xff08;如个人身份、信用卡号等&#x…

数字人解决方案——音频驱动机器人

音频集成 机器人 标志着 人工智能&#xff08;AI&#xff09;。 想象一下&#xff0c;机器人可以通过视觉和听觉导航并与周围环境互动。音频驱动的机器人使这成为可能&#xff0c;提高了它们更高效、更直观地执行任务的能力。这一发展可能会影响到各个领域&#xff0c;包括家庭…

github技巧和bug解决方法短篇收集

有一些几句话就可以说明白的观点或者解决的的问题&#xff0c;小虎单独收集到这里。 Commits没有算入每天的activity fork的仓库是不算的。 Commits made in a fork will not count toward your contributions. 参考&#xff1a; Contribution activity not shown for github…

鸿蒙HarmonyOS开发:如何使用第三方库,加速应用开发

文章目录 一、如何安装 ohpm-cli二、如何安装三方库1、在 oh-package.json5 文件中声明三方库&#xff0c;以 ohos/crypto-js 为例&#xff1a;2、安装指定名称 pacakge_name 的三方库&#xff0c;执行以下命令&#xff0c;将自动在当前目录下的 oh-package.json5 文件中自动添…

C# 中引用类型的探讨

引用类型的变量不直接包含其数据&#xff1b;它包含对其数据的引用。 如果按值传递引用类型参数&#xff0c;则可能更改属于所引 用对象的数据&#xff0c;例如类成员的值。 但是&#xff0c;不能更改引用本身的值&#xff1b;例如&#xff0c;不能使用相同引用为新对象分配内存…

QuanTide-weekly第1期

本周Po文 这周我们共发表5篇文章。《基于 XGBoost 的组合策略…》等两篇详细讲解了机器学习构建组合策略的框架和常见问题。 文章要点与结论&#xff1a; 通过两阶段式方案实现多因子、多资产的组合策略构建。第一阶段基于XGBoost构建多个多因子单标的模型&#xff0c;第二阶…

electron-updater实现electron全量更新和增量更新——渲染进程交互部分

同学们可以私信我加入学习群&#xff01; 正文开始 前言更新功能所有文章汇总一、监听页面渲染完毕1.1 myApi.handleCheckPcUpdate检查更新1.2myApi.onPcUpdateProgress接收下载信息1.3myApi.onPcDownloaded监听下载完毕事件 二、立即更新三、跳过更新四、打开更新模块总结 前言…

vtkConnectivityFilter提取连通区域中的问题

直接使用vtkConnectivityFilter提取连通区域&#xff0c;渲染上没问题&#xff0c;但是打印出polydata中的点数&#xff0c;发现跟原始数据是一致的。 for (int i 0; i < numRegions; i){vtkSmartPointer<vtkConnectivityFilter> connectivityFilter vtkSmartPointe…

Unknown input format pdf Pandoc can convert to PDF, but not from PDF.解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

口碑好的可视耳勺:四款口碑超好产品种草分享

随着科技的进步&#xff0c;越来越多人使用可视耳勺&#xff0c;因为它能够清晰地看到耳道内的状况&#xff0c;从而实现更精准、更安全的清洁。 然而&#xff0c;如今可视耳勺市场产品参差不齐&#xff0c;产品的评价褒贬参半。有的产品声称有超高像素&#xff0c;可实际到手画…

谷歌25亿美金收购Character AI的幕后故事

在科技领域中&#xff0c;并购交易无疑是推动技术发展的重要手段之一。最近&#xff0c;谷歌以25亿美金的对价收购了Character AI&#xff0c;这一交易的方式和细节引起了广泛关注。本文将详细解析谷歌这一奇葩交易方式&#xff0c;探讨其背后的动机和影响。 一、交易背景 1.…

程序员短视频上瘾综合症

一、是你疯了还是面试官疯了&#xff1f; ​ 最近有两个学员咨询问题&#xff0c;把我给整得苦笑不得。大家来看看&#xff0c;你有没有同样的症状。 ​ 第一个学员说去一家公司面试&#xff0c;第一轮面试聊得挺好的。第二轮面试自我感觉良好&#xff0c;但是被面试官给Diss…

《计算机组成原理》(第3版)第3章 系统总线 复习笔记

第3章 系统总线 一、总线的基本概念 总线是连接多个部件的信息传输线&#xff0c;是各部件共享的传输介质&#xff0c;如图3-1所示。 图3-1 面向CPU的双总线结构框图 倘若将CPU、主存和I/O设备都挂到一组总线上&#xff0c;便形成单总线结构的计算机&#xff0c;如图3-2所示…

【Linux 驱动】IMX6ULL input驱动

1. input子系统介绍 input 子系统分为 input 驱动层、input 核心层、input 事件处理层&#xff0c;最终给用户空间提供可访问的设备节点。 驱动层&#xff1a;输入设备的具体驱动程序&#xff0c;比如按键驱动程序&#xff0c;向内核层报告输入内容核心层&#xff1a;承上启下…