Sipeed MAIX Dock K210 运行人脸识别程序
1. 前言
有关Sipeed MAIX Dock K210 的简介可以参考我的这篇文章 Sipeed MAIX Dock K210开箱试用,今天我们来用这个开发板跑下人脸识别的例程
2. 模型下载使用
我们使用MaixPy IDE 来跑这个例程,首先要从MaixHub下载我们所需要的模型
从MaixHub上下载模型需要我们提供机器码,所以我们首先下载可以获取机器码的bin文件烧录到开发板中
ken_gen bin文件地址
获取机器码
- 用kfalsh_gui 烧录ken_gen.bin文件,点击下载下载即可
- 在串口输出中查看机器码
这里需要注意的是如果你用板载串口的话rst后可能读取不到,应该是板载的CH340G启动慢,需要接自己的串口到UART1获取一下
下载模型
有了机器码我们就可以开始下载对应的模型文件了
模型下载地址
填写获取到的机器码提交下载即可,下载速度较慢,大家耐心等待一下即可
下载到的文件时kfpkg的,其实就是zip文件,我们来看下
我画蓝框的是模型文件,黄框是MaixPy的bin文件,这个是精简版的,体积也比较小只有600多Kb,json文件里面是配置,是关于这几个文件都分别要下载到flash的什么位置以及是否需要校验的
下面是json文件的内容
{"version": "0.1.0","files": [{"address": 0,"bin": "maixpy_face_ide.bin","sha256Prefix": true},{"address": 5242880,"bin": "FD_a6e91e13a0de48bafec324646d070358.smodel","sha256Prefix": false},{"address": 6291456,"bin": "KP_chwise_a6e91e13a0de48bafec324646d070358.smodel","sha256Prefix": false},{"address": 7340032,"bin": "FE_mbv1_0.5_a6e91e13a0de48bafec324646d070358.smodel","sha256Prefix": false}]
}
为什么会有三个模型文件呢,在下面的代码中会讲到
然后我们把kfpkg文件用kfalsh_gui下载到我们的开发板运行即可
3. 运行示例代码
代码地址
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_stateglobal key_pressed val=key_gpio.value()if last_key_state == 1 and val == 0:key_pressed=1else:key_pressed=0last_key_state = vallcd.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 128x128a = img.draw_rectangle(i.rect()) # 在屏幕显示人脸方框face_cut=img.cut(i.x(),i.y(),i.w(),i.h()) # 裁剪人脸部分图片到 face_cutface_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 pointsfmap = 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 positionsrc_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 vectorfmap = kpu.forward(task_fe, img_face) # 计算正脸图片的196维特征值feature=kpu.face_encode(fmap[:]) #获取计算结果reg_flag = Falsescores = [] # 存储特征比对分数for j in range(len(record_ftrs)): #迭代已存特征值score = kpu.face_compare(record_ftrs[j], feature) #计算当前人脸特征值与已存特征值的分数scores.append(score) #添加分数总表max_score = 0index = 0for k in range(len(scores)): #迭代所有比对分数,找到最大分数和索引值if max_score < scores[k]:max_score = scores[k]index = kif 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) #将当前特征添加到已知特征列表breakfps =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)
下面用MaixPy IDE运行程序
按boot键可以录入人脸,录入人脸后会按顺序分配名字,识别到后会显示出来
4. 总结
我们的人脸识别就到这里了
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!