Bootstrap

基于亚博K210的人脸识别

前言

博主是通信方向,主要学习的是FPGA,但因和同学参加某个嵌入式比赛,题目是智能门禁系统,需要进行人脸识别,故博主快速学习了K210和Python,最终实现人脸识别。博主是速成而不是专业选手,故代码有很多可以 垃圾 优化的地方,手下留情(勿喷),本文也仅适合需要快速实现人脸识别的选手。


一、软件准备

亚博是推荐使用Vscode+裸机SDK进行C语言开发,需要自己写编译命令和烧录程序,人脸识别模型需要自己训练,博主不是搞这个方向的,不想在这个比赛上花太多时间,故采用MaixPy IDE快速开发K210,模型直接使用MaixHub上的。

具体怎么获取并烧录固件,通过机器码获取模型文件,CSDN上已经有很多博主描述清楚了,博主就不赘述了。这里给个 晨少的博客 的教程,网络上还有很多资料。

获取与烧录固件
机器码获取模型

开发资料:
MaixPy IDE的开发指南
人脸识别模型
官方人脸识别资料
MaixPy IDE是用MicroPython开发,MicroPython和Python基本没区别。(MicroPython是Python的一个精简版本,它是为了运行在单片机这样的性能有限的微控制器上),在此之前博主从未学过Python,此次项目我也未系统性地学,所以各位不用惧怕。
关于Python的资料可参考廖雪峰-Python教程

二、硬件准备

1.读卡器与TF卡

官方的源码是会掉电丢失的。

record_ftrs=[] #空列表 用于存储按键记录下人脸特征, 可以将特征以txt等文件形式保存到sd卡后,读取到此列表,即可实现人脸断电存储。
·········
record_ftrs.append(record_ftr) #将当前特征添加到已知特征列表

可见是把计算的特征值加入程序的列表,断电重开之后,程序重新启动,自然就丢失之前记录的特征值。解决办法就是把特征值写入TF卡即可,断电重启之后,重新从TF卡读取出特征值。

亚博K210有TF卡槽,但不配TF卡,故需要自行购买。由于需要往TF卡存放模型,程序等文件,还需要读卡器。
注意:TF卡一定要是FAT32格式,否则无法读取。
关于K210对TF卡的要求,可参考存储系统介绍

2.下载相关文件

考虑到百度网盘下载不方便,阿里云盘又不支持压缩包分享,故我把程序和模型存放到GitHub
GitHub链接
网络不好的,进不去GitHub的,可与去Gitee上下载
Gitee链接

如果可以的话,下载的时候,顺便点颗星,谢谢

下载好了之后,只需把下图的前5个文本通过读卡器存放到TF卡,然后插入已经支持MaixPy IDE开发的亚博K210上(其它的K210应该也是行的)即可实现人脸识别。
文件描述
注意:features.txt文本在存放到TF卡前需要进行格式化,因为里面存放的是博主的特征值;这个格式化后,存放你们的特征值才会与程序里的名字对应上。

亚博K210按下图接好线,即可实现K210与其它MCU的串口通信。
亚博K210接线示意图
注意:博主的程序是波特率为115200,8位数据位,1位停止位,无校验位。

3.程序自定义部分

names = ['Pang_sen_lin', 'Bai_jing_ting', 'Jiang_wen', 'Peng_yu_yan', 'Zhao_li_ying',  'Jamie_Foxx', 'member.1', 'member.2'] # 人名标签,与上面列表特征值一一对应。

1.这个是LCD上显示出识别的人名,录脸的时候也需要按照这个顺序进行录入,不然会出现名字对不上人脸。

fm.register(13, fm.fpioa.UART1_TX, force=True)
fm.register(12, fm.fpioa.UART1_RX, force=True)
uart = UART(UART.UART1, 115200, 8, None, 1, timeout=50, read_buf_len=4096)

2.这是串口的配置。13是TX,12是RX。UART函数的参数是
UART(uart.UART 号,UART 波特率,UART 数据宽度, 奇偶校验位,停止位,串口接收超时时间,串口接收缓冲)
详细的UART 介绍请参考 UART-API 文档

 uart.write('Y')#识别出已录入的人脸,串口发送Y
 ·········
 uart.write('N')#未识别出已录入的人脸,串口发送N

3.这个是K210对人脸进行识别后,通过串口给其它MCU发送识别结果。

read_data = uart.read()
if read_data == b'A':
   key_left = True		    #key_left是个标志量,为1代表开始识别人脸
   read_data = b'Z'
