python人脸识别系统 人脸检测 实时检测 深度学习 Dlib库 大数据 毕业设计(源码)?

发布时间:2024年01月23日

毕业设计:2023-2024年计算机专业毕业设计选题汇总(建议收藏)

毕业设计:2023-2024年最新最全计算机专业毕设选题推荐汇总

🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业?。🍅

1、项目介绍

技术栈:
Python语言、pyqt5图形界面、opencv、ResNet深度卷积神经网络、Dlib库

系统实现了集识别人脸、录入人脸、管理人脸在内的多项功能:包括通过选择人脸图片、视频、摄像头进行已录入人脸的实时识别;可通过图片和摄像头检测人脸并录入新的人脸;通过系统管理和更新人脸数据等功能,检测速度快、识别精度较高。

2、项目界面

(1)人脸识别—图片识别

在这里插入图片描述

(2)人脸识别–视频识别
在这里插入图片描述

(3)录入人脸

在这里插入图片描述

(4)摄像头实时人脸识别

在这里插入图片描述

(5)摄像头实时人脸识别2

在这里插入图片描述

(6)系统首页界面

在这里插入图片描述

(7)人脸识别记录管理

在这里插入图片描述

3、项目说明

(1)系统实现了集识别人脸、录入人脸、管理人脸在内的多项功能:包括通过选择人脸图片、视频、摄像头进行已录入人脸的实时识别;可通过图片和摄像头检测人脸并录入新的人脸;通过系统管理和更新人脸数据等功能,检测速度快、识别精度较高。

(2)人脸识别原理
如今机器学习、神经网络方法广泛应用于人脸识别领域,而后深度学习广泛应用于各种目标检测领域,2015年,Google团队的FaceNet在LFW数据集上得平均准确率达到了99.63%,基于深度学习的人脸识别的准确率已经高于人类本身,深度学习在人脸识别领域基本占据了统治地位。

Dlib是一个包含机器学习算法的C++开源工具包,目前已经被广泛的用在行业和学术领域,包括机器人,嵌入式设备,移动电话和大型高性能计算环境。作为人脸识别工具之一,Dlib在图像处理及人脸面部特征处理、分类、识别等方面具有计算简单、较容易实现的优点。

Dlib在人脸识别上的应用:(1)接受图像并将其加载到一个像素数组中进行处理;(2)使用局部二进制模式的人脸描述生成新的图像;(3)根据Dlib库中的scan_image_boxes等函数写入读取到的图片,进而计算人脸之间的特征向量;(4)与人脸数据库中的特征向量进行对比并利用全局函数threshold_image计算阈值,完成人脸识别1。

Dlib可通过Python调用,实现对图像预处理、提取特征向量、与人脸数据库中数据进行校验进而判别人物身份的流程。这里我们的人脸识别的过程有人脸检测(Face Detection)、人脸对齐(Face Alignment)、人脸表示(Face Representation)和人脸匹配(Face Matching),示意图如下图所示:

(1)人脸检测(Face Detection):首先利用Dlib的get_frontal_face_detector方法检测人脸区域并输出人脸矩形的四个坐标点。调用get_frontal_face_detector会返回 dlib 库中包含的预训练方向梯度直方图 (HOG)结合线性支持向量机(SVM)的人脸检测器,该检测器快速高效。由于方向梯度直方图 (HOG) 描述符的工作原理,它对图像几何的和光学的形变都能保持很好的不变性。

(2)人脸对齐(Face Alignment):这是人脸识别系统中的一种标准操作,即从人脸区域中检测到人脸特征点,并以特征点为依据对人脸进行归一化操作,使人脸区域的尺度和角度一致,方便特征提取与人脸匹配。一般通过旋转、平移与缩放将目标人脸区域放置在图像特定位置。这样做可以减小需要处理的人脸图像在空间分布上的差异。这里我们使用的是基于回归树的人脸对齐算法2,该算法是Vahid Kazemi 和 Josephine Sullivan在CVPR2014上发表的One Millisecond Face Alignment with an Ensemble of Regression Trees算法(以下简称GBDT),这种方法通过建立一个级联的残差回归树(GBDT)来使人脸形状从当前形状一步一步回归到真实形状。每一个GBDT的每一个叶子节点上都存储着一个残差回归量,当输入落到一个节点上时,就将残差加到改输入上,起到回归的目的,最终将所有残差叠加在一起,就完成了人脸对齐的目的。此处我们使用shape_predictor方法载入shape_predictor_68_face_landmarks.dat模型实现。

