您现在的位置是:首页 >其他 >Python | 人脸识别系统 — 人脸比对网站首页其他

Python | 人脸识别系统 — 人脸比对

-鷾- 2023-07-13 15:06:18
简介Python | 人脸识别系统 — 人脸比对

本博客为人脸识别系统的人脸比对代码解释

人脸识别系统博客汇总:人脸识别系统-博客索引

项目GitHub地址:

注意:阅读本博客前请先参考以下博客

工具安装、环境配置:人脸识别系统-简介

UI界面设计:人脸识别系统-UI界面设计

UI事件处理:人脸识别系统-UI事件处理

摄像头展示画面:人脸识别系统-摄像头画面展示

阅读完本博客后可以继续阅读:

摄像头画面展示:人脸识别系统-摄像头画面展示

用户端逻辑:

管理员端逻辑:

  • 管理员操作:
  • 用户操作:

一、关键代码

        1、主要方法

  • load_image_file —— 加载要识別的人脸图像

    • 加载要识別的人脸图像,加载返回的数据是 Numpy 数組,记录了图片的所有像素的特征向量。
  • face_locations —— 定位图中所有的人脸的像素位置   
    • 返回值是一个列表形式。列表中每一个元素是一张人脸的位置信息,包括[top, right, bottom, left]。
  • face_encodings —— 获取图像文件中所有面部编码信息
    • 返回值是一个编码列表,参数仍然是要识别的图像对象,如果后续访问时需要加上索引或遍历进行访问,每张人脸的编码信息为一个128维向量。
  • face_encodings —— 获取图像文件中所有面部编码信息
    • 返回值是一个编码列表,参数仍然是要识别的图像对象,如果后续访问时需要加上索引或遍历进行访问,每张人脸的编码信息为一个128维向量。
    • 第一个参数是一个面部编码列表(很多张脸), 第二个参数是给出单个面部编码(一张脸), compare_faces 会将第二个参数中的编码信息与第一个参数中的所有编码信息依次匹配,返回值是一个布尔列表,匹配成功则返回 True,匹配失败则返回 False,顺序与第一个参数中脸部编码顺序一致。
    • 参数 tolerance 为识别阈值,默认值是 0.39。tolerance 值越小,匹配越严格。

  更多关于人脸识别库face_recognition基础使用教程请参考:face_recognition GitHub

        2、代码

    def compare_face(self):
        if self.imgA_path == "":
            QMessageBox.information(self, "提示", self.tr("请先导入照片一"))
        elif self.imgB_path == "":
            QMessageBox.information(self, "提示", self.tr("请先导入照片二"))
        else:
            imgA = face_recognition.load_image_file(self.imgA_path)
            imgB = face_recognition.load_image_file(self.imgB_path)
            try:
                A_face_encoding = face_recognition.face_encodings(imgA)[0]
                B_face_encoding = face_recognition.face_encodings(imgB)[0]
                known_faces = [A_face_encoding]
                results = face_recognition.compare_faces(known_faces, B_face_encoding)[0]
                if results:
                    QMessageBox.information(self, "提示", self.tr("两张图片为同一个人"))
                else:
                    QMessageBox.information(self, "提示", self.tr("两张图片为两个不同的人"))
            except IndexError:
                QMessageBox.information(self, "提示", self.tr("图片导入失败,请重新导入图片!"))
                quit()

二、其余代码

