如何在C++中使用YOLO模型进行目标检测

《------往期经典推荐------》

一、AI应用软件开发实战专栏【链接】

项目名称项目名称
1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】
3.【手势识别系统开发】4.【人脸面部活体检测系统开发】
5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】
7.【YOLOv8多目标识别与自动标注软件开发】8.【基于YOLOv8深度学习的行人跌倒检测系统】
9.【基于YOLOv8深度学习的PCB板缺陷检测系统】10.【基于YOLOv8深度学习的生活垃圾分类目标检测系统】
11.【基于YOLOv8深度学习的安全帽目标检测系统】12.【基于YOLOv8深度学习的120种犬类检测与识别系统】
13.【基于YOLOv8深度学习的路面坑洞检测系统】14.【基于YOLOv8深度学习的火焰烟雾检测系统】
15.【基于YOLOv8深度学习的钢材表面缺陷检测系统】16.【基于YOLOv8深度学习的舰船目标分类检测系统】
17.【基于YOLOv8深度学习的西红柿成熟度检测系统】18.【基于YOLOv8深度学习的血细胞检测与计数系统】
19.【基于YOLOv8深度学习的吸烟/抽烟行为检测系统】20.【基于YOLOv8深度学习的水稻害虫检测与识别系统】
21.【基于YOLOv8深度学习的高精度车辆行人检测与计数系统】22.【基于YOLOv8深度学习的路面标志线检测与识别系统】
23.【基于YOLOv8深度学习的智能小麦害虫检测识别系统】24.【基于YOLOv8深度学习的智能玉米害虫检测识别系统】
25.【基于YOLOv8深度学习的200种鸟类智能检测与识别系统】26.【基于YOLOv8深度学习的45种交通标志智能检测与识别系统】
27.【基于YOLOv8深度学习的人脸面部表情识别系统】28.【基于YOLOv8深度学习的苹果叶片病害智能诊断系统】
29.【基于YOLOv8深度学习的智能肺炎诊断系统】30.【基于YOLOv8深度学习的葡萄簇目标检测系统】
31.【基于YOLOv8深度学习的100种中草药智能识别系统】32.【基于YOLOv8深度学习的102种花卉智能识别系统】
33.【基于YOLOv8深度学习的100种蝴蝶智能识别系统】34.【基于YOLOv8深度学习的水稻叶片病害智能诊断系统】
35.【基于YOLOv8与ByteTrack的车辆行人多目标检测与追踪系统】36.【基于YOLOv8深度学习的智能草莓病害检测与分割系统】
37.【基于YOLOv8深度学习的复杂场景下船舶目标检测系统】38.【基于YOLOv8深度学习的农作物幼苗与杂草检测系统】
39.【基于YOLOv8深度学习的智能道路裂缝检测与分析系统】40.【基于YOLOv8深度学习的葡萄病害智能诊断与防治系统】
41.【基于YOLOv8深度学习的遥感地理空间物体检测系统】42.【基于YOLOv8深度学习的无人机视角地面物体检测系统】
43.【基于YOLOv8深度学习的木薯病害智能诊断与防治系统】44.【基于YOLOv8深度学习的野外火焰烟雾检测系统】
45.【基于YOLOv8深度学习的脑肿瘤智能检测系统】46.【基于YOLOv8深度学习的玉米叶片病害智能诊断与防治系统】
47.【基于YOLOv8深度学习的橙子病害智能诊断与防治系统】48.【基于深度学习的车辆检测追踪与流量计数系统】
49.【基于深度学习的行人检测追踪与双向流量计数系统】50.【基于深度学习的反光衣检测与预警系统】
51.【基于深度学习的危险区域人员闯入检测与报警系统】52.【基于深度学习的高密度人脸智能检测与统计系统】
53.【基于深度学习的CT扫描图像肾结石智能检测系统】54.【基于深度学习的水果智能检测系统】
55.【基于深度学习的水果质量好坏智能检测系统】56.【基于深度学习的蔬菜目标检测与识别系统】
57.【基于深度学习的非机动车驾驶员头盔检测系统】58.【太基于深度学习的阳能电池板检测与分析系统】
59.【基于深度学习的工业螺栓螺母检测】60.【基于深度学习的金属焊缝缺陷检测系统】
61.【基于深度学习的链条缺陷检测与识别系统】62.【基于深度学习的交通信号灯检测识别】
63.【基于深度学习的草莓成熟度检测与识别系统】64.【基于深度学习的水下海生物检测识别系统】
65.【基于深度学习的道路交通事故检测识别系统】66.【基于深度学习的安检X光危险品检测与识别系统】
67.【基于深度学习的农作物类别检测与识别系统】68.【基于深度学习的危险驾驶行为检测识别系统】
69.【基于深度学习的维修工具检测识别系统】70.【基于深度学习的维修工具检测识别系统】
71.【基于深度学习的建筑墙面损伤检测系统】72.【基于深度学习的煤矿传送带异物检测系统】
73.【基于深度学习的老鼠智能检测系统】74.【基于深度学习的水面垃圾智能检测识别系统】
75.【基于深度学习的遥感视角船只智能检测系统】

