[嵌入式AI从0开始到入土]10_yolov5在昇腾上应用

[嵌入式AI从0开始到入土]嵌入式AI系列教程

注:等我摸完鱼再把链接补上
可以关注我的B站号工具人呵呵的个人空间,后期会考虑出视频教程,务必催更,以防我变身鸽王。

第一章 昇腾Altas 200 DK上手
第二章 下载昇腾案例并运行
第三章 官方模型适配工具使用
第四章 炼丹炉的搭建(基于Ubuntu23.04 Desktop)
第五章 Ubuntu远程桌面配置
第六章 下载yolo源码及样例运行验证
第七章 转化为昇腾支持的om离线模型
第八章 jupyter lab的使用
第九章 yolov5在昇腾上推理
第十章 yolov5在昇腾上应用
未完待续…


文章目录

  • [嵌入式AI从0开始到入土]嵌入式AI系列教程
  • 前言
  • 一、获取案例
    • 1、获取系统镜像
    • 2、获取案例
    • 3、原始案例
  • 二、修改案例
    • 1、打开jupyter
    • 2、atc转换模型
    • 3、安装依赖
    • 4、修改预处理函数
    • 5、修改模型和标签路径
    • 6、选择你需要的推理模式
  • 三、问题
    • 1、No module named 'scikit'
    • 2、No module named 'ais_bench'
    • 3、 InputTensor Data Type mismatches.
      • 1、怀疑导出onnx模型问题
      • 2、怀疑版本问题
      • 3、om模型有问题!!!
    • 4、预测框错乱
  • 总结


前言

注:本文基于Atlas 200 Dk编写,其他版本可能会有版本依赖问题
上一节中,我们已经完成了图片推理,但是仅仅图像的推理怎么够,起码得视频或者摄像头吧。因此我参考了案例,进行了修改。

一、获取案例

我扒了200i DK A2的案例下来(似乎官方没有给案例的下载地址),当然你也可以使用上一节的资源包,然后新建这个案例文件。
当然你可以使用我本文置顶的资源,都是我测试完成的。

1、获取系统镜像

下载地址:https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/Atlas%20200I%20DK%20A2/DevKit/images/23.0.RC3/1.2.3/A200I-DK-A2_desktop-image_1.2.3_ubuntu22.04-aarch64.img.xz

2、获取案例

下载完后,解压,在Ubuntu中挂载A200I-DK-A2_desktop-image_1.2.3_ubuntu22.04-aarch64.img镜像文件,案例在root_fs/home/HwHiAiUser/samples/notebooks下。这次我们取第一个案例即可。
复制出来,上传到200DK。

3、原始案例

这里贴一份出来,毕竟镜像有一点点大。挂资源大概率过不了审核。

