使用 C++ 编写支持多模型调用的动态连接库,将 yolov5的ONNX 模型加载进来,并编译生成dll与注释供其他程序使用

时间: 2023-11-22 18:56:08 浏览: 116
首先,要使用 C++ 编写支持多模型调用的动态连接库,需要使用一些库,比如 OpenCV 和 ONNX Runtime。以下是一个基本的示例代码: ```c++ #include <iostream> #include <vector> #include <opencv2/opencv.hpp> #include <onnxruntime_cxx_api.h> class YOLOv5Detector { public: YOLOv5Detector(const std::string& model_path) { // Initialize ONNX Runtime Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "test"); Ort::SessionOptions session_options; session_options.SetIntraOpNumThreads(1); session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_BASIC); session_ = std::make_unique<Ort::Session>(env, model_path, session_options); // Get model input and output information auto input_info = session_.get()->GetInputTypeInfo(0); auto output_info = session_.get()->GetOutputTypeInfo(0); input_name_ = input_info.GetOnnxName(); output_name_ = output_info.GetOnnxName(); input_dims_ = input_info.GetTensorTypeAndShapeInfo().GetShape(); output_dims_ = output_info.GetTensorTypeAndShapeInfo().GetShape(); } std::vector<cv::Rect> detect(const cv::Mat& image) { // Preprocess image cv::Mat resized_image; cv::resize(image, resized_image, cv::Size(input_dims_[3], input_dims_[2])); cv::Mat float_image; resized_image.convertTo(float_image, CV_32FC3, 1.0 / 255.0); std::vector<float> input_data(float_image.ptr<float>(), float_image.ptr<float>() + float_image.total() * float_image.channels()); // Initialize input and output tensors Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU); std::vector<int64_t> input_shape = {1, 3, input_dims_[2], input_dims_[3]}; std::vector<int64_t> output_shape = {1, static_cast<int64_t>(output_dims_[1]), static_cast<int64_t>(output_dims_[2]), static_cast<int64_t>(output_dims_[3])}; Ort::Value input_tensor = Ort::Value::CreateTensor<float>(memory_info, input_data.data(), input_data.size(), input_shape.data(), input_shape.size()); Ort::Value output_tensor = Ort::Value::CreateTensor<float>(memory_info, nullptr, output_shape.data(), output_shape.size()); // Run inference std::vector<const char*> input_names = {input_name_.c_str()}; std::vector<const char*> output_names = {output_name_.c_str()}; session_.get()->Run(Ort::RunOptions{nullptr}, input_names.data(), &input_tensor, 1, output_names.data(), 1, &output_tensor); // Postprocess output const float* output_data = output_tensor.GetTensorMutableData<float>(); std::vector<cv::Rect> detected_rects; for (int i = 0; i < output_dims_[1]; i++) { float score = output_data[5 * i + 4]; if (score >= 0.5) { float x_center = output_data[5 * i]; float y_center = output_data[5 * i + 1]; float width = output_data[5 * i + 2]; float height = output_data[5 * i + 3]; int x_left = static_cast<int>((x_center - width / 2) * image.cols); int y_top = static_cast<int>((y_center - height / 2) * image.rows); int rect_width = static_cast<int>(width * image.cols); int rect_height = static_cast<int>(height * image.rows); detected_rects.emplace_back(x_left, y_top, rect_width, rect_height); } } return detected_rects; } private: std::unique_ptr<Ort::Session> session_; std::string input_name_; std::string output_name_; std::vector<int64_t> input_dims_; std::vector<int64_t> output_dims_; }; ``` 此代码创建了一个名为 `YOLOv5Detector` 的类,该类使用 ONNX Runtime 加载 YOLOv5 模型,并在给定图像上运行检测。检测结果是矩形的列表,表示在图像中检测到的对象。 要将此类编译为 DLL,您需要使用 Visual Studio 或其他支持 Windows DLL 编译的 IDE。以下是一个示例项目文件: ```xml <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> <ProjectConfiguration Include="Release|Win32"> <Configuration>Release</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> <VCProjectVersion>16.0</VCProjectVersion> <ProjectGuid>{GUID}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>YOLOv5Detector</RootNamespace> <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> <PlatformToolset>v142</PlatformToolset> <CharacterSet>Unicode</CharacterSet> <CLRSupport>true</CLRSupport> <WholeProgramOptimization>false</WholeProgramOptimization> <UseOfMfc>false</UseOfMfc> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <PlatformToolset>v142</PlatformToolset> <CharacterSet>Unicode</CharacterSet> <CLRSupport>true</CLRSupport> <WholeProgramOptimization>false</WholeProgramOptimization> <UseOfMfc>false</UseOfMfc> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> <ImportGroup Label="Shared"> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> <Optimization>Disabled</Optimization> <AdditionalIncludeDirectories>$(OPENCV_DIR)\include;$(ONNXRUNTIME_DIR)\include;</AdditionalIncludeDirectories> <PreprocessorDefinitions>_DEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader>Create</PrecompiledHeader> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderOutputFile>$(IntDir)\$(TargetName).pch</PrecompiledHeaderOutputFile> <WarningLevel>Level3</WarningLevel> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <CompileAs>Default</CompileAs> <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> <EnableEnhancedInstructionSet>AdvancedVectorExtensions2</EnableEnhancedInstructionSet> <TreatWarningAsError>true</TreatWarningAsError> <LanguageStandard>c++17</LanguageStandard> </ClCompile> <Link> <AdditionalDependencies>onnxruntime.lib;opencv_world450d.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(OPENCV_DIR)\x64\vc15\lib;$(ONNXRUNTIME_DIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <TargetMachine>MachineX64</TargetMachine> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MinimalRebuild>false</MinimalRebuild> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <PrecompiledHeader>Create</PrecompiledHeader> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderOutputFile>$(IntDir)\$(TargetName).pch</PrecompiledHeaderOutputFile> <WarningLevel>Level3</WarningLevel> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <CompileAs>Default</CompileAs> <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> <EnableEnhancedInstructionSet>AdvancedVectorExtensions2</EnableEnhancedInstructionSet> <TreatWarningAsError>true</TreatWarningAsError> <LanguageStandard>c++17</LanguageStandard> </ClCompile> <Link> <AdditionalDependencies>onnxruntime.lib;opencv_world450.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(OPENCV_DIR)\x64\vc15\lib;$(ONNXRUNTIME_DIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <TargetMachine>MachineX64</TargetMachine> </Link> </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="detector.cpp" /> <ClCompile Include="pch.cpp"> <PrecompiledHeader Condition=" '$(Configuration)|$(Platform)'=='Debug|Win32' ">Create</PrecompiledHeader> <PrecompiledHeader Condition=" '$(Configuration)|$(Platform)'=='Release|Win32' ">Create</PrecompiledHeader> </ClCompile> <ClInclude Include="detector.h" /> <ClInclude Include="pch.h" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> </Project> ``` 将此项目文件保存为 `YOLOv5Detector.vcxproj`,然后使用 Visual Studio 打开该文件并构建解决方案。这将生成一个名为 `YOLOv5Detector.dll` 的 DLL 文件。您可以在其他 C++ 程序中使用此 DLL 文件,并调用 `YOLOv5Detector` 类来运行目标检测算法。
阅读全文