二、机器学习实战专栏【链接】,已更新31期,欢迎关注,持续更新中~~
三、深度学习【Pytorch】专栏【链接】
四、【Stable Diffusion绘画系列】专栏【链接】
五、YOLOv8改进专栏【链接】持续更新中~~
六、YOLO性能对比专栏【链接】,持续更新中~

《------正文------》

目录

  • 引言
  • 1.克隆源码,并导出ONNX模型
  • 2.创建TXT文件以存储YOLO模型标签
  • 3.创建CMakeLists.txt文件
  • 4.编写代码
  • 5.编译并运行代码

引言

在Python中运行对象检测模型已经变得非常容易,这要归功于像Ultralytics这样的用户友好的库,但是在C++中运行YOLO模型呢?在本文中,将向您展示如何仅使用OpenCV库使用C++运行YOLO模型。

img

这篇文章是关于如何在CPU上运行YOLOv5模型 ,而不是GPU。在GPU上运行模型需要安装CUDA,CUDNN和其他可能令人困惑和耗时的东西。后续有空再进行详细介绍。

下面介绍详细的实现步骤:

1.克隆源码,并导出ONNX模型

  • 创建一个新的文件夹,并命名为任何你想要的。打开一个终端并将yolov5存储库克隆到此文件夹。我们将使用此存储库将模型导出为onnx格式
git clone https://github.com/ultralytics/yolov5
  • 我将使用yolov5s.pt模型,但您可以使用您的自定义yolov5模型,过程不会改变。您可以从此链接下载预训练模型,也可以使用自己的模型。

img

预训练的yolov5模型

  • 现在让我们将模型导出到onnx。有不同的参数,你可以检查下面的图片。您可以编辑“export.py“文件(yolov 5/export.py)或手动更改参数从终端就像我在这里。对于 自定义模型,需要将权重更改为自定义模型权重( your_model.pt文件)。
 python yolov5/export.py --weights yolov5s.pt --img 640 --include onnx --opset 12

注意:这里需要将opset设置为12,否则可能会出错。这是一个常见的问题,你可以检查github这个错误。

img
parameters /export.py文件

2.创建TXT文件以存储YOLO模型标签

这一步很简单,你只需要创建一个txt文件来存储标签。如下图:
如果你有自定义的模型,然后创建一个新的txt文件,并把你的标签写在里面。你可以给这个文件起任何你想要的名字。

img
coco-classes.txt

3.创建CMakeLists.txt文件

现在,让我们创建一个CMakeLists.txt文件。使用CMake编译C++程序时需要此文件。如果你从我分享的链接安装了OpenCV,你应该已经安装了CMake。

cmake_minimum_required(VERSION 3.10)
project(cpp-yolo-detection) # your folder name here

# Find OpenCV
set(OpenCV_DIR C:/Libraries/opencv/build) # path to opencv
find_package(OpenCV REQUIRED)

add_executable(object-detection object-detection.cpp) # your file name

# Link OpenCV libraries
target_link_libraries(object-detection ${OpenCV_LIBS})

4.编写代码

最后这是最后一步。我使用了这个代码库中的代码。

#include <fstream>
#include <opencv2/opencv.hpp>


// Load labels from coco-classes.txt file
std::vector<std::string> load_class_list()
{
    std::vector<std::string> class_list;
    // change this txt file  to your txt file that contains labels 
    std::ifstream ifs("C:/Users/sirom/Desktop/cpp-ultralytics/coco-classes.txt");
    std::string line;
    while (getline(ifs, line))
    {
        class_list.push_back(line);
    }
    return class_list;
}

