带你动手做AI版的垃圾分类
摘要:本案例将使用YOLOX模型,实现一个简单的垃圾分类应用。
本文分享自华为云社区《ModelBox社区案例 - 使用YOLOX做垃圾分类》,作者:HWCloudAI。
1 ModelBox社区案例 - 使用YOLOX做垃圾分类
本案例将使用YOLOX模型,实现一个简单的垃圾分类应用,最终效果如下所示:

本案例所需资源(代码、模型、测试数据等)均可从garbage_det下载
1.1 模型训练与转换
模型采用的是YOLOX网络结构,YOLOX是YOLO系列的优化版本,引入了解耦头、数据增强、无锚点以及标签分类等目标检测领域的优秀进展,拥有较好的精度表现,同时对工程部署友好。训练使用的是“华为云杯”生活垃圾图片分类数据集,该数据集包含一次性快餐盒、果皮果肉、旧衣服等44个类别,共14964张图片。其中,训练集与验证集划分比例为4/1,下图为模型迭代个300个Epoch取得的结果:

ModelArts提供了包括数据标注,训练环境,预置算法在内的丰富的功能,甚至可以通过订阅预置算法实现0代码的模型训练工作。当然你也可以在本地训练自己的模型。我们假设你现在已经拥有了训练好的模型,接下来我们需要将训练好的模型转换成为可以在开发板上运行的模型。我们发布了开发板模型转换案例,参见RK3568模型转换验证案例:

在这个案例中我们演示了从环境适配到模型的转换验证的全流程样例代码,开发者可以通过“Run in ModelArts”一键将Notebook案例在ModelArts控制台快速打开、运行以及进行二次开发等操作。
1.2 应用开发
打开VS Code,连接到ModelBox sdk所在目录或者远程开发板,开始进行垃圾分类应用的开发。下面以RK3568版本为例进行说明,其他版本与之类似。
1.2.1 1)下载模板
执行python solution.py -l可看到当前公开的技能模板:
███ $ python solution.py -l ... Solutions name: mask_det_yolo3 … hand_det_yolox hand_tracking_yolox single_hand_pose_yolox_mbv2 multi_hand_pose_yolox_mbv2
结果中的hand_det_yolox即为手部检测应用模板,可使用如下命令下载模板:
███ $ python solution.py -s hand_det_yolox ...
solution.py工具的参数中,-l 代表list,即列出当前已有的模板名称;-s 代表solution-name,即下载对应名称的模板。下载下来的模板资源,将存放在ModelBox核心库的solution目录下。
1.2.2 2)创建工程
在ModelBox sdk目录下使用create.py创建garbage_det工程,末尾-s参数,表示将使用后面参数值代表的模板创建工程,而不是创建空的工程。
███/modelbox$ python create.py -t server -n garbage_det -s hand_det_yolox sdk version is modelbox-xxx success: create garbage_det in ███/modelbox/workspace
workspace目录下将创建出garbage_det工程,工程内容如下所示: garbage_det |--bin │ |--main.bat:应用执行入口 │ |--mock_task.toml:应用在本地执行时的输入输出配置,此应用默认使用本地视频文件为输入源,最终结果输出到另一本地视频文件,可根据需要修改 |--CMake:存放一些自定义CMake函数 |--data:存放应用运行所需要的图片、视频、文本、配置等数据 │ |--hand.mp4:手部检测测试用视频文件—>替换为自己的视频 |--dependence │ |--modelbox_requirements.txt:应用运行依赖的外部库在此文件定义 |--etc │ |--flowunit:应用所需的功能单元存放在此目录 │ │ |--cpp:存放C++功能单元编译后的动态链接库,此应用没有C++功能单元 │ │ |--yolox_post:手部检测使用的是YOLOX模型,此处即为后处理功能单元(修改toml文件的类别参数和py文件的draw函数) |--flowunit_cpp:存放C++功能单元的源代码,此应用没有C++功能单元 |--graph:存放流程图 │ |--garbage_det.toml:默认流程图,使用本地视频文件作为输入源 │ |--garbage_det_camera.toml:摄像头输入对应的流程图 │ |--modelbox.conf:modelbox相关配置 |--hilens_data_dir:存放应用输出的结果文件、日志、性能统计信息 |--model:推理功能单元目录 │ |--detect_hand:手部检测推理功能单元 │ │ |--detect_hand.toml:手部检测推理功能单元的配置文件 │ │ |--yolox_hand.onnx:手部检测onnx模型—>更改为自己的模型 |--build_project.sh:应用构建脚本 |--CMakeLists.txt |--rpm:打包rpm时生成的目录,将存放rpm包所需数据 |--rpm_copyothers.sh:rpm打包时的辅助脚本
1.2.3 3)修改后处理功能单元 yolox_post
a. 修改yolox_post.toml流程图,将其内容修改为(以Windows版ModelBox为例):

