OpenCv综合应用——人脸识别

news2024/11/6 21:59:54

一、利用PySimpleGUI构建窗口界面

1.1、 PySimpleGUI 的安装

pip install pysimplegui

1.2、构建主界面

import PySimpleGUI as psg

from face_gui.face_gather import face_gather
from face_gui.face_videos import face_video
from face_gui.face_tuopens import face_tuopen


def face_gui():
    # 创建一个布局组件
    layout = [
        [psg.Text('员工编号', size=(6, 1), font=('微软雅黑', 12)), psg.InputText(key='num', size=(20, 1))],
        [psg.Text('员工姓名', size=(6, 1), font=('微软雅黑', 12)), psg.InputText(key='name', size=(20, 1))],
        [psg.Text(key='nsg')],
        [psg.Text(key='msg')],
        [psg.Button('人脸采集'), psg.Button('打卡'), psg.Button('选择图片'), psg.Button('退出')],
        [psg.Image(key='video', size=(640, 480))]  # 添加摄像头显示区域
    ]
    # 创建一个窗口
    window = psg.Window('人脸识别系统', layout, icon='../images/hq.ico')

    while True:
        # 读取窗口信息,返回窗口数据和事件
        event, values = window.read()
        if event == psg.WIN_CLOSED or event == '退出':
            break
        if event == "人脸采集":
            # 获取编号和姓名
            ygid = values['num']
            name = values['name']
            window['msg'].update(f'编号:{ygid},姓名:{name}')
            face_video(values)  # 传递 values 字典
            # psg.popup('人脸采集成功')
        if event == "打卡":
            # 获取编号和姓名
            # ygid = values['num']
            # name = values['name']
            # window['nsg'].update("正在验证身份信息")
            # window['msg'].update(f'编号:{ygid},姓名:{name}')
            face_gather()
            # psg.popup('打卡成功')
        if event == "选择图片":
            # 调用图片选择功能
            face_tuopen()

    # 关闭窗口,释放资源
    window.close()

1.3、实现人脸信息采集

import cv2
import PySimpleGUI as psg

from face_gui.face_mysql import add


def face_video(values):
    # 开启摄像头
    cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    if not cap.isOpened():
        print("摄像头打开失败")
        return

    # 创建摄像头窗口的布局
    camera_layout = [
        [psg.Image(key='video', size=(640, 480))],
        [psg.Button('识别'), psg.Button('关闭摄像头')]
    ]

    # 创建摄像头窗口
    camera_window = psg.Window('信息采集', camera_layout, icon='../images/hq.ico')

    while True:
        # 读取摄像头窗口信息,返回窗口数据和事件
        event, _ = camera_window.read(timeout=10)
        if event == psg.WIN_CLOSED or event == '关闭摄像头':
            break

        # 读取数据帧
        ret, frame = cap.read()
        if ret:
            # 把数据帧转换成btepy数据类型
            imgbytes = cv2.imencode('.png', frame)[1].tobytes()
            camera_window['video'].update(data=imgbytes)

        if event == '识别':
            # 获取编号和姓名
            num = values['num']
            name = values['name']
            iss = cv2.imwrite(f"../face_train_images/{num}.png", frame)
            if iss:
                isadd = add(name, num)
                if isadd:
                    psg.popup('添加成功')
            else:
                psg.popup('添加失败')
            # psg.popup('识别完成')

    # 关闭摄像头窗口,释放资源
    camera_window.close()
    cap.release()

1.4、实现人脸识别

import os

import cv2
import PySimpleGUI as psg
import face_recognition
import numpy as np

from face_gui.face_mysql import select


