人脸识别项目答辩后的一些思考

最近天气愈发燥热,伴随着互联网整体大环境的下行,网络上的焦虑像病毒一样蔓延。

沉下心,才能做好事————

识别用了MTCNN

  • MTCNN采用多层级的级联结构,可以在不同尺度上检测人脸。这对于应对不同大小的人脸很有用,因为人脸在图像中可能以不同的尺寸出现。通过多尺度检测,MTCNN能够有效捕捉不同尺度下的人脸。
  • 实时性能:MTCNN经过有效的网络设计和优化,使其在实时场景下能够快速运行。级联结构允许模型在每个阶段中进行剪枝和筛选,减少了计算量,提高了检测速度。这使得MTCNN适用于很多实时应用,如人脸识别、表情识别和人脸跟踪等。
  • 本质:一个一个找 + 图像金字塔

损失函数:Arcfaceloss

减小类内聚、增加类间距

纸上得来终觉浅,绝知此事要coding

import cv2
import torch
from PIL import Image
from torchvision import transforms
import os
from MTCNN_Detect import Mtcnn_detect, loader_mtcnn, loader_Densenet201


Mtcnn_net = loader_mtcnn()  # 加载MTCNN
Densenet201 = loader_Densenet201()  # 网络


def library(image, name, Densenet201):     # image 人脸生图,   name 入库人姓名, Densenet201 网络
    Mtcnn_result = Mtcnn_detect(image, Mtcnn_net)   # MTCNN侦测方法,返回的是旋转拉正的人脸图片
    # 判断MTCNN人脸检测是否为None
    if Mtcnn_result==None:
        return

    img = Mtcnn_result    # 入库人脸图片
    img = transforms.ToTensor()(img)
    img = torch.unsqueeze(img, dim=0)

    li = []   # 库字典
    # 网络放入cuda
    Densenet201 = Densenet201.cuda()
    # net.load_state_dict(torch.load(r"D:\pythonProject1\person_face\parames\wight1.pth"))  # 加载权重文件
    # net.eval()   # 打开推理模式(测试模式)

    img = img.cuda()  # 放入cuda
    feature = Densenet201.feature(img)   # 获取网络输出特征向量
    feature = feature.tolist()   # 张量数据结构  转为列表
    li.append([name, feature])  # 姓名:特征向量, 键值对
    print(type(li))

    # pth文件入库
    path = r"D:\FaceProject\Face\faces.pth"   # pth 文件路径

    # 检查.pth文件是否为空
    if os.path.getsize(path) == 0:
        # .pth文件路径
        torch.save([li], path)

    # 当前库文件如果不是空的就需要把入库人脸特征添加进去,防止覆盖
    else:
        existing_data = torch.load(path)
        # 将新数据添加到现有数据中
        existing_data.append(li)
        # 保存更新后的数据回.pth文件
        torch.save(existing_data, path)

    return li


    # 判断库文件是否存在
    # if os.path.exists(r"D:\pythonProject1\person_face\libray.txt"):
    #     pass
    # else:
    #     with open(r"D:\pythonProject1\person_face\libray.txt", "w+", ) as libray:    # 创建库文件   os 是创建文件夹不是文件,
    #         print(f"库文件: libray.txt  创建成功")
    #
    # # 入库
    # with open(r"D:\pythonProject1\person_face\libray.txt", "a", encoding='utf-8') as file:
    #     file.write(f"{li}\n")
    #     print("入库成功")
    #     # file.write(li)
    # return li



# 入库3次
# for i in range(3):
#     image = Image.open(r"E:\FaceImage\陈昊\dst_img\chenhao (1).jpg")
#     a = library(image)




def video_ku():
    # 加载两个网络
    mtcnn_net = loader_mtcnn()
    densenet201_net = loader_Densenet201()

    # 打开视频文件
    video = cv2.VideoCapture(0)

    # 确保视频文件打开成功
    if not video.isOpened():
        print("无法打开视频文件")
        return

    # 获取视频的帧率
    fps = video.get(cv2.CAP_PROP_FPS)
    print(fps)

    # 设置视频窗口大小
    window_width = 800
    window_height = 800
    cv2.namedWindow("Video", cv2.WINDOW_NORMAL)
    cv2.resizeWindow("Video", window_width, window_height)

    # 设置保存区域的起始坐标和大小
    save_x = 80
    save_y = 20
    save_width = 450
    save_height = 400

    # 设置矩形的颜色和线宽
    rectangle_color = (255, 0, 0)  # 蓝色
    rectangle_thickness = 3


    while True:
        # 读取视频的帧
        ret, frame = video.read()    # ret 是一个布尔值,表示是否成功读取到了一帧。如果成功读取到帧,则 ret 的值,   frame是一个表示视频帧的图像数据,通常是一个 NumPy 数组。如果成功读取到帧,

        # 检查是否成功读取帧
        if not ret:
            break

        cv2.rectangle(frame, (save_x, save_y), (save_x + save_width, save_y + save_height), rectangle_color,
                      rectangle_thickness)
        cv2.imshow("Video", frame)       # 显示

        # 检测是否按下空格键
        if cv2.waitKey(1) == ord(' '):
            # 保存当前帧为图片
            frame = frame
            print("截取成功!")
            # 将图像从 BGR 格式转换为 RGB 格式
            image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            # 创建 PIL 对象
            image_pil = Image.fromarray(image_rgb)
            print(image_pil)

            # 入库
            library(image_pil, name=None, Densenet201=None)


        key = cv2.waitKey(1)
        # 如果按下键盘上的 "q" 键,则退出循环
        if key == ord("q"):
            break


    # 释放视频对象
    video.release()

