一、硬件介绍及实现的功能
1.硬件介绍
UnitV2是M5Stack推出的一款高效率的AI识别模块,专为, 采用Sigmstar SSD202D(集成双核Cortex-A7 1.2Ghz处理器)控制核心,集成128MB-DDR3内存,512MB NAND Flash, 1080P摄像头。内嵌Linux操作系统,集成丰富的软硬件资源与开发工具。
2.实现功能
通过图像识别,来甄别流水线的异常品,发现异常品后记录。同时将图像以及相关信息保存到云端,通过桌面自行编程的Python程序,实现对图像和信息的自动下载,标记,并将标记后的图片保存在桌面,并上传到云端,同时删除下载的图像以及信息文件。
其中,流水线通过人工模拟,使用两种不同类型的橡皮模拟正常品,使用订书器模拟异常品,能够识别出异常品并记录,云端平台使用阿里云,模型训练采用官方提供平台,相关链接见文章末尾参考链接
二、实现思路及实现功能的具体介绍
1.安装&配置相应环境
(1)安装Vscode:按照直播:M5Stack UnitV2 设计思路与入门使用中的推荐,安装VsCode编辑器。
(2)安装wsl:为了使用sshpass登录Linux,参考在 Windows 10 上安装 WSL | Microsoft Docs和[安利] WSL Linux 子系统安装wsl。
(3)安装Python以及相关库
(4)配置云端:注册阿里云账号,开通OSS服务(OSS新手入门),设置相应权限,设置AccessID和Accesskey并保存。
(5)配置网络连接:连接摄像头与电脑,进入vscode,打开新的终端窗口,在终端界面中选择wsl,通过sshpass命令进入摄像头内置的Linux系统,参考wifi - How to export the current wpa_cli network to a file? - Unix & Linux Stack Exchangeeep配置WiFi,使得摄像头在连接电脑后能够自动连接网络。
2.选择识别目标
任务二要求识别生产线异常品并记录,但考虑到在生活中,很难直接到生产一线去进行反复测试,因此需要我们制作一个模拟的流水线。在识别目标上,出于简单易行的考虑,我选择了用橡皮表征正常品,用订书器表征异常品。将其置于a4纸上,手动拖动纸张移动,形成流水线的效果
3.训练模型
选定识别目标后,连接摄像头与电脑,访问unitv2.py,使用unitV2摄像头拍摄目标的相关图像,如下图。拍摄完成后保存到本地
在官方提供的平台--模型训练--上进行上传,框选标记图像,上传训练,下图是训练结果,可以看到训练结果比较好在训练完成后,下载模型,在unitv2.py网页上,点击object recognition,并加载模型
4.编写程序
程序分为两部分,主程序是运行在摄像头内嵌的Linux上,主要功能是识别待测物,并将图像和图像相关信息上传云端。第二个程序运行在Win10桌面上,主要功能是将云端的图像和信息下载到本地,并进行加框处理,同时显示识别目标的基本信息。
主程序:在交流群中提供的模板程序上进行改造得来,主要改动有(1)为不同的拍摄图像动态命名,避免图像相互覆盖,用当前的拍照次数命名,进而可以保留所有图像(2)改变了输出信息,为了方便查看,由原来输出meta文档改为输出TXT文档,输出信息的内容和格式进行了修改,新修改的程序输出识别次数,置信率,目标位置,目标大小。原程序以字典的形式输出识别目标数量,每个目标的置信率、位置、大小、以及目标名称,最后是运行的程序名,下面是两种输出内容的对比
本次识别为:第2次识别。
识别可信度为:prob = 0.84191519
物体位于(101.0,163.0)
物体尺寸为:w = 98,h = 104
{'num': 3, 'obj': [
{'prob': 0.754431129, 'x': 360, 'y': 0, 'w': 134, 'h': 155, 'type': 'stapler'},
{'prob': 0.702723324, 'x': 482, 'y': 146, 'w': 113, 'h': 160, 'type': 'erase2'},
{'prob': 0.505101085, 'x': 3, 'y': 0, 'w': 276, 'h': 361, 'type': 'stapler'}
],
'running': 'Object Recognition'}
(3)新建一个TXT文档记录本轮识别的次数,方便桌面程序调用。
下面是主程序
from json.decoder import JSONDecodeError
import subprocess
import json
import requests
import base64
import time
reconizer = subprocess.Popen(['/home/m5stack/payload/bin/object_recognition', '/home/m5stack/payload/uploads/models/v2model_047bc7d6bea9e4dc'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
url = '*********************************'
url_img = url + '/img'
url_msg = url + '/message'
n = 0
reconizer.stdin.write("_{\"stream\":1}\r\n".encode('utf-8'))
reconizer.stdin.flush()
img = b''
begt = time.time()
while 1:
doc = json.loads(reconizer.stdout.readline().decode('utf-8'))
print(doc)
if 'img' in doc:
byte_data = base64.b64decode(doc["img"])
img = bytes(byte_data)
elif 'num' in doc:
for obj in doc['obj']:
if obj['type'] == 'stapler':
offtime=time.time()-begt
if obj['prob'] > 0.7 and offtime > 1 :
n = n + 1
prob = obj['prob']
x1 = round(1/2 * obj['x'])
y1 = round(1/2 * obj['y'])
w1 = round(1/2 * obj['w'])
h1 = round(1/2 * obj['h'])
x2 = x1 + w1
y2 = y1 + h1
s ="{}\n" \
"prob = {}\n" \
"w = {},h = {}\n" \
"({},{})\n" \
"({},{})".format(
n,
prob,
w1,h1,
x1,y1,
x2,y2)
name_img_and_msg = str(n)
r = requests.put(url_img + '/' + name_img_and_msg +'.jpg', data=img)
print(r.status_code)
r = requests.put(url_msg + '/' + name_img_and_msg +'.txt', data=str(s).encode('utf-8'))
print(r.status_code)
r = requests.put(url + '/message_num.txt', data=str(n).encode('utf-8'))
桌面程序:通过调用阿里云oss的相关APIpython安装使用阿里云OSS上传/下载/删除文件,实现批量下载指定的云端图片以及相关信息,在通过OS库和CV2库,根据图像信息对图像进行相关处理以及相关信息的显示,最后将处理后的图像保存到云端。下面是结果演示
下面是相应程序
'''
·自动完成从阿里云平台下载图像及信息,
并完成画框,显示,在完成画框后上传阿里云并删除下载的文件
·其中,口令,bucket,下载以及上传链接需要提前自行设置或准备
'''
import cv2
import numpy as np
import os
import oss2
# API登录口令,bucket设置
auth = oss2.Auth('***************', '********************')
bucket = oss2.Bucket(auth, '************************', '*******')
pathA = 'm5stack_Unit_V2'
pathB = r"C:\Users\io\Downloads"
pathC = r"C:\Users\io\Desktop"
bucket.get_object_to_file(pathA+'/message_num.txt',pathB+"message_num.txt")
with open(pathB+"message_num.txt","r") as Msg_num:
num_end = int(Msg_num.readline().strip())
Msg_num.close()
num_start = 2
#num_end = 10
num_now = num_start
while num_now<=num_end:
name = str(num_now)
#name = '30'
path_download_jpg = pathA + '/img' + '/'+ name + '.jpg'
path_save_jpg = pathB + "\\" + name + ".jpg"
path_download_txt = pathA + '/message'+'/'+ name + '.txt'
path_save_txt = pathB + "\\" + name + ".txt"
path_save_rtg_jpg = pathC + "\\" + name + "_rtg" + ".jpg"
path_upload_rtg_jpg = pathA + '/img_rtg/'+ name + '_rtg' + '.jpg'
# 下载
bucket.get_object_to_file(path_download_jpg,path_save_jpg)
bucket.get_object_to_file(path_download_txt,path_save_txt)
# 文件处理
with open(path_save_txt,"r") as img_txt:
n = img_txt.readline().strip()
prob = img_txt.readline()
w_h = img_txt.readline()
a = img_txt.readline().strip()
b = img_txt.readline().strip()
a = tuple(eval(a))
b = tuple(eval(b))
x1,y1 = a
x2,y2 = b
c1 = 1/2 * (x1 + x2)
c2 = 1/2 * (y1 + y2)
print("本次识别为:第{}次识别。\n\n"
"识别可信度为:{}"
"物体位于({},{})\n"
"物体尺寸为:{}".format(n,prob,c1,c2,w_h))
# print("type a is ",type(a))
# print("type a is ",type(a))
img = cv2.imread(path_save_jpg)
img_rtg = cv2.rectangle(img,a,b,(0,255,0),3)
cv2.imwrite(path_save_rtg_jpg, img_rtg)
cv2.imshow("photo"+name,img_rtg)
img_txt.close()
os.remove(path_save_jpg)
os.remove(path_save_txt)
bucket.delete_object(path_download_jpg)
bucket.delete_object(path_download_txt)
# 上传
bucket.put_object_from_file(path_upload_rtg_jpg,path_save_rtg_jpg)
num_now=num_now+1
5.程序功能介绍
两程序配合,可以实现识别物体,保存到云端,下载,图像处理,信息显示,上传 一系列功能。下图是截取了一张识别结果的图像,可以直观感受到,识别还是很准确的
三、遇到的主要难题
由于之前没有接触过Linux,Python,以及图像识别,在本次任务中,我先后遇到了很多的问题,之所以能够解决大部分问题并完成任务要求,除了自己努力学习检索以及尝试外,要着重感谢群内同学老师们的大力热情帮助,
1.Linux登录及相关命令:
由于之前没有接触过Linux,任务开始时基本是两眼一抹黑,在群内同学和M5stack韩老师的提示讲解下,了解了登录Linux的种种方法,并先后尝试了mobaxterm,putty,winscp等数款软件。随后在韩老师建议下,通过自己在MOOC上检索式地学习了一段时间的Unix入门,对Linux命令有了简单的了解。
2.安装wsl以及vscode和Linux的快捷键:
在二次观看直播:M5Stack UnitV2 设计思路与入门使用时,发现韩老师演示时,在一个wsl的选项中通过sshpass登录,同时输入文件命令时,会有提示。而我并没有找到这个选项,另外在输入sshpass时系统总是报错,开始以为是缺少某个插件,但尝试后无果,经过向群友们提问,了解到,使用sshpass需要在 Windows 10 上安装 WSL,另外在输入文件路径时,可以通过tab键预览和自动补全。
3.在Linux上运行Python程序:
开始时,发现韩老师发到交流群群里的文档task.json中,有命令run一项,惯性地以为通过运行命令来启动上传到Linux中的程序,但经常报错。在群里询问韩无果后,再次观看视频,发现是通过命令行命令来运行程序,后来又通过网络检索,可以通过Ctrl+C中断程序运行。
4.保存图像到阿里云:
在观看直播时,直播中提到了将阿里云设为了公共权限,当时以为可以通通过直播中的阿里云链接存储,在反复尝试打开链接失败后,于群里询问得知,需要自己申请阿里云账号,进而保存。自行摸索着注册了阿里云账号,注册后单纯以为通过网址链接上传,但运行程序后并没有保存,在群里反复交流后,M5的韩工程师指明了该到哪里寻找链接。
5.图像以及信息处理
直播:M5Stack UnitV2 设计思路与入门使用中曾经提到可以给图像加框,在完成了基本的程序设计后,我自然想要进一步对图像进行处理。但在主程序中直接使用opencv2相关函数似乎并不可以,程序会报错,没办法的情况下,我采用了分两个程序处理的方案:即在UnitV2内嵌的Linux系统上运行识别程序,将图像和相关信息上传到云端;在Win10系统上编写Python程序,通过调用API的方法,从云端下载图像和相关信息,进行相关处理后将图像上传云端,同时删除下载到本地的文件以及对应的云端文件。
在测试其成功后,我想,既然可以在桌面端运行程序,那么在Linux上应该也可以,于是我尝试将图像下载、处理,上传程序整合到主程序中,但是在UnitV2内嵌的Linux上安装oss2库失败,由于时间关系,暂时放弃了这个思路。
四、未来的计划建议等
在条件允许的情况下,对主程序做进一步改进,主要为:
- 采用当下时间给识别到的图像命名,同时向云端输出汇总图像名称的文档;
- 加入远程提醒功能,可以在手机端或PC端通过对应软件,实时订阅识别情况;
- 购买或制作专用的4PIN线,实现串口输出特征信号;
- 配置程序开机后自动运行流水线程序;
- 将桌面的Python图像处理程序整合到主程序中,不再使用两个程序互相配合,通过一个整合好的程序实现完整的自动化的图像识别,处理,上传。
五、参考链接
在任务过程中,需要参考开发文档,任务说明等,另外任务过程中前后遇到了很多这样那样的问题,为了解决这些问题,我在网络上进行了相关的检索和学习,下面列出这次任务期间收藏的参考链接,也算是个纪念。
1.官方及硬禾文档
2.linux 相关
在 Windows 10 上安装 WSL | Microsoft Docs
[安利] WSL Linux 子系统,真香!完整实操 - 知乎
linux查找文件路径_mayue_web的博客-CSDN博客_linux查询文件所在路径
linux系统中如何进入退出vim编辑器,方法及区别-百度经验
3.网络&WiFi
通过 Linux 命令行连接 Wifi | Linux 中国
49.Linux-wpa_cli使用之WIFI开启,扫描热点,连接热点,断开热点,WIFI关闭(49) - 诺谦 - 博客园
Wpa_supplicant 调试故障原因分析 - 黄树超 - 博客园
如何配置网络优先顺序,调整 Windows 10 网卡优先级 - 系统极客
wifi - How to export the current wpa_cli network to a file? - Unix & Linux Stack Exchange
4.阿里云相关
阿里云python中文社区_python安装使用阿里云OSS上传/下载/删除文件 - pytorch中文网..._weixin_39774682的博客-CSDN博客
5.Python相关
Python新建动态命名txt文件 - 一点空白 - 博客园
python字符串转换元组_python 字符串,列表,元组,字典相互转换
Python读写txt文本文件的操作方法全解析_python_脚本之家
怎么运行python文件_怎么在linux上运行python
6.报错分析
can't multiply sequence by non-int of type 'float' - 搜狗搜索
解决Vscode中unresolved import “XXX” 问题
成功解决AttributeError: 'str' object has no attribute 'decode'