def face_gather():
    # 开启摄像头像
    cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    if not cap.isOpened():
        print("摄像头没有开启")
        return
    # 创建布局
    layout = [
        [psg.Image(key="video")],
        [psg.Button("验证"), psg.Button("关闭")]
    ]
    # 创建窗口
    camera_window = psg.Window("验证", layout)
    # 循环
    while True:
        event, value = camera_window.read(timeout=10)
        # 读取视频
        ret, frame = cap.read()
        if event in (None, "关闭"):
            # 终止循环
            break
        if ret:
            imttype = cv2.imencode(".png", frame)[1].tobytes()
            camera_window["video"].update(imttype)
        if event == "验证":
            # 查找人脸库
            list_dir = os.listdir("../face_train_images")
            if len(list_dir) > 0:
                for i in list_dir:
                    print(i)
                    # 读取一个图片对象
                    img = cv2.imread(f"../face_train_images/{i}")
                    if img is None:
                        print("没有读取图片")
                        break
                    else:
                        # 获取已知图片的特征变量
                        en1 = face_recognition.face_encodings(img)[0]
                        # 获取需要检测图片的特征变量
                        en2 = face_recognition.face_encodings(frame)[0]
                        # 计算欧几里得距离
                        rs = np.linalg.norm(en1 - en2)
                        print(rs)
                        if rs < 0.6:
                            b = i.split(".")[0]
                            select(b)
                            psg.popup("打卡成功")
                            # 查到此人,终止循环
                            break
                        else:
                            psg.popup("人脸库没有此人")
                            break

    cap.release()
    camera_window.close()

1.5、文件上传

import io
import PySimpleGUI as psg
from PIL import Image


def face_tuopen():
    # 创建layout
    layout = [
        [psg.Text('请选择一张图片或视频:')],
        [psg.Input(key='-FILE-', enable_events=True),
         psg.FileBrowse(
             file_types=(("Image and Video Files", "*.png;*.jpg;*.jpeg;*.gif;*.bmp;*.mp4;*.avi;*.mov;*.mkv"),))],
        [psg.Button('退出')],
        [psg.Image(key='-IMAGE-', size=(640, 480))]
    ]
    # 创建窗口
    window = psg.Window('文件处理', layout, size=(640, 480))
    while True:
        event, values = window.read()
        # 处理事件
        if event in (psg.WINDOW_CLOSED, '退出'):
            break
        elif event == '-FILE-':
            # 更新图片
            image_path = values['-FILE-']
            print(image_path)
            if image_path:
                try:
                    # 使用 Pillow 打开图像
                    image = Image.open(image_path)
                    # 调整图像大小以适应窗口
                    image.thumbnail((640, 480))
                    # 将图像转换为 Tkinter 可以使用的格式
                    bio = io.BytesIO()
                    image.save(bio, format='PNG')
                    window['-IMAGE-'].update(data=bio.getvalue())
                except Exception as e:
                    print(f"Error loading image: {e}")
                    psg.popup_error(f"无法加载图像: {e}")

    window.close()

1.6、数据库操作

import pymysql


# 新增数据
def add(name, num):
    # 创建数据库连接
    con = pymysql.connect(
        host='localhost',  # 数据库地址
        port=3306,  # 数据库端口
        user='root',  # 用户名
        password='123456',  # 密码
        database='face',  # 数据库名称
        charset='utf8'
    )
    # 创建游标对象,包含了增删改查的函数
    cur = con.cursor()
    # 定义sql
    sql = "insert into user(user_name,user_num) value (%s,%s)"
    # 运行sql(增删改查sql的函数)
    cur.execute(sql, (name, num))
    # 执行增删改sql的函数,返回一个受影响行数的数值
    num = cur.rowcount
    # 提交
    con.commit()
    # 释放资源
    cur.close()
    con.close()
    if num > 0:
        print("新增成功")
        return True
    else:
        print("新增失败")
        return False


# 查询数据
def select(num):
    with pymysql.connect(
            host='localhost',  # 数据库地址
            port=3306,  # 数据库端口
            user='root',  # 用户名
            password='123456',  # 密码
            database='face',  # 数据库名称
            charset='utf8'  # 编码格式
    ) as db:
        with db.cursor() as cursor:
            sql = "select * from user where user_num=%s"
            try:
                cursor.execute(sql, (num,))
                # 获取所有记录列表
                results = cursor.fetchall()
                if results:
                    for row in results:
                        uesr_id = row[0]
                        uesr_name = row[1]
                        uesr_num = row[2]
                        print(f"uesr_id:{uesr_id}, uesr_name:{uesr_name}, uesr_num:{uesr_num}")
                else:
                    print("未找到匹配的记录")
            except Exception as e:
                print(f"Error: {e}")


# 删除数据
def delete(num):
    with pymysql.connect(
            host='localhost',  # 数据库地址
            port=3306,  # 数据库端口
            user='root',  # 用户名
            password='123456',  # 密码
            database='face',  # 数据库名称
            charset='utf8'
    ) as db:
        with db.cursor() as cursor:
            sql = "DELETE FROM user WHERE uesr_num=%s"
            try:
                cursor.execute(sql, (num,))
                # 提交数据
                db.commit()
                print("删除成功")
            except Exception as e:
                print(f"Error: {e}")
                db.rollback()
                print("删除失败")


