【雕爷学编程】MicroPython手册之 OpenMV Cam 人脸识别

在这里插入图片描述
MicroPython是为了在嵌入式系统中运行Python 3编程语言而设计的轻量级版本解释器。与常规Python相比,MicroPython解释器体积小(仅100KB左右),通过编译成二进制Executable文件运行,执行效率较高。它使用了轻量级的垃圾回收机制并移除了大部分Python标准库,以适应资源限制的微控制器。

MicroPython主要特点包括:
1、语法和功能与标准Python兼容,易学易用。支持Python大多数核心语法。
2、对硬件直接访问和控制,像Arduino一样控制GPIO、I2C、SPI等。
3、强大的模块系统,提供文件系统、网络、图形界面等功能。
4、支持交叉编译生成高效的原生代码,速度比解释器快10-100倍。
5、代码量少,内存占用小,适合运行在MCU和内存小的开发板上。
6、开源许可,免费使用。Shell交互环境为开发测试提供便利。
7、内置I/O驱动支持大量微控制器平台,如ESP8266、ESP32、STM32、micro:bit、掌控板和PyBoard等。有活跃的社区。

MicroPython的应用场景包括:
1、为嵌入式产品快速构建原型和用户交互。
2、制作一些小型的可 programmable 硬件项目。
3、作为教育工具,帮助初学者学习Python和物联网编程。
4、构建智能设备固件,实现高级控制和云连接。
5、各种微控制器应用如物联网、嵌入式智能、机器人等。

使用MicroPython需要注意:
1、内存和Flash空间有限。
2、解释执行效率不如C语言。
3、部分库函数与标准版有差异。
4、针对平台优化语法,订正与标准Python的差异。
5、合理使用内存资源,避免频繁分配大内存块。
6、利用原生代码提升速度关键部位的性能。
7、适当使用抽象来封装底层硬件操作。

总体来说,MicroPython让Python进入了微控制器领域,是一项重要的创新,既降低了编程门槛,又提供了良好的硬件控制能力。非常适合各类物联网和智能硬件的开发。
在这里插入图片描述
OpenMV Cam 是一款小型、低功耗的微控制器板,可以让你在现实世界中使用机器视觉轻松实现应用程序。你可以使用高级 Python 脚本(由 MicroPython 操作系统提供)而不是 C/C++ 对 OpenMV Cam 进行编程。OpenMV Cam 的技术参数包括以下几个方面:

1、处理器:OpenMV Cam H7 Plus 使用 STM32H743II ARM Cortex M7 处理器,运行频率为 480 MHz,具有 32MB SDRAM + 1MB SRAM 和 32 MB 外部闪存 + 2 MB 内部闪存。OpenMV Cam M4 V2 使用 STM32F427VG ARM Cortex M4 处理器,运行频率为 180 MHz,具有 256KB RAM 和 1 MB 闪存。
2、图像传感器:OpenMV Cam H7 Plus 和 OpenMV Cam M4 V2 都使用 OV7725 图像传感器,能够在分辨率高于 320x240 时以 75 FPS 拍摄 320x240 8 位灰度图像或 320x240 16 位 RGB565 图像,在分辨率低于 320x240 时能够以 150 FPS 拍摄。
3、I/O 接口:OpenMV Cam H7 Plus 和 OpenMV Cam M4 V2 都具有以下 I/O 接口:
(1)全速 USB (12Mbs) 接口,连接到电脑。当插入 OpenMV Cam 后,你的电脑会出现一个虚拟 COM 端口和一个“U盘”。
(2)μSD 卡槽能够进行 100Mbs 读/写,使你的 OpenMV Cam 能够录制视频,并把机器视觉的素材从 μSD 卡提取出来。
(3)SPI 总线的运行速度高达 54Mbs,使你可以简单地把图像流数据传给 LCD 扩展板、WiFi 扩展板,或者其他控制器。
(4)I2C 总线(高达 1Mb/s)、CAN 总线(高达 1Mb/s)和异步串行总线(TX/RX,高达 7.5Mb/s),用于与其他控制器或传感器连接。
(5)一个 12 位 ADC 和一个 12 位 DAC。
(6)所有 I/O 引脚上都有中断和 PWM(板上有 9 或者10个 I/O 引脚)。
4、LED:OpenMV Cam H7 Plus 和 OpenMV Cam M4 V2 都配备了一个 RGB LED(三色)和两个高亮的 850nm IR LED(红外)。
5、镜头:OpenMV Cam H7 Plus 和 OpenMV Cam M4 V2 都配备了标准 M12 镜头接口和一个默认的 2.8 毫米镜头。如果你想在 OpenMV Cam 上使用更专业的镜头,你可以轻松购买并自行安装。

