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

news2024/11/14 16:35:26

[嵌入式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 InferSession

from det_utils import letterbox, scale_coords, nms

def 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)  # HWC2CHW
    img = np.ascontiguousarray(img, dtype=np.float32)
    return img, scale_ratio, pad_size


def 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)):
            continue
        img0 = 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 img0


def 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_dict


def 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_vis


def 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 camera

        for index in range(max_index_to_check):
            cap = cv2.VideoCapture(index)
            if cap.read()[0]:
                cap.release()
                return index

        # If no camera is found
        raise 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.coloradmin.cn/o/1365812.html

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

相关文章

源码编译部署篇(二)源码编译milvus成功后如何启动standalone并调试成功!

Milvus启动和调试 0 前言1 Milvus启动【问题描述】出现Aborted问题【问题分析】【解决方法】安装Pulsar服务执行单机启动命令解决监听端口号 2 Milvus调试编写launch.json验证单例调试成功 3 遇到的问题汇总问题1问题2:Permission denied 0 前言 由于Milvus官方文档只提及如何…

VX小程序Burp抓包

方法有很多&#xff0c;工具也各有差异&#xff0c;主要是学代理流量的思路 Burp流量代理工具小程序 一、Burp证书导入 1、开启代理 开启浏览器的代理&#xff0c;火狐推荐FoxyProxy&#xff0c;Google推荐SwitchyOmega&#xff0c;设置代理为127.0.0.1:8080。 2、下载证书…