相关推荐

zip

最新推荐

recommend-type

使用c++编写和使用.so动态链接库

在C++编程中,动态链接库(.so文件)是一种重要的技术,允许代码在运行时被加载和使用,而不是在编译时静态链接。这使得应用程序可以更灵活地使用库,便于更新和优化,同时也降低了内存占用。以下将详细介绍如何使用...
recommend-type

Qt程序中调用C#编写的dll(推荐)

本文将详细介绍如何在Qt程序中调用C#编写的dll,包括创建C#编写的dll、在Qt程序中使用dll等内容。 创建C#编写的dll 首先,在Visual Studio中新建一个C#的Class Library项目,并选择.Net Framework 4作为项目框架。...
recommend-type

ubuntu中python调用C/C++方法之动态链接库详解

动态链接库允许Python程序利用C或C++编写的高效功能,而无需将整个C/C++代码编译进Python解释器。这种技术在需要高性能计算、系统级操作或调用特定硬件时特别有用。 本篇教程主要讲解了如何使用Boost.Python库来...
recommend-type

在C++中加载TorchScript模型的方法

"在C++中加载TorchScript模型的方法" 知识点1: PyTorch 在生产环境中的限制 PyTorch 作为一个主要的机器学习框架,其主要接口是 Python 编程语言。尽管 Python 是合适于许多需要动态性和易于迭代的场景,但是它在...
recommend-type