b. 修改yolox_post.py的draw函数实现如下:
def draw(self, img, bboxes):
h, w, c = img.shape
thickness = 2
font_scale = 1
text_font = cv2.FONT_HERSHEY_SIMPLEX
clss_to_text = {
0: "Disposable snack box",
1: "Books and papers",
2: "Power bank",
3: "Leftovers",
4: "Package",
5: "Trash can",
6: "Plastic utensils",
7: "Plastic toys",
8: "Plastic coat hanger",
9: "Big Bones",
10: "Dry battery",
11: "Express paper bag",
12: "Plug wire",
13: "Old clothes",
14: "The can",
15: "Pillow",
16: "Skin and pulp",
17: "Stuffed animal",
18: "Defacing plastic",
19: "Soiled paper",
20: "Toiletries",
21: "Cigarette butts",
22: "Toothpick",
23: "Glassware",
24: "Block",
25: "Chopsticks",
26: "Carton carton",
27: "Pot",
27: "Tea residue",
29: "Vegetable help vegetable leaf",
30: "Shell",
31: "The spice bottle",
32: "Paste",
33: "Expired drugs",
34: "Bottle",
35: "Metal kitchenware",
36: "Metal ware",
37: "Metal food cans",
38: "Pot",
39: "Ceramic vessels",
40: "Shoes",
41: "Edible oil drum",
42: "Beverage bottle",
43: "Bones"
}
for box in bboxes:
x1, y1, x2, y2, score, clss = box
cv2.putText(img, clss_to_text[int(clss)]+': '+"{:.3}".format(score*100)+'%', (int(x1 * w)+10, int(y1 * h)+30),text_font, font_scale, (0, int(clss+1)*5, 0), thickness)
cv2.rectangle(img, (int(x1 * w), int(y1 * h)), (int(x2 * w), int(y2 * h)), (0, int(clss+1)*5, 0), 3)
1.2.4 4)修改输入输出配置
我们需要准备一个mp4文件拷贝到data文件夹下,我们使用测试视频garbage.mp4,然后打开工程目录下bin/mock_task.toml文件,修改其中的任务输入和任务输出配置为如下内容:
[input] type = "url" url = "../data/garbage.mp4" [output] type = “local” url = “…/hilens_data_dir/garbage_detection_result.mp4”
该流程图在本地运行时的逻辑过程是:data_source_parser解析bin/mock_task.toml文件中输入配置的data/garbage.mp4文件,video_demuxer和video_decoder对该文件进行解码,resize、packed_planar_transpose、normalize对原始图像进行缩放、转码、归一化等预处理,然后detect_garbage在预处理后的图像上进行垃圾检测,yolox_post从推理结果中解码出检测框,并把检测框画到原始图像上,最后video_out将图像输出到bin/mock_task.toml文件中输出配置的hilens_data_dir/garbage_detection_result.mp4文件中。
1.2.5 5)用启动脚本执行应用
启动应用前执行build_project.sh进行工程构建,该脚本将编译自定义的C++功能单元(本应用不涉及)、将应用运行时会用到的配置文件转码为Unix格式(防止执行过程中的格式错误):
███$ ./build_project.sh dos2unix: converting file xxx.toml to Unix format... ... build success: you can run main.bat in ./bin folder Press ‘p’ to pause…, any key to exit
然后执行bin/main.bat运行应用: ███$ ./bin/main.bat …
运行结束后在hilens_data_dir目录下生成了garbage_detection_result.mp4文件,可以打开查看:

1.2.6 6)用摄像头检测
打开工程目录下bin/mock_task.toml文件,修改其中的任务输入和任务输出配置为如下内容:
[input] type = "url" url = "0" # 表示0号摄像头,即PC自带摄像头,若PC无摄像头需外接USB摄像头 [output] type = “local” url = “0:garbage_det” # 表示名为garbage_det的本地窗口
即使用编号为0的摄像头(默认为PC自带的摄像头),输出画面显示到名为garbage_det的本地屏幕窗口中。
1.2.7 7)运行应用
执行bin/main.bat camera运行应用,将会自动弹出实时的垃圾分类检测画面:

1.3 打包部署
1.3.1 打包
调试完成后,同样可以通过create.py脚本将应用打包发布:
python ./create.py -t rpm -n garbage_det
控制台中输出:
sdk version is modelbox-win10-x64-1.1.0.5 call mb-pkg-tool pack [folder] > [rpm file] to building rpm, waiting... success: create garbage_det.rpm in D:\modelbox-win10-x64-1.1.0.5/workspace/garbage_det
等待稍许,可以看到项目工程下已经生成了rpm文件夹和打包好的应用:

1.3.2 部署
将打包好的应用上传至华为云账号下的obs桶中:

在专业版设备管理中选择一个开发板,

点击创建部署:

最后添加作业:

这样我们就已经完成了一个AI应用,从模型训练到转换到开发到部署的全部流程。

