基于Maix Bit K210的口罩目标检测

基于Maix Bit K210的口罩目标检测

Author:Hao_XL


前言

该项目是基于Maix Bit K210开发板做的一个口罩目标检测项目,项目实现难度不大,按以下步骤操作即可实现。但更重要的是理解项目的实现流程,学到经验,从而应用于其他的项目。

在项目开始前,我有一些小的建议:

  1. 将桌面整理好,整洁的桌面有助于耐心的思考和硬件项目的接线。
  2. 文件夹的路径中不要出现中文。
  3. 硬件接线时候,一定要记得先断电,接电源线的时候尤其用注意不要接短路。
  4. 遇到问题时候,具体思考问题的情况如何描述,先在官方文档、chatgpt或者谷歌进行搜索寻找答案,如果实在解决不了,可加入社区或者交流群询问,当然也欢迎通过文末的联系方式与我交流。

前期准备

  • 硬件准备
  1. maix bit开发板:用于部署模型
  2. ble01蓝牙模块:用于发送数据到手机
  3. usb to ttl串口助手:用于配置蓝牙模块参数
  4. led灯:用于报警显示
  5. 杜邦线:用于连接模块
  • 工具准备
  1. kflash_gui.exe:用于烧录模型
  2. ATK-BLE V1.1.exe:用于蓝牙AT指令的上位机
  • 网站
  1. 官方介绍文档:maxi bit

  2. 模型训练网站:maixhub

具体实现步骤

模型训练

  1. 进入网站maixhub,根据网站指引采集图像,打标签,训练模型。

训练的模型是目标检测类模型。

数据集可以是自己通过手机采集的数据集,拍摄一些戴口罩的数据集(至少需要50张以上,比较有代表性的),然后在网站上打好需要检测的目标的标签框。

在这里插入图片描述

  1. 训练模型时候的配置如下图所示:

在这里插入图片描述

  1. 训练的结果数据如下图所示,在测试集上的损失越低,准确率越高,代表模型越好,有拟合数据的能力。

在这里插入图片描述

