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

博客汇总:Python | 人脸识别系统 — 博客索引

GitHub地址:Su-Face-Recognition

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

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

UI界面设计:Python | 人脸识别系统 — UI界面设计

UI事件处理:Python | 人脸识别系统 — UI事件处理

摄像头画面展示:Python | 人脸识别系统 — 摄像头画面展示

一、关键代码

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

    • 加载要识別的人脸图像,加载返回的数据是 Numpy 数組,记录了图片的所有像素的特征向量。

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

  更多关于人脸识别库 face_recognition 的基础使用教程请移步:face_recognition GitHub

二、其余代码

# 人脸比对界面
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源代码: Su-Face-Recognition

猜你喜欢

转载自blog.csdn.net/sun80760/article/details/130495203