C#封装YOLOv4算法进行目标检测

概述

官网:https://pjreddie.com/darknet/
Darknet:【Github】
C#封装代码:【Github】

YOLO: 是实现实时物体检测的系统,Darknet是基于YOLO的框架
采用C#语言对 YOLOv4 目标检测算法封装,将模型在实际应用系统中落地,实现模型在线远程调用。

环境准备

本章只讲解如何对YOLOv4封装进行详解,具体环境安装过程不做介绍
查看你的GPU计算能力是否支持 >= 3.0:【点击查看】

Windows运行要求

  • CMake >= 3.12: 【点击下载】
  • CUDA >= 10.0: 【点击下载】
  • OpenCV >= 2.4: 【点击下载】
  • cuDNN >= 7.0: 【点击下载】
  • Visual Studio 2017/2019: 【点击下载】

我所使用的环境

  • 系统版本:Windows 10 专业版
  • 显卡:GTX 1050 Ti
  • CMake版本:3.18.2
  • CUDA版本:10.1
  • OpenCV版本:4.4.0
  • cuDNN版本:10.1
  • MSVC 2017/2019: Visual Studio 2019

程序代码准备

源代码下载

下载地址:【Darknet】

使用Git

git clone https://github.com/AlexeyAB/darknet
cd darknet

代码结构

将YOLOv4编译为DLL

详细教程:【点击查看】,这个教程描述的很详细。

进入 darknetbuilddarknet 目录,打开解决方案 yolo_cpp_dll.sln

设置Windows SDK版本和平台工具集为当前系统安装版本

设置Release和x64

然后执行以下操作:Build-> Build yolo_cpp_dll

已完成生成项目“yolo_cpp_dll.vcxproj”的操作。
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========

在打包DLL的过程中可能遇到如下问题

C1041
无法打开程序数据库“D:代码管理Cdarknetbuilddarknetx64DLL_Releasevc142.pdb”;如果要将多个 CL.EXE 写入同一个 .PDB 文件,请使用 /FS    yolo_cpp_dll    C:UsersadministratorAppDataLocalTemptmpxft_00005db0_00000000-6_dropout_layer_kernels.compute_75.cudafe1.cpp   1
MSB3721
命令“"C:Program FilesNVIDIA GPU Computing ToolkitCUDAv10.1binnvcc.exe" -gencode=arch=compute_30,code="sm_30,compute_30" -gencode=arch=compute_75,code="sm_75,compute_75" --use-local-env -ccbin "C:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.27.29110binHostX86x64" -x cu  -IC:opencvbuildinclude -IC:opencv_3.0opencvbuildinclude -I....include -I....3rdpartystbinclude -I....3rdpartypthreadsinclude -I"C:Program FilesNVIDIA GPU Computing ToolkitCUDAv10.1include" -I"C:Program FilesNVIDIA GPU Computing ToolkitCUDAv10.1include" -Iinclude -Iinclude -I"C:Program FilesNVIDIA GPU Computing ToolkitCUDAv10.1include"     --keep-dir x64Release -maxrregcount=0  --machine 64 --compile -cudart static     -DCUDNN_HALF -DCUDNN -DGPU -DLIB_EXPORTS -D_TIMESPEC_DEFINED -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -DWIN32 -DNDEBUG -D_CONSOLE -D_LIB -D_WINDLL -D_MBCS -Xcompiler "/EHsc /W3 /nologo /O2 /Fdx64DLL_Releasevc142.pdb  /Zi  /MD " -o x64DLL_Releasedropout_layer_kernels.cu.obj "D:darknetsrcdropout_layer_kernels.cu"”已退出,返回代码为 2。   yolo_cpp_dll    C:Program Files (x86)Microsoft Visual Studio2019CommunityMSBuildMicrosoftVCv160BuildCustomizationsCUDA 10.1.targets   757

解决方法

在VS 2019 工具》选项》项目和解决方案》生成并运行 中最大并行项目生成数设为 1

在VS 2019 项目-》属性-》配置属性-》常规 将Windows SDK版本设置为系统当前版本即可

封装YOLOv4编译后的DLL

  • 1、进入 darknetbuilddarknetx64 目录,将 pthreadGC2.dllpthreadVC2.dll 拷贝到项目 Dll 文件夹
  • 2、将编译后的YOLOv4 DLL文件拷贝到项目 Dll 文件夹
  • 3、进入 darknetbuilddarknetx64cfg 目录,将 yolov4.cfg 拷贝到项目 Cfg 文件夹
  • 4、进入 darknetbuilddarknetx64data 目录,将 coco.names 拷贝到项目 Data 文件夹
  • 5、下载 yolov4.weights 权重文件 拷贝到 Weights 文件夹,文件245 MB 【点击下载】

