win下C++通过Clion部署yolov5——libtorch+yolov5

news2024/9/21 20:48:04

libtorch+yolov5

  • 一、环境配置
  • 二、下载官网例子
  • 三、测试
    • 3.1、创建项目
    • 3.2、cmakelist.txt编写
    • 3.3、运行测试

一、环境配置

需要配置libtorch+OpenCV,此处参考博文:clion配置libtorch+OpenCV环境配置。

环境解决后即可开始下一步啦。

二、下载官网例子

下载地址:YOLOv5 libtorch版本测试代码。

解压后如图所示:
在这里插入图片描述

三、测试

3.1、创建项目

博主是新建了一个项目,把相关代码复制过去重新运行的。
在这里插入图片描述
这是总的目录结构。
其中【images】和【weights】即为二中下载源码中的【images】和【weights】,其他的头文件和源文件是二中源码在这里插入图片描述
这里博主没有新建【include】和【src】目录,直接将5个文件复制到了新建项目下。

3.2、cmakelist.txt编写

这一步至关重要。

cmakelist.txt如下:

cmake_minimum_required(VERSION 3.19)
project(ModelDeploy)

set(CMAKE_CXX_STANDARD 14)

set(CMAKE_PREFIX_PATH D:/pyTorch/libtorch-win-shared-with-deps-2.0.0+cu117/libtorch)
#set(Torch_DIR "D:/pyTorch/libtorch-win-shared-with-deps-2.0.0+cu117/libtorch/share/cmake/Torch")
#include_directories(D:/pyTorch/libtorch-win-shared-with-deps-2.0.0+cu117/libtorch/include")
#include_directories("D:/pyTorch/libtorch-win-shared-with-deps-2.0.0+cu117/libtorch/include/torch/csrc/api/include")
find_package(Torch REQUIRED )

set(OpenCV_DIR D:/opencv/opencv-4.5.5/cmake-build-release-visual-studio/install)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

add_executable(modelDeploy main.cpp detector.cpp utils.h cxxopts.hpp)
target_link_libraries(modelDeploy ${TORCH_LIBRARIES} ${OpenCV_LIBS})
set_property(TARGET modelDeploy PROPERTY CXX_STANDARD 14)

其实就是博文clion配置libtorch+OpenCV环境配置中的cmakelist.txt做了些许修改。

在这里插入图片描述

其中红色框和绿色框分别是libtorch和OpenCV的相关配置;蓝色框则是添加需要运行的头文件和源文件,这里就是和博文clion配置libtorch+OpenCV环境配置中的cmakelist.txt的不同之处,所以关于红色框和绿色框的路径地址怎么给,也可以参考该博文。

3.3、运行测试

main.cpp

#include <iostream>
#include <torch/script.h>
#include <memory>
#include <torch/torch.h>

#include <iostream>
#include <time.h>
#include<windows.h>

#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "detector.h"
#include "cxxopts.hpp"

using namespace cv;

std::vector<std::string> LoadNames(const std::string& path)
{
    // load class names
    std::vector<std::string> class_names;
    std::ifstream infile(path);
    if (infile.is_open()) {
        std::string line;
        while (std::getline(infile, line)) {
            class_names.emplace_back(line);
        }
        infile.close();
    }
    else {
        std::cerr << "Error loading the class names!\n";
    }

    return class_names;
}
void Demo(cv::Mat& img,
          const std::vector<std::vector<Detection>>& detections,
          const std::vector<std::string>& class_names,
          bool label = true) {

    if (!detections.empty()) {
        for (const auto& detection : detections[0]) {
            const auto& box = detection.bbox;
            float score = detection.score;
            int class_idx = detection.class_idx;

            cv::rectangle(img, box, cv::Scalar(0, 0, 255), 2);

            if (label) {
                std::stringstream ss;
                ss << std::fixed << std::setprecision(2) << score;
                std::string s = class_names[class_idx] + " " + ss.str();

                auto font_face = cv::FONT_HERSHEY_DUPLEX;
                auto font_scale = 1.0;
                int thickness = 1;
                int baseline=0;
                auto s_size = cv::getTextSize(s, font_face, font_scale, thickness, &baseline);
                cv::rectangle(img,
                              cv::Point(box.tl().x, box.tl().y - s_size.height - 5),
                              cv::Point(box.tl().x + s_size.width, box.tl().y),
                              cv::Scalar(0, 0, 255), -1);
                cv::putText(img, s, cv::Point(box.tl().x, box.tl().y - 5),
                            font_face , font_scale, cv::Scalar(255, 255, 255), thickness);
            }
        }
    }

    cv::namedWindow("Result", cv::WINDOW_AUTOSIZE);
    cv::imshow("Result", img);
    cv::waitKey(0);
}

