【K210学习笔记】#MaixPy#(3)人脸检测与人脸识别

目录

  • 一、人脸检测:
    • 1、烧录模型:
    • 2、示例测试:
  • 二、人脸识别:
    • 1、获取机器码:
    • 2、获取人脸识别模型:
    • 3、烧录专用固件:
    • 4、烧录模型:
    • 5、示例测试:
    • 6、报错解决:

一、人脸检测:

1、烧录模型:

在 模型下载 下载 face_model_at_0x300000.kfpkg 这个模型文件,使用 kflash_gui 下载模型到 Flash。
【K210学习笔记】#MaixPy#(3)人脸检测与人脸识别_第1张图片


2、示例测试:

连接开发板,拷贝以下示例代码到 MaixPy IDE 运行,参考:【K210学习笔记】#Maixpy#(1)Maixpy IDE安装与使用
示例脚本:demo_find_face.py

import sensor, image, lcd, time
import KPU as kpu
import gc, sys

def lcd_show_except(e):
    import uio
    err_str = uio.StringIO()
    sys.print_exception(e, err_str)
    err_str = err_str.getvalue()
    img = image.Image(size=(224,224))
    img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00))
    lcd.display(img)

def main(model_addr=0x300000, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):
    try:
        sensor.reset()
    except Exception as e:
        raise Exception("sensor reset fail, please check hardware connection, or hardware damaged! err: {}".format(e))
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    sensor.set_hmirror(sensor_hmirror)
    sensor.set_vflip(sensor_vflip)  # 开启摄像头垂直翻转
    sensor.run(1)

    lcd.init(type=1)
    lcd.rotation(lcd_rotation)
    lcd.clear(lcd.WHITE)

    anchors = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025)
    try:
        task = None
        task = kpu.load(model_addr)
        kpu.init_yolo2(task, 0.5, 0.3, 5, anchors) # threshold:[0,1], nms_value: [0, 1]
        while(True):
            img = sensor.snapshot()
            t = time.ticks_ms()
            objects = kpu.run_yolo2(task, img)
            t = time.ticks_ms() - t
            if objects:
                for obj in objects:
                    img.draw_rectangle(obj.rect(), color=(255,0,0), thickness=3)
            img.draw_string(0, 200, "t:%dms" %(t), scale=2)
            lcd.display(img)
    except Exception as e:
        raise e
    finally:
        if not task is None:
            kpu.deinit(task)


if __name__ == "__main__":
    try:
        main( model_addr=0x300000, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=True)
        # main(model_addr="/sd/m.kmodel")
    except Exception as e:
        sys.print_exception(e)
        lcd_show_except(e)
    finally:
        gc.collect()

二、人脸识别:

1、获取机器码:

使用 kflash_gui 下载:key_gen_v1.2.bin 烧录到开发板
【K210学习笔记】#MaixPy#(3)人脸检测与人脸识别_第2张图片
烧录后从串口终端获取到机器码:
【K210学习笔记】#MaixPy#(3)人脸检测与人脸识别_第3张图片

2、获取人脸识别模型:

进入 MaixHub 下载人脸识别模型:
【K210学习笔记】#MaixPy#(3)人脸检测与人脸识别_第4张图片
填入机器码下载:(地址)
【K210学习笔记】#MaixPy#(3)人脸检测与人脸识别_第5张图片
下载后得到0x3000000x4000000x500000 三个地址的 .smodel 模型文件


3、烧录专用固件:

在 下载站 下载 kmodelv4 支持固件,并用 kflash 烧录。
在这里插入图片描述
【K210学习笔记】#MaixPy#(3)人脸检测与人脸识别_第6张图片


4、烧录模型:

按照文件名分别烧录到不同的地址:
【K210学习笔记】#MaixPy#(3)人脸检测与人脸识别_第7张图片


5、示例测试:

连接开发板,拷贝以下示例代码到 MaixPy IDE 运行,参考:[【K210学习笔记】#Maixpy#(1)Maixpy IDE安装与使用]
示例脚本:demo_face_recognization.py

import sensor
import image
import lcd
import KPU as kpu
import time
from Maix import FPIOA, GPIO
import gc
from fpioa_manager import fm
from board import board_info
import utime

task_fd = kpu.load(0x300000)    # 加载人脸检测模型
task_ld = kpu.load(0x400000)    # 加载人脸五点关键点检测模型
task_fe = kpu.load(0x500000)    # 加载人脸196维特征值模型

clock = time.clock()    # 初始化系统时钟,计算帧率

# 设置按键引脚 按下记录人脸
fm.register(board_info.BOOT_KEY, fm.fpioa.GPIOHS0)
key_gpio = GPIO(GPIO.GPIOHS0, GPIO.IN)
start_processing = False

BOUNCE_PROTECTION = 50


def set_key_state(*_):
    global start_processing
    start_processing = True
    utime.sleep_ms(BOUNCE_PROTECTION)


key_gpio.irq(set_key_state, GPIO.IRQ_RISING, GPIO.WAKEUP_NOT_SUPPORT)

lcd.init()                          # 初始化lcd
sensor.reset()                      # 初始化sensor 摄像头
sensor.set_pixformat(sensor.RGB565) # 设置摄像头输出格式
sensor.set_framesize(sensor.QVGA)   # 设置摄像头输出帧大小,k210最大支持VGA格式
sensor.set_hmirror(1)               # 设置摄像头镜像
sensor.set_vflip(1)                 # 设置摄像头翻转
sensor.run(1)                       # 使能图像捕捉功能
anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437,
          6.92275, 6.718375, 9.01025)  # anchor for face detect 人脸检测的Anchor
