如果一个完整的包裹有多少物品组成?在打包的之前需要对这些零件进行清点看有没有多了什么或者少了什么。一旦需要打包的东西太多,靠人工就很容易出错了。
01—简单的系统硬件设计
如果借助深度学习,我们可以弄个普通的支架+摄像头来帮助打包人员进行清点。非常方便、快捷,相当于我在打包的时候机器帮我在旁边清点打包的物品,有了一个小助理。
准备系统硬件
整个系统的硬件构成,大概就是这个样子(请专注图的内容,忽略我拙劣的画工):
系统有一个支架、一个普通的usb摄像头、一台电脑。电脑肯定是已经有了,只需要再买个支架和一个usb摄像头就行了。支架就用普通的桌面俯拍支架就行,这东西很便宜,某宝上买加usb摄像头总共50左右。
系统有一个支架、一个普通的usb摄像头、一台电脑。电脑肯定是已经有了,只需要再买个支架和一个usb摄像头就行了。支架就用普通的桌面俯拍支架就行,这东西很便宜,某宝上买加usb总共50左右。
好了,硬件准备完成,现在开始写代码。
02—软件设计
这个任务属于多标签图像识别,如果自己设计并实现识别模型太难了,不太现实。就网上找找看有没有合适的,花个把小时在搜索引擎、B站、Github上搜一下发现,现在大家都是用yolo来实现多标签图像识别,而且看看github上有开源的yolov5的代码,翻看一下readme写的还算详尽,把训练、使用、部署基本都说明白了。
然后B站上找一个点击量比较靠前的yolov5的使用说明,大概了解这个模型的使用流程。
- 准备自己的训练集;
- 训练yolov5;
- 给训练好的yolov5套一个pyqt的外壳,让它易于使用;
- 打包成exe文件,当然,自己用的话,第4步可以省略。
本文就只简要介绍前三个步骤的实现。
准备自己的训练集
这是个力气活。首先,你要在接近生产现场的环境拍摄尽量多的图片;然后,再给这些图片打上标签。
那拍摄多少图片才够呢?我在网上极其潦草的搜了一下,好像也没有定论。我就大胆猜了一下,如果识别的场景不太复杂的话,一个类别平均有50张照片应该能达到效果。也就是说,如果我们打包的东西有10种,那我拍摄200张照片应该足够。那怎么从50、10这两个数得到200这个数的呢?也是我的直觉瞎猜的,没有什么严谨的数学公式。后面效果不好再说吧。
方案确定好后,我还花差不多半天时间写了一个摄像头的拍照的应用。
写好代码之后,又等了差不多两天时间*宝上网购的支架、摄像头才到货。迫不及待的连上电脑,调试了一下,摄像头拍照的应用顺利通过我自己的验收。
Ubuntu+PyQt5开发电脑摄像头拍照软件
有了这个小应用的帮助,很快就完成了200张照片的拍摄。此外,在这个小小的程序里我还做了件画蛇添足的事情,就是我在网上胡乱搜索资料的时候发现别人构建的训练图片的长宽都是一样的,所以我把系统默认的640*480的摄像头图片给改成了512*512,后来发现好像也没有必要。
图片拍摄好,就是最无聊的手动打标签了,安装labelImg,然后启动,然后设置为自动保存标签结果、最后改成yolo的标签格式,就可以认真、细致的打标签了。
在使用labelImg的时候还发生了一件非常乌龙的事情,“labelImg”倒数第三个“i”要大写。我安装完成后,使用命令"labelimg?imageView2/2/w/1620"调用labelImg的时候老是提示“command not found”,折腾了好久才发现,差点崩溃!
另外,在使用labelImg打标签的时候,要多使用快捷键提高效率。据说还有一些可以团队协作的打标签工具,我没有尝试。
训练模型
训练模型,需要一个显卡,看看网上动辄好几千块的网卡,没舍得买。翻箱倒柜,发现以前的一台电脑上有一块750Ti的2G显卡,窃喜,训练yolov5的s模型应该够用。
训练过程还是比较简单的,就是一些参数文件的改写。只是2G的显卡太拉跨啦,batch_size设置为4,GPU就90%多的占用了。好在图片不多,200个epochs的训练,个把小时以就可以训练完成。200个epochs的训练完成后,mAP @0.5可以到99%,效果很满意,实在佩服yolo的作者。
PyQt5实现
有了模型,再做个UI就简单的多了,与前面写的摄像头拍照软件类似。
无非就是不停在摄像头中拿图,然后将拿到的图片送给模型识别,将识别到的物体清单用字符显示出来、同时将标注后的图片显示到图片框中,比较简单。
最终效果
03—效果视频
http://mpvideo.qpic.cn/0bc33iaawaaazuad7v7vqzqvbwwdbpnaacya.f10002.mp4?dis_k=678d9cc8a83ce668d1627299291eca3d&dis_t=1646633787&vid=wxv_2245921211786526720&format_id=10002&support_redirect=0&mmversion=false