在这里插入图片描述
MicroPython的OpenMV Cam支持人脸识别功能,可以通过编写MicroPython代码来实现对人脸的检测和识别。下面我将详细解释其主要特点、应用场景以及需要注意的事项。

主要特点:

人脸检测:OpenMV Cam的人脸识别功能可以实时检测图像中的人脸。它利用图像处理算法和机器学习技术,对人脸进行检测和定位,从而实现对人脸的识别和跟踪。

人脸特征提取:除了检测人脸外,OpenMV Cam还可以提取人脸的特征信息。通过特征提取,可以将人脸表示为一个数字向量,用于后续的识别、比对和验证等任务。

实时性能:OpenMV Cam具有较高的实时性能,可以实时捕捉图像并进行人脸识别。这使得它适合于需要快速响应和实时处理的应用场景,例如人脸门禁系统、人脸支付等。

简化开发:MicroPython编程语言简单易学,适合初学者和教育领域使用。OpenMV Cam提供了友好的编程接口和示例代码,使得人脸识别的开发和调试变得更加简单和便捷。

应用场景:

人脸门禁系统:人脸识别可以应用于门禁系统,通过识别和验证人脸信息,实现对特定区域或设备的授权和访问控制。例如,只有预先注册的人脸信息匹配成功才能解锁门禁或控制设备。

人脸支付:在支付系统中,人脸识别可以用于身份验证和交易授权。用户可以通过人脸扫描进行身份确认,从而实现无需密码或卡片的支付操作,提高支付的便捷性和安全性。

人脸识别研究和教育:OpenMV Cam的人脸识别功能可以用于教学和科研项目。学生和研究人员可以利用OpenMV Cam进行实验和研究,探索人脸识别算法、人脸表情分析等相关领域的知识。

需要注意的事项:

面部照明和角度:人脸识别对面部照明和角度敏感。为了获得准确的识别结果,需要注意提供充足的光照,并尽量保持面部在摄像头视野范围内的正常角度。

面部遮挡和变化:面部遮挡(如口罩、墨镜)或面部表情的变化(如笑、张嘴)可能会影响识别效果。在实际应用中,需要根据具体场景和需求,选择合适的人脸识别算法和参数配置,以应对面部遮挡和变化带来的挑战。

数据隐私和安全性:人脸识别涉及个人隐私和数据安全问题。在应用人脸识别技术时,需要遵守相关的法律法规和隐私政策,确保个人数据的安全和合法使用。

总结来说,MicroPython的OpenMV Cam的人脸识别功能可以实现对人脸的检测、识别和特征提取,具有较高的实时性能和简化开发特点。它适用于人脸门禁系统、人脸支付以及教育和研究等应用场景。在使用时需要注意面部照明、角度和遮挡等因素,并遵守相关的隐私和安全规定。

案例一:使用OpenMV Cam进行人脸检测

import sensor, image, time
from pyb import Timer, ADC

sensor.reset() # 初始化摄像头
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为RGB565
sensor.set_framesize(sensor.QVGA) # 设置帧大小为320x240
sensor.skip_frames(time = 2000) # 等待设置生效,延时2秒

timer = Timer(period=1, mode=Timer.PERIODIC, callback=lambda t: None) # 创建一个定时器,每1毫秒触发一次回调函数