// Model 
void load_net(cv::dnn::Net &net)
{   
    // change this path to your model path 
    auto result = cv::dnn::readNet("C:/Users/sirom/Desktop/cpp-ultralytics/yolov5s.onnx");

    std::cout << "Running on CPU/n";
    result.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
    result.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
 
    net = result;
}

const std::vector<cv::Scalar> colors = {cv::Scalar(255, 255, 0), cv::Scalar(0, 255, 0), cv::Scalar(0, 255, 255), cv::Scalar(255, 0, 0)};

// You can change this parameters to obtain better results
const float INPUT_WIDTH = 640.0;
const float INPUT_HEIGHT = 640.0;
const float SCORE_THRESHOLD = 0.5;
const float NMS_THRESHOLD = 0.5;
const float CONFIDENCE_THRESHOLD = 0.5;

struct Detection
{
    int class_id;
    float confidence;
    cv::Rect box;
};

// yolov5 format
cv::Mat format_yolov5(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;
}

// Detection function
void detect(cv::Mat &image, cv::dnn::Net &net, std::vector<Detection> &output, const std::vector<std::string> &className) {
    cv::Mat blob;

    // Format the input image to fit the model input requirements
    auto input_image = format_yolov5(image);
    
    // Convert the image into a blob and set it as input to the network
    cv::dnn::blobFromImage(input_image, blob, 1./255., cv::Size(INPUT_WIDTH, INPUT_HEIGHT), cv::Scalar(), true, false);
    net.setInput(blob);
    std::vector<cv::Mat> outputs;
    net.forward(outputs, net.getUnconnectedOutLayersNames());

    // Scaling factors to map the bounding boxes back to original image size
    float x_factor = input_image.cols / INPUT_WIDTH;
    float y_factor = input_image.rows / INPUT_HEIGHT;
    
    float *data = (float *)outputs[0].data;

    const int dimensions = 85;
    const int rows = 25200;
    
    std::vector<int> class_ids; // Stores class IDs of detections
    std::vector<float> confidences; // Stores confidence scores of detections
    std::vector<cv::Rect> boxes;   // Stores bounding boxes

   // Loop through all the rows to process predictions
    for (int i = 0; i < rows; ++i) {

        // Get the confidence of the current detection
        float confidence = data[4];

        // Process only detections with confidence above the threshold
        if (confidence >= CONFIDENCE_THRESHOLD) {
            
            // Get class scores and find the class with the highest score
            float * classes_scores = data + 5;
            cv::Mat scores(1, className.size(), CV_32FC1, classes_scores);
            cv::Point class_id;
            double max_class_score;
            minMaxLoc(scores, 0, &max_class_score, 0, &class_id);

            // If the class score is above the threshold, store the detection
            if (max_class_score > SCORE_THRESHOLD) {

                confidences.push_back(confidence);
                class_ids.push_back(class_id.x);

                // Calculate the bounding box coordinates
                float x = data[0];
                float y = data[1];
                float w = data[2];
                float h = data[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));
            }
        }

        data += 85;
    }

    // Apply Non-Maximum Suppression
    std::vector<int> nms_result;
    cv::dnn::NMSBoxes(boxes, confidences, SCORE_THRESHOLD, NMS_THRESHOLD, nms_result);

    // Draw the NMS filtered boxes and push results to output
    for (int i = 0; i < nms_result.size(); i++) {
        int idx = nms_result[i];

        // Only push the filtered detections
        Detection result;
        result.class_id = class_ids[idx];
        result.confidence = confidences[idx];
        result.box = boxes[idx];
        output.push_back(result);

        // Draw the final NMS bounding box and label
        cv::rectangle(image, boxes[idx], cv::Scalar(0, 255, 0), 3);
        std::string label = className[class_ids[idx]];
        cv::putText(image, label, cv::Point(boxes[idx].x, boxes[idx].y - 5), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(255, 255, 255), 2);
    }
}