int main(int argc, const char* argv[]) {
  /*  std::cout << "Hello world." << std::endl;
    torch::Tensor a = torch::rand({2, 3});
    std::cout << a << std::endl;
    std::string path = "D:/aniya.jpg";
    Mat im = imread(path);
    imshow("image", im);
    waitKey(0);

    torch::jit::script::Module module;
    std::cout << torch::cuda::is_available() << std::endl;
    try {
        module = torch::jit::load("D:/MCworkspace/ModelDeploy/yolov5s.torchscript.pt");
        module.to(torch::kCUDA);		// set model to cpu / cuda mode
        module.eval();
        std::cout << "MODEL LOADED\n";
    }
    catch (const c10::Error& e) {
        std::cerr << "error loading the model\n";
    }
*/
    cxxopts::Options parser(argv[0], "A LibTorch inference implementation of the yolov5");
    // TODO: add other args
    parser.allow_unrecognised_options().add_options()
            ("weights", "yolov5s.torchscript.pt", cxxopts::value<std::string>()->default_value("../weights/yolov5s.torchscript.pt"))
            ("source", "images", cxxopts::value<std::string>()->default_value("../images/bus.jpg"))
            ("conf-thres", "object confidence threshold", cxxopts::value<float>()->default_value("0.4"))
            ("iou-thres", "IOU threshold for NMS", cxxopts::value<float>()->default_value("0.5"))
            ("gpu", "Enable cuda device or cpu", cxxopts::value<bool>()->default_value("false"))
            ("view-img", "display results", cxxopts::value<bool>()->default_value("true"))
            ("h,help", "Print usage");

    auto opt = parser.parse(argc, argv);

    if (opt.count("help")) {
        std::cout << parser.help() << std::endl;
        exit(0);
    }

    // check if gpu flag is set
    bool is_gpu = opt["gpu"].as<bool>();

    // set device type - CPU/GPU
    torch::DeviceType device_type;
    if (torch::cuda::is_available() && is_gpu) {
        device_type = torch::kCUDA;
    } else {
        device_type = torch::kCPU;
    }

    // load class names from dataset for visualization
    std::vector<std::string> class_names = LoadNames("../weights/coco.names");
    if (class_names.empty()) {
        return -1;
    }

    // load network
    std::string weights = opt["weights"].as<std::string>();
    auto detector = Detector(weights, device_type);

    // load input image
    std::string source = opt["source"].as<std::string>();
    cv::Mat img = cv::imread(source);
    if (img.empty()) {
        std::cerr << "Error loading the image!\n";
        return -1;
    }

    // run once to warm up
    std::cout << "Run once on empty image" << std::endl;
    auto temp_img = cv::Mat::zeros(img.rows, img.cols, CV_32FC3);
    detector.Run(temp_img, 1.0f, 1.0f);

    // set up threshold
    float conf_thres = opt["conf-thres"].as<float>();
    float iou_thres = opt["iou-thres"].as<float>();

    // inference
    auto result = detector.Run(img, conf_thres, iou_thres);

    // visualize detections
    if (opt["view-img"].as<bool>()) {
        Demo(img, result, class_names);
    }

//    cv::destroyAllWindows();
//    Sleep(100000);
//    waitKey(0);

    return 0;

}

