为了账号安全,请及时绑定邮箱和手机立即绑定

关于Opencv人脸识别的一点探究

本文基于上篇文章,对Opencv首先人脸识别过程中的一些细节进行小小的探究。

1.在detect_face函数中,检测所尺度方法返回的faces究竟是什么?我们在代码

faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)

后输出一下faces,即print(faces),结果如下:

https://img1.sycdn.imooc.com//5d15fa470001ed4f01740476.jpg

查看全部代码会发现detect_face函数共出现两次,分别是在函数prepare_training_data和predict中,共被执行了42次,因为有训练图片40张和测试图片2张,输出结果也为42条记录,每一条都是检测到的人脸区域坐标(x,y,宽,高),有的记录包括两项,如[[188 133 53 53] [155 36 112 112]],也就是检测出两张人脸(实际上每张图片只有一张人脸。。),还有的为空,意即没有检测出人脸,所以我们要大量的训练,否则准确度很难保证。

2.同样是在detect_face中,最后我们假设只有一张人脸(检测到两张脸的话就取第一个),我们把faces[0]赋值给(x,y,w,h),那这里的faces[0]又是什么?

有朋友说了,这不是很明显吗,就是从上边的数组中取第一项就行了呗。没毛病,我们在代码

if (len(faces) == 0):
    return None, None

之后输出faces[0],结果为:

https://img1.sycdn.imooc.com//5d15fda40001619d01590403.jpg

跟上图像比较,很好理解,但是如果在代码

faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)

之后输出faces[0]则会报错:索引越界,大家应该也注意到了,在faces中有空(),如果我们在未检测faces长度并返回None之前便引用faces[0]是会越界的,因为此时detectMultiScale返回的数组包含空值,它和None是不一样的,这一块大家可以自行查一下。

3.在prepare_training_data函数中的第二个for循环中,检测脸部函数detect_face返回了face和rect,还有我们在第一个for循环一开始得到的label标签值,这三者到底是长什么样子的?

我们在代码

face, rect = detect_face(image)

后依次输出这三者

print(face)
print(rect)
print(label)

看下结果:

https://img1.sycdn.imooc.com//5d1602190001266802680214.jpg

这是第一张图片的信息,共三部分,分别为图片的人脸区域信息、检测到的脸部区域和标签值,从这里也可以看出一张彩色图片是由一个个数值组成的,也就是一个个的像素值。

4.我们的prepare_training_data函数最后返回了faces和labels,这二者的形式又是怎样的呢?

我们在第三问探究了detect_face函数返回的face和rect,那faces就是face的总和嘛,我们在代码

faces, labels = prepare_training_data("training_data")

后输出二者

print(faces)
print(labels)

看下faces的具体形式:

https://img1.sycdn.imooc.com//5d16058c000135b608300333.jpg

可以看出faces中每一个元素均为数组,格式为uint8

而labels呢?请看:

https://img1.sycdn.imooc.com//5d1606a60001d02309090039.jpg

共40项,即40张训练图片对应的标签,而在之后的

face_recognizer.train(faces, np.array(labels))

中我们将list列表转换为数组形式,关于列表和数组,大概就是python中的list是python的内置数据类型,list中的数据类不必相同的,而array的中的类型必须全部相同。二者具体的不同大家可以自行查阅。

5.最后我们补充两点内容,这是在我查阅资料中发现的一两个问题,第一个就是

cv2.face.LBPHFaceRecognizer_create()

在老版本的代码中用的是

cv2.face.createLBPHFaceRecognizer()

第二个是在自定义的predict函数中

label = face_recognizer.predict(face)

这里的label输出一下为以下形式

https://img1.sycdn.imooc.com//5d16089c0001e57602010049.jpg

共包含两项,分别为标签和系数,后者是和具体的算法有关的,对于LBPH来说低于50可靠,80-90不可靠,高于90纯蒙,由于我们训练数据太少,得到的结果也不太可靠(但还是准确地检测识别了)

本次人脸识别还是很有局限性,属于初级入门程度,比如我们训练0组图片,然后预测的时候也是用的家驹的图片,有点像人为匹配似的,实际上我们测得就是相似度,当程序能够表示出人物并且系数很低(表示可靠),这才是我们想要的结果,之后还会做一些有趣的实验,继续吧

                         如果本篇文章对你有一点点帮助,请点赞或者收藏,让我们一起进步

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消