0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于哪吒开发板部署YOLOv8模型

英特尔物联网 来源:英特尔物联网 2024-11-15 14:13 次阅读

作者:

颜国进 英特尔边缘计算创新大使

2024英特尔“走近开发者”互动活动-哪吒开发套件免费试 用 AI 创新计划:哪吒开发板是专为支持入门级边缘 AI 应用程序和设备而设计,能够满足人工智能学习、开发、实训等应用场景。为了测试该开发板的推理性能,同时测试所推出的 OpenVINO C# API (https://github.com/guojin-yan/OpenVINO-CSharp-API) 项目能否应用到该开发板上,我们使用该开发板,结合 OpenVINO C# API 的异步推理功能,加速深度学习推理速度。

1哪吒开发板

1.1 产品简介

哪吒(Nezha)开发套件以信用卡大小(85 x 56mm)的开发板-哪吒(Nezha)为核心,哪吒采用Intel N97处理器(Alder Lake-N),最大睿频 3.6GHz,Intel UHD Graphics 内核 GPU,可实现高分辨率显示;板载 LPDDR5 内存、eMMC 存储及 TPM 2.0,配备 GPIO 接口,支持 Windows 和 Linux 操作系统,这些功能和无风扇散热方式相结合,为各种应用程序构建高效的解决方案,适用于如自动化、物联网网关、数字标牌和机器人等应用。

该开发板是类树莓派的 x86 主机,可支持 Linux Ubuntu 及完整版 Windows 操作系统。板载英特尔 N97 处理器,最高运行频率可达 3.6 GHz,且内置显卡(iGPU),板载 64GB eMMC 存储及 LPDDR5 4800MHz(4GB/8GB),支持 USB 3.0、HDMI 视频输出、3.5mm 音频接口、1000Mbps 以太网口。完全可把它作为一台 mini 小电脑来看待,且其可外接 ArduinoSTM32单片机,扩展更多应用及各种传感器模块。

此外, 其主要接口与 Jetson Nano 载板兼容,GPIO 与树莓派兼容,能够最大限度地复用树莓派、Jetson Nano 等生态资源,无论是自动化、物联网网关、数字标牌或是摄像头物体识别、3D 打印,还是 CNC 实时插补控制都能稳定运行。可作为边缘计算引擎用于人工智能产品验证、开发;也可以作为域控核心用于机器人产品开发。

1.2 功能特点

Intel Processor N97

板载 LPDDR5 内存, 8GB

板载 eMMC 存储, 64GB

1Gigabit LAN x 1

HDMI 1.4b x 1

USB 3.2 Gen 2 (Type-A) x 3, 10针 USB 2.0 x 2/UART x 1

40针 GPIO x 1

12V 直流输入, 5A

TPM 2.0

下图为哪吒开发板产品介绍图片:

104f3a38-9db3-11ef-93f3-92fbcf53809c.png

2环境配置

2.1NET 8.0 安装

进入微软官网下载地址:

https://dotnet.microsoft.com/zh-cn/download

显示如下页面直接下载即可:

107c22aa-9db3-11ef-93f3-92fbcf53809c.png

下载完成过后,右击以管理员方式运行即可,进入一下页面后,直接点击安装,按照默认方式安装即可:

1092ddce-9db3-11ef-93f3-92fbcf53809c.png

安装完成后,在 CMD 中输入 dotnet --info 指令,查看是否安装成功:

10bd51d0-9db3-11ef-93f3-92fbcf53809c.png

2.2VS Code 配置 C# 环境

VS Code 安装较为简单,大家直接网上下载安装包安装即可,此处不做太多的赘述。进入 VS Code,在扩展中,依次安装一下插件:

10cbc094-9db3-11ef-93f3-92fbcf53809c.png

安装完成后,便可以进行 C# 项目编辑。

3创建并配置 YOLOv8 推理项目

3.1创建 YOLOv8 推理项目

此处我们使用 CMD 创建项目,首先输入以下指令:

dotnet new console -o yolov8_async_csharp -f net8.0

输入指令后,结果如下图所示:

10d7fe68-9db3-11ef-93f3-92fbcf53809c.png

3.2配置 YOLOv8 推理项目

该项目中需要配置 OpenCV 和 OpenVINO 依赖,其中 OpenCV 我们在 C# 使用的是 OpenCvSharp4,而 OpenVINO 就是使用的我们开发的[OpenVINO C# API] (https://github.com/guojin-yan/OpenVINO-CSharp-API) 项目,该项目均可以通过 NUGET 安装,在该项目中,输入以下指令,进行以来安装:

OpenCvSharp4 安装指令:

dotnet add package OpenCvSharp4 --version 4.9.0.20240103
dotnet add package OpenCvSharp4.runtime.win --version 4.9.0.20240103