这里可以先在clion编辑器端运行,所以博主在源码的基础上添加了两个默认值,可以直接运行:

在这里插入图片描述
在这里插入图片描述

终端运行

进入到生成的.exe可执行文件目录,也就是编译目录下:
在这里插入图片描述
在运行之前,需要将【images】复制到编译目录下,这是方便自定义给测试图片时路径书写方便。
运行modelDeploy.exe:

modelDeploy.exe --source ../images/bus.jpg --view-img

在这里插入图片描述

如果不自定义图片,直接运行modelDeploy.exe,效果则和编译器端直接运行的结果一样
在这里插入图片描述
对于终端会闪退的问题,可以添加如下代码解决。

#include<windows.h>
Sleep(100000);

代码Sleep(100000)的时间可以自行设置。

至此就结束啦。部署有什么问题可以私信博主。

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

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

相关文章

【debug】分立式网络切片部署

文章目录 启动代码部署全流程网络配置配置静态IP 部署核心网部署基站部署基站1部署基站2部署基站3查看amf日志 问题routing-config的问题不加routing-config与加的对比调查 nr-binder功能测试基站1基站2ifconfig路由表方向解决 路由规则 启动代码 启动OAI核心网 #开启数据转发…

WebAssembly--执行与内存模型

前言 在WebAssembly初探中&#xff0c;我们已经了解了WebAssembly的发展和标准演进过程&#xff0c;并简单地体验了一把Wasm的应用&#xff0c;本篇文章会通过对比WASM和JS的执行流程&#xff0c;WebAssembly的内存模型深入分析&#xff0c;带大家理解下WebAssembly部分核心原…

IOC/DI注解开发管理第三方bean

文章目录 1 环境准备2 注解开发管理第三方bean步骤1:导入对应的jar包步骤2:在配置类中添加一个方法步骤3:在方法上添加Bean注解步骤4:从IOC容器中获取对象并打印 3 引入外部配置类3.1 使用包扫描引入步骤1:在Spring的配置类上添加包扫描步骤2:在JdbcConfig上添加配置注解步骤3:…

谷歌浏览器F请求解析说明

请求 Queued at 0s&#xff1a;表示该请求加入到请求队列中的时刻&#xff0c;请求队列在打开F12后第一次发送请求的时候创建&#xff0c;直到关闭控制台的时候销毁。 Started at 7.14s&#xff1a;表示请求开始处理的时刻。 Queueing&#xff1a;表示请求从加入到请求队列…

LeetCode 107. 二叉树的层序遍历 II

107. 二叉树的层序遍历 II 描述 给你二叉树的根节点 root &#xff0c;返回其节点值 自底向上的层序遍历 。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历&#xff09; 示例 示例1 输入&#xff1a;root [3,9,20,null,null,15,7] 输出…

Alibaba(一)项目环境合理选择

在学习以及开始使微服务架构前&#xff0c;我们需要先选择各各模块适配的版本。以此来避免生产过程或者学习过程出现令人头疼的版本问题&#xff0c;避免花费大量时间去找更正这些版本错误&#xff0c;导致耽误学习&#xff0c;影响项目进度。 项目源码&#xff0c;及源文档地址…

XPATH 使用备忘

xpath的基础使用 一.xpath简介 XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。 XPath 使用路径表达式在 XML 文档中进行导航XPath 包含一个标准函数库XPath 是 XSLT 中的主要元素XPath 是一个 W3C 标准 节点 在 XPath 中&…

【Linux】有名管道介绍及使用

目录 有名管道有名管道使用 橙色 有名管道 有名管道(FIFO)和匿名管道(pipe)有一些特点是相同的,不一样的地方在于: FIFO在文件系统中作为一个特殊文件存在&#xff0c;但文件中是没有内容的&#xff0c; FIFO中的内容存放在内存中。当使用FIFO的进程退出后&#xff0c; FIFO文…

在离散混合制造环境中应用制造运营模型