# 导入代码依赖
import cv2
import numpy as np
import ipywidgets as widgets
from IPython.display import display
import torch
from skvideo.io import vreader, FFmpegWriter
import IPython.display
from ais_bench.infer.interface import InferSessionfrom det_utils import letterbox, scale_coords, nmsdef preprocess_image(image, cfg, bgr2rgb=True):"""图片预处理"""img, scale_ratio, pad_size = letterbox(image, new_shape=cfg['input_shape'])if bgr2rgb:img = img[:, :, ::-1]img = img.transpose(2, 0, 1)  # HWC2CHWimg = np.ascontiguousarray(img, dtype=np.float32)return img, scale_ratio, pad_sizedef draw_bbox(bbox, img0, color, wt, names):"""在图片上画预测框"""det_result_str = ''for idx, class_id in enumerate(bbox[:, 5]):if float(bbox[idx][4] < float(0.05)):continueimg0 = cv2.rectangle(img0, (int(bbox[idx][0]), int(bbox[idx][1])), (int(bbox[idx][2]), int(bbox[idx][3])),color, wt)img0 = cv2.putText(img0, str(idx) + ' ' + names[int(class_id)], (int(bbox[idx][0]), int(bbox[idx][1] + 16)),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)img0 = cv2.putText(img0, '{:.4f}'.format(bbox[idx][4]), (int(bbox[idx][0]), int(bbox[idx][1] + 32)),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)det_result_str += '{} {} {} {} {} {}\n'.format(names[bbox[idx][5]], str(bbox[idx][4]), bbox[idx][0], bbox[idx][1], bbox[idx][2], bbox[idx][3])return img0def get_labels_from_txt(path):"""从txt文件获取图片标签"""labels_dict = dict()with open(path) as f:for cat_id, label in enumerate(f.readlines()):labels_dict[cat_id] = label.strip()return labels_dictdef draw_prediction(pred, image, labels):"""在图片上画出预测框并进行可视化展示"""imgbox = widgets.Image(format='jpg', height=720, width=1280)img_dw = draw_bbox(pred, image, (0, 255, 0), 2, labels)imgbox.value = cv2.imencode('.jpg', img_dw)[1].tobytes()display(imgbox)def infer_image(img_path, model, class_names, cfg):"""图片推理"""# 图片载入image = cv2.imread(img_path)# 数据预处理img, scale_ratio, pad_size = preprocess_image(image, cfg)# 模型推理output = model.infer([img])[0]output = torch.tensor(output)# 非极大值抑制后处理boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"])pred_all = boxout[0].numpy()# 预测坐标转换scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size))# 图片预测结果可视化draw_prediction(pred_all, image, class_names)def infer_frame_with_vis(image, model, labels_dict, cfg, bgr2rgb=True):# 数据预处理img, scale_ratio, pad_size = preprocess_image(image, cfg, bgr2rgb)# 模型推理output = model.infer([img])[0]output = torch.tensor(output)# 非极大值抑制后处理boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"])pred_all = boxout[0].numpy()# 预测坐标转换scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size))# 图片预测结果可视化img_vis = draw_bbox(pred_all, image, (0, 255, 0), 2, labels_dict)return img_visdef img2bytes(image):"""将图片转换为字节码"""return bytes(cv2.imencode('.jpg', image)[1])def infer_video(video_path, model, labels_dict, cfg):"""视频推理"""image_widget = widgets.Image(format='jpeg', width=800, height=600)display(image_widget)# 读入视频cap = cv2.VideoCapture(video_path)while True:ret, img_frame = cap.read()if not ret:break# 对视频帧进行推理image_pred = infer_frame_with_vis(img_frame, model, labels_dict, cfg, bgr2rgb=True)image_widget.value = img2bytes(image_pred)def infer_camera(model, labels_dict, cfg):"""外设摄像头实时推理"""def find_camera_index():max_index_to_check = 10  # Maximum index to check for camerafor index in range(max_index_to_check):cap = cv2.VideoCapture(index)if cap.read()[0]:cap.release()return index# If no camera is foundraise ValueError("No camera found.")# 获取摄像头camera_index = find_camera_index()cap = cv2.VideoCapture(camera_index)# 初始化可视化对象image_widget = widgets.Image(format='jpeg', width=1280, height=720)display(image_widget)while True:# 对摄像头每一帧进行推理和可视化_, img_frame = cap.read()image_pred = infer_frame_with_vis(img_frame, model, labels_dict, cfg)image_widget.value = img2bytes(image_pred)cfg = {'conf_thres': 0.4,  # 模型置信度阈值,阈值越低,得到的预测框越多'iou_thres': 0.5,  # IOU阈值,高于这个阈值的重叠预测框会被过滤掉'input_shape': [640, 640],  # 模型输入尺寸
}model_path = 'yolo.om'
label_path = './coco_names.txt'
# 初始化推理模型
model = InferSession(0, model_path)
labels_dict = get_labels_from_txt(label_path)infer_mode = 'video'if infer_mode == 'image':img_path = 'world_cup.jpg'infer_image(img_path, model, labels_dict, cfg)
elif infer_mode == 'camera':infer_camera(model, labels_dict, cfg)
elif infer_mode == 'video':video_path = 'racing.mp4'infer_video(video_path, model, labels_dict, cfg)

