ITPub博客

首页 > 嵌入式/内核开发 > 嵌入式/内核开发 > 《ESP32-S3使用指南—MicroPython版 V1.0》第三十七章 AI实验

《ESP32-S3使用指南—MicroPython版 V1.0》第三十七章 AI实验

原创 嵌入式/内核开发 作者:正点原子 时间:2024-11-26 09:28:28 0 删除 编辑

第三十七章 AI实验


       到了这里,作者不得不感慨,市面上的MicroPython教程和例程虽然众多,但它们大多并未公开相关的技术,例如编译和匹配MicroPython固件、如何编写MicroPython的C模块以及乐鑫AI库的移植等。这些领域的知识对于我们来说是相当重要的缺失。为了帮助读者填补这些知识空白,作者决定将这些知识分享给各位,希望读者在ESP32这条学习道路上能够走得更远、收获更多。本章,作者把乐鑫官方提供的AI库移植到MicroPython固件当中,使得开发者调用API接口完成人脸识别、人脸检测、猫脸检测、颜色识别等相关AI实验。

       37.1 AI C模块解析

       37.2 硬件设计

       37.3 软件设计

       37.4 下载验证


        37.1 AI C模块解析

       关于乐鑫ESP-WHO AI库移植到MicroPython固件流程,作者已经在本书籍的第七章7.4小节讲解过了,这里,作者无需重复讲述。下面我们来看一下人脸识别、人脸检测、二维码识别等例程C模块文件,如下图所示。


图37.1.1 AI C模块文件


       上图中,.cpp文件用于实现AI检测或识别功能的案例,它们都是参考乐鑫官方提供的IDF版的AI示例改编过来的(有关原理,请读者参考IDF版的AI例程)。实际上,就是调用乐鑫AI库的API函数,对摄像头图像进行操作,最后返回处理过的图像,这一帧图像会在显示屏上显示。esp_config.c/.h文件是用来管理这些AI例程,并且把这些例程登记到MicroPython当中,以便MicroPython调用。作者还定义了lcd.c/.h文件,主要用来区别是否使用AI库。前面作者也讲解过,本书籍会提供两种固件,它们唯一的区别是否支持AI调用。至于.camke和.mk文件,作者已经在前面的章节有讲解。

       下面作者讲解一下esp_config.c文件,此文件是将.cpp函数登记到MicroPython当中,如下代码所示。

QueueHandle_t xQueueAIFrameO;
 