[C#]Onnxruntime部署Chinese CLIP实现以文搜图以文找图功能

【官方框架地址】 https://github.com/OFA-Sys/Chinese-CLIP 【算法介绍】 在当今的大数据时代&#xff0c;文本信息处理已经成为了计算机科学领域的核心议题之一。为了高效地处理海量的文本数据&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术应运而生。而在诸多N…

性能分析与调优: Linux 使用ELRepo升级CentOS内核

目录 一、实验 1.环境 2.agent 服务器使用ELRepo升级CentOS内核 二、问题 1. RHEL-7, SL-7 或者 CentOS-7系统如何安装ELRepo 2.RHEL-8或者RHEL-9系统如何安装ELRepo 一、实验 1.环境 &#xff08;1&#xff09;主机 表1-1 主机 主机架构组件IP备注prometheus 监测 系…

超维空间M1无人机使用说明书——21、基于opencv的人脸识别

引言&#xff1a;M1型号无人机不仅提供了yolo进行物体识别&#xff0c;也增加了基于opencv的人脸识别功能包&#xff0c;仅需要启动摄像头和识别节点即可 链接: 源码链接 一、一键启动摄像头和人脸识别节点 roslaunch robot_bringup bringup_face_detect.launch无报错&#…

Maven在java中的实现(对java的项目进行打包)

前言: 在前面的文章中我们了解了Maven的作用,并在自己的电脑上安装配置好了Maven,也成功的在IDEA中添加了Maven,但是具体的实现还是有一些些小问题,那么接下来,我将带着大家对Java项目进行一次打包,系统的完成一次,并在途中解决一下会出现的问题. 我以图片中选中的这个包为例,…

在docker上运行LCM

目录 1.加载镜像并进入容器 2.安装依赖 3.在docker外部git-clone lcm 4.将get-clone的lcm复制到容器中 5.编译库 6.将可执行文件复制到容器中 7.进入可执行文件 8.编译可执行文件 9.再开一个终端运行程序 10.将以上容器打成镜像并导出 1.加载镜像并进入容器 sudo do…

【无标题】山姆奥特曼喊话AI创业者

这里写自定山姆奥特曼充满激情地向创业者们发出呼吁&#xff0c;他表示AI是一个可以媲美互联网早期机遇的巨大机会。与此相关的人士认为&#xff0c;现在是互联网和移动互联网创业者们行动起来的时候了&#xff01;他们应该全面拥抱大模型的应用层创业。第一波红利期在6-8个月内…

STM32F103使用硬件SPI+缓冲区的模式刷新硬件显示模块

上次讲到使用全屏做一个缓冲区&#xff0c;因为cpuRAM空间不足&#xff0c;无法实现&#xff0c;想办法使用一行作为一个缓冲区的模式&#xff1a; 老的全屏刷新程序&#xff1a; void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color) { …

3.2 MAPPING THREADS TO MULTIDIMENSIONAL DATA

1D、2D或3D线程组织的选择通常基于数据的性质。图片是2D像素阵列。使用由2D块组成的2D网格通常可以方便地处理图片中的像素。图3.2显示了处理7662图片P的这种安排&#xff08;水平或x方向为76像素&#xff0c;垂直或y方向为62像素&#xff09;。假设我们决定使用16 x 16块&…

桌面图标变成白色文件?学会这4个方法,轻松解决!

“不知道为什么&#xff0c;我有些文件夹直接保存在电脑桌面了&#xff0c;但是今天查看的时候却发现它们变成了白色的文件。有什么方法可以解决这个问题吗&#xff1f;” 在使用电脑时&#xff0c;可能由于各种原因&#xff0c;会出现桌面图标变成白色文件的情况。这不仅会让用…

听GPT 讲Rust源代码--compiler(36)

File: rust/compiler/rustc_middle/src/mir/graphviz.rs 在Rust源代码中&#xff0c;rust/compiler/rustc_middle/src/mir/graphviz.rs文件的作用是生成MIR&#xff08;Mid-level Intermediate Representation&#xff09;的图形可视化表示。MIR是Rust编译器中间表示的一种形式…

如何解决海量数据的问题

近年来&#xff0c;高并发、分布式以及大数据成了后端开发者绕不开的话题&#xff0c;招聘软件上几呼都写着有高并发、大数据等项目经历优先时。很多人实际项目往往都是 CRUD&#xff0c;也没机会接触到这些场景啊。 但是&#xff0c;有位伟人曾经说过&#xff1a;没有条件&am…

九、HTML头部<head>

一、HTML头部<head> 1、<title>- 定义了HTML文档的标题 使用 <title> 标签定义HTML文档的标题 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>我的 HTML 的第一页</title> </head><b…

ant-design-vue的日期组件a-range-picker赋值的问题

在使用ant-design-vue的日期组件时&#xff0c;总是会碰到赋值问题&#xff0c;习惯性的赋值就是直接给日期组件的变量赋值字符串类型&#xff0c;如下 // html部分 <a-range-picker v-model"dateValue" :format"YYYY-MM-DD"/> // js部分 data() {r…

2024年大数据不完全预测

人工智能的进步可能是2024年的主要推动力&#xff0c;也凸显出大数据的挑战——如何存储、管理、管理和使用大数据——从未如此紧迫。&#xff0c;因为如果作为基石的数据失控&#xff0c;人工智能就没有意义了。当然反之亦然。 人工智能的进步可能是2024年的主要推动力&#…

1999-2022年上市公司微观企业劳动生产率数据(原始数据+计算代码+处理结果)

1999-2022年上市公司微观企业劳动生产率数据&#xff08;原始数据计算代码处理结果&#xff09; 1、时间&#xff1a;1999-2022年 2、来源&#xff1a;原始数据整理自csmar 3、指标&#xff1a;证券代码&#xff0c;证券简称、员工人数&#xff0c;营业收入 4、范围&#x…

C++ 学习系列 -- tuple 原理

一 可变参数模板 variadic template 前面的章节 C 学习系列 -- 模板 template-CSDN博客 我们介绍了 c 中的模板概念&#xff0c;本章则在其基础上介绍了新的概念 可变参数模板 variadic template &#xff0c;顾名思义&#xff0c;可变参数模板意思为模板参数的类型与数量是变…

浅谈智能照明系统调试阶段节能方案的探究与产品选型

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 【摘要】针对当今智能照明系统调试完成前能源浪费的问题&#xff0c;本文结合工程案例&#xff0c;分析研究了智能照明系统调试阶段的节能方法&#xff0c;提出了采用时间控制器来解决能源及人工浪费等问题的方式。实践证明&a…

微众区块链观察节点的架构和原理 | 科普时间

践行区块链公共精神&#xff0c;实现更好的公众开放与监督&#xff01;2023年12月&#xff0c;微众区块链观察节点正式面向公众开放接入功能。从开放日起&#xff0c;陆续有多个观察节点在各地运行&#xff0c;同步区块链数据&#xff0c;运行区块链浏览器观察检视数据&#xf…