在Visual Studio中用C++语言创建DLL动态链接库图文教程

主要介绍了在Visual Studio中用C++语言创建DLL动态链接库图文教程,本文详细讲解了DLL库的创建过程,并给出了代码示例,需要的朋友可以参考下
recommend-type

PureMVC AS3在Flash中的实践与演示:HelloFlash案例分析

资源摘要信息:"puremvc-as3-demo-flash-helloflash:PureMVC AS3 Flash演示" PureMVC是一个开源的、轻量级的、独立于框架的用于MVC(模型-视图-控制器)架构模式的实现。它适用于各种应用程序,并且在多语言环境中得到广泛支持,包括ActionScript、C#、Java等。在这个演示中,使用了ActionScript 3语言进行Flash开发,展示了如何在Flash应用程序中运用PureMVC框架。 演示项目名为“HelloFlash”,它通过一个简单的动画来展示PureMVC框架的工作方式。演示中有一个小蓝框在灰色房间内移动,并且可以通过多种方式与之互动。这些互动包括小蓝框碰到墙壁改变方向、通过拖拽改变颜色和大小,以及使用鼠标滚轮进行缩放等。 在技术上,“HelloFlash”演示通过一个Flash电影的单帧启动应用程序。启动时,会发送通知触发一个启动命令,然后通过命令来初始化模型和视图。这里的视图组件和中介器都是动态创建的,并且每个都有一个唯一的实例名称。组件会与他们的中介器进行通信,而中介器则与代理进行通信。代理用于保存模型数据,并且中介器之间通过发送通知来通信。 PureMVC框架的核心概念包括: - 视图组件:负责显示应用程序的界面部分。 - 中介器:负责与视图组件通信,并处理组件之间的交互。 - 代理:负责封装数据或业务逻辑。 - 控制器:负责管理命令的分派。 在“HelloFlash”中,我们可以看到这些概念的具体实现。例如,小蓝框的颜色变化,是由代理来处理的模型数据;而小蓝框的移动和缩放则是由中介器与组件之间的通信实现的。所有这些操作都是在PureMVC框架的规则和指导原则下完成的。 在Flash开发中,ActionScript 3是主要的编程语言,它是一种面向对象的语言,并且支持复杂的事件处理和数据管理。Flash平台本身提供了一套丰富的API和框架,使得开发者可以创建动态的、交互性强的网络应用。 最后,我们还看到了一个压缩包文件的名称列表“puremvc-as3-demo-flash-helloflash-master”,这表明该演示项目的源代码应该可以在该压缩包中找到,并且可以在支持ActionScript 3的开发环境中进行分析和学习。开发者可以通过这个项目的源代码来深入了解PureMVC框架在Flash应用中的应用,并且学习到如何实现复杂的用户交互、数据处理和事件通信。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

YRC1000 EtherNet_IP通信协议:掌握连接与数据交换的6个关键策略