项目文件

代码下载:【Github】

  • YoloWrapper - YOLOv4封装项目
  • Cfg - 配置文件夹
  • Data - label文件夹
  • Dll - YOLOv4 编译后的DLL文件夹
  • Weights - YOLOv4 权重文件夹
  • BboxContainer.cs
  • BoundingBox.cs
  • YoloWrapper.cs - 封装主文件,调用 YOLOv4 的动态链接库
  • YoloWrapperConsole - 调用封装DLL控制台程序
  • Program.cs - 控制台主程序,调用 YOLOv4 封装文件

代码

YOLOv4封装项目

YoloWrapper.cs - 封装主文件,调用 YOLOv4 的动态链接库

using System;
using System.Runtime.InteropServices;namespace YoloWrapper
{public class YoloWrapper : IDisposable{private const string YoloLibraryName = @"Dllsyolo_cpp_dll.dll";[DllImport(YoloLibraryName, EntryPoint = "init")]private static extern int InitializeYolo(string configurationFilename, string weightsFilename, int gpu);[DllImport(YoloLibraryName, EntryPoint = "detect_image")]private static extern int DetectImage(string filename, ref BboxContainer container);[DllImport(YoloLibraryName, EntryPoint = "detect_mat")]private static extern int DetectImage(IntPtr pArray, int nSize, ref BboxContainer container);[DllImport(YoloLibraryName, EntryPoint = "dispose")]private static extern int DisposeYolo();public YoloWrapper(string configurationFilename, string weightsFilename, int gpu){InitializeYolo(configurationFilename, weightsFilename, gpu);}public void Dispose(){DisposeYolo();}public BoundingBox[] Detect(string filename){var container = new BboxContainer();var count = DetectImage(filename, ref container);return container.candidates;}public BoundingBox[] Detect(byte[] imageData){var container = new BboxContainer();var size = Marshal.SizeOf(imageData[0]) * imageData.Length;var pnt = Marshal.AllocHGlobal(size);try{Marshal.Copy(imageData, 0, pnt, imageData.Length);var count = DetectImage(pnt, imageData.Length, ref container);if (count == -1){throw new NotSupportedException($"{YoloLibraryName} has no OpenCV support");}}catch (Exception exception){return null;}finally{Marshal.FreeHGlobal(pnt);}return container.candidates;}}}

BboxContainer.cs

using System.Runtime.InteropServices;namespace YoloWrapper
{[StructLayout(LayoutKind.Sequential)]public struct BboxContainer{[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]public BoundingBox[] candidates;}
}

BoundingBox.cs

using System;
using System.Runtime.InteropServices;namespace YoloWrapper
{[StructLayout(LayoutKind.Sequential)]public struct BoundingBox{public UInt32 x, y, w, h;public float prob;public UInt32 obj_id;public UInt32 track_id;public UInt32 frames_counter;public float x_3d, y_3d, z_3d;}
}

调用封装DLL控制台程序

BoundingBox.cs

using ConsoleTables;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using YoloWrapper;namespace YoloWrapperConsole
{class Program{private const string configurationFilename = @".Cfgyolov4.cfg";private const string weightsFilename = @".Weightsyolov4.weights";private const string namesFile = @".Datacoco.names";private static Dictionary<int, string> _namesDic = new Dictionary<int, string>();private static YoloWrapper.YoloWrapper _wrapper;static void Main(string[] args){Initilize();Console.Write("ImagePath:");string imagePath = Console.ReadLine();var bbox = _wrapper.Detect(imagePath);Convert(bbox);Console.ReadKey();}private static void Initilize(){_wrapper = new YoloWrapper.YoloWrapper(configurationFilename, weightsFilename, 0);var lines = File.ReadAllLines(namesFile);for (var i = 0; i < lines.Length; i++)_namesDic.Add(i, lines[i]);}private static void Convert(BoundingBox[] bbox){Console.WriteLine("Result:");var table = new ConsoleTable("Type", "Confidence", "X", "Y", "Width", "Height");foreach (var item in bbox.Where(o => o.h > 0 || o.w > 0)){var type = _namesDic[(int)item.obj_id];table.AddRow(type, item.prob, item.x, item.y, item.w, item.h);}table.Write(Format.MarkDown);}}
}

测试返回结果

控制台