while True:
    img = sensor.snapshot() # 捕获一帧图像
    faces = img.find_features(image.HaarCascade("haarcascade_frontalface_default.xml")) # 使用Haar级联分类器检测人脸
    for face in faces:
        img.draw_rectangle(face.rect(), color=(255, 0, 0)) # 在图像上绘制矩形框,颜色为红色
    print("Found", len(faces), "faces") # 输出检测到的人脸数量
    time.sleep_ms(100) # 延时100毫秒

解读:这个程序首先导入了sensor、image、time和pyb.Timer、pyb.ADC模块。然后初始化摄像头,设置像素格式为RGB565,帧大小为320x240,并等待设置生效,延时2秒。接着创建一个定时器,每1毫秒触发一次回调函数。在无限循环中,不断捕获摄像头的图像。使用Haar级联分类器检测人脸,并在图像上绘制矩形框。最后输出检测到的人脸数量,并延时100毫秒。

案例二:使用OpenMV Cam进行人脸识别

import sensor, image, time
from pyb import Timer, ADC

sensor.reset() # 初始化摄像头
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为RGB565
sensor.set_framesize(sensor.QVGA) # 设置帧大小为320x240
sensor.skip_frames(time = 2000) # 等待设置生效,延时2秒

timer = Timer(period=1, mode=Timer.PERIODIC, callback=lambda t: None) # 创建一个定时器,每1毫秒触发一次回调函数
face_recognition = Timer(period=1, mode=Timer.PERIODIC, callback=lambda t: None) # 创建一个定时器,每1毫秒触发一次回调函数

face_recognition.start() # 开始人脸识别计时器

while True:
    img = sensor.snapshot() # 捕获一帧图像
    faces = img.find_features(image.HaarCascade("haarcascade_frontalface_default.xml")) # 使用Haar级联分类器检测人脸
    if len(faces) > 0:
        face = faces[0] # 获取第一个检测到的人脸
        x, y, w, h = face.rect() # 获取人脸矩形框的坐标和宽高
        img.draw_rectangle(x, y, w, h, color=(255, 0, 0)) # 在图像上绘制矩形框,颜色为红色
        face_id = face.feature_id() # 获取人脸的特征ID
        if face_id not in known_faces: # 如果特征ID不在已知人脸列表中
            face_recognition.stop() # 停止人脸识别计时器
            known_faces.append(face_id) # 将特征ID添加到已知人脸列表中
            face_recognition.start() # 重新开始人脸识别计时器
    else:
        face_recognition.stop() # 停止人脸识别计时器
        time.sleep_ms(100) # 延时100毫秒
    print("Found", len(known_faces), "known faces") # 输出已知人脸数量
    time.sleep_ms(100) # 延时100毫秒

解读:这个程序与第一个案例类似,只是添加了人脸识别功能。首先导入了sensor、image、time和pyb.Timer、pyb.ADC模块。然后初始化摄像头,设置像素格式为RGB565,帧大小为320x240,并等待设置生效,延时2秒。接着创建一个定时器,每1毫秒触发一次回调函数。在无限循环中,不断捕获摄像头的图像。使用Haar级联分类器检测人脸,并在图像上绘制矩形框。如果检测到人脸,获取其特征ID,并将其添加到已知人脸列表中。然后重新开始人脸识别计时器。最后输出已知人脸数量,并延时100毫秒。

案例三:使用OpenMV Cam进行人脸识别(升级版)

import sensor, image, time
from pyb import Timer, ADC

sensor.reset() # 初始化摄像头
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为RGB565
sensor.set_framesize(sensor.QVGA) # 设置帧大小为320x240
sensor.skip_frames(time = 2000) # 等待设置生效,延时2秒

timer = Timer(period=1, mode=Timer.PERIODIC, callback=lambda t: None) # 创建一个定时器,每1毫秒触发一次回调函数
face_recognition = Timer(period=1, mode=Timer.PERIODIC, callback=lambda t: None) # 创建一个定时器,每1毫秒触发一次回调函数
face_recognition_threshold = 0.6 # 人脸识别阈值

face_recognition.start() # 开始人脸识别计时器

known_faces = [] # 已知人脸列表