二、修改案例

1、打开jupyter

yolov5_ascend_example文件夹下打开终端,输入

jupyter lab --ip 192.168.3.2 --allow-root

电脑浏览器访问http://192.168.3.2:8888,右侧打开我们的mian.ipynb文件。

2、atc转换模型

200DK照抄,200I DK A2最后改成Ascend 310B1

atc --model=models/best.onnx --framework=5 --output=models/mymodel --input_format=NCHW --input_shape="images:1,3,640,640" --input_fp16_nodes=images --log=error --soc_version=Ascend310

运行结果如下,大约5到10分钟。当然,你也可以用ubuntu主机去做,会快很多,我用pc转换只需要半分钟左右,还是一台4代i7的老年机。
在这里插入图片描述

3、安装依赖

使用我的案例代码的直接运行即可
在这里插入图片描述

其他的请按照以下方法安装

!pip install scikit_video
!pip install pip_packages/aclruntime-0.0.2-cp39-cp39-linux_aarch64.whl
!pip install pip_packages/ais_bench-0.0.2-py3-none-any.whl

注意,aclruntime和ais_bench推理程序的whl包请前往昇腾gitee仓库下载。

4、修改预处理函数

这里我们使用自己训练的模型,需要做如下修改。
img = np.ascontiguousarray(img, dtype=np.float32)改为img = np.ascontiguousarray(img, dtype=np.float16)/255.0
在这里插入图片描述

5、修改模型和标签路径

在这里插入图片描述

6、选择你需要的推理模式

在这里插入图片描述
这里务必注意,如果是在vscode里远程打开main.ipynb的,不要推理视频!!! 不仅不显示推理的图像,还会导致内存占用不断升高,且无法终止内核,甚至杀不死进程,最后爆内存断开ssh连接。最终我只能按下复位。

三、问题

1、No module named ‘scikit’

pip install scikit-video

别搞错名字就行。

2、No module named ‘ais_bench’

访问Gitee仓库,这里有三种方法,作为懒人肯定是选择whl包安装啦。
在这里插入图片描述
我的pc机python是3.9,所以下载这两个,按照下方说明进行安装就行。
咱就粗暴一点,强制覆盖安装啦。

pip3 install ./aclruntime-{version}-{python_version}-linux_{arch}.whl --force-reinstall
pip3 install ./ais_bench-{version}-py3-none-any.whl --force-reinstall

安装成功会提示

# 成功安装aclruntime
Successfully installed aclruntime-{version}
# 成功安装ais_bench推理程序
Successfully installed ais_bench-{version}

安装失败的话检查版本然后祭出重启大法。

3、 InputTensor Data Type mismatches.

在这里插入图片描述
这里是折磨了我三天的问题,甚至进行了一下几个可能的排列组合(请不要笑)

1、怀疑导出onnx模型问题

我对比了两个onnx模型结构
在这里插入图片描述
发现只有这里不一样,但是不应该会导致这个问题啊

2、怀疑版本问题

这里怀疑的是转换时的版本问题。因此进行了一波友好的控制变量法测试(手动狗头)。键盘差点不保!

  1. pc机cann7.0
  2. 200dkcann5.1
  3. best.onnx我自己的模型
  4. yolov5s.onnx 200i案例的模型
  5. yolo.om 200i案例的模型
  6. best.om我pc机转的模型
  7. mymodel.om 200dk转的模型

最终,耗时一下午,还是失败了。

3、om模型有问题!!!

最后,只能怀疑是om模型有问题,于是我使用atc指令查询其信息,果然发现了问题所在。关于用法请参考文档。
在这里插入图片描述
对比两个模型,在Atc command linebest.om多了--input_fp16_nodes=images。我回去一查,嘿,mindx似乎只能用fp16做输入,而我之后转换的模型都是fp32的,怪不得main.py报错。但是,这时ais_bench推理的main.ipynb又报错了,我们只需要把这个32改成16.
在这里插入图片描述

4、预测框错乱