OpenVINO C# API 安装指令:

dotnet add package OpenVINO.CSharp.API --version 2024.3.0.2
dotnet add package OpenVINO.runtime.win --version 2024.3.0.1
dotnet add package OpenVINO.CSharp.API.Extensions.OpenCvSharp --version 1.0.6.1

4编写推理代码

下面为该项目所使用的所有代码,为了提高推理速度,此处使用的为异步推理过程。

using OpenCvSharp.Dnn;
using OpenCvSharp;
using OpenVinoSharp;
using OpenVinoSharp.Extensions.result;
using OpenVinoSharp.Extensions.process;
using System.Diagnostics;
using OpenVinoSharp.preprocess;
namespace openvino_async_csharp
{
  internal class Program
 {
    static void Main(string[] args)
{
      Console.WriteLine("Hello, World!");
      yolov8_async_det();
   }
    static void yolov8_async_det()
{
      string video_path = "video.mp4";
      string model_path = "yolov8s.onnx";
      Core core = new Core();
      Model model = core.read_model(model_path);
      CompiledModel compiled_model = core.compile_model(model, "GPU.0");
      VideoCapture capture = new VideoCapture(video_path);
      if (!capture.IsOpened())
     {
        Console.WriteLine("ERROR: 视频无法打开");
        return;
     }
      List requests = new List { compiled_model.create_infer_request(), compiled_model.create_infer_request() };
      Mat frame = new Mat();
      capture.Read(frame);
      float factor = 0f;
      float[] input_data = preprocess(frame, out factor);
      requests[0].get_input_tensor().set_data(input_data);
      requests[0].start_async();
      Stopwatch sw = new Stopwatch();
      float[] total_infs = new float[3];


      while (true)
     {
        Mat next_frame = new Mat();
        if (!capture.Read(next_frame))
       {
          break;
       }
        sw.Restart();
        input_data = preprocess(frame, out factor);
        requests[1].get_input_tensor().set_data(input_data);
        sw.Stop();
        total_infs[0] = sw.ElapsedMilliseconds;
        sw.Restart();
        requests[1].start_async();
        requests[0].wait();
        sw.Stop();
        total_infs[1] = sw.ElapsedMilliseconds;
        sw.Restart();
        float[] output_data = requests[0].get_output_tensor().get_data(8400 * 84);
        DetResult result = postprocess(output_data, factor);
        sw.Stop();
        total_infs[2] = sw.ElapsedMilliseconds;


        Cv2.PutText(frame, "PreProcess: " + (1000.0 / total_infs[0]).ToString("0.00") + "FPS " + (total_infs[0]).ToString("0.00") + "ms",
          new Point(20, 40), HersheyFonts.HersheyPlain, 2, new Scalar(255, 0, 255), 2);
        Cv2.PutText(frame, "Inference: " + (1000.0 / total_infs[1]).ToString("0.00") + "FPS " + (total_infs[1]).ToString("0.00") + "ms",
          new Point(20, 70), HersheyFonts.HersheyPlain, 2, new Scalar(255, 0, 255), 2);
        Cv2.PutText(frame, "PostProcess: " + (1000.0 / total_infs[2]).ToString("0.00") + "FPS " + (total_infs[2]).ToString("0.00") + "ms",
          new Point(20, 100), HersheyFonts.HersheyPlain, 2, new Scalar(255, 0, 255), 2);
        Cv2.PutText(frame, "Total: " + (1000.0 / (total_infs[0] + total_infs[1] + total_infs[2])).ToString("0.00")
          + "FPS  " + ((total_infs[0] + total_infs[1] + total_infs[2])).ToString("0.00") + "ms",
          new Point(20, 130), HersheyFonts.HersheyPlain, 2, new Scalar(255, 0, 255), 2);
        Mat res_mat = Visualize.draw_det_result(result, frame);
        Cv2.ImShow("Result", res_mat);
        Cv2.WaitKey(10);
        swap(requests);
        frame = next_frame;
     }
   }
    public static float[] preprocess(Mat img, out float factor)
   {
      Mat mat = new Mat();
      Cv2.CvtColor(img, mat, ColorConversionCodes.BGR2RGB);
      mat = Resize.letterbox_img(mat, 640, out factor);
      mat = Normalize.run(mat, true);
      return Permute.run(mat);
   }
    public static DetResult postprocess(float[] result, float factor)
{
      // Storage results list
      List positionBoxes = new List();
      List classIds = new List();
      List confidences = new List();
      // Preprocessing output results
      for (int i = 0; i < 8400; i++)
          {
               for (int j = 4; j < 84; j++)
              {
                   float source = result[8400 * j + i];
                   int label = j - 4;
                   if (source > 0.2)
         {
            float maxSource = source;
            float cx = result[8400 * 0 + i];
            float cy = result[8400 * 1 + i];
            float ow = result[8400 * 2 + i];
            float oh = result[8400 * 3 + i];
            int x = (int)((cx - 0.5 * ow) * factor);
            int y = (int)((cy - 0.5 * oh) * factor);
            int width = (int)(ow * factor);
            int height = (int)(oh * factor);
            Rect box = new Rect(x, y, width, height);
            positionBoxes.Add(box);
            classIds.Add(label);
            confidences.Add(maxSource);
         }
       }
     }
      DetResult re = new DetResult();
      int[] indexes = new int[positionBoxes.Count];
      CvDnn.NMSBoxes(positionBoxes, confidences, 0.2f, 0.5f, out indexes);
      for (int i = 0; i < indexes.Length; i++)
          {
               int index = indexes[i];
               re.add(classIds[index], confidences[index], positionBoxes[index]);
          }
           return re;
      }


