• 【毕业设计】stm32机器视觉的口罩佩戴检测系统 - 单片机 物联网 嵌入式



    0 前言

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

    为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

    🚩 基于stm32与机器视觉的口罩佩戴检测系统

    🥇学长这里给一个题目综合评分(每项满分5分)

    • 难度系数:3分
    • 工作量:5分
    • 创新点:3分

    🧿 选题指导, 项目分享:

    https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md


    1 简介

    2 主要器件

    • STM32F103C8T6
    • K210 AI模块
    • OV5642摄像头
    • MLX90614非接触测温传感器
    • 蜂鸣器模块

    3 实现效果

    不佩戴口罩时在这里插入图片描述
    佩戴口罩时
    在这里插入图片描述

    温度测量
    手指放到传感器模块后会测量温度,超过设定的温度阈值后,蜂鸣器会报警。
    在这里插入图片描述

    4 设计原理

    测温部分
    主要由STM32F103C8T6 + MLX90614测温模块实现。

    MLX90614 是一款红外非接触温度计。TO-39 金属封装里同时集成了红外感应热电堆探测器芯片和信号处理专用集成芯片。由于集成了低噪声放大器、17 位模数转换器和强大的数字信号处理单元,使得高精度和高分辨度的温度计得以实现。温度计具备出厂校准化,有数字 PWM 和 SMBus(系统管理总线)输出模式。作为标准,配置为 10 位的 PWM 输出格式用于连续传送温度范围为-20…120 ˚C 的物体温度,其分辨率为 0.14 ˚C。POR默认模式是SMBus输出格式 。

    MLX90614器件图
    在这里插入图片描述

    串口温度测试
    在这里插入图片描述

    STM32单片机采集代码

    void SMBus_StartBit(void)
    {
        SMBUS_SDA_H();		// Set SDA line
        SMBus_Delay(5);	    // Wait a few microseconds
        SMBUS_SCK_H();		// Set SCL line
        SMBus_Delay(5);	    // Generate bus free time between Stop
        SMBUS_SDA_L();		// Clear SDA line
        SMBus_Delay(5);	    // Hold time after (Repeated) Start
        // Condition. After this period, the first clock is generated.
        //(Thd:sta=4.0us min)
        SMBUS_SCK_L();	    // Clear SCL line
        SMBus_Delay(5);	    // Wait a few microseconds
    }
    
    void SMBus_StopBit(void)
    {
        SMBUS_SCK_L();		// Clear SCL line
        SMBus_Delay(5);	    // Wait a few microseconds
        SMBUS_SDA_L();		// Clear SDA line
        SMBus_Delay(5);	    // Wait a few microseconds
        SMBUS_SCK_H();		// Set SCL line
        SMBus_Delay(5);	    // Stop condition setup time(Tsu:sto=4.0us min)
        SMBUS_SDA_H();		// Set SDA line
    }
    
    u8 SMBus_SendByte(u8 Tx_buffer)
    {
        u8	Bit_counter;
        u8	Ack_bit;
        u8	bit_out;
    
        for(Bit_counter=8; Bit_counter; Bit_counter--)
        {
            if (Tx_buffer&0x80)
            {
                bit_out=1;   // If the current bit of Tx_buffer is 1 set bit_out
            }
            else
            {
                bit_out=0;  // else clear bit_out
            }
            SMBus_SendBit(bit_out);		// Send the current bit on SDA
            Tx_buffer<<=1;				// Get next bit for checking
        }
    
        Ack_bit=SMBus_ReceiveBit();		// Get acknowledgment bit
        return	Ack_bit;
    }
    
    void SMBus_SendBit(u8 bit_out)
    {
        if(bit_out==0)
        {
            SMBUS_SDA_L();
        }
        else
        {
            SMBUS_SDA_H();
        }
        SMBus_Delay(2);					// Tsu:dat = 250ns minimum
        SMBUS_SCK_H();					// Set SCL line
        SMBus_Delay(6);					// High Level of Clock Pulse
        SMBUS_SCK_L();					// Clear SCL line
        SMBus_Delay(3);					// Low Level of Clock Pulse
    //	SMBUS_SDA_H();				    // Master release SDA line ,
        return;
    }
    
    u8 SMBus_ReceiveBit(void)
    {
        u8 Ack_bit;
    
        SMBUS_SDA_H();          //引脚靠外部电阻上拉,当作输入
    	SMBus_Delay(2);			// High Level of Clock Pulse
        SMBUS_SCK_H();			// Set SCL line
        SMBus_Delay(5);			// High Level of Clock Pulse
        if (SMBUS_SDA_PIN())
        {
            Ack_bit=1;
        }
        else
        {
            Ack_bit=0;
        }
        SMBUS_SCK_L();			// Clear SCL line
        SMBus_Delay(3);			// Low Level of Clock Pulse
    
        return	Ack_bit;
    }
    
    u8 SMBus_ReceiveByte(u8 ack_nack)
    {
        u8 	RX_buffer;
        u8	Bit_Counter;
    
        for(Bit_Counter=8; Bit_Counter; Bit_Counter--)
        {
            if(SMBus_ReceiveBit())			// Get a bit from the SDA line
            {
                RX_buffer <<= 1;			// If the bit is HIGH save 1  in RX_buffer
                RX_buffer |=0x01;
            }
            else
            {
                RX_buffer <<= 1;			// If the bit is LOW save 0 in RX_buffer
                RX_buffer &=0xfe;
            }
        }
        SMBus_SendBit(ack_nack);			// Sends acknowledgment bit
        return RX_buffer;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112

    K210视觉开发部分
    首先,我们需要在spieed官网上下载MaixpyIDE,想编代码总是要磨其器的,由于Sipeed Maix Bit是没有c环境的,所以我使用mcriopyhton来编程;

    将IDE搭建只是第一步,还需要能跑mcriopyhton的固件,在sipeed官网的下载站里面找到最新的固件支持包(最好是最新的固件包)找到下载站后,直接点击第一个,然后会发现有很多的固件,究竟选哪一个呢?。会点英语的其实不难读懂,带minimum就是轻量级的意思,而带kmodel的就是支持模型放入的意思,当然我还需要支持ide的,所以选择maixpy_v0.6.2_83_gf0280db50_openmv_kmodel_v4_with_ide_support即可。

    同时项目所需要的文件有:模型文件,程序运行的脚本文件,ide需要的bin文件。

    烧录
    下载好后,接下来实现的就是固件烧录,我们需要准备一个软件kflash_gui,是专门用来烧录固件的,在sipeed官网会提供一个GitHub网址,里面不仅有该软件,还有大伙所需要的例程,在例程中可以找到已经训练好的人脸模型。如下图,按照这样配置即可,连接好板子就可以烧录了。
    在这里插入图片描述
    终于,现在就可以点击ide打开了,这就是ide的界面,点左下角的连接板子,就可以愉快的跑程序了。
    在这里插入图片描述

    5 部分核心代码

    K210部分代码

    import sensor,lcd,time
    import KPU as kpu
    
    from Maix import GPIO
    from fpioa_manager import fm
    
    fm.register(10, fm.fpioa.GPIO0)
    LCD_BL = GPIO(GPIO.GPIO0, GPIO.OUT)
    LCD_BL.value(1)
    
    
    sensor.reset()
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    sensor.set_vflip(1)
    
    lcd.init()
    lcd.rotation(0)
    
    clock = time.clock()
    
    task = kpu.load("/sd/facedetect.kmodel")
    
    anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025)
    
    a = kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)
    
    while(True):
        clock.tick()
        img = sensor.snapshot()
        code = kpu.run_yolo2(task, img)
    
        if code:
            for i in code:
                print(i)
                b = img.draw_rectangle(i.rect())
    
        lcd.display(img)
    
        print(clock.fps())
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    6 最后

  • 相关阅读:
    【无标题】esp8266替代产品
    mfc 疑难杂症之一
    苹果电脑如何优化MAC系统内存?怎么清理系统垃圾?
    重学Android基础系列篇(三):架构动态编程技术原理
    【零基础学Python】Day3 Python基本数据类型之Number
    Scala的函数式编程与高阶函数,匿名函数,偏函数,函数的闭包、柯里化,抽象控制,懒加载等
    java基础-集合
    SpringBoot整合shiro-spring-boot-starterqi
    软考高级及杭州E类人才申请经验分享
    如何判断mysql innodb buffer pool内存配置不足
  • 原文地址:https://blog.csdn.net/m0_71572576/article/details/126343069