在这里插入图片描述
这里在经过我刨地三尺,翻了三遍论坛,终于找到了罪魁祸首。详情请参考原文链接。
在这里插入图片描述
我们只需要在这个案例这一行后面添加/255.0即可。

总结

不要问我为什么放鸽子,当你被bug折磨,别说解决方案了,甚至这个报错百度都搜不到,那是心态直接爆炸啊。
强烈建议直接使用我置顶提供的案例文件,避免踩坑,从我做起!!!
我是替你们踩坑的工具人呵呵,下期继续,希望能尽快爬出来吧。

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

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

相关文章

Android 车联网——多屏多用户(十五)

前面几篇文章介绍了多用户和多屏相关的 Manager 和 Service。上一篇文章最后虽然车内乘员都根据配置有自己的对应屏幕,但默认情况下,所有车内乘员依然使用的是当前主用户(司机用户),这一篇我们继续放下看一下用户的创建与分配。 一、用户创建分配 1、创建用户 对于创建用…

【AI视野·今日NLP 自然语言处理论文速览 第七十一期】Fri, 5 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Fri, 5 Jan 2024 Totally 28 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers LLaMA Pro: Progressive LLaMA with Block Expansion Authors Chengyue Wu, Yukang Gan, Yixiao Ge, Zeyu Lu, …

JavaScript实现的复杂功能:自动生成带水印的图片

#程序员的崩溃瞬间 在本文中&#xff0c;我们将讨论一个JavaScript实现的复杂功能&#xff0c;该功能可以自动为图片添加水印。这个功能在许多场景中都非常有用&#xff0c;例如&#xff0c;如果你想保护你的图片版权&#xff0c;或者你想在你的网站上显示自定义的水印。 一、…

java导出word套打

这篇文档手把手教你完成导出word套打&#xff0c;有这个demo&#xff0c;其他word套打导出都通用。 1、主要依赖 <!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.0</ve…

IPv6路由协议---IPv6动态路由(RIPng)

IPv6动态路由协议 动态路由协议有自己的路由算法,能够自动适应网络拓扑的变化,适用于具有一定数量三层设备的网络。缺点是配置对用户要求比较高,对系统的要求高于静态路由,并将占用一定的网络资源和系统资源。 路由表和FIB表 路由器转发数据包的关键是路由表和FIB表,每…

CreateDIBSection失败的问题记录

错误记录 [ERROR] (:0, ): QPixmap::fromWinHICON(), failed to GetIconInfo() (操作成功完成。) [ERROR] (:0, ): QPixmap::fromWinHICON(), failed to GetIconInfo() (参数错误。) [ERROR] (:0, ): QPixmap::fromWinHICON(), failed to GetIconInfo() (参数错误。) [ERROR] …

升级 Vite 5 出现警告 The CJS build of Vite‘s Node API is deprecated.

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

C++核心编程——内存分区、引用、函数提高和函数重载

本专栏记录C学习过程包括C基础以及数据结构和算法&#xff0c;其中第一部分计划时间一个月&#xff0c;主要跟着黑马视频教程&#xff0c;学习路线如下&#xff0c;不定时更新&#xff0c;欢迎关注。 当前章节处于&#xff1a; ---------第1阶段-C基础入门 ---------第2阶段实战…

数仓建设学习路线(一)

前言 数仓建设实践路线是语兴发布在B站的系列课程&#xff0c;搜索语兴呀即可学习完整的数仓建设理论。 大数据相关岗位 大数据常见的岗位主要包括实时开发、数据治理、数据安全、数据资产等。 其中&#xff1a; 实时开发组的主要任务是实时可视化制作(大屏/彩蛋/战报&…

前端结合MQTT实现连接 订阅发送信息等操作 VUE3

MQTT客户端下载 使用测试 在我之前文章中 MQTT下载基础使用 下面记录一下前端使用的话的操作 1.安装 npm i mqtt引入 import * as mqtt from "mqtt/dist/mqtt.min"; //VUE3 import mqtt from mqtt //VUE2 一、MQTT协议中的方法 Connect。等待与服务器建立连接…