while True:
    img = sensor.snapshot() # 捕获一帧图像
    faces = img.find_features(image.HaarCascade("haarcascade_frontalface_default.xml")) # 使用Haar级联分类器检测人脸
    if len(faces) > 0:
        face = faces[0] # 获取第一个检测到的人脸
        x, y, w, h = face.rect() # 获取人脸矩形框的坐标和宽高
        img.draw_rectangle(x, y, w, h, color=(255, 0, 0)) # 在图像上绘制矩形框,颜色为红色
        face_id = face.feature_id() # 获取人脸的特征ID
        if face_id not in known_faces and face_recognition.is_running(): # 如果特征ID不在已知人脸列表中且人脸识别计时器正在运行
            # 计算人脸区域的平均亮度
            face_region = img.crop((x, y, x+w, y+h)) # 截取人脸区域
            avg_brightness = (sum(c for c in face_region.pixels()) / face_region.width * face_region.height) / 255 # 计算平均亮度
            if avg_brightness > face_recognition_threshold: # 如果平均亮度大于阈值
                face_recognition.stop() # 停止人脸识别计时器
                known_faces.append(face_id) # 将特征ID添加到已知人脸列表中
                face_recognition.start() # 重新开始人脸识别计时器
    else:
        face_recognition.stop() # 停止人脸识别计时器
        time.sleep_ms(100) # 延时100毫秒
    print("Found", len(known_faces), "known faces") # 输出已知人脸数量
    time.sleep_ms(100) # 延时100毫秒

解读:这个程序与第二个案例类似,只是添加了人脸识别功能。首先导入了sensor、image、time和pyb.Timer、pyb.ADC模块。然后初始化摄像头,设置像素格式为RGB565,帧大小为320x240,并等待设置生效,延时2秒。接着创建一个定时器,每1毫秒触发一次回调函数。在无限循环中,不断捕获摄像头的图像。使用Haar级联分类器检测人脸,并在图像上绘制矩形框。如果检测到人脸,获取其特征ID,并根据人脸识别阈值判断是否将其添加到已知人脸列表中。然后重新开始人脸识别计时器。最后输出已知人脸数量,并延时100毫秒。

案例四:简单的人脸识别程序

import sensor, image, time  
  
sensor.reset() # 初始化摄像头  
sensor.set_pixformat(sensor.RGB565) # 设置像素格式  
sensor.set_framesize(sensor.QVGA) # 设置帧大小  
sensor.skip_frames(time = 2000) # 等待摄像头稳定  
  
face_cascade = image.HaarCascade('haarcascade_frontalface_default.xml') # 加载人脸级联分类器  
  
while(True):  
    img = sensor.snapshot() # 拍摄照片  
    faces = img.find_haarcascades(face_cascade) # 查找人脸  
    if len(faces) > 0: # 如果找到了人脸  
        print('Face detected') # 打印消息

要点解读:

首先初始化摄像头,设置像素格式和帧大小。
加载人脸级联分类器,这里使用的是OpenCV提供的人脸级联分类器。
在一个无限循环中,拍摄照片并查找人脸。如果找到了人脸,则打印消息。使用find_haarcascades()函数查找人脸。

案例五:在LCD屏幕上显示人脸识别结果

import sensor, image, time, lcd  
  
lcd.init() # 初始化LCD屏幕  
sensor.reset() # 初始化摄像头  
sensor.set_pixformat(sensor.RGB565) # 设置像素格式  
sensor.set_framesize(sensor.QVGA) # 设置帧大小  
sensor.skip_frames(time = 2000) # 等待摄像头稳定  
  
face_cascade = image.HaarCascade('haarcascade_frontalface_default.xml') # 加载人脸级联分类器  
  
while(True):  
    img = sensor.snapshot() # 拍摄照片  
    faces = img.find_haarcascades(face_cascade) # 查找人脸  
    if len(faces) > 0: # 如果找到了人脸  
        lcd.clear() # 清空LCD屏幕  
        for face in faces: # 在LCD屏幕上绘制人脸矩形框  
            lcd.draw_rectangle(face.rect(), lcd.COLOR_RED)

