今天总结一下前段时间实践的基于opencv实时人脸识别软件的实现。
利用opencv来做人脸识别,对于想快速上手学习opencv以及机器学习方面知识的同学是个不错的选择。人脸识别,一般分为两个步骤,第一个就是人脸检测,第二步才是识别。
首先,人脸检测,opencv常用方法为基于adaboost的haar特征分类器,如何利用其提供的api训练自己的分类器,可参考这篇文章。
然后,找到人脸后,利用人脸区域的一些特征(LBP?HOG?),通过MLP或者CNN然后训练自己的识别资料库,最后进行识别。当然,opencv为我们提高了便捷快速的api,你甚至可以不去了解它怎么工作的,就可以训练自己的资料库进行识别。
以下为opencv提供的三种算法:
Eigenfaces特征脸createEigenFaceRecognizer()
Fisherfaces createFisherFaceRecognizer()
LocalBinary Patterns Histograms局部二值直方图 createLBPHFaceRecognizer()
以下为python版本和c++版本的实现:
Python版本的实现:
(实现了一个按键人脸识别考勤系统,当然如果要一直进行识别,去掉按键触发就好了)
pyqt5
opencv-python3.4.4
由于手机中的照片为样本拍的,所以准确率还算可以。我用的是lbp特征,置信度在80内认为识别到了,但多场景以及光线变化明显效果就不是很好。
贴出界面外识别线程的程序,多线程为了在qt-label中实时显示画面。
class Thread(QThread):#采用线程来播放视频
global id, minH, minW, font, recognizer, faceCascade, names
changePixmap = pyqtSignal(QtGui.QImage)
#线程主函数
def run(self):
#HardWare.IO_Init()
global none_save
none_save = 0
if_dist = 1
#pdb.set_trace() # start debug
while 1:
#time.sleep(2)
if_dist = HardWare.if_distance()
print(if_dist)
if if_dist == 0:
flag = self.if_recognize(100,1) #用户自己修改,100代表检测一百帧,1代表识别到就跳出
print(flag)
#识别失败,保存图片
if flag == 'False':
none_save += 1
#识别到用户开门
else:
HardWare.openDoor()
time.sleep(5)
HardWare.closeDoor()
else:
HardWare.closeDoor() #没人始终关门
#封装人脸识别函数,实现功能: 输入 指定帧数 图像,凡是指定帧有 n张 识别成功 or 识别到连续的为同一个人,则返回 name;否则返回 false。
def if_recognize(self,in_nums,ok_nums):
cap = cv2.VideoCapture(0)
last_id = 0
i = 0