# video_ku()

Qt的展示界面:

import os
import sys
import cv2
from PIL import Image
from PyQt5.QtGui import QImage, QPixmap, QFont, QColor
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QLineEdit, QPushButton, QLabel, QTextEdit
from MTCNN_Detect import loader_mtcnn, loader_Densenet201
from input_library import library

# 加载网络和权重
Mtcnn_net = loader_mtcnn()  # 加载MTCNN
Densenet201 = loader_Densenet201()  # 网络
print("网络加载成功")


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("中建八局员工人脸录入系统")
        self.setFixedSize(500, 500)  # 设置固定大小

        layout = QVBoxLayout()

        self.button = QPushButton("请正视摄像头")  # 创建一个按钮
        self.button.clicked.connect(self.button_clicked)
        self.button.setMinimumSize(200, 50)  # 设置按钮的最小宽度为200像素,高度为50像素
        self.button.setMaximumSize(300, 70)  # 设置按钮的最大宽度为300像素,高度为70像素
        layout.addWidget(self.button)

        layout.addWidget(QLabel("请输入员工姓名:"))

        self.text_input = QLineEdit()  # 创建一个文本输入框
        layout.addWidget(self.text_input)

        self.image_label = QLabel()  # 创建一个标签用于显示图像
        layout.addWidget(self.image_label)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

        # 设置布局为自适应窗口大小
        layout.setSizeConstraint(QVBoxLayout.SetNoConstraint)

        # 将图像标签的缩放模式设置为自适应布局
        self.image_label.setScaledContents(True)

        # 初始化按键
        self.key = None

        # 功能按钮二  截取图片入库
        self.button2 = QPushButton("人脸入库")
        self.button2.clicked.connect(self.button2_clicked)
        self.button2.setMinimumSize(200, 50)  # 设置按钮的最小宽度为200像素,高度为50像素
        self.button2.setMaximumSize(300, 70)  # 设置按钮的最大宽度为300像素,高度为70像素
        layout.addWidget(self.button2)

        # 显示结果
        self.result_text = QTextEdit()
        font = QFont()
        font.setPointSize(12)  # 设置字体大小为12
        self.result_text.setFont(font)

        # 设置字体颜色
        text_color = QColor(255, 0, 0)  # 设置为红色 (R, G, B)
        self.result_text.setTextColor(text_color)

        layout.addWidget(self.result_text)

        # 获取输入文本
        self.input_text = None

    # 入库按钮
    def button2_clicked(self):
        self.key = " "  # 空格截取
        self.input_text = self.text_input.text()  # 获取文本输入框中的字符串

    # 打开摄像头
    def button_clicked(self):

        # 判断库文件pth 收否存在,
        path = r"D:\FaceProject\Face\faces.pth"  # pth 文件路径
        # 判断当前有无库文件, 没有就创建
        if os.path.exists(path):
            pass
        else:
            with open(path, "w+", ) as libray:  # 创建库文件   os 是创建文件夹不是文件,
                pass

        # if True:
        # 打开视频文件
        video = cv2.VideoCapture(0)

        # 确保视频文件打开成功
        if not video.isOpened():
            print("无法打开视频文件")
            return

        # 获取视频的帧率
        fps = video.get(cv2.CAP_PROP_FPS)
        print(fps)

        while True:
            # 读取视频的帧
            ret, frame = video.read()

            # 检查是否成功读取帧
            if not ret:
                break

            # 将OpenCV的图像转换为QImage格式
            image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            height, width, channel = image.shape
            bytes_per_line = 3 * width
            q_image = QImage(frame.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped()

            # 将QImage显示在QLabel控件中
            self.image_label.setPixmap(QPixmap.fromImage(q_image))

            QApplication.processEvents()  # # 更新界面

            # 检测是否按下空格键
            if self.key == " ":
                # 保存当前帧为图片
                frame = frame
                # print("截取成功!")
                # 将图像从 BGR 格式转换为 RGB 格式
                image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                # 创建 PIL 对象
                image_pil = Image.fromarray(image_rgb)
                print(image_pil)

                # 入库
                print("姓名:", self.input_text)
                result = library(image_pil, self.input_text,
                                 Densenet201)
                self.result_text.setPlainText(f"入库信息:\n {
      
      str(result)}")
                self.key = None

            else:
                pass


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

import sys
import cv2
from PIL import Image
from PyQt5.QtGui import QImage, QPixmap, QColor, QFont
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton, QLabel, QTextEdit
from Face_Detect import face_detect
from MTCNN_Detect import Mtcnn_detect, loader_Densenet201, loader_mtcnn

Densenet201 = loader_Densenet201()
Mtcnn = loader_mtcnn()
print("网络加载成功")


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("中建八局人脸识别系统")
        self.setFixedSize(500, 500)  # 设置固定大小

        # self.setWindowTitle("人脸识别检测")

        layout = QVBoxLayout()
        self.button = QPushButton("请正视摄像头")  # 按钮1
        self.button.clicked.connect(self.button_clicked)
        self.button.setMinimumSize(200, 50)  # 设置按钮的最小宽度为200像素,高度为50像素
        self.button.setMaximumSize(300, 70)  # 设置按钮的最大宽度为300像素,高度为70像素
        layout.addWidget(self.button)

        self.image_label = QLabel()  # 添加一个QLabel控件用于显示图像
        layout.addWidget(self.image_label)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

        self.button3 = QPushButton("开始检测")
        self.button3.clicked.connect(self.button3_clicked)
        self.button3.setMinimumSize(200, 50)  # 设置按钮的最小宽度为200像素,高度为50像素
        self.button3.setMaximumSize(300, 70)  # 设置按钮的最大宽度为300像素,高度为70像素
        layout.addWidget(self.button3)

        # 设置布局为自适应窗口大小
        layout.setSizeConstraint(QVBoxLayout.SetNoConstraint)

        # 将图像标签的缩放模式设置为自适应布局
        self.image_label.setScaledContents(True)

        # 显示结果
        self.result_text = QTextEdit()
        font = QFont()
        font.setPointSize(12)  # 设置字体大小为12
        self.result_text.setFont(font)

        # 设置字体颜色
        text_color = QColor(255, 0, 0)  # 设置为红色 (R, G, B)
        self.result_text.setTextColor(text_color)

        layout.addWidget(self.result_text)

        # 继续检测开关
        self.num = 0
        # 开始检测按钮
        self.start = None

    # 继续检测按钮
    def button2_clicked(self):
        # 在这里调用你自己的函数
        self.num = 0

    # 开始检测按钮
    def button3_clicked(self):
        # 在这里调用你自己的函数
        self.start = 0

    # 检测人脸
    def button_clicked(self):
        print("正在识别,请稍后......")
        # 在这里调用您自己的函数

        # if True:
        # 打开视频文件
        video = cv2.VideoCapture(0)

        # 确保视频文件打开成功
        if not video.isOpened():
            print("无法打开视频文件")
            return

        # 获取视频的帧率
        fps = video.get(cv2.CAP_PROP_FPS)
        print(fps)

        # 设置检测区域的起始坐标和大小
        save_x = 80
        save_y = 20
        save_width = 450
        save_height = 400

        # 设置矩形的颜色和线宽
        rectangle_color = (255, 0, 0)  # 蓝色
        rectangle_thickness = 3

        frame_count = 0  # 计数
        interval = 20  # 设置检测帧率, 多少帧检测一次

        while True:
            # 读取视频的帧
            ret, frame = video.read()

            # 检查是否成功读取帧
            if not ret:
                break

            # 在视频帧上画出矩形区域
            # cv2.rectangle(frame, (save_x, save_y), (save_x + save_width, save_y + save_height), rectangle_color,
            #               rectangle_thickness)

            # # 将OpenCV的图像转换为QImage格式
            image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            height, width, channel = image.shape
            bytes_per_line = 3 * width
            q_image = QImage(frame.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped()

            # 将QImage显示在QLabel控件中
            self.image_label.setPixmap(QPixmap.fromImage(q_image))

            QApplication.processEvents()  # 更新界面

            if self.start != None:
                # 设置检测帧率
                if frame_count % interval == 0 and self.num == 0:  # 添加检测开关

                    save_image = frame[save_y:save_y + save_height, save_x:save_x + save_width]
                    # 将图像从 BGR 格式转换为 RGB 格式
                    image_rgb = cv2.cvtColor(save_image, cv2.COLOR_BGR2RGB)
                    image_pil = Image.fromarray(image_rgb)
                    if Mtcnn_detect(image_pil, Mtcnn) == None:
                        continue
                    else:
                        result = Mtcnn_detect(image_pil, Mtcnn)  # 返回MTCNN结果
                        face_result = face_detect(result, threshold=0.6, loader_net=Densenet201)
                        # 显示结果
                        self.result_text.setPlainText(f"人脸识别结果:\n {
      
      str(face_result)}")
                        if face_result != None:  # 设置开关
                            self.num = 1
                        else:
                            pass
            else:
                pass
            frame_count += 1
        video.release()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

猜你喜欢

转载自blog.csdn.net/weixin_44659309/article/details/131398266