基于C# 和OpenVINO部署PP-Human

目 录

1.1 飞桨实时行人分析工具PP-Human

1.1.1 PP-Human技术架构

1.1.2 构建C#开发环境

1.1.3 项目完整代码已开源

1.2 C#中调用OpenVINOTM实现

1.2.1 构建OpenVINOTM动态链接库

1.2.2 在C#中引入动态链接库文件

1.2.3 C#构建Core类

本文将详细介绍基于OpenVINOTM工具包,在C#语言下,部署飞桨PP-Human的全流程,帮助开发者快速掌握并部署产业级AI人体分析解决方案。

1.1 飞桨实时行人分析工具PP-Human

PP-Human是飞桨目标检测套件PaddleDetection中开源的实时行人分析工具,提供了五大异常行为识别和四大产业级功能:人体属性分析、人流计数、跨镜ReID,如下图所示:

图 1-1 PP-Human v2全功能全景图

1.1.1 PP-Human技术架构

PP-Human支持单张图片、图片文件夹单镜头视频和多镜头视频输入,经目标检测以及特征关联,实现属性识别、关键点检测、轨迹/流量计数以及行为识别等功能,如下图所示。本文将以行人摔倒识别为例,基于OpenVINOTM进行多种模型联合部署。

图 1-2 PP-Human技术架构

1.1.2 构建C#开发环境

为了防止复现代码出现问题,列出以下代码开发环境,可以根据自己需求设置,注意OpenVINOTM一定是2022版本,其他依赖项可以根据自己的设置修改。

  • 操作系统:Windows 11

  • OpenVINOTM:2022.3

  • OpenCV:4.5.5

  • Visual Studio:2022 Community

  • C#框架:.NET 6.0

  • OpenCvSharp:OpenCvSharp4

1.1.3 项目完整代码已开源

项目所涉及的源码已在Gitee上开源,直接克隆到本地即可使用:

git clone https://github.com/guojin-yan/Csharp_and_OpenVINO_deploy_PP-Human.git

1.2 C#中调用OpenVINOTM实现

1.2.1 构建OpenVINOTM动态链接库

由于OpenVINOTM只有C++和Python接口,无法直接在C#中使用OpenVINOTM部署模型,为了实现在C#中使用,通过动态链接库的方式实现。具体教程参考《在C#中调用OpenVINO™ 模型》。

1.2.2 在C#中引入动态链接库文件

在C#中需要使用[DllImport()]方法引入动态链接库文件,其完整的使用方式如以下代码所示:

