|
本帖最后由 正点原子 于 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当中,如下代码所示。
- 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 颜色识别效果图 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|