int ai_flag;
/* 开始AI例程 */
STATIC mp_obj_t mp_py_ai_strat(mp_obj_t flag)
{
    ai_flag = mp_obj_get_int(flag);
    /* 人脸检测 */
    if (ai_flag == FACE_DETECTION)
    {
        esp_face_detection_ai_strat();
    }
    /* 人脸识别 */
    else if (ai_flag == FACE_RECONGNITION)
    {
        esp_face_recognition_ai_strat();
    }
    /* 二维码识别 */
    else if (ai_flag == QR_RECONGNITION)
    {
        esp_qr_detection_ai_strat();
    }
    /* 颜色识别 */
    else if (ai_flag == COLOR_RECONGNITION)
    {
        esp_color_detection_ai_strat();
    }
    /* 猫脸识别 */
    else if (ai_flag == CAT_DETECTION)
    {
        esp_cat_face_detection_ai_strat();
    }
    
    return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(ai_strat, mp_py_ai_strat);
 
/* 卸载AI,实际上就是释放内存 */
STATIC mp_obj_t mp_py_ai_deinit(mp_obj_t flag)
{
    if (ai_flag == FACE_DETECTION)
    {
        esp_face_detection_ai_deinit();
    }
    else if (ai_flag == FACE_RECONGNITION)
    {
        esp_face_recognition_ai_deinit();
    }
    else if (ai_flag == QR_RECONGNITION)
    {
        esp_qr_detection_ai_deinit();
    }
    else if (ai_flag == COLOR_RECONGNITION)
    {
        esp_color_detection_ai_deinit();
    }
    else if (ai_flag == CAT_DETECTION)
    {
        esp_cat_face_detection_ai_deinit();
    }
    
    return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(ai_deinit, mp_py_ai_deinit);
 
STATIC const mp_rom_map_elem_t mp_module_ai_globals_table[] = {
    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp_who) },
    { MP_ROM_QSTR(MP_QSTR_ai_detection_strat), MP_ROM_PTR(&ai_strat) },
    { MP_ROM_QSTR(MP_QSTR_ai_detection_deinit), MP_ROM_PTR(&ai_deinit) },
    { MP_ROM_QSTR(MP_QSTR_FACE_DETECTION), MP_ROM_INT(FACE_DETECTION) },
    { MP_ROM_QSTR(MP_QSTR_FACE_RECONGNITION), MP_ROM_INT(FACE_RECONGNITION) },
    { MP_ROM_QSTR(MP_QSTR_QR_RECONGNITION), MP_ROM_INT(QR_RECONGNITION) },
    { MP_ROM_QSTR(MP_QSTR_COLOR_RECONGNITION), MP_ROM_INT(COLOR_RECONGNITION) },
    { MP_ROM_QSTR(MP_QSTR_CAT_DETECTION), MP_ROM_INT(CAT_DETECTION) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_ai_globals, mp_module_ai_globals_table);
 
 
const mp_obj_module_t mp_module_ai = {
    .base = { &mp_type_module },
    .globals = (mp_obj_dict_t *)&mp_module_ai_globals,
};
 
MP_REGISTER_MODULE(MP_QSTR_esp_who, mp_module_ai);

       从上述源码可以看出,这个C模块实现方式是模块扩展,利用模块.函数名的形式调用ai_detection_strat函数、ai_detection_deinit函数和相关宏定义。从ai_detection_strat函数可以看出,当我们传入不同的参数时,系统会相对应地执行哪个AI例程,而ai_detection_deinit函数用来删除例程所需的内存。剩下的代码在之前的章节有讲述过,望读者参考第七章节的内容。


        37.2 硬件设计


       1. 例程功能

       本章实验功能简介:根据esp_who.ai_detection_strat函数传入的参数不同,来执行相应的操作。如果传入的参数为esp_who.FACE_DETECTION,则系统执行人脸检测示例;如果传入的参数为esp_who.FACE_RECOGNITION,则系统执行人脸识别示例;如果传入的参数为esp_who.CAT_DETECTION,则系统执行猫脸检测示例;如果传入的参数为esp_who.QR_RECOGNITION,则系统执行二维码识别示例;如果传入的参数为esp_who.COLOR_RECOGNITION,则系统执行颜色检测示例。


       2. 硬件资源


       1)XL9555

              IIC_INT-IO0(需在P5连接IO0)

              IIC_SDA-IO41

              IIC_SCL-IO42


       2)SPILCD

              CS-IO21

              SCK-IO12

              SDA-IO11

              DC-IO40(在P5端口,使用跳线帽将IO_SET和LCD_DC相连)

              PWR- IO1_3(XL9555)

              RST- IO1_2(XL9555)


       3)CAMERA

              OV_SCL-IO38

              OV_SDA- IO39

              VSYNC- IO47

              HREF- IO48

              PCLK- IO45

              D0- IO4

              D1- IO5

              D2- IO6

              D3- IO7

              D4- IO15

              D5- IO16

              D6- IO17

              D7- IO18

              RESET-IO0_5(XL9555)

              PWDN-IO0_4(XL9555)


       3. 原理图

       本章实验使用的KPU为ESP32-S3的片上资源,因此并没有相应的连接原理图。


        37.3 软件设计


       37.3.1 程序流程图

       程序流程图能帮助我们更好的理解一个工程的功能和实现的过程,对学习和设计工程有很好的主导作用。下面看看本实验的程序流程图。


图37.3.1.1 程序流程图


       37.3.2 程序解析

       本书籍的代码都在main.py脚本下编写的,读者可在光盘资料下找到对应的源码。AI实验main.py源码如下:

import time
import camera
import esp_who
import atk_xl9555 as io_ex
import atk_lcd as lcd
from machine import Pin,SPI,I2C
 
 
if __name__ == '__main__':
    # IIC初始化
    i2c0 = I2C(0, scl = Pin(42), sda = Pin(41), freq = 400000)
    # XL9555初始化
    xl9555 = io_ex.init(i2c0)
    # 复位摄像头
    xl9555.write_bit(io_ex.OV_RESET,0)
    time.sleep_ms(100)
    xl9555.write_bit(io_ex.OV_RESET,1)
    time.sleep_ms(100)
    # 开启摄像头
    xl9555.write_bit(io_ex.OV_PWDN,1)
    time.sleep_ms(100)
    xl9555.write_bit(io_ex.OV_PWDN,0)
    time.sleep_ms(100)
    # 给复位留时间
    time.sleep_ms(1000)
    # 初始化摄像头
    for i in range(5):
        cam = camera.init(0, format=camera.RGB565, fb_location=camera.PSRAM,
framesize = camera.FRAME_240X240,xclk_freq = 24000000)
        print("Camera ready?: ", cam)
        if cam:
            print("Camera ready")
            break
        else:
            camera.deinit()
            camera.init(0, format=camera.RGB565, fb_location=camera.PSRAM,
framesize = camera.FRAME_240X240,xclk_freq = 24000000)
            time.sleep(2)
    else:
        print('Timeout')
        reset()
    # 复位LCD
    xl9555.write_bit(io_ex.SLCD_RST,0)
    time.sleep_ms(100)
    xl9555.write_bit(io_ex.SLCD_RST,1)
    time.sleep_ms(100)
    # 初始化SPI
    spi = SPI(2,baudrate = 80000000, sck = Pin(12), mosi=Pin(11), miso=Pin(13))
    # 初始化LCD
