搜索
bottom↓
回复: 0
打印 上一主题 下一主题

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

[复制链接]

出0入234汤圆

跳转到指定楼层
1
发表于 2024-9-2 16:44:54 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 正点原子 于 2024-9-2 16:44 编辑


1)实验平台:正点原子ESP32S3开发板
2)购买链接:https://detail.tmall.com/item.htm?id=768499342659
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-347618-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子手把手教你学ESP32S3快速入门视频教程:https://www.bilibili.com/video/BV1sH4y1W7Tc
6)正点原子FPGA交流群:132780729



第三十七章 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当中,如下代码所示。
  1. QueueHandle_t xQueueAIFrameO;

  2. int ai_flag;
  3. /* 开始AI例程 */
  4. STATIC mp_obj_t mp_py_ai_strat(mp_obj_t flag)
  5. {
  6.     ai_flag = mp_obj_get_int(flag);
  7.     /* 人脸检测 */
  8.     if (ai_flag == FACE_DETECTION)
  9.     {
  10.         esp_face_detection_ai_strat();
  11.     }
  12.     /* 人脸识别 */
  13.     else if (ai_flag == FACE_RECONGNITION)
  14.     {
  15.         esp_face_recognition_ai_strat();
  16.     }
  17.     /* 二维码识别 */
  18.     else if (ai_flag == QR_RECONGNITION)
  19.     {
  20.         esp_qr_detection_ai_strat();
  21.     }
  22.     /* 颜色识别 */
  23.     else if (ai_flag == COLOR_RECONGNITION)
  24.     {
  25.         esp_color_detection_ai_strat();
  26.     }
  27.     /* 猫脸识别 */
  28.     else if (ai_flag == CAT_DETECTION)
  29.     {
  30.         esp_cat_face_detection_ai_strat();
  31.     }
  32.    
  33.     return mp_const_none;
  34. }
  35. STATIC MP_DEFINE_CONST_FUN_OBJ_1(ai_strat, mp_py_ai_strat);

  36. /* 卸载AI,实际上就是释放内存 */
  37. STATIC mp_obj_t mp_py_ai_deinit(mp_obj_t flag)
  38. {
  39.     if (ai_flag == FACE_DETECTION)
  40.     {
  41.         esp_face_detection_ai_deinit();
  42.     }
  43.     else if (ai_flag == FACE_RECONGNITION)
  44.     {
  45.         esp_face_recognition_ai_deinit();
  46.     }
  47.     else if (ai_flag == QR_RECONGNITION)
  48.     {
  49.         esp_qr_detection_ai_deinit();
  50.     }
  51.     else if (ai_flag == COLOR_RECONGNITION)
  52.     {
  53.         esp_color_detection_ai_deinit();
  54.     }
  55.     else if (ai_flag == CAT_DETECTION)
  56.     {
  57.         esp_cat_face_detection_ai_deinit();
  58.     }
  59.    
  60.     return mp_const_none;
  61. }
  62. STATIC MP_DEFINE_CONST_FUN_OBJ_0(ai_deinit, mp_py_ai_deinit);

  63. STATIC const mp_rom_map_elem_t mp_module_ai_globals_table[] = {
  64.     { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp_who) },
  65.     { MP_ROM_QSTR(MP_QSTR_ai_detection_strat), MP_ROM_PTR(&ai_strat) },
  66.     { MP_ROM_QSTR(MP_QSTR_ai_detection_deinit), MP_ROM_PTR(&ai_deinit) },
  67.     { MP_ROM_QSTR(MP_QSTR_FACE_DETECTION), MP_ROM_INT(FACE_DETECTION) },
  68.     { MP_ROM_QSTR(MP_QSTR_FACE_RECONGNITION), MP_ROM_INT(FACE_RECONGNITION) },
  69.     { MP_ROM_QSTR(MP_QSTR_QR_RECONGNITION), MP_ROM_INT(QR_RECONGNITION) },
  70.     { MP_ROM_QSTR(MP_QSTR_COLOR_RECONGNITION), MP_ROM_INT(COLOR_RECONGNITION) },
  71.     { MP_ROM_QSTR(MP_QSTR_CAT_DETECTION), MP_ROM_INT(CAT_DETECTION) },
  72. };
  73. STATIC MP_DEFINE_CONST_DICT(mp_module_ai_globals, mp_module_ai_globals_table);


  74. const mp_obj_module_t mp_module_ai = {
  75.     .base = { &mp_type_module },
  76.     .globals = (mp_obj_dict_t *)&mp_module_ai_globals,
  77. };

  78. 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源码如下:
  1. import time
  2. import camera
  3. import esp_who
  4. import atk_xl9555 as io_ex
  5. import atk_lcd as lcd
  6. from machine import Pin,SPI,I2C


  7. if __name__ == '__main__':
  8.     # IIC初始化
  9.     i2c0 = I2C(0, scl = Pin(42), sda = Pin(41), freq = 400000)
  10.     # XL9555初始化
  11.     xl9555 = io_ex.init(i2c0)
  12.     # 复位摄像头
  13.     xl9555.write_bit(io_ex.OV_RESET,0)
  14.     time.sleep_ms(100)
  15.     xl9555.write_bit(io_ex.OV_RESET,1)
  16.     time.sleep_ms(100)
  17.     # 开启摄像头
  18.     xl9555.write_bit(io_ex.OV_PWDN,1)
  19.     time.sleep_ms(100)
  20.     xl9555.write_bit(io_ex.OV_PWDN,0)
  21.     time.sleep_ms(100)
  22.     # 给复位留时间
  23.     time.sleep_ms(1000)
  24.     # 初始化摄像头
  25.     for i in range(5):
  26.         cam = camera.init(0, format=camera.RGB565, fb_location=camera.PSRAM,
  27. framesize = camera.FRAME_240X240,xclk_freq = 24000000)
  28.         print("Camera ready?: ", cam)
  29.         if cam:
  30.             print("Camera ready")
  31.             break
  32.         else:
  33.             camera.deinit()
  34.             camera.init(0, format=camera.RGB565, fb_location=camera.PSRAM,
  35. framesize = camera.FRAME_240X240,xclk_freq = 24000000)
  36.             time.sleep(2)
  37.     else:
  38.         print('Timeout')
  39.         reset()
  40.     # 复位LCD
  41.     xl9555.write_bit(io_ex.SLCD_RST,0)
  42.     time.sleep_ms(100)
  43.     xl9555.write_bit(io_ex.SLCD_RST,1)
  44.     time.sleep_ms(100)
  45.     # 初始化SPI
  46.     spi = SPI(2,baudrate = 80000000, sck = Pin(12), mosi=Pin(11), miso=Pin(13))
  47.     # 初始化LCD
  48. display = lcd.init(spi,dc = Pin(40,Pin.OUT,Pin.PULL_UP,value = 1),
  49. cs=Pin(21,Pin.OUT,Pin.PULL_UP,value = 1),dir = 1,lcd = 0)
  50.     # 打开背光
  51.     xl9555.write_bit(io_ex.SLCD_PWR,1)
  52.     time.sleep_ms(100)
  53.     display.clear(lcd.BLACK)
  54.     # 其他设置:
  55.     # 上翻下翻(OV5640必须要上下翻,而OV2640无需上下翻)
  56.     camera.flip(1)
  57.     #左/右
  58.     camera.mirror(1)
  59.     # 特效
  60.     camera.speffect(camera.EFFECT_NONE)
  61.     # 饱和
  62.     camera.saturation(0)
  63.     #-2,2(默认为0). -2灰度
  64.     # -2,2 (default 0). -2 grayscale
  65.     # 亮度
  66.     camera.brightness(0)
  67.     #-2,2(默认为0). 2亮度
  68.     # -2,2 (default 0). 2 brightness
  69.     # 对比度
  70.     camera.contrast(0)
  71.     #-2,2(默认为0).2高对比度
  72.     #-2,2 (default 0). 2 highcontrast
  73.     # 质量
  74.     camera.quality(10)
  75.     # 开启颜色识别
  76.     esp_who.ai_detection_strat(esp_who.COLOR_RECONGNITION)
  77.     # 显示检测结果
  78.     display.ai_identify_camerashow(42,0)
  79.     # 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 颜色识别效果图

阿莫论坛20周年了!感谢大家的支持与爱护!!

阿莫论坛才是最爱国的,关心国家的经济、社会的发展、担心国家被别国牵连卷入战争、知道珍惜来之不易的和平发展,知道师夷之长,关注世界的先进文化与技术,也探讨中国文化的博大精深,也懂得警惕民粹主义的祸国殃民等等等等,无不是爱国忧民的表现。(坛友:tianxian)
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-9-17 14:12

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表