m5stack unitv2 流水线异常品识别
运用unitv2的物体识别功能,区分带盖和不带盖的stlink(分别记为正常品和异常品),保存拍摄到的图片,并用不同颜色的框选出正常品和异常品。此外,检测到异常品时点亮模块上的红色LED。
标签
嵌入式系统
氢化脱氯次氯酸
更新2021-07-21
928

1 平台介绍

UnitV2是M5Stack推出的一款高效率的AI识别模块,专为, 采用Sigmstar SSD202D(集成双核Cortex-A7 1.2Ghz处理器)控制核心,集成128MB-DDR3内存,512MB NAND Flash, 1080P摄像头。内嵌Linux操作系统,集成丰富的软硬件资源与开发工具,致力带给用户开箱即用,简洁高效的Ai开发体验。

Fp_OQSXLYoRbCKF8CFz-rfr64XKPFgrIu8MklWOcCd1Jxf2YrH0hAjPy

2 任务及实现方案

2.1 任务题目

通过图像识别,来甄别流水线的异常品,发现异常品后记录。

2.2 方案简介

运用unitv2的物体识别功能,区分带盖和不带盖的stlink(分别记为正常品和异常品),保存拍摄到的图片,并用不同颜色的框选出正常品和异常品。此外,检测到异常品时点亮模块上的红色LED。

终端输出:

FqaXEdlOLnpfcOfG4czv3UgohhVY

识别正常品与异常品:

FpK_LK7PW_KOWOugyhqjq1H0OZNQ

FuMd_H0e0BhUDfj2HkyJDwwkWEYJ

3 实现过程

3.1 采集数据

利用unitv2网页端的拍照功能,分别采集不同角度的带盖与不带盖的stlink图片共61张。为了防止背景对识别造成影响,需要在桌面上铺一张白纸。

3.2 标签标记与模型训练

通过M5Stack的V-Training(Ai模型训练服务,网址:http://v-training.m5stack.com/build/index.html),可以构建识别的模型。首先需要导入上一步采集的图片,之后对图片进行手动标记,即分别框选出图片中的stlink并标记其是正常品还是异常品。

Fkka_fOg2s5F0Od9PaZYTBY9aDZMFoDVtQAraVIzf8xxdEduBk6-P2Un

全部图片均标记完成后,点击右下角的next即可开始训练。几分钟后训练完成即可下载训练模型。若训练曲线(下图)为递减趋势则代表训练较为成功。

FjNfKHHwTmtgLFMk26Kq-sS2rVl6

3.3 网页上测试模型

在模块的网页端(unitv2.py)选择物体识别功能,上传模型,即可对模型进行测试。

Fj-MEwfAbsbR-zKENh96EdK4m57H

 

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 未来的计划建议

可以在程序中添加统计正常品与异常品数量的功能,并上传至云端。

另外,模型训练网站上训练模型很方便快捷,但其功能较少,希望未来可以添加手动调整模型参数等功能。

附件下载
v2model_82bef89d4a5cd8e3.tar
训练模型
code.zip
Python代码
团队介绍
团队成员
氢化脱氯次氯酸
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号