1 平台介绍
UnitV2是M5Stack推出的一款高效率的AI识别模块,专为, 采用Sigmstar SSD202D(集成双核Cortex-A7 1.2Ghz处理器)控制核心,集成128MB-DDR3内存,512MB NAND Flash, 1080P摄像头。内嵌Linux操作系统,集成丰富的软硬件资源与开发工具,致力带给用户开箱即用,简洁高效的Ai开发体验。
2 任务及实现方案
2.1 任务题目
通过图像识别,来甄别流水线的异常品,发现异常品后记录。
2.2 方案简介
运用unitv2的物体识别功能,区分带盖和不带盖的stlink(分别记为正常品和异常品),保存拍摄到的图片,并用不同颜色的框选出正常品和异常品。此外,检测到异常品时点亮模块上的红色LED。
终端输出:
识别正常品与异常品:
3 实现过程
3.1 采集数据
利用unitv2网页端的拍照功能,分别采集不同角度的带盖与不带盖的stlink图片共61张。为了防止背景对识别造成影响,需要在桌面上铺一张白纸。
3.2 标签标记与模型训练
通过M5Stack的V-Training(Ai模型训练服务,网址:http://v-training.m5stack.com/build/index.html),可以构建识别的模型。首先需要导入上一步采集的图片,之后对图片进行手动标记,即分别框选出图片中的stlink并标记其是正常品还是异常品。
全部图片均标记完成后,点击右下角的next即可开始训练。几分钟后训练完成即可下载训练模型。若训练曲线(下图)为递减趋势则代表训练较为成功。
3.3 网页上测试模型
在模块的网页端(unitv2.py)选择物体识别功能,上传模型,即可对模型进行测试。
3.4 代码编写
在模块上运行python程序(由直播中的程序修改而来),实现图片记录与点亮LED的功能。部分代码片段如下:
向终端中打印识别到的信息:(这里除以2是因为代码得到的图片尺寸是320*240,而json中给出的坐标是640*480图片的坐标)
x, y, w, h = obj['x']//2, obj['y']//2, obj['w']//2, obj['h']//2
# print information
print('type: ', obj['type'])
print('position: ', (x, y))
print('probability:', obj['prob'], '\n')
led控制,若检测到异常品熄灭白色led,点亮红色led;检测到正常品则熄灭红色led,点亮白色led:
# led control
if obj['type'] == 'normal':
# white led on, red led off
control_white_led(0)
control_red_led(1)
elif obj['type'] == 'defective':
# red led on, white led off
control_red_led(0)
control_white_led(1)
其中control_red_led和control_white_led在另一个文件ledcontrol.py中定义,写入1为熄灭,0为点亮:
def control_white_led(value):
open('/sys/class/gpio/export', 'w').write('0') # Export the GPIO0
open('/sys/class/gpio/gpio0/direction', 'w').write('out') # Set the direction of the GPIO
open('/sys/class/gpio/gpio0/value', 'w').write(str(value)) # Set the calute, '1' or '0'
def control_red_led(value):
open('/sys/class/gpio/export', 'w').write('1') # Export the GPIO0
open('/sys/class/gpio/gpio1/direction', 'w').write('out') # Set the direction of the GPIO
open('/sys/class/gpio/gpio1/value', 'w').write(str(value)) # Set the calute, '1' or '0'
临时保存摄像头得到的原始图片,再用opencv打开,根据物体的坐标绘制一个矩形框住物体,其中矩形的颜色代表识别类型,绿色矩形为正常品,红色矩形为异常品。之后删除之前的临时图片,并保存绘制矩形之后的图片:
byte_data = base64.b64decode(doc["img"])
img = bytes(byte_data)
# save original image
fp = open("temp.jpg", 'wb')
fp.write(img)
fp.close()
# draw a rectangle
img_cv = cv2.imread('temp.jpg')
img_rec = cv2.rectangle(img_cv, (x, y), (x+w, y+h), color, 2)
os.unlink("temp.jpg")
cv2.imwrite('product.jpg', img_rec)
run.py程序完整的代码如下:
from json.decoder import JSONDecodeError
import subprocess
import json
import base64
import time
import cv2
import os
from ledcontrol import control_white_led, control_red_led
reconizer = subprocess.Popen(['/home/m5stack/payload/bin/object_recognition', '/home/m5stack/payload/uploads/models/v2model_82bef89d4a5cd8e3'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
reconizer.stdin.write("_{\"stream\":1}\r\n".encode('utf-8'))
reconizer.stdin.flush()
img = b''
while 1:
doc = json.loads(reconizer.stdout.readline().decode('utf-8'))
if 'num' in doc:
for obj in doc['obj']:
x, y, w, h = obj['x']//2, obj['y']//2, obj['w']//2, obj['h']//2
# print information
print('type: ', obj['type'])
print('position: ', (x, y))
print('probability:', obj['prob'], '\n')
# led control
if obj['type'] == 'normal':
# white led on, red led off
control_white_led(0)
control_red_led(1)
color = (0, 255, 0) # green rectangle
elif obj['type'] == 'defective':
# red led on, white led off
control_red_led(0)
control_white_led(1)
color = (0, 0, 255) # red rectangle
elif 'img' in doc:
byte_data = base64.b64decode(doc["img"])
img = bytes(byte_data)
# save original image
fp = open("temp.jpg", 'wb')
fp.write(img)
fp.close()
# draw a rectangle
img_cv = cv2.imread('temp.jpg')
img_rec = cv2.rectangle(img_cv, (x, y), (x+w, y+h), color, 2)
os.unlink("temp.jpg")
cv2.imwrite('product.jpg', img_rec)
4 遇到的主要难题
项目中我遇到的主要难题是识别物体的选择和识别率的问题。
一开始我使用中性笔作为被识别物体,通过是否有笔帽来判断是正常品还是异常品。但是中性笔有无笔帽在摄像头中区别不明显,且模型训练网站中只能框选矩形,和中性笔的形状相差较大,训练的模型识别很不准确。
识别率方面,模型训练的网站上要求至少需要30张图片作为训练集,但我使用30张图片识别效果较差,需要较多图片才能达到较好的识别效果。
5 未来的计划建议
可以在程序中添加统计正常品与异常品数量的功能,并上传至云端。
另外,模型训练网站上训练模型很方便快捷,但其功能较少,希望未来可以添加手动调整模型参数等功能。