要点解读:
首先初始化LCD屏幕和摄像头,设置像素格式和帧大小。
加载人脸级联分类器,这里使用的是OpenCV提供的人脸级联分类器。
在一个无限循环中,拍摄照片并查找人脸。如果找到了人脸,则清空LCD屏幕并在其上绘制人脸的矩形框。使用draw_rectangle()函数绘制矩形框。

案例六:使用人脸识别控制机器人移动

import sensor, image, time, pyb, machine  
  
motor1 = machine.PWM(pyb.Pin('X1'), freq=100) # 初始化电机1引脚为PWM输出,频率为100Hz  
motor2 = machine.PWM(pyb.Pin('X2'), freq=100) # 初始化电机2引脚为PWM输出,频率为100Hz  
sensor.reset() # 初始化摄像头  
sensor.set_pixformat(sensor.RGB565) # 设置像素格式  
sensor.set_framesize(sensor.QVGA) # 设置帧大小  
sensor.skip_frames(time = 2000) # 等待摄像头稳定  
  
face_cascade = image.HaarCascade('haarcascade_frontalface_default.xml') # 加载人脸级联分类器  
speed = 1000 # 设置电机速度,这里是1000(占空比)  
  
while(True):  
    img = sensor.snapshot() # 拍摄照片  
    faces = img.find_haarcascades(face_cascade) # 查找人脸  
    if len(faces) > 0: # 如果找到了人脸  
        x, y = faces[0].center() # 获取人脸中心坐标  
        if x < img.width() / 2: # 如果人脸在图像左半部分  
            motor1.duty(speed) # 左电机前进  
            motor2.duty(0) # 右电机停止  
        else: # 如果人脸在图像右半部分  
            motor1.duty(0) # 左电机停止  
            motor2.duty(speed) # 右电机前进  
    else: # 如果没有找到人脸  
        motor1.duty(0) # 左电机停止  
        motor2.duty(0) # 右电机停止  
    time.sleep(100) # 延时100ms,以减少CPU的使用率

要点解读:
首先初始化电机引脚为PWM输出,并设置频率为100Hz。初始化摄像头,设置像素格式和帧大小。加载人脸级联分类器,这里使用的是OpenCV提供的人脸级联分类器。设置电机速度,这里是1000(占空比)。
在一个无限循环中,拍摄照片并查找人脸。如果找到了人脸,则根据人脸的位置控制电机前进或停止。如果没有找到人脸,则两个电机都停止。使用duty()函数设置电机的占空比。
使用time.sleep()函数延时100ms,以减少CPU的使用率。

案例七:检测并绘制人脸边界框:

import sensor
import image
import time

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)

face_cascade = image.HaarCascade("frontalface.xml")

while True:
    img = sensor.snapshot()
    faces = img.find_features(face_cascade, threshold=0.5, scale=1.5)
    
    for face in faces:
        img.draw_rectangle(face)
    
    time.sleep(100)

要点解读:
该程序通过OpenMV Cam进行人脸识别,并在检测到人脸时绘制边界框。
使用sensor.reset()重置传感器设置。
设置图像格式、帧大小,并禁用自动增益和自动白平衡。
使用image.HaarCascade(“frontalface.xml”)实例化一个HaarCascade对象,用于人脸检测。需要将"frontalface.xml"文件放置在OpenMV Cam上。
在一个无限循环中,使程序持续执行以下操作:
使用sensor.snapshot()获取图像快照。
使用img.find_features(face_cascade, threshold=0.5, scale=1.5)检测图像中的人脸。可以调整阈值和比例参数以达到更好的人脸检测效果。
针对每个检测到的人脸,使用img.draw_rectangle(face)在图像上绘制矩形边界框。
使用time.sleep(100)延迟100毫秒,以控制处理频率。

案例八:人脸识别并输出识别结果:

import sensor
import image
import time

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)

face_cascade = image.HaarCascade("frontalface.xml")

known_face_image = image.Image("/known_face.jpg")
known_face_descriptor = image.vector_descriptor(known_face_image)

while True:
    img = sensor.snapshot()
    faces = img.find_features(face_cascade, threshold=0.5, scale=1.5)
    
    for face in faces:
        descriptor = img.get_descriptor(face)
        match = image.match_descriptor(known_face_descriptor, descriptor, threshold=85)
        if match:
            print("Recognized face!")
        else:
            print("Unknown face!")
    
    time.sleep(100)

