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

整个代码是在PyCharm上运行的

代码的结构如图:haarcascade_frontalface_alt2.xml  这个文件需要自己下载Opencv库里面有对应的文件

基于OpenCv的人脸识别系统设计_第1张图片

环境配置如下图:

基于OpenCv的人脸识别系统设计_第2张图片

整个运作流程:用PyQt5做了一个简单的图形化界面

基于OpenCv的人脸识别系统设计_第3张图片

代码的主体部分: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 cv2

flag = 0
def face_detection():
    cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    facecascade = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml')
    while True:
        global  flag;
        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:
            break

         cv2.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

你可能感兴趣的:(opencv,pycharm,python,人脸识别)