opencv|基于OpenCv的人脸识别系统设计

整个代码是在PyCharm上运行的
代码的结构如图:haarcascade_frontalface_alt2.xml这个文件需要自己下载Opencv库里面有对应的文件
opencv|基于OpenCv的人脸识别系统设计
文章图片

环境配置如下图:
opencv|基于OpenCv的人脸识别系统设计
文章图片

整个运作流程:用PyQt5做了一个简单的图形化界面
【opencv|基于OpenCv的人脸识别系统设计】opencv|基于OpenCv的人脸识别系统设计
文章图片

代码的主体部分:main.py

import sys #包含了四个函数 from detection import face_detection,close_cam from photo import take_photo from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QLineEdit,QLabel from train import train_face from discern import discern_face def do_take_phpto(): close_cam() print('采集照片100张') take_photo() print('采集结束.....')def do_train(): print('开始训练人脸') train_face() print('训练完成') def do_discern(): print('开始识别人脸') discern_face()def do_login():if user_edit.text() == 'admin'and pwd_edit.text() == '123456': print('登录成功') user_edit.hide() pwd_edit.hide() user_label.hide() pwd_label.hide() login_btn2.hide() login_btn1.hide() discern_btn.show() train_btn.show() photo_btn.show() #调用检查摄像头和人脸的动作 face_detection() else: print('登录失败')if __name__ == '__main__':app = QApplication(sys.argv) #创建一个窗口 my_win = QWidget() my_win.setWindowTitle('登录窗口')#创建窗口大小 my_win.resize(300,300)#创建一个标签对象 user_label = QLabel('用户名:',my_win) pwd_label= QLabel('密 码:',my_win) user_label.setGeometry(50,50,80,40) pwd_label.setGeometry(50,100,80,40)#创建登录按钮 login_btn1 = QPushButton('登录',my_win) login_btn2 = QPushButton('注册',my_win)#设置按钮大小位置前面为坐标,后面为大小 login_btn1.setGeometry(50,160,80,40) login_btn2.setGeometry(200,160,80,40)#绑定按钮 login_btn1.clicked.connect(do_login)#创建三个个按钮采集照片 训练按钮 识别按钮 #采集照片 photo_btn = QPushButton('采集照片', my_win) photo_btn.setGeometry(100, 100, 80, 40) photo_btn.clicked.connect(do_take_phpto) photo_btn.hide(); #训练按钮 train_btn = QPushButton('开始训练',my_win) train_btn.setGeometry(100,160,80,40) train_btn.clicked.connect(do_train) train_btn.hide(); #识别的按钮 discern_btn = QPushButton('开始识别',my_win) discern_btn.setGeometry(100,220,80,40) discern_btn.clicked.connect(do_discern) discern_btn.hide(); #设置编辑框 user_edit = QLineEdit(my_win) pwd_edit = QLineEdit(my_win) #设置编辑框的大小位置 user_edit.setGeometry(110,50,150,30) pwd_edit.setGeometry(110,100,150,30) #设置密码的查看格式密文显示 pwd_edit.setEchoMode(QLineEdit.Password)

接下来就是定义的四个函数:
检测:detection.py
import cv2flag = 0 def face_detection(): cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) facecascade = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml') while True: globalflag; ok,img = cap.read() gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) faces = facecascade.detectMultiScale( gray, scaleFactor=1.5,#为每一个图像尺度中的尺度参数,默认为1.1 minNeighbors=5,#参数为每一个级联矩阵应该保留的近邻个数,默认值为3,经历过几次后才确定下来 minSize=(32,32) # 检测的像素点大小 ) for (x,y,w,h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2) cv2.imshow('video',img) k = cv2.waitKey(1) if flag == 1 or k == 27: break cap.release() cv2.destroyAllWindows() def close_cam(): global flag; flag = 1 print(flag)