dst_point = [(44, 59), (84, 59), (64, 82), (47, 105),
             (81, 105)]  # standard face key point position 标准正脸的5关键点坐标:左眼 右眼 鼻子 左嘴角 右嘴角
a = kpu.init_yolo2(task_fd, 0.5, 0.3, 5, anchor)
img_lcd = image.Image()                 # 创建一个新的图像对象
img_face = image.Image(size=(128, 128)) # 设置图像大小
a = img_face.pix_to_ai()                # 将RGB565的图像手动更新到RGB888的区域,供kpu功能使用
record_ftr = []                         # 用于存储当前196维特征
record_ftrs = []                        # 用于存储按键记录下人脸特征, 可以将特征以txt等文件形式保存到sd卡后,读取到此列表,即可实现人脸断电存储
names = ['Mr.1', 'Mr.2', 'Mr.3', 'Mr.4', 'Mr.5',
         'Mr.6', 'Mr.7', 'Mr.8', 'Mr.9', 'Mr.10']   # 人名标签,与上面列表特征值一一对应

ACCURACY = 85                           # 人脸匹配分数值定义(判定识别成功)

while (1):
    img = sensor.snapshot()             # 从摄像头获取图像
    clock.tick()                        # 记录时间,用于计算帧率
    code = kpu.run_yolo2(task_fd, img)  # 运行人脸检测模型,获取人脸坐标位置
    if code:    # 检测到人脸
        for i in code:
            # Cut face and resize to 128x128
            a = img.draw_rectangle(i.rect())                # 在屏幕显示人脸方框
            face_cut = img.cut(i.x(), i.y(), i.w(), i.h())  # 裁剪人脸部分图片到 face_cut
            face_cut_128 = face_cut.resize(128, 128)        # 将裁出的人脸图片 缩放到128 * 128像素
            a = face_cut_128.pix_to_ai()                    # 将RGB565的图像转为kpu格式
            # a = img.draw_image(face_cut_128, (0,0))
            # Landmark for face 5 points
            fmap = kpu.forward(task_ld, face_cut_128)       # 运行人脸5点关键点检测模型
            plist = fmap[:]                                 # 获取关键点预测结果
            le = (i.x() + int(plist[0] * i.w() - 10), i.y() + int(plist[1] * i.h()))    # 计算左眼位置, 这里在w方向-10 用来补偿模型转换带来的精度损失
            re = (i.x() + int(plist[2] * i.w()), i.y() + int(plist[3] * i.h()))         # 计算右眼位置
            nose = (i.x() + int(plist[4] * i.w()), i.y() + int(plist[5] * i.h()))       # 计算鼻子位置
            lm = (i.x() + int(plist[6] * i.w()), i.y() + int(plist[7] * i.h()))         # 计算左嘴角位置
            rm = (i.x() + int(plist[8] * i.w()), i.y() + int(plist[9] * i.h()))         # 计算右嘴角位置
            # 在相应位置处画小圆圈
            a = img.draw_circle(le[0], le[1], 4)
            a = img.draw_circle(re[0], re[1], 4)
            a = img.draw_circle(nose[0], nose[1], 4)
            a = img.draw_circle(lm[0], lm[1], 4)
            a = img.draw_circle(rm[0], rm[1], 4)
            # align face to standard position
            src_point = [le, re, nose, lm, rm]                      # 图片中 5 坐标的位置
            T = image.get_affine_transform(src_point, dst_point)    # 根据获得的5点坐标与标准正脸坐标获取仿射变换矩阵
            a = image.warp_affine_ai(img, img_face, T)              # 对原始图片人脸图片进行仿射变换,变换为正脸图像
            a = img_face.ai_to_pix()                                # 将正脸图像转为kpu格式
            # a = img.draw_image(img_face, (128,0))
            del (face_cut_128)                                      # 释放裁剪人脸部分图片
            # calculate face feature vector
            fmap = kpu.forward(task_fe, img_face)                   # 计算正脸图片的196维特征值
            feature = kpu.face_encode(fmap[:])                      # 获取计算结果
            reg_flag = False
            scores = []                                             # 存储特征比对分数
            for j in range(len(record_ftrs)):                       # 迭代已存特征值
                score = kpu.face_compare(record_ftrs[j], feature)   # 计算当前人脸特征值与已存特征值的分数
                scores.append(score)                                # 添加分数总表
            max_score = 0
            index = 0
            for k in range(len(scores)):                            # 迭代所有比对分数,找到最大分数和索引值
                if max_score < scores[k]:
                    max_score = scores[k]
                    index = k
            if max_score > ACCURACY:                                 # 如果最大分数大于设定值,可以被认定为同一个人
                a = img.draw_string(i.x(), i.y(), ("%s :%2.1f" % (
                    names[index], max_score)), color=(0, 255, 0), scale=2)  # 显示人名 与 分数
            else:
                a = img.draw_string(i.x(), i.y(), ("X :%2.1f" % (
                    max_score)), color=(255, 0, 0), scale=2)        # 显示未知 与 分数
            if start_processing:
                record_ftr = feature
                record_ftrs.append(record_ftr)
                start_processing = False

            break
    fps = clock.fps()
    print("%2.1f fps" % fps)    # 打印帧率
    a = lcd.display(img)        # 刷屏显示
    gc.collect()
    # kpu.memtest()

# a = kpu.deinit(task_fe)
# a = kpu.deinit(task_ld)
# a = kpu.deinit(task_fd)

基本图像变换 和 常用操作


6、报错解决:

报错:only support kmodel V3/V4 now
MaixPy AI 硬件加速基本知识
【K210学习笔记】#MaixPy#(3)人脸检测与人脸识别_第8张图片
**原因:**模型未烧录或者烧录地址错误,重新烧录下模型文件

你可能感兴趣的:(#,K210,人脸识别)