# 人脸比对界面
class FaceCompareWindow(QMainWindow, FaceCompareUi):
    def __init__(self):
        super(FaceCompareWindow, self).__init__()
        self.setupUi(self)

        self.imgA_path = ""
        self.imgB_path = ""
        self.imgB = None
        self.imgA = None

        self.img_a_button.clicked.connect(self.open_imgA)
        self.img_b_button.clicked.connect(self.open_imgB)
        self.compare_button.clicked.connect(self.compare_face)
        self.close_button.clicked.connect(self.close_window)

    def open_imgA(self):
        imgA_path, fileType = QtWidgets.QFileDialog.getOpenFileName(self, "选取文件", os.getcwd(),
                                                                    "All Files(*);;Text Files(*.txt)")
        if not imgA_path.endswith('jpg') | imgA_path.endswith('png'):
            QMessageBox.about(self, '提示', '请选择jpg或者png类型图片')
        else:
            # 如果使用 cv2.imread 不能导入中文路径
            imgA = cv2.imdecode(np.fromfile(imgA_path, dtype=np.uint8), -1)
            frame_location = face_recognition.face_locations(imgA)
            if len(frame_location) == 0:
                QMessageBox.information(self, "提示", self.tr("没有检测到人脸,请重新导入图片!"))
            else:
                QApplication.processEvents()
                self.imgA = imgA
                self.imgA_path = imgA_path
                show = cv2.resize(imgA, (221, 261))  # 截取图片
                show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)  # 显示原图
                showImage = QImage(show.data, show.shape[1], show.shape[0], show.shape[1] * 3, QImage.Format_RGB888)
                self.img_a_show.setPixmap(QPixmap.fromImage(showImage))
                self.img_a_path.setText(imgA_path)

    def open_imgB(self):
        imgB_path, fileType = QtWidgets.QFileDialog.getOpenFileName(self, "选取文件", os.getcwd(),
                                                                    "All Files(*);;Text Files(*.txt)")
        if not imgB_path.endswith('jpg') | imgB_path.endswith('png'):
            QMessageBox.about(self, '提示', '请选择jpg或者png类型图片')
        else:
            imgB = cv2.imdecode(np.fromfile(imgB_path, dtype=np.uint8), -1)
            frame_location = face_recognition.face_locations(imgB)
            if len(frame_location) == 0:
                QMessageBox.information(self, "提示", self.tr("没有检测到人脸,请重新导入图片!"))
            else:
                QApplication.processEvents()
                self.imgB = imgB
                self.imgB_path = imgB_path
                show = cv2.resize(imgB, (221, 261))
                show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)
                showImage = QImage(show.data, show.shape[1], show.shape[0], show.shape[1] * 3, QImage.Format_RGB888)
                self.img_b_show.setPixmap(QPixmap.fromImage(showImage))
                self.img_b_path.setText(imgB_path)

    def compare_face(self):
        if self.imgA_path == "":
            QMessageBox.information(self, "提示", self.tr("请先导入照片一"))
        elif self.imgB_path == "":
            QMessageBox.information(self, "提示", self.tr("请先导入照片二"))
        else:
            imgA = face_recognition.load_image_file(self.imgA_path)
            imgB = face_recognition.load_image_file(self.imgB_path)
            try:
                A_face_encoding = face_recognition.face_encodings(imgA)[0]
                B_face_encoding = face_recognition.face_encodings(imgB)[0]
                known_faces = [A_face_encoding]
                results = face_recognition.compare_faces(known_faces, B_face_encoding)[0]
                if results:
                    QMessageBox.information(self, "提示", self.tr("两张图片为同一个人"))
                else:
                    QMessageBox.information(self, "提示", self.tr("两张图片为两个不同的人"))
            except IndexError:
                QMessageBox.information(self, "提示", self.tr("图片导入失败,请重新导入图片!"))
                quit()

    def close_window(self):
        self.img_a_show.setText("照片一")
        self.img_b_show.setText("照片二")
        self.img_a_path.setText("")
        self.img_b_path.setText("")
        self.imgA_path = ""
        self.imgB_path = ""
        self.imgB = None
        self.imgA = None
        self.close()

阅读完本博客后可以继续阅读:

摄像头画面展示:人脸识别系统-摄像头画面展示

用户端逻辑:

管理员端逻辑:

  • 管理员操作:
  • 用户操作:

 注:以上代码仅为参考,若需要运行,请参考项目GitHub完整源代码:

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。