模型部署

  1. 训练好模型后,选择右上角的部署,点击下载解压后会得到三个文件。
    在这里插入图片描述

  2. maix bit烧录固件官方教程,先在官网下载对应固件(”固件“文件夹中有下载好的)

    在这里插入图片描述

  3. 打开kflash_gui软件,进行固件的烧录,打开软件后,选择固件,直接点击下载按钮。

  4. 烧录好固件后,烧录刚才训练好的kmodel模型,注意模型烧录的起始地址为0x3000000,固件的起始地址为0x000000。

    在这里插入图片描述

  5. 上传代码到K210的文件系统中,官方教程,在网站中下载uPyLoader软件,打开软件后连接板子。连接好后,就可以将main.py文件上传到K210的文件系统中,注意命名为boot.py,这样板子上电后就会自动执行这个脚本。

    在这里插入图片描述

  6. 代码解析,主要是在生成代码的基础上,加入了串口。详细函数说明参考官方文档。在默认生成的代码中进行了如下修改:

    • 修改1:更改串口发送的信息
    • 修改2:添加了一个定时器,用于控制串口的消息发送频率
    • 修改3:LED初始化,添加了LED代码
    • 修改4:修改模型的地址为0x3000000(必须修改,因为我们的模型是烧录在这个地址)
    • 其余修改细节可仔细对比源代码查看区别
    # 导入需要用到的包
    from machine import UART
    from machine import Timer
    
    class Comm:
        def __init__(self, uart):
            self.uart = uart
    
        def send_detect_result(self, objects, labels):
            msg = ""
            for obj in objects:
                p = obj.value() 
                # 修改1:更改串口发送的信息
            self.uart.write(msg.encode())
    
    def init_uart():
        fm.register(9, fm.fpioa.UART1_TX, force=True)
        fm.register(10, fm.fpioa.UART1_RX, force=True)
    	# 串口参数修改波特率为9600
        uart = UART(UART.UART1, 9600, 8, 1, 0, timeout=1000, read_buf_len=256)
        return uart
    
    # 修改2:添加了一个定时器,用于控制串口的消息发送频率
    def on_timer(timer):
        global flag
        flag = True
    
    # 定义主函数
    def main(anchors, labels = None, model_addr="/sd/m.kmodel", sensor_window=input_size, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):
        # 声明定时器中的全局变量flag
        global flag
        
        # 对摄像头的初始化
        sensor.reset()
        sensor.set_pixformat(sensor.RGB565)
        sensor.set_framesize(sensor.QVGA)
        sensor.set_windowing(sensor_window)
        sensor.set_hmirror(sensor_hmirror)
        sensor.set_vflip(sensor_vflip)
        sensor.run(1)
        
    	# 对lcd屏幕的初始化
        lcd.init(type=1)
        lcd.rotation(lcd_rotation)
        # lcd.mirror(True)
        lcd.clear(lcd.WHITE)
    
        # 修改3:LED初始化
        fm.register(35,fm.fpioa.GPIO0)
        led1 = GPIO(GPIO.GPIO0,GPIO.OUT)
    
        # 定时器初始化
        tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=1000, callback=on_timer, arg=on_timer)
    
    
        if not labels:
            with open('labels.txt','r') as f:
                exec(f.read())
        if not labels:
            print("no labels.txt")
            img = image.Image(size=(320, 240))
            img.draw_string(90, 110, "no labels.txt", color=(255, 0, 0), scale=2)
            lcd.display(img)
            return 1
        try:
            img = image.Image("startup.jpg")
            lcd.display(img)
        except Exception:
            img = image.Image(size=(320, 240))
            img.draw_string(90, 110, "loading model...", color=(255, 255, 255), scale=2)
            lcd.display(img)
    	# 调用串口初始化函数生成串口对象
        uart = init_uart()
        comm = Comm(uart)
    
        try:
            task = None
            task = kpu.load(model_addr)
            kpu.init_yolo2(task, 0.5, 0.3, 5, anchors) # threshold:[0,1], nms_value: [0, 1]
            # 循环检测摄像头捕获到的数据
            while(True):
                img = sensor.snapshot()
                t = time.ticks_ms()
                objects = kpu.run_yolo2(task, img)
                t = time.ticks_ms() - t
                # 如果检测到有口罩
                if objects:
                    for obj in objects:
                        pos = obj.rect()
                        img.draw_rectangle(pos)
                        img.draw_string(pos[0], pos[1], "%s : %.2f" %(labels[obj.classid()], obj.value()), scale=2, color=(255, 0, 0))
                    # 避免重复发送过多消息
                    if (flag):
                        comm.send_detect_result(objects, labels)
                        flag = False
                    led1.value(0)
                # 如果没有检测到口罩
                else:
                    led1.value(1)
                # 在图片左上角绘制字符串
                img.draw_string(0, 2, "Hao_XL JinShan", scale=1.2, color=(255, 0, 0))
                lcd.display(img)
        except Exception as e:
            raise e
        finally:
            if not task is None:
                kpu.deinit(task)
    
    
    if __name__ == "__main__":
        try:
            flag = True
            # 修改4:修改模型的地址为0x3000000
            main(anchors = anchors, labels=labels, model_addr=0x300000, lcd_rotation=2)
        except Exception as e:
            sys.print_exception(e)
            lcd_show_except(e)
        finally:
            gc.collect()
    
    
  7. 经过前面的这些步骤,已经可以实现K210口罩目标检测,可在pin35口,连接一个LED灯,低电平触发。当检测到口罩时候,该LED灯会亮。

蓝牙配置

  • 接下来的步骤是实现将识别到口罩的标签和概率通过蓝牙模块,发送到手机上显示。

  • 先用usb to ttl,连接蓝牙模块和电脑。(注意:接线的时候,TX接RX,RX接TX,GND一定要记得接)

  • 打开ATK-BLE软件,这是一个用AT指令配置蓝牙的上位机软件,具体步骤,如下图所示:

  1. 点击左上角,选择好串口号。

  2. 点击扫描波特率,注意观察右边窗口打印出的信息,显示连接成功才能继续后续的设置操作。(注意:连接不成功再认真检查接线,重新打开软件)

  3. 点击查询参数,将目前蓝牙的配置参数显示在上位机中。

  4. 将波特率设置为9600(可以设置为其他值,不过要注意统一接收方和发送方的值),然后点击下方的设置。

  5. 点击透传模式,开启透传。

  6. 可以自己更改蓝牙名称,设置一些其他的参数等。
    在这里插入图片描述

  7. 配置好后,将蓝牙模块的RX,TX分别接在K210的pin9,pin10口(这两个口我们已经在代码中配置为串口的TX,RX接收口),然后连接GND,VCC给蓝牙模块供电。

结语

  • 通过以上的操作,可以实现一个简单的口罩目标检测项目,可以结合自身经验,对该项目进行一些创新。

  • 推荐跟着官方介绍文档中的入门指南入门该开发板,maxi bit,该文档内容详尽,而且该开发板相比于stm32,操作简单,功能强大,可以快速实现深度学习项目落地。

在这里插入图片描述


  • 在文末,我非常感谢宋老师的数字化医疗硬件课程,通过该课程让我学到了一种快速落地深度学习项目的方法。

  • 对该文档中的内容有任何疑问,欢迎通过如下联系方式进行学习交流:

  • 邮箱:xl667766lx@gmail.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值