MaixPy实现人脸识别

视频演示

烧录key_gen获取机器码

Burn key_gen to get machine code
1. 首先下载 key_gen 固件 并解压的到 key_gen_v1.2.bin
Download at The First key_gen Firmware and IT to the unzip key_gen_v1.2.bin

  1. 使用kflash_gui烧录key_gen_v1.2.bin
    The Use kflash_gui to Flashkey_gen_v1.2.bin

  2. 打开串口终端可以看到如下输出
    Open the serial terminal and you can see the following output

Please Send Bellow Data to Sipeed --> support@sipeed.com:

844871aac6843da7a3******591d27bcd77d7b

Generate key end

其中第二行 844871aac6843da7a3******591d27bcd77d7b 即为我们所需要的机器码。
Line at The SECOND, the WHERE 844871aac6843da7a3******591d27bcd77d7bIS WE need at The Machine code.

注意: 机器码信息会在开发板上电第一时间显示,如果没有看到输出的机器码信息,请保持串口终端打开并按reset键重启开发板。
Note: The machine code information will be displayed on the development board immediately after power on If you do not see the output machine code information, please keep the serial port terminal open and press the reset key to restart the development board..

从Maixhub模型平台下载人脸识别模型

Download face recognition model from Maixhub model platform
1. 访问Maixhub 模型平台首页, 注册并登录。
At The from Visit Maixhub Model Platform Homepage, the Register and login.

  1. 选择[MaixPy 人脸识别模型]
    (https://www.maixhub.com/index.php/index/index/detail/id/235) 点击下载按钮。
    The SELECT MaixPy Face Recognition Model the Click the Button at The download.

  2. 在跳转的页面中输入上一步获得的机器码
    Enter the machine code obtained in the previous step in the page that is jumped to.

  3. 点击提交即可获得人脸识别模型
    Click Submit to get a face recognition model.

注意:此步点击提交后需耐心等待约30秒,未开始下载前请不要关闭页面。
Note: Please wait patiently for about 30 seconds after clicking Submit in this step Please do not close the page before downloading..

  1. (可选步骤)可以将获得的kfpkg后缀改为zip, 解压获得三个模型文件以及Maixpy精简版固件。用户可以自行将模型拷贝到SD卡中加载模型。kfpkg中打包的Maixpy固件可能会版本过时, 用户可以自行替换为最新的精简版固件。

(Optional the STEP) Obtained by You CAN Change at The kfpkg suffix to ZIP, and Decompress IT to Obtain Three Model Files and Maixpy Lite Firmware. The Users CAN Copy to SD Card at The Model to the Load at The Model by Themselves. At The Version of Maixpy Packaged in kfpkg May BE Firmware outdated, and the replace the Users CAN IT at The Latest with the Streamlined Firmware.

注意:目前不支持在完整版Maixpy固件中使用人脸识别模型
Note: Face recognition models are not currently supported in the full version of Maixpy firmware

烧录人脸识别模型

Burning face recognition model
1. 使用 kflash_gui 烧录上一步获取的kfpkg模型
Use kflash_gui to flash the kfpkg model obtained in the previous step.

  1. 烧录完成后,开发板显示 MaixPy 欢迎界面。
    After the programming is complete, the development board displays the MaixPy welcome interface.

使用 MaixPy IDE 运行 MaixPy 人脸识别脚本

Run MaixPy Face Recognition Script with MaixPy IDE

  1. 安装 MaixPy IDE, 具体见MiaxPy IDE.
    Install the MaixPy IDE, See MiaxPy IDE for the Details .

  2. 从 Github 仓库获取人脸识别脚本 demo_face_recognition.py
    Recognition Script at The face GET demo_face_recognition.py from Github at The Repository

  3. 使用 MaixPy IDE 打开人脸识别脚本, 连接开发板, 上传脚本到开发板, 可以看到到人脸识别已经在MaixPy 上成功运行起来了。 用户可以修改我们的识别脚本, 来创造更有趣的应用。
    The Use MaixPy IDE to Open at The face Recognition Script, Connect at The Development Board, the Upload at The Script to at The Development Board, and you CAN See that at The face Recognition has been successfully RUN ON MaixPy. The Users CAN the Modify Our Recognition Script to the Create More interesting Applications.

人脸识别脚本解读

Interpretation of face recognition script

import sensor,image,lcd  # import 相关库
import KPU as kpu
import time
from Maix import FPIOA,GPIO
task_fd = kpu.load(0x200000) # 从flash 0x200000 加载人脸检测模型
task_ld = kpu.load(0x300000) # 从flash 0x300000 加载人脸五点关键点检测模型
task_fe = kpu.load(0x400000) # 从flash 0x400000 加载人脸196维特征值模型
clock = time.clock()  # 初始化系统时钟,计算帧率
key_pin=16 # 设置按键引脚 FPIO16
fpioa = FPIOA()
fpioa.set_function(key_pin,FPIOA.GPIO7)
key_gpio=GPIO(GPIO.GPIO7,GPIO.IN)
last_key_state=1
key_pressed=0 # 初始化按键引脚 分配GPIO7 到 FPIO16
def check_key(): # 按键检测函数,用于在循环中检测按键是否按下,下降沿有效
    global last_key_state
    global key_pressed 
    val=key_gpio.value()
    if last_key_state == 1 and val == 0:
        key_pressed=1
    else:
        key_pressed=0
    last_key_state = val

lcd.init() # 初始化lcd
sensor.reset() #初始化sensor 摄像头
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
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() # 设置显示buf
img_face=image.Image(size=(128,128)) #设置 128 * 128 人脸图片buf
a=img_face.pix_to_ai() # 将图片转为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'] # 人名标签,与上面列表特征值一一对应。
while(1): # 主循环
    check_key() #按键检测
    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() # 将猜出图片转换为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 > 85: # 如果最大分数大于85, 可以被认定为同一个人
                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 key_pressed == 1: #如果检测到按键
                key_pressed = 0 #重置按键状态
                record_ftr = feature 
                record_ftrs.append(record_ftr) #将当前特征添加到已知特征列表
            break
    fps =clock.fps() #计算帧率
    print("%2.1f fps"%fps) #打印帧率
    a = lcd.display(img) #刷屏显示
    #kpu.memtest()

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

发表评论