人脸识别系统之动态人脸识别

二.动态人脸识别

1.摄像头人脸识别

1.1.导入资源包

import dlib
import cv2
import face_recognition
from PIL import Image, ImageTk
import tkinter as tk
import os

:这些导入语句允许您在代码中使用这些库和模块提供的功能,例如创建图形用户界面、处理文件、进行图像处理和人脸识别等。
Dlib:是一个开源的机器学习库,包含了许多常用的机器学习算法。它还包含了一个名为shape_predictor的模块,用于检测人脸的关键点。

1.2.初始化摄像头

# 初始化摄像头
cap = cv2.VideoCapture(0)
#参数0指定要使用的摄像头设备。在大多数情况下,0表示默认摄像头。

:这行代码初始化了摄像头,并将其作为cap对象返回。cv2.VideoCapture(0)中的0参数通常表示默认摄像头。这行代码是用于从摄像头上捕获实时视频流。

1.3.创建主窗口

root = tk.Tk()
root.title("人脸识别程序")
root.geometry('600x600')

:这段代码通常用于创建一个Tkinter窗口,并为其设置一个标题和一个初始大小。在后续的代码中,您可以添加更多的组件,如按钮、标签、图像等,来构建图形用户界面。

1.4.创建画布

# 创建画布
canvas = tk.Canvas(root, width=600, height=600)
canvas.pack()

:这段代码首先导入了 Tkinter 模块,并创建了一个名为 root 的窗口。然后,它创建了一个画布(canvas),并设置了其宽度和高度。最后,它将画布添加到窗口中,并启动了 Tkinter 的主循环,这样窗口才会显示出来。

1.5.显示摄像头部分

# 摄像头画面显示部分
camera_frame = tk.Label(root)
camera_frame.place(x=50, y=50, width=400, height=400)

:这段代码创建了一个 Label 对象,并将其放置在窗口(root)的坐标 (50, 50) 处,大小为 400x400。然而,由于 Label 控件本身不支持显示动态内容,如摄像头捕获的帧,您需要使用其他方法(如前面提到的 Canvas 控件和 PIL/Pillow 库)来显示摄像头画面。

1.6.显示文本

# 文本显示部分
text_label = tk.Label(root, text="", font=('Helvetica', 12))
text_label.place(x=50, y=460, width=500, height=100)

:这段代码创建了一个 Label 对象,并将其放置在窗口(root)的坐标 (50, 460) 处,大小为 500x100。标签的初始文本内容为空,字体为 Helvetica 字体,字号为 12。

1.7.按钮的点击事件处理函数

# 按钮部分
def capture_face():
    ret, frame = cap.read()
    if ret:
        # 将人脸图像转换为RGB
        rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        # 检测人脸位置
        face_locations = face_recognition.face_locations(rgb_frame)

        # 如果检测到人脸
        if face_locations:
            # 对检测到的人脸进行编码
            face_encoding = face_recognition.face_encodings(rgb_frame, face_locations)[0]

            # 加载已保存的人脸编码
            known_face_encodings = []
            known_face_names = []
            for file in os.listdir("facecomparison"):
                image = face_recognition.load_image_file(f"facecomparison/{file}")
                encoding = face_recognition.face_encodings(image)[0]
                known_face_encodings.append(encoding)
                known_face_names.append(file)

            # 比较当前人脸与已知人脸
            matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
            if True in matches:
                text_label.config(text="该人脸已存在,请勿重复录入")
            else:
                # 裁剪人脸图像
                top, right, bottom, left = face_locations[0]
                face_image = frame[top:bottom, left:right]

                # 生成唯一的文件名
                unique_filename = f"facecomparison/face_{len(os.listdir('facecomparison')) + 1}.jpg"

                # 保存人脸到指定文件夹
                cv2.imwrite(unique_filename, face_image)
                text_label.config(text="人脸已录入")
        else:
            text_label.config(text="未检测到人脸")
    else:
        text_label.config(text="无法从摄像头读取帧")