得到照片:photo.py
import cv2 #cv2 opencv模块 #cv2.VideoCapture(0) 使用默认视频捕捉器 #加载脸的xml文件 加载器 def take_photo(): user_id = input('请输入用户id:') cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) facecascade = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml') font = cv2.FONT_HERSHEY_SCRIPT_SIMPLEX count = 1 while True: #img读到的照片 ok,img = cap.read() #检测这张照片有没有脸 #把彩色照片转换为灰度照片 #gray就是转换完的灰度的图片 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #检测脸要用灰度图片进行检测 #face 自己定义的变量 这里面放了所有的脸的坐标和大小 #脸的坐标:这张脸在图片的坐标和这张脸在图片里面的大小 faces = facecascade.detectMultiScale( gray, scaleFactor=1.5,#为每一个图像尺度中的尺度参数,默认为1.1 minNeighbors=5,#参数为每一个级联矩阵应该保留的近邻个数,默认值为3,经历过几次后才确定下来 minSize=(32,32) # 检测的像素点大小 )#如果有脸把脸框起来 for (x,y,w,h) in faces: #画矩形 cv2.putText(img,'xiaozhanzhan',(x+1,y-20),font,1,(0,25,255),2)#1表示大小,2表示粗细 cv2.imwrite('./Face_data/user.' + user_id + '.' + str(count) + '.jpg', gray[y:y + h, x:x + w]) cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 3) count += 1 #count = count +1 if count == 101: breakcv2.imshow('video',img)key = cv2.waitKey(1) if key == 27: break cap.release() cv2.destroyAllWindows()


训练部分:train.py
import os import numpy as np import cv2 from PIL import Image #创建一个训练器 def train_face(): recongizer = cv2.face.LBPHFaceRecognizer_create() facecascade = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml') #写照片的路径是啥 Facedata/xxxxx.jpg #取照片的路径是啥 Facedata/xxxxx.jpg # face03.py Facedata/user.1001.1.jpg img_path = 'Face_data'#照片的路径文件夹 #ret = os.listdir(img_path)#显示指定路径下面的所有文件夹名字 #print(ret)#ret是一个列表 数组 #for f in ret: #print(os.path.join(img_path,f)) all_img_paths = [os.path.join(img_path,f) for f in os.listdir(img_path)] print(all_img_paths) #图片已知路径 #训练照片 需要两组数据 一个是ID 一个是图片特征 #这两组数据都需要存起来 ids =[]#id face_samples = []#放脸的信息 for each_img in all_img_paths: #print(each_img) id =int(os.path.split(each_img)[1].split('.')[1]) #把图片转换成训练所需要的格式数据PIL_img放的照片的数据 PIL_img数据是数组 PIL_img = Image.open(each_img).convert('L') #把读到的数据转换成灰度数据 #把图片数据进行格式长度转换为8位数据矩阵 np_img = np.array(PIL_img,'uint8') #检测转换后的数据矩阵里面有没有脸 faces = facecascade.detectMultiScale(np_img) for (x,y,w,h) in faces: #脸的信息放入数组face_samples face_samples.append(np_img[y:y+h,x:x+w]) ids.append(id) print(np.array(ids)) recongizer.train(face_samples,np.array(ids)) #people.yml 训练完的照片的特征文件,识别的时候会用到 recongizer.write('people.yml')

最后就是识别:discern.py
import os import numpy as np import cv2 from PIL import Image def discern_face(): font = cv2.FONT_HERSHEY_SCRIPT_SIMPLEX cap = cv2.VideoCapture(0,cv2.CAP_DSHOW) #创建一个训练器 recongizer = cv2.face.LBPHFaceRecognizer_create() facecascade = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml')#加载训练好的文件 用来识别 recongizer.read('people.yml')while True: ok,img = cap.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = facecascade.detectMultiScale( gray, scaleFactor=1.5,# 为每一个图像尺度中的尺度参数,默认为1.1 minNeighbors=5,# 参数为每一个级联矩阵应该保留的近邻个数,默认值为3,经历过几次后才确定下来 minSize=(32, 32)# 检测的像素点大小 ) for (x, y, w, h) in faces: # 画矩形 cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2) #开始识别脸 con是准确率 id,con = recongizer.predict(gray[y:y+h,x:x+w]) #print(type(id))if id == 1001: name = 'xiaozhanzhan' if id == 1002: name = 'lisi' cv2.putText(img, str(id), (x + 1, y - 20), font, 1, (0, 25, 255), 2) cv2.imshow('video', img) key = cv2.waitKey(1) if key == 27:# esc这个按键 break


    推荐阅读