关于ModelBox核心概念、功能单元和流程图开发的更多介绍,可查看ModelBox手册。
带你动手做AI版的垃圾分类的更多相关文章
- 自己动手做AI:Google AIY开发工具包解析
2018年国际消费性电子展(CES)上,最明显的一个趋势是Amazon与Google的语音技术进驻战,如AmazonAlexa进驻到Acer笔电内,Google Assist进驻到KIA汽车内,其他如 ...
- 【雕爷学编程】MicroPython动手做(01)——春节后入手了K210开发板
Python的开放.简洁.黏合正符合了现发展阶段对人工智能.大数据分析.可视化.各种平台程序协作产生了快速的促进作用.自Python3的发布到现在已有五六年的时间,从刚发布的反对声音到慢慢被接受与喜欢 ...
- 如何用python制作贪吃蛇以及AI版贪吃蛇
用python制作普通贪吃蛇 哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很 ...
- Qt做发布版,解决声音和图片、中文字体乱码问题(需要在main里写上QApplication::addLibraryPath("./plugins")才能加载图片,有图片,很清楚)
前些天做Qt发布版,发现居然不显示图片,后来才发现原来还有图片的库没加!找找吧,去qt的安装包,我装在了F盘,在F盘F:/QT/qt/plugins,找到了plugins,这里面有个 imagefor ...
- 线程安全使用(四) [.NET] 简单接入微信公众号开发:实现自动回复 [C#]C#中字符串的操作 自行实现比dotcore/dotnet更方便更高性能的对象二进制序列化 自已动手做高性能消息队列 自行实现高性能MVC WebAPI 面试题随笔 字符串反转
线程安全使用(四) 这是时隔多年第四篇,主要是因为身在东软受内网限制,好多文章就只好发到东软内部网站,懒的发到外面,现在一点点把在东软写的文章给转移出来. 这里主要讲解下CancellationT ...
- 生活娱乐 WIFI机器人(某机器发烧友自己动手做一台)
某机器发烧友自己动手做一台WIFI机器人,以下是这位发烧友的自述!让我们一起来分享他的劳动成果-- 在经历了十多天的疯狂淘宝.组装.调试.拆卸.再组装.再调试的过程后,俺的Wifi Robot终于于2 ...
- 「雕爷学编程」Arduino动手做(9)——火焰传感器模块
37款传感器和模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器与模块,依照实践出真知(动手试试)的理念,以学习和交流为目的,这里准备 ...
- 「雕爷学编程」Arduino动手做(10)——敲击传感器模块
37款传感器和模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器与模块,依照实践出真知(动手试试)的理念,以学习和交流为目的,这里准备 ...
- 「雕爷学编程」Arduino动手做(15)——手指侦测心跳模块
37款传感器和模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器与模块,依照实践出真知(动手试试)的理念,以学习和交流为目的,这里准备 ...
- 【雕爷学编程】MicroPython动手做(02)——尝试搭建K210开发板的IDE环境
喜欢今日头条,偶然看到广告,半个多月前交了8.9元,报名参加了头条上Python的四天培训课,呵呵,总算是有了零的开始(还是有点收获的,见https://www.sohu.com/a/38112874 ...
随机推荐
- 定位java程序中占用cpu最高的线程堆栈信息
找出占用cpu最高的线程堆栈信息 在java编码中,有时会因为粗心导致cpu占用较高的情况,为了避免影响程序的正常运行,需要找到问题并解决.这里模拟一个cpu占用较高的场景,并尝试定位到代码行. 示例 ...
- 从 洛谷P5309 Ynoi2011 初始化 看卡常
一般情况下,程序运行消耗时间主要与时间复杂度有关,超时与否取决于算法是否正确. 但对于某些题目,时间复杂度正确的程序也无法通过,这时我们就需要卡常数,即通过优化一些操作的常数因子减少时间消耗. 比如这 ...
- 【网络】内网穿透方案&FRP内网穿透实战(基础版)
目录 前言 方案 方案1:公网 方案2:第三方内网穿透软件 花生壳 cpolar 方案3:云服务器做反向代理 FRP简介 FRP资源 FRP原理 FRP配置教程之SSH 前期准备 服务器配置 下载FR ...
- Go语言核心36讲20
在上两篇文章中,我主要为你讲解了与go语句.goroutine和Go语言调度器有关的知识和技法. 内容很多,你不用急于完全消化,可以在编程实践过程中逐步理解和感悟,争取夯实它们. 现在,让我们暂时走下 ...
- c++ *和& 指针,取内容,别名,取地址
*前面有类型符时为定义指针 &前面有类型符时为定义引用变量(别名) (int ,float,long,double,char等 ) *p:定义xx类型的指针 int *p 整型指针,char ...
- esp-01和esp-01s烧录固件和程序
准备工具 USB-TTL 杜邦线若干 esp-01s烧录固件 我烧录的固件是 micropython, 使用的软件是 uPyCraft esp-01s烧录固件接线方法: esp-01s usb-ttl ...
- python调用c++生成的dll
前言 这个我查询了很多资料,所以到此为止,相当于做一个总结 c++代码如何生成dll #include<iostream> using namespace std; extern &quo ...
- day29-JQuery02
JQuery02 4.jQuery选择器02 4.3过滤选择器 4.3.1基础过滤选择器 $("li:first") //第一个li $("li:last") ...
- C++编程笔记(QT)
目录 入门基础 模态对话框 消息提示框(messagebox) 文件和目录 字体选择框 输入对话框 进度条 工具栏 控件布局 Windows托盘案例 控件 button 下拉菜单按钮 `radioBu ...
- 【Shell案例】【awk每行执行一次】11、转置文件的内容
描述写一个 bash脚本来转置文本文件nowcoder.txt中的文件内容. 为了简单起见,你可以假设:你可以假设每行列数相同,并且每个字段由空格分隔 示例:假设 nowcoder.txt 内容如下: ...