Scanner:键盘输入功能的实现、Java程序获取一个随机数

目录 一、 Scanner&#xff1a;键盘输入功能的实现 二、Java程序获取一个随机数 一、 Scanner&#xff1a;键盘输入功能的实现 如何从键盘获取不同类型&#xff08;基本数据类型、String类型&#xff09;的变量&#xff1a;使用Scanner类 键盘输入代码的四个步骤&#xff1a…

uView Gap 间隔槽

该组件一般用于内容块之间的用一个灰色块隔开的场景&#xff0c;方便用户风格统一&#xff0c;减少工作量 #平台差异说明 App&#xff08;vue&#xff09;App&#xff08;nvue&#xff09;H5小程序√√√√ #基本使用 直接引入即可使用 通过height配置高度&#xff0c;单位…

fmt中uint128_fallback的实现分析

数据结构 class uint128_fallback {private:uint64_t lo_, hi_;public:constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {}constexpr uint128_fallback(uint64_t value 0) : lo_(value), hi_(0) {}constexpr uint64_t high() const noexcept { ret…

[VUE]2-vue的基本使用

目录 vue基本使用方式 1、vue 组件 2、文本插值 3、属性绑定 4、事件绑定 5、双向绑定 6、条件渲染 7、axios 8、⭐跨域问题 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅…

气膜建筑:舒适、智能、可持续

气膜建筑之所以能够拥有广阔的发展空间&#xff0c;源于其融合了诸多优势特点&#xff0c;使其成为未来建筑领域的前沿趋势。 气膜建筑注重环境可持续性和能源效率。在材料和设计上&#xff0c;它采用可回收材料、提高热保温效果&#xff0c;并积极利用太阳能等可再生能源&…

【洛谷学习自留】p9226 糖果

解题思路&#xff1a; 简单的计算题&#xff0c;用n对k取余&#xff0c;如果余数为0&#xff0c;则输出k的值&#xff0c;否则输出&#xff08;k-余数&#xff09;的值。 代码实现&#xff1a; import java.util.Scanner;public class p9226 {public static void main(Strin…

Go、Docker、云原生学习笔记全攻略:从零开始,一步步走向精通!(2024版)

第一章、Go语言学习宝典 一、介绍 01.Go 语言的前生今世 二、开发环境搭建 01.Go 语言开发环境搭建 三、初识GO语言 01.Go 多版本管理工具 02.第一个 Go 程序“hello&#xff0c;world“ 与 main 函数 03.Go 常用命令介绍 04.Go 项目代码布局 05.探索 GO 项目依赖包管…

【2023 CCF 大数据与计算智能大赛】基于TPU平台实现超分辨率重建模型部署 基于QuickRNet的TPU超分模型部署

2023 CCF 大数据与计算智能大赛 《赛题名称》 基于QuickRNet的TPU超分模型部署 巴黎欧莱雅 林松 智能应用业务部算法工程师 中信科移动 中国-北京 gpu163.com 团队简介 巴黎欧莱雅团队包含一个队长和零个队员。 队长林松&#xff0c;研究生学历&#xff0c;2019-202…

【一份老网工珍藏多年的网络配置笔记,很重要!】

01、交换机、路由器的几种配置模式及模式转换 1. 用户模式 登录到交换机&#xff08;路由器&#xff09;时会自动进入用户模式&#xff0c;提示符为 switchname>。在该模式下只能够查看相关信息&#xff0c; 对 IOS的运行不产生任何影响。 2. 特权模式 用户模式下&#xff…

精进单元测试技能 —— Pytest断言的艺术!

本篇文章主要是阐述Pytest在断言方面的应用。让大家能够了解和掌握Pytest针对断言设计了多种功能以适应在不同测试场景上使用。 了解断言的基础 在Pytest中&#xff0c;断言是通过 assert 语句来实现的。简单的断言通常用于验证预期值和实际值是否相等&#xff0c;例如&#…