# 修改数据
def update(name, num, new_name=None, new_num=None):
    with pymysql.connect(
            host='localhost',  # 数据库地址
            port=3306,  # 数据库端口
            user='root',  # 用户名
            password='123456',  # 密码
            database='face',  # 数据库名称
            charset='utf8'
    ) as db:
        with db.cursor() as cursor:
            # 动态生成 SQL 语句
            updates = []
            params = []
            if new_name is not None:
                updates.append("uesr_name=%s")
                params.append(new_name)
            if new_num is not None:
                updates.append("uesr_num=%s")
                params.append(new_num)

            if not updates:
                print("未提供任何更新内容")
                return

            sql = f"UPDATE user SET {', '.join(updates)} WHERE user_name=%s AND user_num=%s"
            params.extend([name, num])

            try:
                cursor.execute(sql, params)
                # 提交数据
                db.commit()
                print("更新成功")
            except Exception as e:
                print(f"Error: {e}")
                db.rollback()
                print("更新失败")

1.7、主函数调用

from face_gui.face_gui_windows import face_gui

if __name__ == '__main__':
    face_gui()

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

辐射传输方程的分解

Decomposition of the Boundary Value Problem for Radiative Transfer Equation of MODIS and MISR instruments 0.Notions Let L L L be the straming-collision operator, and S S S is scattering operator: L I Ω ⋅ ∇ I ( r , Ω ) σ ( r , Ω ) I ( r , Ω ) S…

智会智展,活动必备

智会智展 APP 各大应用市场均可下载统一链接https://m.malink.cn/s/r6nQVf

Hive操作库、操作表及数据仓库的简单介绍

数据仓库和数据库 数据库和数仓区别 数据库与数据仓库的区别实际讲的是OLTP与OLAP的区别 操作型处理(数据库)&#xff0c;叫联机事务处理OLTP&#xff08;On-Line Transaction Processing&#xff09;&#xff0c;也可以称面向用户交易的处理系统&#xff0c;它是针对具体业务…

如何选择适合小团队的项目管理工具?免费与开源软件推荐

目录 一、小团队项目管理工具的重要性 二、热门项目管理工具介绍 &#xff08;一&#xff09;禅道 &#xff08;二&#xff09;Trello &#xff08;三&#xff09;Asana &#xff08;四&#xff09;JIRA 三、免费项目管理软件推荐 &#xff08;一&#xff09;ES 管理器 …

kafka如何获取 topic 主题的列表?

大家好&#xff0c;我是锋哥。今天分享关于【kafka如何获取 topic 主题的列表&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; kafka如何获取 topic 主题的列表&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在Kafka中&#xff0c;可以…

Maven详解—(详解Maven,包括Maven依赖管理以及声明周期,Maven仓库、idea集成Maven)

文章目录 Maven详解一.初始Maven1.1 概述1.2 作用 二.Maven模型2.1 概述2.2 构建生命周期/阶段2.3 项目对象模型2.4 依赖管理模型 三.Maven仓库四.Maven安装4.1 下载4.2 安装步骤 五.Idea集成Maven Maven详解 一.初始Maven 1.1 概述 Maven是Apache旗下的一个开源项目&#x…

虚拟滚动 - 从基本实现到 Angular CDK

简介 在大数据列表的处理上&#xff0c;虚拟滚动是一种优化性能的有效方式。本篇文章将详细介绍两种常见的虚拟滚动实现方式&#xff1a;使用 transform 属性和 Intersection Observer。重点讲解如何通过 transform 属性实现高效的虚拟滚动&#xff0c;并对比Angular CDK中的实…

Spring Boot 配置文件启动加载顺序

前言 Spring Boot的启动加载顺序是一个涉及多个步骤和组件的过程。Spring Boot通过一系列默认设置简化了应用程序的配置&#xff0c;使得开发者能够快速地搭建和部署应用。为了实现这一目标&#xff0c;Spring Boot采用了一种分层和优先级机制来加载配置文件。 一、Spring Bo…

C# Modbus RTU通讯回顾