       public static void swap(List requests) 
{
      //(requests[0], requests[1]) = (requests[1], requests[0]);
      var tmp = requests[0];
      requests[0] = requests[1];
      requests[1] = tmp;
   }
 }
}

打开创建的项目,编辑 Program.cs 文件,将上述代码替换该文件中的代码即可。

5项目编译与运行

输入以下指令后进行项目编译:

dotnet build --configuration Release
10f4257a-9db3-11ef-93f3-92fbcf53809c.png

通过上图可以看出,该项目编译成功,未出现任何问题,接下来输入以下指令进行项目运行:

dotnet run --configuration Release
1100c910-9db3-11ef-93f3-92fbcf53809c.png

上图为运行后的输出和推理效果,可以看出使用异步推理后,可以实现20帧以上的推理速度。

为了对比推理效果,此处还开展了同步推理实现,异步推理速度可以实现到 25FPS 以上,而同步推理只能达到 12FPS 左右,其推理速度提升了一倍,且满足视频的实时推理要求。

6总结

在该项目中,我们使用哪吒开发板套件,通过前期推出的 OpenVINO C# API 项目,实现了在开发板环境下部署 YOLOv8 模型,并进行了视频推理测试。在使用哪吒开发板套件的 IGPU 设备进行推理时,其推理速度平均可以达到 25FPS 以上,可以实现视频实时推理。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 英特尔
    +关注

    关注

    61

    文章

    9941

    浏览量

    171677
  • 接口
    +关注

    关注

    33

    文章

    8564

    浏览量

    150992
  • AI
    AI
    +关注

    关注

    87

    文章

    30643

    浏览量

    268824
  • 开发板
    +关注

    关注

    25

    文章

    5024

    浏览量

    97352
  • OpenVINO
    +关注

    关注

    0

    文章

    92

    浏览量

    195

原文标题:开发者实战|使用 OpenVINO™ C# 异步推理接口部署 YOLOv8 ——在哪吒开发板上也可以实现视频推理