int main(int argc, char **argv)
{   
    // Load class list 
    std::vector<std::string> class_list = load_class_list();

    // Load input image
    std::string image_path = cv::samples::findFile("C:/Users/sirom/Desktop/cpp-ultralytics/test2.jpg");
    cv::Mat frame = cv::imread(image_path, cv::IMREAD_COLOR);

    // Load the  modeL
    cv::dnn::Net net;
    load_net(net);

    // Vector to store detection results
    std::vector<Detection> output;
    // Run detection on the input image
    detect(frame, net, output, class_list);

    // Save the result to a file
    cv::imwrite("C:/Users/sirom/Desktop/cpp-ultralytics/result.jpg", frame);

    while (true)
    {       
        // display image
        cv::imshow("image",frame);

        // Exit the loop if any key is pressed
        if (cv::waitKey(1) != -1)
        {
            std::cout << "finished by user\n";
            break;
        }
    }

    std::cout << "Processing complete. Image saved /n";
    return 0;
}

5.编译并运行代码

mkdir build
cd build 
cmake ..
cmake --build .
.\Debug\object-detection.exe

img


在这里插入图片描述

好了,这篇文章就介绍到这里,喜欢的小伙伴感谢给点个赞和关注,更多精彩内容持续更新~~
关于本篇文章大家有任何建议或意见,欢迎在评论区留言交流!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【第10章:自然语言处理高级应用—10.4 NLP领域的前沿技术与未来趋势】