(3)人脸表示(Face Representation):这一步我们从归一化的人脸区域中进行面部特征提取,采用深度神经网络方法得到具有128个特征的特征向量。这里利用Dlib中的残差学习深度神经网络(ResNet)3为待识别人脸创建128维特征向量。人脸的特征表示,最理想的情况是不同人脸的照片提取出的特征向量差异较大,而同一人脸在不同照片中可以提取出相似度高的特征向量。此处我们使用的是dlib库中的face_recognition_model_v1方法,使用预训练的dlib_face_recognition_resnet_model_v1.dat模型。

(4)人脸匹配(Face Matching):将待识别图片中提取的特征向量与比对图中的进行对比,通过评估方法计算两幅照片的相似度。可以根据相似得分,将得分高的判断为同一人,得分低的判断为不同人。这里我们使用欧式距离计算,两个人脸特征向量的欧式距离越小,则两张人脸越相似,若人脸图像与待识别人像之间的欧式距离小于设定的阈值(这里我设置为0.4)时,则判定为同一人。

4、核心代码

# -*- coding: utf-8 -*-
# 人脸识别与管理系统:本程序用于图片、视频及摄像头中人脸识别


import csv
import glob
import os
import re
import shutil
import time
import warnings
from os import getcwd

import cv2
import dlib
import numpy as np
import pandas as pd
from PIL import Image, ImageDraw, ImageFont
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QMovie
from PyQt5.QtWidgets import QFileDialog, QTableWidgetItem, QAbstractItemView
from PyQt5.QtCore import Qt
import datetime

from FaceRecognition_UI import Ui_MainWindow

# 忽略警告
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
warnings.filterwarnings(action='ignore')