涉及技术&#xff1a; 1.使用NMdbus4 库 2.ushort[]转int 记得之前刚学习的时候&#xff0c;是ushort[] → Hex字符串→byte[] → 翻转byte[] →BitConverter.ToInt32()&#xff0c;饶了一大圈&#xff1b;实际上可以直接转&#xff1b;这里也有小细节&#xff1a;使用BitCo…

HFSS学习笔记(五)金属过孔、复制模型带激励等问题(持续更新...)

HFSS学习笔记&#xff08;五&#xff09;金属过孔、复制模型带激励等问题&#xff08;持续更新…&#xff09; 一、金属过孔设计 方法一&#xff1a;用介质减去金属圆柱体&#xff0c;然后再添加金属圆柱体 方法二&#xff1a;嵌入金属圆柱 圆柱过孔选择材料为“copper” HFS…

Late Chunking×Milvus:如何提高RAG准确率

01. 背景 在RAG应用开发中&#xff0c;第一步就是对于文档进行chunking&#xff08;分块&#xff09;&#xff0c;高效的文档分块&#xff0c;可以有效的提高后续的召回内容的准确性。而对于如何高效的分块是个讨论的热点&#xff0c;有诸如固定大小分块&#xff0c;随机大小分…

大屏可视化:舞动数据与美观的“设计秘籍”

大屏可视化鉴赏&#xff1a;踏入软件系统产品设计之旅&#xff0c;让我们一同鉴赏那些闪耀在智慧农业、智慧园区、智慧社区及智慧港口等领域的大屏可视化杰作。每一帧画面&#xff0c;都是科技与创新的完美融合&#xff0c;数据跃然屏上&#xff0c;智慧触手可及。 >> 数…

基于STM32的智能声音跟随小车设计

引言 本项目基于STM32微控制器设计了一个智能声音跟随小车&#xff0c;通过集成麦克风阵列实现声音源定位和跟随功能。该系统可以检测环境中的声音信号&#xff0c;如手掌拍击声或语音指令&#xff0c;驱动小车向声源方向移动。项目涉及硬件设计、声音信号处理算法以及电机控制…

Bruno解决SSL验证问题

在测试接口的时候&#xff0c;我使用的是Bruno这个软件&#xff0c;开源离线的API测试软件。 主页是这样子的 今天在测试一个HTTPS的接口时候&#xff0c;因为这个HTTPS接口是用的是自签证书&#xff0c;所以就报错误了。 Error invoking remote method send-http-request: …

【论文速读】| APOLLO:一种基于 GPT 的用于检测钓鱼邮件并生成警告用户的解释的工具

基本信息 原文标题&#xff1a;APOLLO: A GPT-based tool to detect phishing emails and generate explanations that warn users 原文作者&#xff1a;Giuseppe Desolda, Francesco Greco, Luca Vigan 作者单位&#xff1a;University of Bari “A. Moro”, Italy, King’…

jfrog artifactory oss社区版,不支持php composer私库

一、docker安装 安装环境&#xff1a;centos操作系统&#xff0c;root用户。 如果是mac或ubuntu等操作系统的话&#xff0c;会有许多安装的坑等着你。 一切都是徒劳&#xff0c;安装折腾那么久&#xff0c;最后还是不能使用。这就是写本文的初衷&#xff0c;切勿入坑就对了。 …

WindowsDocker安装到D盘,C盘太占用空间了。

Windows安装 Docker Desktop的时候,默认位置是安装在C盘,使用Docker下载的镜像文件也是保存在C盘,如果对Docker使用评率比较高的小伙伴,可能C盘空间,会被耗尽,有没有一种办法可以将Docker安装到其它磁盘,同时Docker的数据文件也保存在其他磁盘呢? 答案是有的,我们可以…

vue常见题型(1-10)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 2.2双向绑定的原理是什么vue框架采用的是数据双向绑定的方式&#xff0c;由三个重要部分构成2.2.1.ViewModel2.2.2 双向绑定2.2.3.1.编译Compile2.2.3.2.依赖收集 3…

python怎么将字符串转换为数字

python如何将列表中的字符串转为数字&#xff1f;具体方法如下&#xff1a; 有一个数字字符的列表&#xff1a; numbers [1, 5, 10, 8] 想要把每个元素转换为数字&#xff1a; numbers [1, 5, 10, 8] 用一个循环来解决&#xff1a; new_numbers []; for n in numbers:new_n…

大数据新视界 -- 大数据大厂之 Impala 性能优化:解锁大数据分析的速度密码(上)(1/30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…