介绍 本文所描述的所有制造过程、场景、操作模式和技术应用目前都在一个成熟的离散和离散/批量混合制造企业中使用&#xff0c;该企业生产和维修复杂的机器。该企业生产的产品范围从从棒材加工的简单零件到复杂的机械装配&#xff1b;最终产品包括许多内部和第三方提供的子装配…

5.2————运算符重载

对于基本的数据类型&#xff0c;C提供来许多预先定义的运算符&#xff0c;如“&#xff0c;-&#xff0c;*&#xff0c;/”等&#xff0c;他们的运用大家应该已经很熟悉了。那么我们引入运算符重载的概念到底是为什么&#xff0c;比如是我们的加号可以完成基本数据类型的相加&a…

mysql 修改最大连接数max_connections

mysql 修改最大连接数max_connections 1、编辑mysql service文件2、编辑mysql 配置文件3、重启MySQL服务4、查看max_connections 1、编辑mysql service文件 查找mysql service文件 find / -name mysql*.service先备份再编辑 cp /usr/lib/systemd/system/mysqld.service /usr…

【C++ STL】 那年我双手插兜,学会了stackqueuepriority_queue基础知识及其模拟实现【对话情景版】

文章目录 &#x1f4cd;前言C STL 之 stack&queue基础知识及其模拟实现&#x1f4cd;容器适配器&#x1f388;什么是适配器&#xff1f;&#x1f388;STL标准库中stack和queue的底层结构&#x1f388;deque的简单介绍(了解)&#x1f4cc;deque的原理介绍&#x1f4cc;deque…

基于SSM的书画拍卖网站

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

软件系统外包开发流程及注意事项

当企业发展到一定规模后&#xff0c;市场上通用的软件系统往往就无法满足自身的业务需要&#xff0c;这时就需要企业开发属于自己软件系统。软件系统是一项比较复杂的系统工程&#xff0c;从需求分析、代码开发到最后的上线需要比较长的时间&#xff0c;需要有系统的管理方法才…

问题记录:Datax+Datax-web2.1.2的一系列问题

问题1&#xff1a;DataX报错解决办法 - 在有总bps限速条件下&#xff0c;单个channel的bps值不能为空&#xff0c;也不能为非正数 问题原因&#xff1a; 正如中文字面上所说&#xff0c;DataX的配置有问题&#xff0c;单个channel的bps值不能为空&#xff0c;也不能为非正数。…

教你怎么翻译英语语音

在当今全球化的时代&#xff0c;跨语言交流是一种常态。无论你是在国外旅游时无法理解当地人说的英文意思&#xff0c;还是因为职业需要与国外客户、供应商进行交流&#xff0c;这时候通过翻译英文语音就可以帮助你获取对话内容&#xff0c;缩短沟通时间和提升工作效率。那对于…

【windows批处理batch】.bat文件循环判断语句

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、…

计算机毕业论文内容参考|基于java的学生成绩分析系统的设计与实现

文章目录 导文摘要前言课题背景国内外现状与趋势课题内容相关技术与方法介绍技术分析技术设计系统架构设计数据库设计安全认证设计数据可视化设计技术实现后端实现安全认证实现数据可视化实现总结与展望本文总结后续工作展望导文 基于java的学生成绩分析

【逆向工程核心原理:TLS回调函数】

TLS 代码逆向分析领域中&#xff0c;TLS&#xff08;Thread Local Storage&#xff0c;线程局部存储&#xff09;回调函数&#xff08;Callback Function&#xff09;常用反调试。TLS回调函数的调用运行要先于EP代码的执行&#xff0c;该特征使它可以作为一种反调试技术的使用…

【经验总结】你想知道的BGA焊接问题都在这里

BGA是一种芯片封装的类型&#xff0c;英文 (Ball Grid Array)的简称&#xff0c;封装引脚为球状栅格阵列在封装底部&#xff0c;引脚都成球状并排列成一个类似于格子的图案&#xff0c;由此命名为BGA。 主板控制芯片诸多采用此类封装技术&#xff0c;采用BGA技术封装的内存&am…