文章出处:【微信号:英特尔物联网,微信公众号:英特尔物联网】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    【爱芯派 Pro 开发板试用体验】yolov8模型转换

    通过开发板上预制的ax_run_model 工具,测试模型速度和精度。 示例都是yolov5的,没有yolov8模型怎么运行还需进一步
    发表于 11-20 12:19

    使用YOLOv8做目标检测和实例分割的演示

    YOLOv8是来自Ultralytics的最新的基于YOLO的对象检测模型系列,提供最先进的性能。
    的头像 发表于 02-06 10:11 7427次阅读

    YOLOv8自定义数据集训练到模型部署推理简析

    如果你只是想使用而不是开发,强烈推荐通过pip安装方式获取YOLOv8包!YOLOv8安装命令行
    的头像 发表于 03-24 09:27 4645次阅读

    TensorRT 8.6 C++开发环境配置与YOLOv8实例分割推理演示

    YOLOv8实例分割TensorRT 推理代码已经完成C++类封装,三行代码即可实现YOLOv8对象检测与实例分割模型推理,不需要改任何代码即可支持自定义数据训练部署推理
    的头像 发表于 04-25 10:49 5734次阅读
    TensorRT 8.6 C++<b class='flag-5'>开发</b>环境配置与<b class='flag-5'>YOLOv8</b>实例分割推理演示

    在AI爱克斯开发板上用OpenVINO™加速YOLOv8分类模型

    本系列文章将在 AI 爱克斯开发板上使用 OpenVINO 开发套件依次部署并测评 YOLOv8 的分类模型、目标检测
    的头像 发表于 05-05 11:47 1048次阅读
    在AI爱克斯<b class='flag-5'>开发板</b>上用OpenVINO™加速<b class='flag-5'>YOLOv8</b>分类<b class='flag-5'>模型</b>

    在AI爱克斯开发板上用OpenVINO™加速YOLOv8目标检测模型

    《在 AI 爱克斯开发板上用 OpenVINO 加速 YOLOv8 分类模型》介绍了在 AI 爱克斯开发板上使用 OpenVINO 开发套件
    的头像 发表于 05-12 09:08 1306次阅读
    在AI爱克斯<b class='flag-5'>开发板</b>上用OpenVINO™加速<b class='flag-5'>YOLOv8</b>目标检测<b class='flag-5'>模型</b>

    AI爱克斯开发板上使用OpenVINO加速YOLOv8目标检测模型

    《在AI爱克斯开发板上用OpenVINO加速YOLOv8分类模型》介绍了在AI爱克斯开发板上使用OpenVINO 开发套件
    的头像 发表于 05-26 11:03 1234次阅读
    AI爱克斯<b class='flag-5'>开发板</b>上使用OpenVINO加速<b class='flag-5'>YOLOv8</b>目标检测<b class='flag-5'>模型</b>

    在AI爱克斯开发板上用OpenVINO™加速YOLOv8-seg实例分割模型

    《在 AI 爱克斯开发板上用 OpenVINO 加速 YOLOv8 目标检测模型》介绍了在 AI 爱克斯开发板上使用 OpenVINO 开发
    的头像 发表于 06-05 11:52 996次阅读
    在AI爱克斯<b class='flag-5'>开发板</b>上用OpenVINO™加速<b class='flag-5'>YOLOv8</b>-seg实例分割<b class='flag-5'>模型</b>

    教你如何用两行代码搞定YOLOv8各种模型推理

    大家好,YOLOv8 框架本身提供的API函数是可以两行代码实现 YOLOv8 模型推理,这次我把这段代码封装成了一个类,只有40行代码左右,可以同时支持YOLOv8对象检测、实例分割
    的头像 发表于 06-18 11:50 3047次阅读
    教你如何用两行代码搞定<b class='flag-5'>YOLOv8</b>各种<b class='flag-5'>模型</b>推理

    在AI爱克斯开发板上用OpenVINO™加速YOLOv8-seg实例分割模型

    《在 AI 爱克斯开发板上用 OpenVINO 加速 YOLOv8 目标检测模型》介绍了在 AI 爱克斯开发板上使用 OpenVINO 开发
    的头像 发表于 06-30 10:43 897次阅读
    在AI爱克斯<b class='flag-5'>开发板</b>上用OpenVINO™加速<b class='flag-5'>YOLOv8</b>-seg实例分割<b class='flag-5'>模型</b>

    三种主流模型部署框架YOLOv8推理演示

    深度学习模型部署有OpenVINO、ONNXRUNTIME、TensorRT三个主流框架,均支持Python与C++的SDK使用。对YOLOv5~YOLOv8的系列
    的头像 发表于 08-06 11:39 2718次阅读

    解锁YOLOv8修改+注意力模块训练与部署流程

    很多人也想跟修改YOLOv5源码一样的方式去修改YOLOv8的源码,但是在github上面却发现找到的YOLOv8项目下面TAG分支是空的
    的头像 发表于 08-11 14:14 4327次阅读
    解锁<b class='flag-5'>YOLOv8</b>修改+注意力模块训练与<b class='flag-5'>部署</b>流程

    YOLOv8实现任意目录下命令行训练

    的,在其他目录下的预训练模型文件,YOLOv8还是会一样去下预训练模型文件,直接无视model参数指定,于是多数开发者都是确保在当前目录下有YOLO
    的头像 发表于 09-04 10:50 1096次阅读
    <b class='flag-5'>YOLOv8</b>实现任意目录下命令行训练

    基于YOLOv8的自定义医学图像分割

    YOLOv8是一种令人惊叹的分割模型;它易于训练、测试和部署。在本教程中,我们将学习如何在自定义数据集上使用YOLOv8。但在此之前,我想告诉你为什么在存在其他优秀的分割
    的头像 发表于 12-20 10:51 765次阅读
    基于<b class='flag-5'>YOLOv8</b>的自定义医学图像分割

    基于OpenCV DNN实现YOLOv8模型部署与推理演示

    基于OpenCV DNN实现YOLOv8推理的好处就是一套代码就可以部署在Windows10系统、乌班图系统、Jetson的Jetpack系统
    的头像 发表于 03-01 15:52 1544次阅读
    基于OpenCV DNN实现<b class='flag-5'>YOLOv8</b>的<b class='flag-5'>模型</b><b class='flag-5'>部署</b>与推理演示