各位技术探险家们,今天我们要开启一场穿越语言智能奇点的时空之旅。从正在改写物理定律的万亿参数大模型,到能看懂《星际穿越》剧本的跨模态AI,再到正在颠覆编程方式的神经-符号混合系统……这篇万字长文将带你摸清NLP技术进化的七块关键拼图。(建议边读边做笔记,文末有技…

SpringBoot+微信小程序+数据可视化的宠物到家喂宠服务(程序+论文+讲解+安装+调试+售后等)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统介绍 在经济高速发展、物质生活极大丰富的当下&#xff0c;人们的精神需求愈发凸显&#xff0…

案例-06.部门管理-根据ID查询

一.根据ID查询-接口文档 二.根据ID查询-Controller层 package com.gjw.controller;/*** 部门管理Controller*/import com.gjw.anno.Log; import com.gjw.pojo.Dept; import com.gjw.pojo.Result; import com.gjw.service.DeptService; import com.gjw.service.impl.DeptServi…

C++17中的LegacyContiguousIterator(连续迭代器)

文章目录 特点内存连续性与指针的兼容性更高的性能 适用场景与C接口交互高性能计算 支持连续迭代器的容器示例代码性能优势缓存局部性指针算术优化 注意事项总结 在C17标准里&#xff0c;LegacyContiguousIterator&#xff08;连续迭代器&#xff09;是一类特殊的迭代器。它不仅…

【Kubernetes】k8s 部署指南

1. k8s 入门 1.1 k8s 简介 需要最需要明确的就是&#xff1a;kubernetes&#xff08;简称 k8s &#xff09; 是一个 容器编排平台 &#xff0c;换句话说就是用来管理容器的&#xff0c;相信学过 Docker 的小伙伴对于容器这个概念并不陌生&#xff0c;打个比方&#xff1a;容器…

Redis 03章——10大数据类型概述

一、which10 &#xff08;1&#xff09;一图 &#xff08;2&#xff09;提前声明 这里说的数据类型是value的数据类型&#xff0c;key的类型都是字符串 官网&#xff1a;Understand Redis data types | Docs &#xff08;3&#xff09;分别是 1.3.1redis字符串&#xff0…

基于矩阵分解-协同过滤推荐算法的视频播放平台【源码+部署+论文】

作者简介&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容&#xff1a;&#x1f31f;Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…

FPGA的星辰大海

编者按 时下风头正盛的DeepSeek,正值喜好宏大叙事的米国大统领二次上岗就业,OpenAI、软银、甲骨文等宣布投资高达5000亿美元“星际之门”之际,对比尤为强烈。 某种程度上,,是低成本创新理念的直接落地。 包括来自开源社区的诸多赞誉是,并非体现技术有多“超越”,而是…

「AI学习笔记」机器学习与深度学习的区别:从技术到产品的深度解析(四)...

随着人工智能&#xff08;AI&#xff09;的快速发展&#xff0c;机器学习&#xff08;ML&#xff09;和深度学习&#xff08;DL&#xff09;已经成为我们日常生活中不可忽视的技术力量。无论是推荐系统、语音助手&#xff0c;还是自动驾驶汽车&#xff0c;它们背后都离不开ML和…

MATLAB图像处理:图像分割方法

图像分割将图像划分为具有特定意义的子区域&#xff0c;是目标检测、医学影像分析、自动驾驶等领域的核心预处理步骤。本文讲解阈值分割、边缘检测、区域生长、聚类分割、基于图的方法等经典与前沿技术&#xff0c;提供MATLAB代码实现。 目录 1. 图像分割基础 2. 经典分割方…

动手实现一个PDF阅读器

1、简介 使用 pdf.js 库加载和显示 PDF 文件。 实现了翻页、缩放功能。 提供了基本的错误处理。 功能特点&#xff1a; 支持选择本地 PDF 文件。 可以逐页查看 PDF 内容。 支持放大缩小功能。 界面简洁&#xff0c;易于使用。 2、使用方法 <!DOCTYPE html> <html la…

利用亚马逊AI代码助手生成、构建和编译一个游戏应用(下)

在上篇文章中中&#xff0c;我们介绍了如何通过亚马逊AI代码生成助手 - Amazon Q Developer代理的代码生成、构建和测试功能&#xff0c;让开发者可以更高效地交付高质量代码项目&#xff0c;同时减少代码中bug错误&#xff0c;提升整体开发体验。在本篇中&#xff0c;我们将通…

unity学习42:动画状态机:混合动画状态 blend tree

目录 1 动画状态机 1.1 新建动画状态 2 混合动画状态 blend Tree 2.1 new blend Tree 2.2 blend tree state 和普通的 state的属性不同 2.3 双击blend tree 进入下一层 blend tree内部 2.3.1 blend tree 内部 2.3.2 blend type 2.3.3 参数类型默认是float&#xff0…

ipfs安装及其访问webui

在区块链应用场景里&#xff0c;常常需要借助专门的存储系统来保存各类文件。IPFS&#xff08;星际文件系统&#xff0c;InterPlanetary File System&#xff09;便是一种适用于区块链网络的分布式存储解决方案&#xff0c;它能够让用户便捷高效地存储和管理文件。 下面&#…

全方位探索DeepSeek

目录 前言1. DeepSeek的基础功能与应用场景2. 使用DeepSeek的多种方式2.1 通过Web界面快速体验2.2 调用API实现自动化处理2.3 集成到本地开发环境2.4 结合第三方工具扩展功能 3. 高效使用DeepSeek的进阶技巧3.1 参数调优与性能优化3.2 数据处理与结果分析 4. 实际案例分析与应用…

【STM32】外部时钟|红外反射光电开关

1.外部时钟 单片机如何对外部触发进行计数&#xff1f;先看一下内部时钟&#xff0c;内部时钟是接在APB1和APB2时钟线上的&#xff0c;APB1,APB2来自stm32单片机内部的脉冲信号&#xff0c;也叫内部时钟。我们用来定时。同样我们可以把外部的信号接入单片机&#xff0c;来对其…

核货宝外贸订货系统:批发贸易企业出海的强劲东风

在全球贸易一体化的汹涌浪潮中&#xff0c;批发贸易企业正积极探寻海外市场的广阔天地&#xff0c;试图开辟新的增长版图。然而&#xff0c;出海之路绝非坦途&#xff0c;众多难题如暗礁般潜藏在前行的航道上。从复杂繁琐的跨境交易流程、变幻莫测的国际市场需求&#xff0c;到…

4090单卡挑战DeepSeek r1 671b:尝试量化后的心得的分享

引言&#xff1a; 最近&#xff0c;DeepSeek-R1在完全开源的背景下&#xff0c;与OpenAI的O1推理模型展开了激烈竞争&#xff0c;引发了广泛关注。为了让更多本地用户能够运行DeepSeek&#xff0c;我们成功将R1 671B参数模型从720GB压缩至131GB&#xff0c;减少了80%&#xff…

uni-app 学习(一)

一、环境搭建和运行 &#xff08;一&#xff09;创建项目 直接进行创建 &#xff08;二&#xff09;项目结构理解 pages 是页面 静态资源 打包文件&#xff0c;看我们想输出成什么格式 app.vue 页面的入口文件 main.js 是项目的入口文件 存放对打包文件的配置 pages 存放整…

AIGC图生视频保姆级教程

一、AI文生图高阶技巧 推荐工具 ▸ MidJourney&#xff08;艺术感最强&#xff09; ▸ DALLE 3&#xff08;与ChatGPT深度联动&#xff09; ▸ Leonardo.ai&#xff08;精细化参数控制&#xff09; 核心策略 提示词架构&#xff1a; [主体描述][环境氛围][镜头语言][风格参数…