![YRC1000 EtherNetIP通信功能说明书](https://5.imimg.com/data5/SELLER/Default/2022/12/EE/XV/JL/4130645/yrc1000-csra-cdc101aa-3--1000x1000.jpg) # 摘要 YRC1000 EtherNet/IP通信协议作为工业自动化领域的重要技术之一,本论文对其进行了系统性的介绍和分析。从通信连接策略的实施到数据交换机制的详细阐述,再到高级应用与实践案例的深入探讨,本文全面覆盖了YRC1000的操作原理、配置方法、安全性和性能监控等方面。通过对各种典型应用场景的案例分析,本文不仅总结了
recommend-type

如何设置 OpenFileDialog 用户只能在固定文件夹及其子文件夹里选择文件

在Windows应用程序中,如果你想要限制OpenFileDialog让用户只能在特定的文件夹及其子文件夹中选择文件,你可以通过设置`InitialDirectory`属性和`Filter`属性来实现。以下是步骤: 1. 创建一个`OpenFileDialog`实例: ```csharp OpenFileDialog openFileDialog = new OpenFileDialog(); ``` 2. 设置初始目录(`InitialDirectory`)为你要限制用户选择的起始文件夹,例如: ```csharp string restrictedFolder = "C:\\YourR
recommend-type

掌握Makefile多目标编译与清理操作

资源摘要信息:"makefile学习用测试文件.rar" 知识点: 1. Makefile的基本概念: Makefile是一个自动化编译的工具,它可以根据文件的依赖关系进行判断,只编译发生变化的文件,从而提高编译效率。Makefile文件中定义了一系列的规则,规则描述了文件之间的依赖关系,并指定了如何通过命令来更新或生成目标文件。 2. Makefile的多个目标: 在Makefile中,可以定义多个目标,每个目标可以依赖于其他的文件或目标。当执行make命令时,默认情况下会构建Makefile中的第一个目标。如果你想构建其他的特定目标,可以在make命令后指定目标的名称。 3. Makefile的单个目标编译和删除: 在Makefile中,单个目标的编译通常涉及依赖文件的检查以及编译命令的执行。删除操作则通常用clean规则来定义,它不依赖于任何文件,但执行时会删除所有编译生成的目标文件和中间文件,通常不包含源代码文件。 4. Makefile中的伪目标: 伪目标并不是一个文件名,它只是一个标签,用来标识一个命令序列,通常用于执行一些全局性的操作,比如清理编译生成的文件。在Makefile中使用特殊的伪目标“.PHONY”来声明。 5. Makefile的依赖关系和规则: 依赖关系说明了一个文件是如何通过其他文件生成的,规则则是对依赖关系的处理逻辑。一个规则通常包含一个目标、它的依赖以及用来更新目标的命令。当依赖的时间戳比目标的新时,相应的命令会被执行。 6. Linux环境下的Makefile使用: Makefile的使用在Linux环境下非常普遍,因为Linux是一个类Unix系统,而make工具起源于Unix系统。在Linux环境中,通过终端使用make命令来执行Makefile中定义的规则。Linux中的make命令有多种参数来控制执行过程。 7. Makefile中变量和模式规则的使用: 在Makefile中可以定义变量来存储一些经常使用的字符串,比如编译器的路径、编译选项等。模式规则则是一种简化多个相似规则的方法,它使用模式来匹配多个目标,适用于文件名有规律的情况。 8. Makefile的学习资源: 学习Makefile可以通过阅读相关的书籍、在线教程、官方文档等资源,推荐的书籍有《Managing Projects with GNU Make》。对于初学者来说,实际编写和修改Makefile是掌握Makefile的最好方式。 9. Makefile的调试和优化: 当Makefile较为复杂时,可能出现预料之外的行为,此时需要调试Makefile。可以使用make的“-n”选项来预览命令的执行而不实际运行它们,或者使用“-d”选项来输出调试信息。优化Makefile可以减少不必要的编译,提高编译效率,例如使用命令的输出作为条件判断。 10. Makefile的学习用测试文件: 对于学习Makefile而言,实际操作是非常重要的。通过提供一个测试文件,可以更好地理解Makefile中目标的编译和删除操作。通过编写相应的Makefile,并运行make命令,可以观察目标是如何根据依赖被编译和在需要时如何被删除的。 通过以上的知识点,你可以了解到Makefile的基本用法和一些高级技巧。在Linux环境下,利用Makefile可以有效地管理项目的编译过程,提高开发效率。对于初学者来说,通过实际编写Makefile并结合测试文件进行练习,将有助于快速掌握Makefile的使用。