class Face_MainWindow(Ui_MainWindow):
    def __init__(self, MainWindow):
        self.path_face_dir = "../data/database_faces/"
        self.fontC = ImageFont.truetype("./Font/platech.ttf", 14, 0)

        self.cap_video = None  # 视频流对象

        self.path = getcwd()
        self.video_path = getcwd()

        self.timer_camera = QtCore.QTimer()  # 定时器
        self.timer_camera_load = QtCore.QTimer()  # 载入相机定时器
        self.timer_video = QtCore.QTimer()  # 视频定时器
        self.flag_timer = ""  # 用于标记正在进行的功能项(视频/摄像)

        self.CAM_NUM = 0  # 摄像头标号
        self.cap = cv2.VideoCapture(self.CAM_NUM)  # 屏幕画面对象
        self.cap_video = None  # 视频流对象

        self.current_image = None  # 当前的画面
        self.current_face = None  # 当前的人脸

        self.setupUi(MainWindow)  # 界面生成
        self.retranslateUi(MainWindow)  # 界面控件
        self.resetUi()
        self.slot_init()  # 槽函数

        self.count = 0
        self.count_face = 0
        self.col_row = []
        # Dlib 正向人脸检测器
        self.detector = dlib.get_frontal_face_detector()
        self.predictor = dlib.shape_predictor('../data/data_dlib/shape_predictor_68_face_landmarks.dat')
        self.face_reco_model = dlib.face_recognition_model_v1("../data/data_dlib"
                                                              "/dlib_face_recognition_resnet_model_v1.dat")
        self.face_feature_exist = []  # 用来存放所有录入人脸特征的数组
        self.face_name_exist = []  # 存储录入人脸名字

        # 用来存储上一帧和当前帧 ROI 的质心坐标
        self.last_centroid = []
        self.current_centroid = []

        # 用来存储上一帧和当前帧检测出目标的名字
        self.last_face_name = []
        self.current_face_name = []

        # 上一帧和当前帧中人脸数的计数器
        self.last_face_cnt = 0
        self.current_face_cnt = 0

        # 存储当前摄像头中捕获到的所有人脸的坐标名字
        self.current_face_position = []
        # 存储当前摄像头中捕获到的人脸特征
        self.current_face_feature = []

        self.reclassify_cnt = 0
        self.reclassify_interval = 20

        # 前后帧的距离
        self.last_current_distance = 0

        # 用来存放识别的距离
        self.current_face_distance = []

        self.exist_flag = None

    def resetUi(self):
        # 设置表格形式
        self.tableWidget_rec.horizontalHeader().setVisible(True)
        self.tableWidget_mana.horizontalHeader().setVisible(True)
        self.tableWidget_rec.setColumnWidth(0, 80)
        self.tableWidget_rec.setColumnWidth(1, 200)
        self.tableWidget_rec.setColumnWidth(2, 150)
        self.tableWidget_rec.setColumnWidth(3, 200)
        self.tableWidget_rec.setColumnWidth(4, 120)

        self.tableWidget_mana.setColumnWidth(0, 80)
        self.tableWidget_mana.setColumnWidth(1, 350)
        self.tableWidget_mana.setColumnWidth(2, 150)
        self.tableWidget_mana.setColumnWidth(3, 150)
        self.tableWidget_mana.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tabWidget.setCurrentIndex(0)
        self.tabWidget.setTabVisible(0, True)
        self.tabWidget.setTabVisible(1, False)
        self.tabWidget.setTabVisible(2, False)

        # 设置初始取图和录入按钮不可用
        self.toolButton_get_pic.setEnabled(False)
        self.toolButton_load_pic.setEnabled(False)
        self.toolButton_file_2.setEnabled(False)
        self.toolButton_camera_load.setEnabled(False)

        # 设置界面动画
        self.gif_movie()

    def gif_movie(self):
        # 设置界面动画
        gif = QMovie(':/newPrefix/images_test/face_rec.gif')
        self.label_display.setMovie(gif)
        self.label_display.setScaledContents(True)
        gif.start()

    def ini_value(self):
        self.face_feature_exist = []  # 用来存放所有录入人脸特征的数组
        self.face_name_exist = []  # 存储录入人脸名字

        # 用来存储上一帧和当前帧 ROI 的质心坐标
        self.last_centroid = []
        self.current_centroid = []

        # 用来存储上一帧和当前帧检测出目标的名字
        self.last_face_name = []
        self.current_face_name = []

        # 上一帧和当前帧中人脸数的计数器
        self.last_face_cnt = 0
        self.current_face_cnt = 0

        # 存储当前摄像头中捕获到的所有人脸的坐标名字
        self.current_face_position = []
        # 存储当前摄像头中捕获到的人脸特征
        self.current_face_feature = []

        self.reclassify_cnt = 0
        self.reclassify_interval = 20

        # 前后帧的距离
        self.last_current_distance = 0

        # 用来存放识别的距离
        self.current_face_distance = []

    def slot_init(self):
        self.toolButton_run_load.clicked.connect(self.change_size_load)
        self.toolButton_run_rec.clicked.connect(self.change_size_rec)
        self.toolButton_run_manage.clicked.connect(self.change_size_mana)
        self.toolButton_new_folder.clicked.connect(self.new_face_doing)
        self.toolButton_file_2.clicked.connect(self.choose_file)
        self.toolButton_get_pic.clicked.connect(self.get_img_doing)
        self.toolButton_load_pic.clicked.connect(self.load_img_doing)
        self.toolButton_file.clicked.connect(self.choose_rec_img)
        self.toolButton_runing.clicked.connect(self.run_rec)
        self.toolButton_camera.clicked.connect(self.button_open_camera_click)
        self.timer_camera.timeout.connect(self.show_camera)
        self.toolButton_video.clicked.connect(self.button_open_video_click)
        self.timer_video.timeout.connect(self.show_video)
        self.toolButton_camera_load.clicked.connect(self.button_open_camera_load)
        self.timer_camera_load.timeout.connect(self.show_camera_load)
        self.toolButton_mana_update.clicked.connect(self.do_update_face)
        self.tableWidget_mana.cellPressed.connect(self.table_review)
        self.toolButton_mana_delete.clicked.connect(self.delete_doing)

    def choose_rec_img(self):
        self.flag_timer = ""
        # 选择图片或视频文件后执行此槽函数
        self.timer_camera.stop()
        self.timer_video.stop()
        if self.cap:
            self.cap.release()
        if self.cap_video:
            self.cap_video.release()  # 释放视频画面帧
        # 清除UI上的label显示
        self.label_plate_result.setText("未知人脸")
        self.label_score_fps.setText("0")
        self.label_score_num.setText("0")
        self.label_score_dis.setText("0")
        # 清除文本框的显示内容
        self.textEdit_camera.setText("实时摄像已关闭")
        self.textEdit_camera.setStyleSheet("background-color: transparent;\n"
                                           "border-color: rgb(0, 170, 255);\n"
                                           "color: rgb(0, 170, 255);\n"
                                           "font: regular 12pt \"华为仿宋\";")
        self.textEdit_video.setText('实时视频已关闭')
        self.textEdit_video.setStyleSheet("background-color: transparent;\n"
                                          "border-color: rgb(0, 170, 255);\n"
                                          "color: rgb(0, 170, 255);\n"
                                          "font: regular 12pt \"华为仿宋\";")
        self.label_display.clear()
        # self.label_display.setStyleSheet("border-image: url(:/newPrefix/images_test/ini-image.png);")
        self.gif_movie()
        self.label_pic_newface.clear()
        # 使用文件选择对话框选择图片
        fileName_choose, filetype = QFileDialog.getOpenFileName(
            self.centralwidget, "选取图片文件",
            self.path,  # 起始路径
            "图片(*.jpg;*.jpeg;*.png)")  # 文件类型
        self.path = fileName_choose  # 保存路径
        if self.path != '':
            self.flag_timer = "image"
            self.textEdit_file.setText(self.path + '文件已选中')
            self.textEdit_file.setStyleSheet("background-color: transparent;\n"
                                             "border-color: rgb(0, 170, 255);\n"
                                             "color: rgb(0, 170, 255);\n"
                                             "font: regular 12pt \"华为仿宋\";")
            image = self.cv_imread(self.path)  # 读取选择的图片
            # image = cv2.imread("../LicensePlateRecognition/test3.jpeg")  # 读取选择的图片

            image = cv2.resize(image, (500, 500))  # 设定图像尺寸为显示界面大小

            if len(image.shape) < 3:
                self.path = ''
                self.label_display.setText("需要正常彩色图片,请重新选择!")
                self.label_display.setStyleSheet("border-image: url(:/newPrefix/images_test/ini-image.png);")
                self.gif_movie()

                return

            self.current_image = image.copy()
            show = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
            # show = image.copy()
            showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)
            a = QtGui.QPixmap.fromImage(showImage)
            self.label_display.setPixmap(a)
            self.label_display.setScaledContents(True)
            QtWidgets.QApplication.processEvents()

        else:
            # 选择取消,恢复界面状态
            self.flag_timer = ""
            self.textEdit_file.setText('图片文件未选中')
            self.textEdit_file.setStyleSheet("background-color: transparent;\n"
                                             "border-color: rgb(0, 170, 255);\n"
                                             "color: rgb(0, 170, 255);\n"
                                             "font: regular 12pt \"华为仿宋\";")

    def change_table(self, path, res, time_now, distance):
        # 更新表格记录
        self.count += 1  # 每识别出结果增加一条记录
        if self.count > 6:
            self.tableWidget_rec.setRowCount(self.count)
        newItem = QTableWidgetItem(str(self.count))  # 在表格中记录序号
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget_rec.setItem(self.count - 1, 0, newItem)

        newItem = QTableWidgetItem(path)  # 在表格中记录车牌路径
        newItem.setTextAlignment(Qt.AlignVCenter)
        self.tableWidget_rec.setItem(self.count - 1, 1, newItem)

        newItem = QTableWidgetItem(res)  # 记录识别出的车牌在表格中
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget_rec.setItem(self.count - 1, 2, newItem)
        self.tableWidget_rec.setCurrentItem(newItem)

        newItem = QTableWidgetItem(time_now)  # 记录识别出的车牌位置在表格中
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget_rec.setItem(self.count - 1, 3, newItem)
        self.tableWidget_rec.setCurrentItem(newItem)

        newItem = QTableWidgetItem(str(round(distance, 4)))  # 记录识别出的车牌置信度在表格中
        newItem.setTextAlignment(Qt.AlignCenter)
        self.tableWidget_rec.setItem(self.count - 1, 4, newItem)
        self.tableWidget_rec.setCurrentItem(newItem)

5、源码获取方式

🍅由于篇幅限制,获取完整文章或源码、代做项目的,查看我的【用户名】、【专栏名称】、【顶部选题链接】就可以找到我啦🍅

感兴趣的可以先收藏起来,点赞、关注不迷路,下方查看👇🏻获取联系方式👇🏻

文章来源:https://blog.csdn.net/vx_biyesheji0001/article/details/135758701
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。