:这段代码的作用是实现一个面部识别系统,该系统能够从摄像头捕获实时帧,检测帧中的人脸,并将新检测到的人脸与已保存的人脸编码进行比较。如果新检测到的人脸与已保存的人脸匹配,它会显示一个消息,告知用户该人脸已存在,不应该重复录入。如果新检测到的人脸与已保存的人脸不匹配,它会将新的人脸图像保存到指定的文件夹中,并显示一个消息,告知用户人脸已录入。如果无法从摄像头读取帧,或者没有检测到人脸,它会显示相应的错误消息。

1.8.识别摄像头捕获的人脸

def recognize_face():
    # 识别摄像头捕获的人脸
    ret, frame = cap.read()
    if ret:
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        rgb_frame = frame.copy()
        face_locations = face_recognition.face_locations(rgb_frame)
        face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)

        # 加载已保存的人脸编码和文件名
        known_face_encodings = []
        known_face_names = []
        for file in os.listdir("facecomparison"):
            image = face_recognition.load_image_file(f"facecomparison/{file}")
            encoding = face_recognition.face_encodings(image)[0]
            known_face_encodings.append(encoding)
            known_face_names.append(file)

        # 标记人脸并显示信息
        for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
            matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
            if True in matches:
                first_match_index = matches.index(True)
                text_label.config(text=f"识别到人脸,人脸属于:{known_face_names[first_match_index]}")
            else:
                cv2.rectangle(frame, (left, top), (right, bottom), (255, 0, 0), 2)  # 使用蓝色线条画框
                cv2.putText(frame, "新的人脸", (left + 10, top + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
                text_label.config(text="人脸不存在,请先录入人脸")

        # 更新画布
        image = Image.fromarray(frame)
        image = ImageTk.PhotoImage(image)
        camera_frame.configure(image=image)
        camera_frame.image = image
    else:
        text_label.config(text="无法从摄像头读取帧")

:这段代码是一个函数,当按钮被点击时,它会执行这个函数。这个函数的作用是识别摄像头捕获的实时帧中的人脸,并与已保存的人脸编码进行比较,以确定是否已存在。如果人脸存在,它会标记并显示该人脸的名称;如果人脸不存在,它会标记新的人脸并提示用户先录入人脸。

1.9.点击关闭程序的按钮

def close_program():
#关闭 Tkinter 应用程序
    root.quit()
#释放摄像头(cap)资源
    cap.release()

:当用户点击关闭程序的按钮时,这两个操作会确保 Tkinter 应用程序和摄像头资源都能被正确地关闭和释放,从而避免资源泄漏和潜在的系统问题。

1.10.创建按钮

button1 = tk.Button(root, text="录入人脸", command=capture_face, width=10, height=2)
button1.place(x=460, y=50, width=100, height=100)

button2 = tk.Button(root, text="识别人脸", command=recognize_face, width=10, height=2)
button2.place(x=460, y=200, width=100, height=100)

button3 = tk.Button(root, text="结束程序", command=close_program, width=10, height=2)
button3.place(x=460, y=350, width=100, height=100)

:这三行代码分别创建了三个按钮,并设置了它们的位置、大小和功能,当用户点击这些按钮时,会触发相应的函数执行。

1.11.更新摄像头的画面

# 更新摄像头画面的函数
def update_image():
    ret, frame = cap.read()
    if ret:
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        face_locations = face_recognition.face_locations(frame)
        for (top, right, bottom, left) in face_locations:
            cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)  # 使用绿色线条画框
        image = Image.fromarray(frame)
        image = ImageTk.PhotoImage(image)
        camera_frame.configure(image=image)
        camera_frame.image = image
    root.after(10, update_image)

# 开始更新画面
update_image()

# 主循环
root.mainloop()

# 释放摄像头
cap.release()

:这段代码的作用是在 Tkinter 窗口(root)中创建一个循环,用于从摄像头捕获实时帧,并在窗口中显示这些帧。这个循环会在每次捕获新帧后立即更新显示的图像。
运行结果
在这里插入图片描述

2.视频流人脸识别

2.1.导入资源包

import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
import cv2
import os
import subprocess
from pathlib import Path

:导入了所需的模块,这些模块将用于创建一个图形用户界面 (GUI) 应用程序,该应用程序可以处理图像文件、使用摄像头、执行命令行操作等。
cv2:这是 OpenCV 模块,用于处理图像和视频,包括摄像头捕捉、图像处理、特征检测等。os:这是 Python 的标准库,用于操作文件和目录,例如创建目录、删除文件、获取文件路径等。
pathlib:这是 Python 的标准库,用于处理文件和目录路径,提供了一个面向对象的接口,可以更方便地处理路径。

2.2.创建界面窗口

# 初始化窗口
win = tk.Tk()
win.title('视频流人脸识别')
win.geometry('600x600')
#创建了一个字体对象 title_font,用于设置标题的字体、大小和样式。title_font = ("Verdana", 20, 'italic')

:这段代码创建了一个名为 “视频流人脸识别” 的窗口,窗口的初始大小为 600x600 像素,并准备了一个斜体字体的对象,用于后续设置窗口标题的字体。

2.3.创建视频播放框架

# 视频播放框架
video_frame = tk.Frame(win, width=300, height=300, bg='black')
video_frame.pack()
#将 video_frame 框架放置在窗口中

:这段代码创建了一个视频播放框架,并将其放置在窗口中,设置其大小为 300x300 像素,背景颜色为黑色。这个框架可以用来显示摄像头捕捉的实时帧或视频文件。

在视频播放框架 video_frame 中创建一个画布

# 视频播放的Canvas
canvas = tk.Canvas(video_frame, width=900, height=900)
canvas.pack(side=tk.TOP, anchor=tk.CENTER)

:这段代码创建了一个画布,并将其放置在视频播放框架中,设置其大小为 900x900 像素。这个画布可以用来显示摄像头捕捉的实时帧或视频文件。

2.5. 加载人脸识别预训练的模型

# 加载人脸识别的预训练模型
face_cascade=cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_default.xml')

:这段代码创建了一个名为 face_cascade 的级联分类器对象,用于检测图像或视频帧中的人脸。OpenCV 提供了许多预训练的级联分类器,包括正面人脸检测、眼睛检测等,这些分类器可以提高检测的准确性和效率。

2.6.人脸检测

# 人脸检测函数
def detect_faces(frame):
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
    return frame, faces

:这个函数通过级联分类器在输入图像中检测人脸,并在图像上标记出这些人脸,以便进一步的处理或显示。
1.3:是尺度缩放因子,用于调整检测窗口大小。
5:是邻域内像素的最低匹配数,用于确定检测到的候选框是否真正是人脸。

2.7.在循环外部创建全局的PhotoImage对象

# 在循环外部创建全局的PhotoImage对象
imgtk = None

:在 Tkinter 中,PhotoImage 是一个用于在 Tkinter 控件中显示图像的类。当您创建一个 PhotoImage 对象时,它会占用一些内存来存储图像数据。如果您在循环中创建多个 PhotoImage 对象,并且循环会多次迭代,那么每次迭代都会创建一个新的对象,这将导致内存占用逐渐增加。为了避免这种情况,您可以创建一个全局的 PhotoImage 对象,并在循环中使用它。这样做的好处是,无论循环迭代多少次,都只会有一个 PhotoImage 对象在内存中。

2.8.定义播放视频的函数

# 播放视频的函数
def play_video():
    global imgtk
    video_path = filedialog.askopenfilename(title='选择视频', filetypes=[('视频文件', '*.mp4')])
    if video_path:
        cap = cv2.VideoCapture(video_path)
        while cap.isOpened():
            ret, frame = cap.read()
            if ret:
                frame, faces = detect_faces(frame)
                display_frame(frame)
            else:
                break
        cap.release()
#在循环后释放视频文件资源

:这个函数允许用户选择一个视频文件,并播放该视频。在播放过程中,它将视频帧显示在窗口中,并使用人脸检测算法检测帧中的人脸。

2.9.在 Tkinter 窗口的画布上显示图像帧。

#定义了一个函数 display_frame,它接受一个名为 frame 的参数,该参数是一个表示图像的 NumPy 数组。
def display_frame(frame):
    global imgtk
    if imgtk:
        canvas.delete(imgtk)
        imgtk = None
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    img = Image.fromarray(frame)
    imgtk = ImageTk.PhotoImage(image=img)
#在画布上创建图像
    canvas.create_image(0, 0, anchor=tk.NW, image=imgtk)
#更新image属性
    canvas.image = imgtk
#更新窗口状态
    win.update_idletasks()
    win.update()

:这个函数负责将处理后的图像帧转换为 Tkinter 可以显示的格式,并在画布上显示这些帧。

2.10.让用户选择要查看的人脸图片,并在图像上显示这些图片

def view_faces():
    directory = 'C:/Users/HUAWEI/Desktop/机器学习的人脸识别/机器学习的人脸识别/动态人脸识别/视频流人脸识别/保存图片'
    [os.path.join(directory, f) for f in os.listdir(directory) if f.endswith('.jpg')]
    face_paths = filedialog.askopenfilenames(title='查看人脸', initialdir=directory, filetypes=[('图片文件', '*.jpg')])
    if face_paths:
        for face_path in face_paths:
            img = cv2.imread(face_path)
            if img is not None:
                cv2.imshow('Face', img)
                cv2.waitKey(0)
                cv2.destroyAllWindows()
            else:
                print(f"无法加载图片: {face_path}")

:这行代码检查用户是否选择了图片文件。如果选择了,它将遍历用户选择的图片文件,并使用 cv2.imread() 函数尝试读取每个图片文件。如果成功读取,它将使用 cv2.imshow() 函数在窗口中显示图片,并使用 cv2.waitKey(0) 函数等待用户按键,然后使用 cv2.destroyAllWindows() 函数关闭所有打开的 OpenCV 窗口。如果无法加载图片,它会打印一个错误消息。

2.11.返回到主界面

def return_to_system():
    subprocess.Popen(["python", "rlsb.py"])
    win.destroy()
#调用 win.destroy() 方法来关闭当前的 Tkinter 窗口。

:这个函数的作用是在当前 Tkinter 窗口中执行 rlsb.py 脚本,并在脚本执行完毕后关闭窗口。这通常用于将控制权返回到操作系统或另一个应用程序。
subprocess.Popen([“python”, “rlsb.py”]):这行代码使用 subprocess.Popen() 函数启动一个新的进程,该进程将执行 rlsb.py 脚本。subprocess.Popen() 函数用于执行外部命令和程序,参数 [“python”, “rlsb.py”] 指定使用 Python 解释器执行 rlsb.py 脚本。

2.12.创建按钮

# 创建播放视频按钮,并放置在窗口的右侧
button1 = tk.Button(win, text="选择视频", command=play_video, width=10, height=2)
button1.place(x=150, y=500, width=100, height=50)


# 创建返回程序按钮,并放置在窗口的右侧
button2 = tk.Button(win, text="返回程序", command=return_to_system, width=10, height=2)
button2.place(x=400, y=500, width=100, height=50)

:这两行代码分别创建了两个按钮,并设置了它们的位置、大小和功能。当用户点击这些按钮时,会触发相应的函数执行。

2.13.更新窗口以确保按钮大小被计算

# 更新窗口以确保按钮大小被计算
win.update_idletasks()

:这行代码的作用是更新 Tkinter 窗口,以确保按钮的大小被正确计算。在 Tkinter 中,按钮的大小是通过其 place 或 pack 方法设置的,但这些方法并不会立即更新按钮的实际大小。update_idletasks() 方法用于在布局管理器(如 pack 或 grid)计算所有控件的最终位置和大小后更新窗口。

2.14.事件循环

# 进入Tkinter事件循环
win.mainloop()

:这行代码确保了 Tkinter 窗口和所有绑定的事件处理函数能够正常工作,并且用户可以与应用程序进行交互。它是 Tkinter 应用程序中不可或缺的一部分。
运行结果
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/677858.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

联邦学习数据集划分Dirichlet划分法及其可视化

文章目录 前言图片效果:独立同分布效果非独立同分布效果 一、参数输入输出 二、代码可视化:标签划分:代码调用 前言 用于实现并控制联邦学习客户端之间数据集非独立同分布,并将效果可视化 图片效果: 独立同分布效果 对不同类别…

python中的循环控制语句break与continue

学习这两个语句之前,我们要先了解这两个语句是什么意思: break:中断、打破的意思。所以它的跳出循环的意思 continue:继续的意思,意思是跳过当前条件,继续循环 新需求来了!我们不仅要告诉 Py…

运营干货:用户运营体系

1、用户生命周期 2、用户引入阶段 3、用户留存阶段 4、用户回流阶段

Camunda BPM架构

Camunda BPM既可以单独作为流程引擎服务存在,也能嵌入到其他java应用中。Camunda BPM的核心流程引擎是一个轻量级的模块,可以被Spring管理或者加入到自定义的编程模型中,并且支持线程模型。 1,流程引擎架构 流程引擎由多个组件构成,如下所示: API服务 API服务,允许ja…

创意KMS知识图谱ui设计合集来了

创意KMS知识图谱ui设计合集来了

Redis的一致性

一、产生的原因 使用缓存,在进行写操作的时候就会出现不一致的问题。 一致性分为三类:强一致性,弱一致性,最终一致性 二、方案 2.1 延时双删 在更新数据库的操作前后分别进行一次删除缓存的操作,并在更新数据库之后…

广工电工与电子技术实验报告-按键键值识别和LED数码管显示

实验代码 Key_LED.v module Key_LED (key, HEX0); input[3:0] key; output[6:0] HEX0; reg[3:0] A; always (key) begin if (key[0] < 0) begin A 4b0001; end else if (key[1] < 0) begin A 4b0010; end else if (key[2] < 0) begin A 4b0011; end else if (key[…

Java——分支语句

控制结构是管理代码执行流程的基础。主要包括顺序控制、分支控制和循环控制。 一、顺序控制 顺序控制是最基本的控制结构&#xff0c;程序按照代码的书写顺序逐行执行。 public class SequentialControl {public static void main(String[] args) {int a 5;int b 10;int s…

jupyter notebook使用conda环境

pycharm中安装过可以使用的库在jupyter notebook中导入不进来 1 检查pycharm中安装的库的位置 2 检查jupyter notebook中安装的库的位置 3 查看jupyter notebook内核名字 可以看到jupyter notebook中内核名字叫ipykernel 4 安装ipykernel 在pycharm的terminal中 pip instal…

微服务:Rabbitmq利用jackson序列化消息为Json发送并接收

消息序列化 Spring默认会把你发送的消息通过JDK序列化为字节发送给MQ&#xff0c;接收消息的时候&#xff0c;再把字节反序列化为Java对象。 我们可以配置JSON方式来序列化&#xff0c;这样体积更小&#xff0c;可读性更高。 引入依赖&#xff1a; <dependency><g…

CV每日论文---2024.6.3

1、Video-MME: The First-Ever Comprehensive Evaluation Benchmark of Multi-modal LLMs in Video Analysis 中文标题&#xff1a;Video-MME&#xff1a;视频分析领域首个多模态法学硕士综合评估基准 简介&#xff1a;Video-MME 是一个全面评估多模态大语言模型&#xff08;M…

18、Go Gin框架中的binding验证器使用

一、binding功能介绍 Gin的binding包提供了一组功能&#xff0c;用于将请求的数据自动绑定到结构体&#xff0c;并根据结构体标签进行数据验证。常用的标签有binding和validate&#xff0c;通过这些标签可以指定数据的类型和验证规则。 常见标签 binding:"required"…

今日好料推荐(运维服务管理流程+互联网运维)

今日好料推荐&#xff08;运维服务管理流程互联网运维&#xff09; 本文内容是运维服务管理的梳理 参考资料内容&#xff1a;运维服务管理流程设计&互联网运维理论与实践 参考资料在文末获取&#xff0c;关注我&#xff0c;分享优质前沿资料&#xff08;IT、运维、编码、…

斜拉桥智慧施工数字孪生

基于图扑自主研发的 HT for Web 产品&#xff0c;利用现场照片及 CAD 图纸&#xff0c;结合 PBR 材质&#xff0c;搭建了具有赛博朋克风格的智慧斜拉桥可视化解决方案&#xff0c;精准复现斜拉桥建造规划过程&#xff0c;辅助运维人员对桥梁基建过程的网格化管理。提高桥梁的建…

【Spring Cloud Alibaba】Nacos统一配置管理

目录 回顾问题 统一配置管理配置中心的解决方案&#xff1a;Nacos的关键特性动态配置服务小结 Nacos的架构 Spring Cloud Alibaba Nacos Config1.创建项目2.添加依赖3.添加启动注解4.添加配置信息5.使用控制器类动态读取配置信息6.Nacos Server添加配置信息7.测试 Nacos Namesp…

大疆、西圣、枫笛领夹麦哪个好?大疆、西圣领夹麦克风测评对比

不知道大家有没有想过一个问题&#xff0c;为什么有些视频或直播的声音听起来那么清晰&#xff0c;仿佛身临其境&#xff1f;其实最主要的就是麦克风的原因&#xff0c;我们以前用的麦克风或多或少都会存在一些小毛病例如&#xff1a;音质不清晰、传输不稳定容易断断续续、声音…

国内PLM系统厂商,国内PLM系统哪个公司最受欢迎

国内PLM系统厂商,国内PLM系统哪个公司最受欢迎 国内PLM系统厂商中&#xff0c;要确定哪个公司的产品最受欢迎&#xff0c;需要考虑多个因素&#xff0c;包括市场份额、客户评价、技术实力、产品线完整性以及服务支持等。虽然无法直接给出一个具体的“最受欢迎”的排名&#xff…

centos7安装kubernetes v1.28.2

centos7安装kubernetes v1.28.2 一&#xff0e;环境部署 1.1基础环境配置 主机IP 主机名规划 172.17.48.15 master 172.17.48.3 node1 1.2修改机器名称 #永久修改主机名 hostnamectl set-hostname master && bash #在master上操作 hostnamectl set-hostname …

分层存储的图片的3d显示

分层存储的图片叠层成为3d&#xff0c;并显示。 文件夹D:\mask内的分层存储的图像文件&#xff1a; 1、显示为3d点云&#xff1a; import open3d as o3d import numpy as np from PIL import Imagedef convert_images_to_point_cloud(image_paths):points []for i, image_pa…

windows中安装zookeeper

https://zhuanlan.zhihu.com/p/692451839 【zookeeper】在Windows上启动zookeeper_windows启动zk-CSDN博客 Index of /apache/zookeeper/zookeeper-3.9.2 Index of /apache/zookeeper/zookeeper-3.9.2 Zookeeper的应用场景 1、配置管理 2、服务注册中心 3、主从协调 4、…