要点解读:
该程序通过OpenMV Cam进行人脸识别,并根据已知人脸图像进行识别结果输出。
使用sensor.reset()重置传感器设置。
设置图像格式、帧大小,并禁用自动增益和自动白平衡。
使用image.HaarCascade(“frontalface.xml”)实例化一个HaarCascade对象,用于人脸检测。需要将"frontalface.xml"文件放置在OpenMV Cam上。
使用image.Image(“/known_face.jpg”)加载已知人脸图像,将其转换为特征描述符。
在一个无限循环中,使程序持续执行以下操作:
使用sensor.snapshot()获取图像快照。
使用img.find_features(face_cascade, threshold=0.5, scale=1.5)检测图像中的人脸。
针对每个检测到的人脸,使用img.get_descriptor(face)获取人脸的特征描述符。
使用image.match_descriptor(known_face_descriptor, descriptor, threshold=85)将检测到的人脸特征描述符与已知人脸特征描述符进行匹配,设置匹配阈值为85。
根据匹配结果,使用print()输出"Recognized face!“或"Unknown face!”。

案例九:人脸识别并标识识别结果:

import sensor
import image
import time

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)

face_cascade = image.HaarCascade("frontalface.xml")

known_face_image = image.Image("/known_face.jpg")
known_face_descriptor = image.vector_descriptor(known_face_image)

tag_color = (0, 255, 0)  # 识别结果标签的颜色

while True:
    img = sensor.snapshot()
    faces = img.find_features(face_cascade, threshold=0.5, scale=1.5)
    
    for face in faces:
        descriptor = img.get_descriptor(face)
        match = image.match_descriptor(known_face_descriptor, descriptor, threshold=85)
        if match:
            img.draw_string(face[0], face[1], "Recognized", color=tag_color)
        else:
            img.draw_string(face[0], face[1], "Unknown", color=tag_color)
    
    time.sleep(100)

要点解读:
该程序通过OpenMV Cam进行人脸识别,并在图像上标识识别结果。
使用sensor.reset()重置传感器设置。
设置图像格式、帧大小,并禁用自动增益和自动白平衡。
使用image.HaarCascade(“frontalface.xml”)实例化一个HaarCascade对象,用于人脸检测。需要将"frontalface.xml"文件放置在OpenMV Cam上。
使用image.Image(“/known_face.jpg”)加载已知人脸图像,将其转换为特征描述符。
定义标签的颜色。
在一个无限循环中,使程序持续执行以下操作:
使用sensor.snapshot()获取图像快照。
使用img.find_features(face_cascade, threshold=0.5, scale=1.5)检测图像中的人脸。
针对每个检测到的人脸,使用img.get_descriptor(face)获取人脸的特征描述符。
使用image.match_descriptor(known_face_descriptor, descriptor, threshold=85)将检测到的人脸特征描述符与已知人脸特征描述符进行匹配,设置匹配阈值为85。
根据匹配结果,在图像上使用img.draw_string()标识识别结果(“Recognized"或"Unknown”)。
使用time.sleep(100)延迟100毫秒,以控制处理频率。

这些实际运用程序示例展示了如何使用OpenMV Cam进行人脸识别。第一个示例演示了如何检测并绘制人脸边界框,通过使用HaarCascade对象进行人脸检测,并在图像上绘制边界框。第二个示例展示了如何进行人脸识别并输出识别结果,通过将已知人脸图像转换为特征描述符,并将检测到的人脸特征描述符与之进行匹配,输出相应的识别结果。第三个示例演示了如何进行人脸识别并标识识别结果,通过在图像上使用字符串标签来标识识别结果。

请注意,以上案例只是为了拓展思路,可能存在错误或不适用的情况。不同的硬件平台、使用场景和MicroPython版本可能会导致不同的使用方法。在实际编程中,您需要根据您的硬件配置和具体需求进行调整,并进行多次实际测试。确保正确连接硬件并了解所使用的传感器和设备的规范和特性非常重要。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41659040/article/details/133577849