本文共 3382 字,大约阅读时间需要 11 分钟。
“识别人脸关键点”案例源码详解
- 构建APP框架和添加主要控件
- 人脸关键点识别的方法
- 商业应用案例拓展训练
打开人脸关键点案例
- 在Examples中点击FacePose进入代码编辑状态。
- 代码存在路径在/home/facencnn/facepose.py。

导入相关库
- from cvs import *——导入cvs图形控件的库
- import facerecognition——导入人脸识别的库
- import numpy as np——导入开源的数值科学计算库,别名为np

定义并初始化APP类
- class MyApp(App)——定义一个名为MyApp的类,用于构建程序的图形化APP
- def init(self, *args): super(MyApp,self).init(*args) 初始化函数,self表示创建实例本身,*args传递可变参数,init()的第一个参数永远是self.

设置标签的值
- self.lbl.set_text(cvs.getLbs()),设置标签控件中文本的值为cvs中全局变量的值。
- def idle(self):并未清空cvs.getLbs()中的值,目的是为了动态的显示程序运行的图片识别的速率情况(程序每秒识别几张图片)。

构建APP的框架
- 定义变量main_container,它的作用是整个APP的主框架,用于包含其他APP中的控件,相当于容器。
- VBox(width=360, height=680, style={‘margin’:‘0px auto’}),这段代码是在手机上画出一个宽度为360px,高度为680px的程序主框架范围,style是它的样式。

添加摄像头控件
- OpencvVideoWidget函数是在手机中画一个用于显示调用手机摄像头拍摄图像的框,宽度340px,高度480px,将它赋值给self.aidcam,aidcam是摄像头控件。
- self.aidcam.style[‘margin’] = ‘10px’,摄像头框架的边界和主框架相隔10px。
- self.aidcam.set_identifier(“myimage_receiver”),给aidcam取一个别名
- main_container.append(self.aidcam),这个时候将设置好的摄像头显示框添加到APP主框架中。

添加标签控件
- self.lbl = Label(‘This show fps!’, width=360, height=30, margin=‘50px’,),设置一个默认文本为’This show fps!’,宽度360px,高度30px,边界为50px的标签控件,将它赋值给 self.lbl, self.lbl是标签控件。
- main_container.append(self.lbl),这个时候将设置好的标签控件添加到APP主框架中。
- main函数返回设置好的VBox主框架控件。

加载人脸识别的学习模型
- main()定义了一个主函数
- cvs.VideoCapture(1)是调用手机前置摄像头,如果是cvs.VideoCapture(0)就是调用手机后置摄像头。
- facerecognition.FaceRecognition("./models", 0.63),是加载人脸识别的学习模型,第一个参数路径,第二个是阈值,0.63是默认值,阈值的范围是0-1,阈值约高,识别越严格,通过率约低,例如如果一个人的头发乱了,或者脸上有一些遮挡等,一般建议不要设定太高。

人脸图像转化为特征值
- start = time.time(),获取程序开始的运行时间。fcount=0是图像处理的张数。
- 定义了一个while循环,作用是将人脸图像的特征点添加到数据库。
- sleep(30)是让程序休眠30毫秒。
- img =cap.read(),读取当前摄像头下拍摄的图像。
- if img is None:如果图像为空,则重复该循环。

- fcount=fcount+1,图像处理的张数加1。
- lbs = 'Average FPS: '+ str(fcount / (time.time() - start)),计算程序的运行时间(time.time() - start),fcount是程序处理几张图像,用facount除时间得到图像处理速率,例如10秒内处理了30张图片,得到的结果是3,意思就是程序每秒识别了3张图片的意思,然后将结果连接到字符串’Average FPS: '后,并赋值给lbs 变量。
- cvs.setLbs(lbs)将结果赋值给cvs中的全局变量。

- if camid==1:判断是否是前置摄影头,如果是img=cv2.flip(img,1),镜面翻转,维度 0 是上下翻转,1是左右翻转,和镜子一样,不然是反的。
- if ret==0:,如果返回的值是0,表示添加成功,否则添加失败,并用print函数写入一段文字到日志文件。
- userId=’’ 和 cvs.setLbs(userId)是编程的一个必要动作,将全局变量重新设置为空,避免后面出现不必要的错误。
- image_char = img.astype(np.uint8).tostring(),将图像转为unint8的格式再转化为一组字符串格式。

人脸特征值提取开始
- rets = facerecog.getfacepose(img.shape[0], img.shape[1], image_char),获取人脸数据的特征点,每个人脸一个字典 然后组成一个列表,存储在rets变量中。
- for ret in rets:循环提取人脸特征值数据,则用print将一段文字写入日志文件。
- rect = ret[‘rect’],提取人脸绿色框的位置,人脸外框是个矩形。
- mtcnn = ret[‘mtcnn’],得到一个数组,表示人脸关键点的坐标x0,x1,x2,x3,x4,y0,y1,y2,y3,y4 其中x0,y0是左眼,x1,y1是右眼,x2,y2是鼻子,x3,y3是左嘴角,x4,y4是右嘴角,均是中心点位置。
- cvs.circle(img,(mtcnn[i],mtcnn[5+i]),2,(0,0,255),2),在摄像头人脸图片上画圆点,人脸上5个点,左右眼,鼻子,左右嘴角,画出5个红点,第一个2是半径,第二个2是线宽,(0,0,255)是红色。
- for i in range(5):,通过循环是把mtcnn获取到数据提取出来。
- keypoint=ret[‘keypoints’],获取人脸特征点,一组列表,x0,y0,x1,y1,x2,y2……x105,y105 。
- p1 = (int(rect[0]), int(rect[1])),rect[0]是绿色框的左上角x坐标,rect[1]是绿色框的左上角y坐标。
- p2 = (int(rect[0]+rect[2]), int(rect[1]+rect[3])),rect[2]是人脸外框宽度,rect[3]是人脸外框高度,画矩形。
- cvs.rectangle(img, p1,p2, (0, 255, 0) , 3, 1),img是图像,p1左上角,p2右上角,(0, 255, 0)外框的颜色,3是指线的宽度,1是指线的类型,可以改变使线更平滑,作用是在摄像头中的人脸图像上画框。
- for p in range(0,106):画出106个绿色的特征点,其实keypoint的坐标就是参考rect[0],rect[1],也就是绿色框的左上角为原点。
- k1=int(rect[0]+keypoint[p*2]),绿色点x坐标。
- k2=int(rect[1]+keypoint[p*2+1]),绿色点y坐标。
- cv2.circle(img,(k1,k2),2,(253,0,0),2),img是图像,x坐标k1,y坐标k2,2是圆半径,(253,0,0)圆点的颜色,第二个2是线宽cvs.imshow(img)是将画好的框和名字显示出来。

默认启动函数
- initcv(main)设置线程启动
- startcv(MyApp)启动APP

人脸关键点识别程序的步骤

拓展思考

转载地址:http://ildo.baihongyu.com/