当前位置: 首页 > news >正文

opencv-人脸识别

 对https://blog.csdn.net/weixin_46291251/article/details/117996591这哥们代码的一些修改

import cv2
import numpy as np
import os
import shutil
import threading
import tkinter as tk
from PIL import Image, ImageTkchoice = 0# 首先读取config文件,第一行代表当前已经储存的人名个数,接下来每一行是(id,name)标签和对应的人名
id_dict = {}  # 字典里存的是id——name键值对
Total_face_num = 999  # 已经被识别有用户名的人脸个数,camera = cv2.VideoCapture(0)  # 摄像头
success, img = camera.read()  # 从摄像头读取照片
W_size = 0.1 * camera.get(3)
H_size = 0.1 * camera.get(4)def init():  # 将config文件内的信息读入到字典中f = open('config.txt')global Total_face_numTotal_face_num = int(f.readline())for i in range(int(Total_face_num)):line = f.readline()id_name = line.split(' ')id_dict[int(id_name[0])] = id_name[1]f.close()init()# 加载OpenCV人脸检测分类器Haar
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")# 准备好识别方法LBPH方法
recognizer = cv2.face.LBPHFaceRecognizer_create()# 打开标号为0的摄像头
# camera = cv2.VideoCapture(0)  # 摄像头
# success, img = camera.read()  # 从摄像头读取照片
# W_size = 0.1 * camera.get(3)
# H_size = 0.1 * camera.get(4)system_state_lock = 0  # 标志系统状态的量 0表示无子线程在运行 1表示正在刷脸 2表示正在录入新面孔。
# 相当于mutex锁,用于线程同步'''
============================================================================================
以上是初始化
============================================================================================
'''def Get_new_face():global choiceprint("正在从摄像头录入新人脸信息 \n")# 存在目录data就清空,不存在就创建,确保最后存在空的data目录filepath = "data"if not os.path.exists(filepath):os.mkdir(filepath)else:shutil.rmtree(filepath)os.mkdir(filepath)sample_num = 0  # 已经获得的样本数while True:  # 从摄像头读取图片choice = 2global successglobal img  # 因为要显示在可视化的控件内,所以要用全局的success, img = camera.read()# 转为灰度图片if success is True:gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)else:break# 检测人脸,将每一帧摄像头记录的数据带入OpenCv中,让Classifier判断人脸# 其中gray为要检测的灰度图像,1.3为每次图像尺寸减小的比例,5为minNeighborsfaces = face_cascade.detectMultiScale(gray, 1.3, 5)# 框选人脸,for循环保证一个能检测的实时动态视频流for (x, y, w, h) in faces:# xy为左上角的坐标,w为宽,h为高,用rectangle为人脸标记画框cv2.rectangle(img, (x, y), (x + w, y + w), (255, 0, 0))# 样本数加1sample_num += 1# 保存图像,把灰度图片看成二维数组来检测人脸区域,这里是保存在data缓冲文件夹内T = Total_face_numcv2.imwrite("./data/User." + str(T) + '.' + str(sample_num) + '.jpg', gray[y:y + h, x:x + w])pictur_num = 1000  # 表示摄像头拍摄取样的数量,越多效果越好,但获取以及训练的越慢cv2.waitKey(1)if sample_num > pictur_num:breakelse:  # 控制台内输出进度条l = int(sample_num / pictur_num * 50)r = int((pictur_num - sample_num) / pictur_num * 50)print("\r" + "%{:.1f}".format(sample_num / pictur_num * 100) + "=" * l + "->" + "_" * r, end="")var.set("%{:.1f}".format(sample_num / pictur_num * 100))  # 控件可视化进度信息# tk.Tk().update()window.update()  # 刷新控件以实时显示进度def Train_new_face():print("\n正在训练")# cv2.destroyAllWindows()path = 'data'# 初始化识别的方法recog = recognizer# 调用函数并将数据喂给识别器训练faces, ids = get_images_and_labels(path)print('本次用于训练的识别码为:')  # 调试信息print(ids)  # 输出识别码# 训练模型  #将输入的所有图片转成四维数组recog.train(faces, np.array(ids))# 保存模型yml = str(Total_face_num) + ".yml"rec_f = open(yml, "w+")recog.save(yml)rec_f.close()# recog.save('aaa.yml')# 创建一个函数,用于从数据集文件夹中获取训练图片,并获取id
# 注意图片的命名格式为User.id.sampleNum
def get_images_and_labels(path):image_paths = [os.path.join(path, f) for f in os.listdir(path)]# 新建连个list用于存放face_samples = []ids = []# 遍历图片路径,导入图片和id添加到list中for image_path in image_paths:# 通过图片路径将其转换为灰度图片img = Image.open(image_path).convert('L')# 将图片转化为数组img_np = np.array(img, 'uint8')if os.path.split(image_path)[-1].split(".")[-1] != 'jpg':continue# 为了获取id,将图片和路径分裂并获取id = int(os.path.split(image_path)[-1].split(".")[1])# 调用熟悉的人脸分类器detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')faces = detector.detectMultiScale(img_np)# 将获取的图片和id添加到list中for (x, y, w, h) in faces:face_samples.append(img_np[y:y + h, x:x + w])ids.append(id)return face_samples, idsdef write_config():global user_nameprint("新人脸训练结束")f = open('config.txt', "a")T = Total_face_numf.write(str(T) + " "+ user_name + " \n")f.close()id_dict[T] = user_name# 这里修改文件的方式是先读入内存,然后修改内存中的数据,最后写回文件f = open('config.txt', 'r+')flist = f.readlines()flist[0] = str(int(flist[0]) + 1) + " \n"f.close()f = open('config.txt', 'w+')f.writelines(flist)f.close()'''
============================================================================================
以上是录入新人脸信息功能的实现
============================================================================================
'''def scan_face():# 使用之前训练好的模型for i in range(Total_face_num):  # 每个识别器都要用i += 1yml = str(i) + ".yml"print("\n本次:" + yml)  # 调试信息recognizer.read(yml)ave_poss = 0global choicefor times in range(10):  # 每个识别器扫描十遍times += 1cur_poss = 0global successglobal imgglobal system_state_lockwhile system_state_lock == 2:  # 如果正在录入新面孔就阻塞print("\r刷脸被录入面容阻塞", end="")passchoice = 1success, img = camera.read()gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 识别人脸faces = face_cascade.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=5,minSize=(int(W_size), int(H_size)))# 进行校验for (x, y, w, h) in faces:# global system_state_lockwhile system_state_lock == 2:  # 如果正在录入新面孔就阻塞print("\r刷脸被录入面容阻塞", end="")pass# 这里调用Cv2中的rectangle函数 在人脸周围画一个矩形cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)# 调用分类器的预测函数,接收返回值标签和置信度idnum, confidence = recognizer.predict(gray[y:y + h, x:x + w])conf = confidence# 加载一个字体用于输出识别对象的信息font = cv2.FONT_HERSHEY_SIMPLEX# 输出检验结果以及用户名# 展示结果# cv2.imshow('camera', img)print("conf=" + str(conf), end="\t")if 65 > conf > 0:cur_poss = 1  # 表示可以识别else:cur_poss = 0  # 表示不可以识别k = cv2.waitKey(1)if k == 27:# cam.release()  # 释放资源cv2.destroyAllWindows()breakave_poss += cur_possif ave_poss >= 5:  # 有一半以上识别说明可行则返回return ireturn 0  # 全部过一遍还没识别出说明无法识别'''
============================================================================================
以上是关于刷脸功能的设计
============================================================================================
'''def f_scan_face_thread():global choice# 使用之前训练好的模型# recognizer.read('aaa.yml')var.set('刷脸')ans = scan_face()if ans == 0:print("最终结果:无法识别")var.set("最终结果:无法识别")else:ans_name = "最终结果:" + str(ans) + id_dict[ans]print(ans_name)var.set(ans_name)global system_state_lockprint("锁被释放0")system_state_lock = 0  # 修改system_state_lock,释放资源choice = 0def f_scan_face():print(choice)global system_state_lockprint("\n当前锁的值为:" + str(system_state_lock))if system_state_lock == 1:print("阻塞,因为正在刷脸")return 0elif system_state_lock == 2:  # 如果正在录入新面孔就阻塞print("\n刷脸被录入面容阻塞\n""")return 0system_state_lock = 1p = threading.Thread(target=f_scan_face_thread)p.setDaemon(True)  # 把线程P设置为守护线程 若主线程退出 P也跟着退出p.start()def f_rec_face_thread():global choicevar.set('录入')cv2.destroyAllWindows()global Total_face_numTotal_face_num += 1Get_new_face()  # 采集新人脸print("采集完毕,开始训练")global system_state_lock  # 采集完就可以解开锁print("锁被释放0")system_state_lock = 0choice = 0Train_new_face()  # 训练采集到的新人脸write_config()  # 修改配置文件#    recognizer.read('aaa.yml')  # 读取新识别器# global system_state_lock
# print("锁被释放0")
# system_state_lock = 0  # 修改system_state_lock,释放资源def f_rec_face():global user_nameglobal choiceglobal system_state_lockprint("当前锁的值为:" + str(system_state_lock))user_name = var_user_name.get()if system_state_lock == 2:print("阻塞,因为正在录入面容")return 0else:system_state_lock = 2  # 修改system_state_lockprint("改为2", end="")print("当前锁的值为:" + str(system_state_lock))p = threading.Thread(target=f_rec_face_thread)p.setDaemon(True)  # 把线程P设置为守护线程 若主线程退出 P也跟着退出p.start()# tk.Tk().update()#  system_state_lock = 0  # 修改system_state_lock,释放资源def f_exit():  # 退出按钮exit()'''
============================================================================================
以上是关于多线程的设计
============================================================================================
'''window = tk.Tk()
window.title('wjh lxq\' Face_rec 3.0')   # 窗口标题
window.geometry('1000x500')  # 这里的乘是小x# 在图形界面上设定标签,类似于一个提示窗口的作用
var = tk.StringVar()
l = tk.Label(window, textvariable=var, bg='green', fg='white', font=('Arial', 12), width=50, height=4)
# 说明: bg为背景,fg为字体颜色,font为字体,width为长,height为高,这里的长和高是字符的长和高,比如height=2,就是标签有2个字符这么高
l.pack()  # 放置l控件
var.set("wjh  lxq 人脸识别系统")# 在窗口界面设置放置Button按键并绑定处理函数
button_a = tk.Button(window, text='开始刷脸', font=('Arial', 12), width=10, height=2, command=f_scan_face)
button_a.place(x=800, y=120)button_b = tk.Button(window, text='录入人脸', font=('Arial', 12), width=10, height=2, command=f_rec_face)
button_b.place(x=800, y=220)button_c = tk.Button(window, text='退出', font=('Arial', 12), width=10, height=2, command=f_exit)
button_c.place(x=800, y=320)panel = tk.Label(window, width=500, height=350)  # 摄像头模块大小
panel.place(x=10, y=100)  # 摄像头模块的位置
window.config(cursor="arrow")tk.Label(window, text='name: ').place(x=600, y=235)
var_user_name = tk.StringVar()
entry_user_name = tk.Entry(window, textvariable=var_user_name)
entry_user_name.place(x=650, y=235)def video_loop():  # 用于在label内动态展示摄像头内容(摄像头嵌入控件)global successglobal imgglobal choiceif not choice:success, img = camera.read()if success:cv2.waitKey(1)cv2image = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)  # 转换颜色从BGR到RGBAcurrent_image = Image.fromarray(cv2image)  # 将图像转换成Image对象imgtk = ImageTk.PhotoImage(image=current_image)panel.imgtk = imgtkpanel.config(image=imgtk)window.after(1, video_loop)video_loop()#  窗口循环,用于显示
window.mainloop()'''
============================================================================================
以上是关于界面的设计
============================================================================================
'''

自备config.txt和haarcascade_frontalface_default.xml文件

config.txt 第一行写一个0即可

录脸的时候输入name.

相关文章:

opencv-人脸识别

对https://blog.csdn.net/weixin_46291251/article/details/117996591这哥们代码的一些修改 import cv2 import numpy as np import os import shutil import threading import tkinter as tk from PIL import Image, ImageTkchoice 0# 首先读取config文件,第一行…...

九、idSpanMap使用基数树代替原本的unordered_map 十、使用基数树前后性能对比

九、idSpanMap使用基数树代替原本的unordered_map 我们原本的idSpanMap用的是STL容器中的unordered_map哈希桶,因为STL的容器本身是不保证线程安全的,所以我们在访问时需要加锁保证线程安全,这也就是我们写的内存池的性能的瓶颈点。因为我做…...

政府科技项目验收全流程分享

科技验收测试 (验收申请→主管部门初审→科技厅审核→组织验收→归档备案→信用管理): (一)验收申请 项目承担单位通过省科技业务管理系统提交验收申请。 按期完成的项目,项目承担单位应当在项目合同书…...

基于Matlab实现生活中的图像信号分类(附上源码+数据集)

在我们的日常生活中,我们经常会遇到各种各样的图像信号,例如照片、视频、图标等等。对这些图像信号进行分类和识别对于我们来说是非常有用的。在本文中,我将介绍如何使用Matlab来实现生活中的图像信号分类。 文章目录 介绍源码数据集下载 介…...

YOLOv5算法改进(12)— 替换主干网络之Swin Transformer

前言:Hello大家好,我是小哥谈。Swin Transformer是一种基于Transformer的深度学习模型,它在视觉任务中表现出色。与之前的Vision Transformer(ViT)不同,Swin Transformer具有高效和精确的特性,并…...

php 权限节点的位运算

一,概述 在 PHP 中,位运算可以用来进行权限节点的判断。通常,每个权限节点都会用一个不同的位表示(2的n次方,从0开始),可以将这些位组合成一个权限值。然后,可以使用位运算符来检查…...

ClickHouse进阶(六):副本与分片-2-Distributed引擎

进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容! 🏡个人主页:含各种IT体系技术,IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 📌订阅…...

Git和Github的基本用法

目录 背景 下载安装 安装 git for windows 安装 tortoise git 使用 Github 创建项目 注册账号 创建项目 下载项目到本地 Git 操作的三板斧 放入代码 三板斧第一招: git add 三板斧第二招: git commit 三板斧第三招: git push 小结 🎈个人主页&#xf…...

279. 完全平方数

279.完全平方数 给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。 完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 …...

一篇文章学会C#的正则表达式

https://blog.csdn.net/qq_38507850/article/details/79179128 正则表达式 一句话概括就是用来对字符串根据自己的规则进行匹配的,可以匹配(返回)出符合自己要求的匹配结果,有人说字符串类的函数也可以,确实是这样,但是字符串的函…...

智慧工地源码 智慧大屏、手机APP、SaaS模式

一、智慧工地可以通过安全八要素来提升安全保障,具体措施包括: 1.安全管理制度:建立科学完善的安全管理制度,包括安全标准规范、安全生产手册等,明确各项安全管理职责和要求。 2.安全培训教育:对工地人…...

C# WPF监听USB插入拨出

可以全部监听。好用 private void FormF100WriteCortexLicense_Load(object sender, EventArgs e){this.Text this.Text " " FT_Tools.Program.version;USB USBWatcher new USB();USBWatcher.AddUSBEventWatcher(USBEventHandler, USBEventHandler, new TimeSpa…...

Prometheus监控(三)架构

文章目录 Prometheus架构图Prometheus生态圈组件Prometheus Serverclient librariesPushgatewayexporterAlartmanager Prometheus架构理解存储计算层采集层应用层 Prometheus架构图 Prometheus生态圈组件 Prometheus Server 主服务器,负责收集和存储时间序列数据 …...

linux kvm网桥br简单理解和持久化配置

linux网桥简单理解和持久化配置 文章目录 前言一、Linux 网桥是什么?二、网桥主要作用三、网桥配置命令及安装(CentOS系统) 1 网桥配置命令2.持久化网桥配置 前言 linux bridge是网络虚拟化中非常重要的一种设备,今天就来学习下linux bridge的相关知…...

【LeetCode-中等题】105. 从前序与中序遍历序列构造二叉树

文章目录 题目方法一:递归 题目 方法一:递归 preorder [3,9,20,15,7] inorder [9,3,15,20,7] 首先根据 preorder 找到根节点是 3然后根据根节点将 inorder 分成左子树和右子树 左子树 inorder [9]右子树 inorder [15,20,7]这时候3是根节点 3的左子树…...

uniapp 配置网络请求并使用请求轮播图

由于平台的限制,小程序项目中不支持 axios,而且原生的 wx.request() API 功能较为简单,不支持拦截器等全局定制的功能。因此,建议在 uni-app 项目中使用 escook/request-miniprogram 第三方包发起网络数据请求。 官方文档&#xf…...

c#在MVC Api(.net framework)当中使用Swagger,以及Demo下载

主要的步骤就是创建项目,通过nuget 添加Swashbuckle包,然后在SwaggerConfig当中进行相关的配置。 具体的步骤,可以参考下面的链接: https://www.cnblogs.com/94pm/p/8046580.htmlhttps://blog.csdn.net/xiaouncle/article/detail…...

Linux 常见命令操作

一、目录管理 1.1 列出目录 ls # ls 命令 # -a 参数,查看全部的文件,包括隐藏的文件 # -l 参数,列出所有的文件,包括文件的属性和权限,不显示隐藏文件 [rootlocalhost /]# ls bin boot dev etc home lib lib64…...

前端实习第七周周记

前言 第六周没写,是因为第六周的前两天在处理第五周的样本库部分。问题解决一个是嵌套问题(因为我用到了递归),还有一个问题在于本机没有问题,打包上线接口404。这个问题我会在这周的总结中说。 第六周第三天才谈好新…...

DevOps理念:开发与运维的融合

在现代软件开发领域,DevOps 不仅仅是一个流行的词汇,更是一种文化、一种哲学和一种方法论。DevOps 的核心理念是通过开发和运维之间的紧密合作,实现快速交付、高质量和持续创新。本文将深入探讨 DevOps 文化的重要性、原则以及如何在团队中实…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...