[DllImport(openvino_dll_path, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]public extern static IntPtr set_input_image_sharp(IntPtr inference_engine, string input_node_name, ref ulong input_size);

针对[DllImport()]括号中的内容:

  • openvino_dll_path为dll文件路径

  • CharSet = CharSet.Unicode代表支持中文编码格式字符串

  • CallingConvention = CallingConvention.Cdecl指示入口点的调用约定为调用方清理堆栈

在声明动态链接库后,就可以引入动态链接库中的方法,由于我们在C++环境下生成的动态链接库,为了让编译器识别,需要方法名、变量类型一一对应,才可以引入成功:

表 1 C++与C#方法对应关系

基于以上方法,我们将动态链接库中的所有方法引入到C#中。

1.2.3 C#构建Core类

上一步我们引入了封装的OpenVINOTM动态链接库,为了更方便的使用,将其封装到Core类中。在不同方法之间,主要通过推理核心结构体指针在各个方法之间传递,在C#是没有指针这个说法的,不过可以通过IntPtr结构体来接收这个指针,为了防止该指针被篡改,将其封装在类中作为私有成员使用。

根据模型推理的步骤,构建模型推理类:

(1)构造函数

public Core(string model_file, string device_name){   // 初始化推理核心   ptr = NativeMethods.core_init(model_file, device_name);}

在该方法中,主要是调用推理核心初始化方法,初始化推理核心,读取本地模型,将模型加载到设备、创建推理请求等模型推理步骤。

(2)设置模型输入形状

        // @brief 设置推理模型的输入节点的大小        // @param input_node_name 输入节点名        // @param input_size 输入形状大小数组        public void set_input_sharp(string input_node_name, ulong[] input_size) {            // 获取输入数组长度            int length = input_size.Length;            if (length == 4) {                // 长度为4,判断为设置图片输入的输入参数,调用设置图片形状方法                ptr = NativeMethods.set_input_image_sharp(ptr, input_node_name, ref input_size[0]);            }            else if (length == 2) {                // 长度为2,判断为设置普通数据输入的输入参数,调用设置普通数据形状方法                ptr = NativeMethods.set_input_data_sharp(ptr, input_node_name, ref input_size[0]);            }            else {                // 为防止输入发生异常,直接返回                return;            }        }

OpenVINOTM2022.3支持模型动态输入,读入模型可以不固定输入大小,在使用时固定模型的输入大小,并且可以随时修改输入形状。当前设置情况下,至此设置二维、以及四维的输入形状,在当前模型中足够使用。

(3)加载推理数据

  // @brief 加载推理数据        // @param input_node_name 输入节点名        // @param input_data 输入数据数组        public void load_input_data(string input_node_name, float[] input_data) {            ptr = NativeMethods.load_input_data(ptr, input_node_name, ref input_data[0]);        }        // @brief 加载图片推理数据        // @param input_node_name 输入节点名        // @param image_data 图片矩阵        // @param image_size 图片矩阵长度        public void load_input_data(string input_node_name, byte[] image_data, ulong image_size, int type) {            ptr = NativeMethods.load_image_input_data(ptr, input_node_name, ref image_data[0], image_size, type);        }

加载推理数据主要包含图片数据和普通的矩阵数据,其中对于图片的预处理,也已经在C++中进行封装,保证了图片数据在传输中的稳定性。

(5)模型推理

        // @brief 模型推理        public void infer() {            ptr = NativeMethods.core_infer(ptr);        }

(6)读取推理结果数据

        // @brief 读取推理结果数据        // @param output_node_name 输出节点名        // @param data_size 输出数据长度        // @return 推理结果数组        public T[] read_infer_result<T>(string output_node_name, int data_size) {            // 获取设定类型            string t = typeof(T).ToString();            // 新建返回值数组            T[] result = new T[data_size];            if (t == "System.Int32") { // 读取数据类型为整形数据                int[] inference_result = new int[data_size];                NativeMethods.read_infer_result_I32(ptr, output_node_name, data_size, ref inference_result[0]);                result = (T[])Convert.ChangeType(inference_result, typeof(T[]));                return result;            }            else { // 读取数据类型为浮点型数据                float[] inference_result = new float[data_size];                NativeMethods.read_infer_result_F32(ptr, output_node_name, data_size, ref inference_result[0]);                result = (T[])Convert.ChangeType(inference_result, typeof(T[]));                return result;            }        }

在读取模型推理结果时,支持读取整形数据和浮点型数据,且需要知晓模型输出数据的大小,这就要求我们对自己所使用的模型有很好的把握。

(7)清除地址

        // @brief 删除创建的地址        public void delet() {            NativeMethods.core_delet(ptr);        }

此处的清除地址需要调用fengzhuangd额地址删除方法实现,不可以直接删除C#中创建的IntPtr,这样会导致内存泄漏,影响程序性能。

通过上面的封装,比可以在C#平台下,调用Core类,间接调用OpenVINOTM工具包署自己的模型了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
手把手讲授如何搭建成功OpenVINO框架,并且使用预训练模型快速开发超分辨率、道路分割、汽车识别、人脸识别、人体姿态和行人车辆分析。得益于OpenVINO框架的强大能力,这些例子都能够基于CPU达到实时帧率。课程的亮点在于在调通Demo的基础上更进一步:一是在讲Demo的时候,对相关领域问题进行分析(比如介绍什么是超分辨率,有什么作用)、预训练模型的来龙去脉(来自那篇论文,用什么训练的)、如何去查看不同模型的输入输出参数、如何编写对应的接口参数进行详细讲解;二是基本上对所有的代码进行重构,也就是能够让例子独立出来,并且给出了带有较详细注释的代码;三是注重实际运用,将Demo进一步和实时视频处理框架融合,形成能够独立运行的程序,方便模型落地部署;四是重难点突出、注重总结归纳,对OpenVINO基本框架,特别是能够提高视频处理速度的异步机制和能够直接部署解决实际问题的骨骼模型着重讲解,帮助学习理解;五是整个课程准备精细,每一课都避免千篇一律,前一课有对后一课的预告,后一课有对前一课的难点回顾,避免学习过程中出现突兀;六是在适当的时候拓展衍生,不仅讲OpenVINO解决图像处理问题,而且还补充图像处理的软硬选择、如何在手机上开发图像处理程序等内容,帮助拓展视野,增强对行业现状的了解。基本提纲:1、课程综述、环境配置2、OpenVINO范例-超分辨率(super_resolution_demo)3、OpenVINO范例-道路分割(segmentation_demo)4、OpenVINO范例-汽车识别(security_barrier_camera_demo)5、OpenVINO范例-人脸识别(interactive_face_detection_demo)6、OpenVINO范例-人体姿态分析(human_pose_estimation_demo)7、OpenVINO范例-行人车辆分析(pedestrian_tracker_demo)8、NCS和GOMFCTEMPLATE9、课程小结,资源分享

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一枚爱吃大蒜的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值