elif read_data == b'B':
   start_processing = True  #start_processing是个标志量,为1代表开始录入人脸
   read_data = b'Z'

4.这个是K210串口接收到其它MCU发送的字符后,通过判读字符进行功能的选择。例:如果K210接收到字符A则开始识别当前人脸,识别出后K210串口发送字符Y给其它MCU;若没识别出,则发送字符N给其它MCU。如果K210接收到字符B则开始计算当前人脸的特征值并记录到TF卡里的features.txt文本。

注意:key_left和start_processing其实是全局变量。通过串口给K210发送字符A和向左滑动Keypad按键都能使key_left赋值为1;同样,通过串口给K210发送字符B和按下BOOT按键都能使start_processing赋值为1。之所以这样做,其实是在测试/调试程序的时候,比较方便。

到这里,如果你像我一样只是单纯地想实现人脸识别的功能,而不是深究下去的话,后面可以不用看了。如果出现什么BUG可以去文章的总结部分和评论区看看。

4.部分程序解释

if max_score > ACCURACY:
   a = img.draw_string(i.x()-30, i.y(), ("%s :%2.1f" % (names[index], max_score)), color=(0, 255, 0), scale=2)
   if flag == -1:
      flag = index
   if flag == index:
      record_1+=1
   else:
      record_1-=1
   if record_1<0:
      flag = -1
   if record_1 == 8:
      uart.write('Y')
      record_1 = 0
      flag = -1
      record_2 = 0
      key_left = False
   else:
      a = img.draw_string(i.x()-20, i.y(), ("Stranger :%2.1f" % (max_score)), color=(255, 0, 0), scale=2)
      record_2+=1
      if record_2 == 16:
      uart.write('N')
      record_1 = 0
      flag = -1
      record_2 = 0
      key_left = False

这里的意思是如果一个人被识别出8次,则可认为确定就是录取人的那个人;同理,如果识别不出有16次,则可以认为这个人没有录入是陌生人。因博主的Python能力,这个地方肯定是有问题的,而且极不好。对于Python比较熟悉的人,强烈建议对这个地方进行重写,欢迎在评论区进行讨论。

这个地方的作用在于检测环境不良或者模型精度无法得到保证时,加入一个检测次数判断,当识别出某人一定的次数才算确切识别出那个人,同理识别不出一定的次数则可判断为陌生人。

当你使用官方的源码,就会发现这个地方的作用。比如K210对1号人物进行识别,它的识别结果是2号人物···5号人物或者陌生人之间一直跳变,当然出现次数最多的肯定是1号人物。

看到这里估计你是想深入学习K210,而不是糊弄,那么博主就建议在官方的源码上进行重写。如果可以的话,可自己去训练获取模型。

三、总结

提示:
1.Maixpy IDE还是存在很多的BUG,有些地方我对代码进行优化,甚至为减小冗余把一些重复的代码进行合并变成一个函数就会出现死循环等等问题,这就使程序变得非常冗余。
2.固件也是有问题的。有时会死机,这个时候建议重启多次;有时检测不到TF卡,在确认K210支持这个TF卡时,也是建议重启多次,并拔插TF卡。
3.如果Maixpy IDE出现模型加载错误。这个时候有两种办法,第一种,断开K210与IDE的连接,然后重新连接并编译;第二种,重新导入模型。大多数情况第一种就能解决,如果是把模型是放在Flash里面大概率就是第二种,很麻烦,这也是为什么博主放TF卡里的原因之一。
4.使用 IDE 的时候出现 TypeError: Can’t convert to type 错误。保存程序,断开K210与IDE的连接,然后重新连接并编译或者重启 IDE 。
5.总结IDE报各种错误时,就进行断开K210与IDE的连接,然后重新连接并编译,如果还不行,大概率就是你程序的问题。
6.出现问题可以去这里常见问题看看。

以上就是关于亚博K210的人脸识别的内容,博主水平有限,代码写的很差,本文仅仅实现了亚博K210的人脸识别和K210与其它MCU的串口通信,K210还有很多操作待开发。

不过博主建议K210的开发最好还是用C语言开发,虽然C语言开发让上手变得有些困难,但是C语言就不会出现那么多的语言BUG和IDE的BUG。Python脚本的开发虽然上手容易且灵活,但是本身固件就会占用一定内存,如果模型再大点就有内存不足的问题,所以C语言开发才能更好的压榨K210。不过开发方式要根据自己的需求来,就像博主没学过Python和K210,但是赶时间,博主也不靠K210吃饭,故选择资料较多且开发简单的Maixpy IDE来开发。

四、参考资料

Mrli0530
L.LL

;