display = lcd.init(spi,dc = Pin(40,Pin.OUT,Pin.PULL_UP,value = 1),
cs=Pin(21,Pin.OUT,Pin.PULL_UP,value = 1),dir = 1,lcd = 0)
    # 打开背光
    xl9555.write_bit(io_ex.SLCD_PWR,1)
    time.sleep_ms(100)
    display.clear(lcd.BLACK)
    # 其他设置:
    # 上翻下翻(OV5640必须要上下翻,而OV2640无需上下翻)
    camera.flip(1)
    #左/右
    camera.mirror(1)
    # 特效
    camera.speffect(camera.EFFECT_NONE)
    # 饱和
    camera.saturation(0)
    #-2,2(默认为0). -2灰度
    # -2,2 (default 0). -2 grayscale
    # 亮度
    camera.brightness(0)
    #-2,2(默认为0). 2亮度
    # -2,2 (default 0). 2 brightness
    # 对比度
    camera.contrast(0)
    #-2,2(默认为0).2高对比度
    #-2,2 (default 0). 2 highcontrast
    # 质量
    camera.quality(10)
    # 开启颜色识别
    esp_who.ai_detection_strat(esp_who.COLOR_RECONGNITION)
    # 显示检测结果
    display.ai_identify_camerashow(42,0)
    # display.ai_identify_camerashow(0,42)

       从上述源码可以看到,作者经过一系列初始化和配置之后,调用esp_who模块的ai_detection_strat函数执行相应的AI例程。开发者可根据传入的参数来区分AI例程。最终,调用display.ai_identify_camerashow函数把AI处理后的图像显示在LCD显示屏上。


        37.4 下载验证


       1,当esp_who.ai_detection_strat函数传入参数esp_who.FACE_DETECTION时,系统会运行人脸检测示例。如果在检测过程中发现人脸,该系统会将此帧的图像数据发送给人脸检测API进行处理。处理成功后,此帧的图像将被显示在LCD上,如下图所示。


图37.4.1 人脸检测效果图


       2,当esp_who.ai_detection_strat函数传入参数esp_who.FACE_RECONGNITION时,系统会运行人脸识别示例。如果在检测过程中发现人脸,需要长按BOOT按键,将人脸信息录入人脸存储区。当再次检测到人脸时,只需短按BOOT按键,系统就会识别当前的人脸(与存储区的人脸数据进行匹配)。如果识别成功,该系统会将人脸识别处理的图像数据显示在LCD上,否则,提示人脸识别失败,如下图所示。


图37.4.2 人脸识别效果图


       另外,我可以双击BOOT按键删除当前识别的人脸,但前提是当前的人脸与人脸存储区有匹配的图像才能删除人脸数据。


       3,当esp_who.ai_detection_strat函数传入参数esp_who.CAT_DETECTION时,系统会运行猫脸检测示例。如果在检测过程中发现猫脸,该系统会将此帧的图像数据发送给猫脸检测API进行处理。处理成功后,此帧的图像将被显示在LCD上,如下图所示。


图37.4.3 猫脸检测效果图


       4,当esp_who.ai_detection_strat函数传入参数esp_who.QR_RECONGNITION时,系统会运行二维码检测示例。如果在检测过程中发现二维码,该系统会对当前二维码进行解码,并把解码数据以串口形式输出。另外,当检测二维码时,图像左上角显示蓝色矩形弹出,如下图所示。


图37.4.4 二维码识别效果图


       5,当esp_who.ai_detection_strat函数传入参数esp_who.COLOR_RECONGNITION时,系统会运行颜色识别示例。如果在检测过程中发现比较明显的颜色物体,该系统会将此帧的图像数据发送给颜色识别API进行处理。处理成功后,此帧的图像将被显示在LCD上,如下图所示。


图37.4.5 颜色识别效果图


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70040860/viewspace-3051169/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2024-08-30

  • 博文量
    588
  • 访问量
    764481