.net 多个dll 封装成一个dll_C#封装YOLOv4算法进行目标检测相关推荐

  1. c 语言 封装dll_C#封装YOLOv4算法进行目标检测

    C#封装YOLOv4算法进行目标检测 概述 官网:https://pjreddie.com/darknet/ Darknet:[Github] C#封装代码:[Github] YOLO: 是实现实时物 ...

  2. [课程][原创]yolox检测封装成类调用几句代码完成目标检测任务

    搞定系列:yolox检测封装成类调用 课程地址:搞定系列:yolox检测封装成类调用--深度学习视频教程-人工智能-CSDN程序员研修院 你将收获 1.学会Yolox封装基本技巧和大体思路 2.学会Y ...

  3. 快速上手Xilinx DDR3 IP核(4)----把MIG IP核封装成一个FIFO(下)(Native接口)

    写在前面 本文将把Xilinx的MIG IP核DDR3的Native接口进行二次封装,将其封装成一个类似FIFO的接口,使其应用起来更加方便简单. 本文为下篇,建议与上篇一起阅读,有利于理解: 快速上 ...

  4. winform把所有dll打包成一个exe

    大家都知道做winform开发,是可以利用visual studio进行打包的,但是这种打包的方式需要双击安装,那么有没有什么方法,可以把winform程序打包成绿色版呢?当然,这里的"绿色 ...

  5. 快速上手Xilinx DDR3 IP核(3)----把MIG IP核封装成一个FIFO(上)(Native接口)

    写在前面 本文将把Xilinx的MIG IP核DDR3的Native接口进行二次封装,将其封装成一个类似FIFO的接口,使其应用起来更加方便简单. DDR3系列文章: 快速上手Xilinx DDR3 ...

  6. 开源项目|从0到1教你搭建一个适配于智能车的目标检测系统

    引言 本教程连载一辆能够用 ROS 控制的带摄像头的小车,用 ROS 发布图像数据,对获取到的图像进行处理,例如目标检测.这里主要介绍如何把本教程后面的的内容汇聚起来,实现一个能目标检测的小车. 先归 ...

  7. 直播项目之 将SDK提供的C 头文件,封装成C++类 管理

    一:封装前准备 以网易直播SDK为例解析,将其封装成一个类,便于管理. 提供了 SDK/include目录: 存放直播推流 SDK API的头文件.             SDK/lib目录: 存放 ...

  8. 如何将自己写的verilog模块封装成IP核(二)

    =======================第一篇======================= 如何将自己写的verilog模块封装成IP核 将你的设计制作成BlackBox,也就是网表文件,这样 ...

  9. python list合并_python基础===两个list合并成一个dict的方法

    def Run(): list2 = [, , , , ]; list3 = ["a", "b", "c", "d",& ...

最新文章

  1. [Buzz.Today]HP停止 webOS 设备的研发和运作
  2. (Prototype)原型模式的Java实现(转)
  3. 一篇文章教你如何制作二次元角色建模!
  4. 从流量控制算法谈网络优化-TCP核心原理理解
  5. Eclipse C++的配置问题launch failed binary not found
  6. php+tp框架+API,【路由】利用Thinkphp路由实现API开发版本管理
  7. BZOJ 1567: [JSOI2008]Blue Mary的战役地图 矩阵二维hash
  8. c# dynamic动态类型和匿名类
  9. 单机上搭建Node集群
  10. Android Studio 工具窗口浮动与布局恢复【申明:来源于网络】
  11. 数字代理在持续由内而外重塑创新
  12. 英文论文写作必备网站
  13. Python 学习笔记 - 函数
  14. 【Android】Android Studio Profiler Memery (一)
  15. LNK1104:无法打开文件d3dx11.lib
  16. 上班聊天,摸鱼神器,手写一款即时通讯工具(附源码!!!)
  17. 考研数学复习建议与资料
  18. 设计师们都在用的3D软件汇总,确定不来学学嘛
  19. 1985—1990年《ISTP》收录的世界主要国家(地区)科技会议论文情况
  20. 重用地图的单目视觉惯导SLAM系统

热门文章

  1. unity3d android assets,Unity3D之Android同步方法读取streamingAssets(八十八)
  2. php价格结算,PHP根据用户折扣计算商品价格
  3. 23_python基础—模块和包
  4. java 子类必须实现_Java学习之接口的子类必须实现接口的全部方法吗?
  5. python中metaclass的理解
  6. bat 自动输入密码_三轴自动焊接,三轴搬运机械手示教系统简易说明,分秒学会...
  7. 节能与新能源汽车技术路线图2.0 pdf_《节能与新能源汽车技术路线图(2.0版)》正式发布...
  8. oracle中通过distinct为什么过滤不了重复的数据_spark | 手把手教你用spark进行数据预处理...
  9. python坐标定位_Python_元素定位浏览器坐标定位
  10. 安卓学习笔记22:常用控件 - 可展开列表视图