当前位置: 首页 > 编程日记 > 正文

「摸鱼」神器来了,Python 实现人脸监测制作神器

作者 | 李秋键

出品 | AI科技大本营(ID:rgznai100)

最近都在讨论工作摸鱼,网易云音乐也出了合理摸鱼时间表,今天给大家推荐如何用python实现摸鱼~码住呦!

引言:脸部表情是人类情绪的最直接外部表现之一和进行社交活动的重要方式,而赋予机器感知人类情绪的能力,使得机器可以识别人的情感状态,是实现人机交互的重要目标之一。随着人工智能的迅速发展,在过去十多年,科技工作者在人脸表情的自动识别领域进行了深入研究。人脸表情识别的研究在心理学、疲劳驾驶检测、课堂教学效果评价、智能医疗、公安测谎系统、车载安全系统等领域都受到广泛的关注。

在人脸识别的算法中,首先需要判定视频或图片中是否存在人脸,并定位人脸所处的位置。目前主要有基于知识和基于统计的两种人脸判定和定位方法。其中,基于知识的人脸检测定位主要是利用人脸器官特征和器官之间的几何关系来确定是否有人脸存在于图像中。基于统计的检测方式,则是利用过往照片中的像素分布和当前目标图片的像素分布是否相似来判定人脸。

今天我们就将使用KNN算法实现人脸分类,并在分类的基础上实现监测。当检测到未进行训练过的人脸时,自动执行设定好的命名。在这里我们设为打开文档。即可形成我们的人脸检测“摸鱼”神器,或者及时遮挡祝自己的下巴,即可以执行程序。效果如下:

d9deeb1bc338906fba66b324707ed44f.png

bc799a90dac32baca92d5e72468a1fff.png

KNN人脸分类算法介绍

KNN算法是一种惰性学习算法,其思想是待分类样本的类别由其近邻的k个样本投票决定,已广泛应用于数据挖掘和数据分类中。在模式识别中,K近邻算法的优势在于简单且对异常值不敏感,泛化能力强。其核心内容:任意样本在数据集中的K个最相似样本中,如果大部分样本归并为某一类别,那么此样本也属于这个类别。其意义在于通过待测样本周边的已知数据类别来预测此样本的归属问题,极大弱化了数据集的高维度、高耦合给数据特征分析带来的困难。

其优点有:对数据噪声有较强的忍耐能力,非常适合零售业复杂多变的特征选择情景;分析数据特征时,只关注最相邻的K个样本即可,极大地降低了数据集的维度。

731878d4cc57cd66845b5f91d04d4266.png

缺点:K近邻算法属于惰性算法,不能主动学习;K值的选择对数据分析的结果有影响.

基于kNN的人脸分类算法以异常人脸样本相较于正常工况样本会产生偏移量为根据,通过比较正常样本与异常样本在训练集中的前k个最近邻样本距离平方和判断是否为异常人脸。KNN人脸分类算法由模型建立和故障检测两部分组成。

1.1  模型建立

第一部分为模型建立。首先在训练集中确定每个样本的k个最近邻样本,然后计算每个样本到其k个最近邻样本的欧式距离平方和作为统计量。

1.2  ThreeDPoseUnityBarracuda介绍

第二部分为故障检测。首先在训练集中寻找待测样本x的前k个近邻,然后运用公式计算x与其k个近邻样本的欧式距离平方和。最后将平方和与标准的进行比较,若大于,则样本x为异常样本,否则为正常样本。

人脸特征提取

人脸特征提取这里使用的是face_recognition。Face Recognition 库主要封装了dlib这一 C++ 图形库,通过 Python 语言将它封装为一个非常简单就可以实现人脸识别的 API 库,屏蔽了人脸识别的算法细节,大大降低了人脸识别功能的开发难度。Face Recognition 库进行人脸识别主要经过几个步骤:人脸检测,找出所有的面孔;检测面部特征点:使用特征点矫正姿态,将侧脸转为正脸;给脸部编码:根据面部特征点计算这个面孔的特征值(特征向量)。

244fbb90b2d477b3c67026bbca17a3b4.png

程序设计

这里程序的设计分为以下几个步骤,分别为数据集记录和制作、KNN人脸分类训练和检测异常执行程序。

3.1 人脸数据制作

这里我们简单采样1000个人脸样本,通过face_recognition提取人脸位置,并分割保存。代码如下:

facial_features = ['chin','left_eyebrow','right_eyebrow','nose_bridge','nose_tip','left_eye','right_eye','top_lip','bottom_lip']
video_capture = cv2.VideoCapture(0)
label="flase"
num=0
try:os.mkdir("img/"+label)
except:pass
while True:ret,frame=video_capture.read()face_locations = face_recognition.face_locations(frame)face_landmarks_list = face_recognition.face_landmarks(frame)for face_location in face_locations:top, right, bottom, left = face_locationif len(face_landmarks_list)==1:num+=1face_image = frame[top:bottom, left:right]cv2.imwrite("img/"+label+"/"+str(num)+".jpg",face_image)print("保存第"+str(num)+"张人脸")cv2.imshow("test",face_image)cv2.waitKey(1)else:print("未能检测到人脸,或人脸数目不止一个,请保证只有一个人脸")if num == 1000:breakcv2.destroyAllWindows()

b49b8e1962cebd0bc14340e346446104.png

3.2 KNN人脸分类

KNN对人脸进行分类,首先要遍历训练集中的每一个人脸样本,通过计算每个人脸编码之间的距离判断是否为正样本。其总程序结构如下图,即face_record记录人脸,face_recognition_knn训练人脸并监测,test为检测异常所要执行的脚本,这里已经打包成了exe文件。代码如下:

def train(train_dir, model_save_path=None, n_neighbors=None, knn_algo='ball_tree', verbose=False):X = []y = []for class_dir in os.listdir(train_dir):if not os.path.isdir(os.path.join(train_dir, class_dir)):continuefor img_path in image_files_in_folder(os.path.join(train_dir, class_dir)):image = face_recognition.load_image_file(img_path)face_bounding_boxes = face_recognition.face_locations(image)if len(face_bounding_boxes) != 1:if verbose:print("Image {} not suitable for training: {}".format(img_path,"Didn't find a face" if len(face_bounding_boxes) < 1 else "Found more than one face"))else:X.append(face_recognition.face_encodings(image, known_face_locations=face_bounding_boxes)[0])y.append(class_dir)if n_neighbors is None:n_neighbors = int(round(math.sqrt(len(X))))if verbose:print("Chose n_neighbors automatically:", n_neighbors)knn_clf = neighbors.KNeighborsClassifier(n_neighbors=n_neighbors, algorithm=knn_algo, weights='distance')knn_clf.fit(X, y)if model_save_path is not None:with open(model_save_path, 'wb') as f:pickle.dump(knn_clf, f)return knn_clf
def predict(X_img_path, knn_clf=None, model_path=None, distance_threshold=0.5):if knn_clf is None and model_path is None:raise Exception("Must supply knn classifier either thourgh knn_clf or model_path")if knn_clf is None:with open(model_path, 'rb') as f:knn_clf = pickle.load(f)X_img = X_img_pathX_face_locations = face_recognition.face_locations(X_img)if len(X_face_locations) == 0:return []faces_encodings = face_recognition.face_encodings(X_img, known_face_locations=X_face_locations)closest_distances = knn_clf.kneighbors(faces_encodings, n_neighbors=1)are_matches = [closest_distances[0][i][0] <= distance_threshold for i in range(len(X_face_locations))]return [(pred, loc) if rec else ("unknown", loc) for pred, loc, rec inzip(knn_clf.predict(faces_encodings), X_face_locations, are_matches)]

16c2490e5417261bd540511bf9ce7d7b.png

3.3 异常人脸行为执行

为了防止异常人脸持续执行动作造成电脑卡死,需要制定个GUI按钮,确保只持续执行一次,按确定按钮才会继续监测。以下代码分别包括了GUI界面的定义,主要也就只有一个按钮功能,按钮点击就会让异常程序恢复正常,而始终不会影响人脸检测程序。即本程序和人脸分类互不干扰。代码如下:

def get_window_positon(width, height):window_x_position = (window.winfo_screenwidth() - width) // 2window_y_position = (window.winfo_screenheight() - height) // 2return window_x_position, window_y_position
pos = get_window_positon(tk_width, tk_height) 
window.geometry(f'+{pos[0]}+{pos[1]}')
def closewindow():messagebox.showinfo(title="警告",message="请点击确定")return
def t():try:os.remove("ok.txt")except:passwindow.destroy()
window.protocol("WM_DELETE_WINDOW",closewindow)
bnt=Button(window,text="确定",width=15,height=2,command=t)
bnt.pack()
window.mainloop()
if temp>num:if os.path.exists("ok.txt"):passelse:t2 = threading.Thread(target=test2)t2.start()os.system("1.jpg")f = open("ok.txt", "w")f.close()t1 = threading.Thread(target=test1)t1.start()for name, (top, right, bottom, left) in predictions:draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))text_width, text_height = draw.textsize(name)draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255))draw.text((int((left + right)/2), bottom - text_height - 10), name,font=myfont, fill=(0,0,0))del drawpil_image = np.array(pil_image)temp = num
else:pil_image=img_path
def test2():os.system('1.caj')
def test1():os.system('test.exe')

b3f9acf4ee630082916c97cc3aaf37d7.png

完整代码:

https://codechina.csdn.net/qq_42279468/face-monitor/-/tree/master

李秋键,CSDN博客专家,CSDN达人课作者。硕士在读于中国矿业大学,开发有taptap竞赛获奖等。

相关文章:

初学Java——选择

1.boolean数据类型 1)取值为true/false 2)关系操作符的运算结果是boolean类型&#xff08;6种关系运算符同C语言&#xff09;2.分支语句 1)单分支if 2)双分支if-else 3)多分支if-else(此编码风格可避免深度缩进) if(){ } else if(){ } else if(){ } …

C语言宏定义使用技巧

写好C语言&#xff0c;漂亮的宏定义很重要&#xff0c;使用宏定义可以防止出错&#xff0c;提高可移植性&#xff0c;可读性&#xff0c;方便性等等。下面列举一些成熟软件中常用得宏定义。。。。。。1&#xff0c;防止一个头文件被重复包含#ifndef COMDEF_H#define COMDEF_H//…

java显示本地磁盘所有盘符,显示桌面路径

import java.io.File; import javax.swing.filechooser.FileSystemView;/** 显示本地磁盘根盘符&#xff0c;显示桌面路径 */ public class RDDemo {static File[] files;public static void main(String[] args) {FileSystemView sys FileSystemView.getFileSystemView();fil…

Twitter 禁止未经用户同意分享照片和视频

整理 | 禾木木 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; Twitter 宣布将扩大私人信息政策&#xff0c;包括在未经个人许可的情况下共享的私人媒体&#xff0c;例如照片和视频&#xff0c;因为该社交媒体平台旨在改善用户隐私和安全。 “分享个人媒体&#xff…

这就是我向您推荐使用Thunderbird邮件客户端的理由

E-MAIL服务是最古老的互联网服务之一&#xff0c;相信很多人都在使用&#xff0c;只不过频率不同。IM出现后的&#xff08;及时通信工具&#xff09;一段时间&#xff0c;E-MAIL的通信不及时性估计让很多人交流会更倾向于IM。但是电子邮件&#xff08;E-MAIL&#xff09;仍然是…

ATT汇编语言与GCC内嵌汇编简介

AT&T汇编语言与GCC内嵌汇编简介1 AT&T 与INTEL的汇编语言语法的区别1.1大小写1.2操作数赋值方向1.3前缀1.4间接寻址语法1.5后缀1.6指令2 GCC内嵌汇编2.1简介2.2内嵌汇编举例2.3语法2.3.1汇编语句模板2.3.2输出部分2.3.3输入部分2.3.4限制字符2.3.5破坏描述部分2.4GCC如…

递归和迭代之间的差

递归的基本概念:编程技巧程序调用自身递归调用,是一个函数&#xff0c;调用自身. 在一个函数的定义直接或间接调用自己的方法,它通常是一个大的&#xff0c;复杂的问题分解成一个需要解决的问题类似于原来小问题,它可以大大减少的代码量.使用递归的能力是有限的语句来定义对象的…

智能交通:影响人类未来10-40年的重大变革

作者 | 百度创始人、董事长兼CEO李彦宏 《智能交通&#xff1a;影响人类未来10—40年的重大变革》&#xff0c;是我写的第三本关于人工智能的书。第一本是2017年编写的《智能革命&#xff1a;迎接人工智能时代的社会、经济与文化变革》&#xff0c;第二本是2020年编写的《智能…

Python--日志模块

# 时间 哪个文件里面的 第几行代码import loggingfrom logging import handlers# logging.debug(debug级别&#xff0c;最低级别&#xff0c;一般开发人员用来打印一些调试信息)# logging.info(info级别&#xff0c;正常输出信息&#xff0c;一般用来打印一些正常的操作)# logg…

Linux动态库(.so)搜索路径

众所周知&#xff0c;Linux动态库的默认搜索路径是/lib和/usr/lib。动态库被创建后&#xff0c;一般都复制到这两个目录中。当程序执行时需要某动态库&#xff0c;并且该动 态库还未加载到内存中&#xff0c;则系统会自动到这两个默认搜索路径中去查找相应的动态库文件&#xf…

redis-3.0.2集群部署

Redis 集群安装集群搭建步骤1、创建多个节点.2、为每个节点指派槽&#xff0c;并将多个节点连接起来&#xff0c;组成一个集群.3、当集群数据库的16384个槽都有节点在处理时&#xff0c;集群进入上线状态.要求&#xff1a;搭建一个包含6个节点的Redis集群&#xff0c;其中三个主…

联邦学习应用思考:需求还是方法?

作者 | 徐葳 清华大学交叉信息研究院长聘副教授、华控清交首席科学家前言&#xff1a;目前&#xff0c;“联邦学习”这个术语在市场上存在很多认识上的误解和混淆&#xff0c;主要原因是其既在广义上表达了保护数据前提下联合多方数据训练模型的需求&#xff0c;又在狭义上表示…

monkey如何获取app包名

别人学习网址&#xff1a;http://www.51testing.com/html/58/15092658-2984032.html 使用aapt aapt是sdk自带的一个工具&#xff0c;在sdk\builds-tools\目录下&#xff0c; 1. 在cmd中&#xff0c;切换至sdk\builds-tools\目录下&#xff0c;即aapt.exe目录下2.以QQ音乐为例…

嵌入式Web服务器移植

第一步 Boa程序的移植1、下载Boa源码下载地址: http://www.boa.org/&#xff0c; 或者http://sourceforge.net最新发行版本&#xff1a; 0.94.13下载 boa-0.94.13.tar.gz&#xff0c;注意&#xff1a;从boa上下载的是boa-0.94.13.tar.tar&#xff0c;解压方式一样解压&#xff…

一文详解 RNN 及股票预测实战(Python)!

作者 | 泳鱼来源 | 算法进阶循环神经网络&#xff08;RNN&#xff09;是基于序列数据&#xff08;如语言、语音、时间序列&#xff09;的递归性质而设计的&#xff0c;是一种反馈类型的神经网络&#xff0c;其结构包含环和自重复&#xff0c;因此被称为“循环”。它专门用于处理…

symfony2 Process 组件的学习笔记

2019独角兽企业重金招聘Python工程师标准>>> 安装 composer require "symfony/process:2.7.1" ##描述 process组件是可以开启一个子进程 去执行一个命令 ##例子 use Symfony\Component\Process\Process; $process new Process(ls -lsa); $process->ru…

C++模式学习------策略模式

当遇到同一个对象有不同的行为&#xff0c;方法&#xff0c;为管理这些方法可使用策略模式。 策略模式就是对算法进行包装&#xff0c;是把使用算法的责任和算法本身分割开来。通常把一个系列的算法包装到一系列的策略类里面&#xff0c;这些类继承一个抽象的策略类。使用这些算…

自动生成Makefile的全过程详解

automake/autoconf入门作为Linux下的程序开发人员&#xff0c;大家一定都遇到过Makefile&#xff0c;用make命令来编译自己写的程序确实是很方便。一般情况下&#xff0c;大家都是手工写一个简单Makefile&#xff0c;如果要想写出一个符合自由软件惯例的Makefile就不那么容易了…

Meta 开移动端 AI 生成神器 PyTorch Live,打造人工智能驱动的移动体验

整理 | 禾木木 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 近日&#xff0c;PyTorch 开发者大会如期召开。在会上&#xff0c;Meta 发布了PyTorch Live&#xff0c;这是一套可以为移动端用户提供人工智能体验的工具。PyTorch Live 支持单一的编程语言JavaScript…

在NewLisp中实现匿名函数的递归

2019独角兽企业重金招聘Python工程师标准>>> 匿名函数在很多语言中的表现形式大概如下&#xff1a; (lambda (n)(* ( n 1) (- n 1))) 只有参数列表和函数体&#xff0c;而没有名字。在大部分情况下没问题&#xff0c;但是一旦需要用到递归的话&#xff0c;就有点麻烦…

C# Obsolete(已弃用方法属性)

class Realization : Interface{/// <summary>/// 已弃用的方法&#xff0c;Obsolete第二个参数设置为true,调用此方法会产生警告并引起编译器报错/// </summary>/// <param name"skey">参数</param>/// <returns></returns>[Ob…

如何训练2457亿参数量的中文巨量模型“源1.0”

如何训练2457亿参数量的中文巨量模型“源1.0” 浪潮人工智能研究院 从2018年的BERT到2020年的GPT-3&#xff0c;NLP语言模型经历了爆发式的发展过程&#xff0c;其中BERT模型的参数量为3.4亿&#xff0c;而GPT-3的模型参数量达到了1750亿。2021年9月&#xff0c;浪潮人工智能…

Linux驱动程序编写

工作需要写了我们公司一块网卡的Linux驱动程序。经历一个从无到有的过程&#xff0c;深感技术交流的重要。Linux作为挑战微 软垄断的强有力武器&#xff0c;日益受到大家的喜爱。真希望她能在中国迅速成长。把程序文档贴出来&#xff0c;希望和大家探讨Linux技术和应用&#xf…

PHP+socket+SMTP、POP3协议发送、接收邮件

1、实现SMTP协议的类dsmtp.cls.php&#xff1a;<?php//通过socket实现SMTP协议的功能//version: 1.1//author : DCC//create : 2014-01-17 23:38:24//modify : 2014-01-18 16:59:04//more : http://www.thinkful.cn/archives/389.htmlclass Dmail_smtp{var $socket;var $…

JavaScript学习记录 (三) 函数和对象

1.函数使用 function 关键字来声明函数函数的命名规则和变量一样JS没有函数签名&#xff0c;所以没有函数重载JS函数中的所有参数都是值传递&#xff1b;不能通过引用传递// 定义函数 function test(arg) {return arg 10; } // 定义一个同名函数 function test(arg, arg1) {re…

基于jQuery图片自适应排列显示代码

基于jQuery图片自适应排列显示代码。这是一款基于jquery.flex-images插件实现的类似谷歌图片流效果。效果图如下&#xff1a; 在线预览 源码下载 实现的代码。 html代码&#xff1a; <div style"max-width:900px;margin:auto;padding:0 10px"><h3>演示…

计算机史最疯狂一幕:豪赌50亿美元,“蓝色巨人”奋身一跃

作者 | OneFlow社区来源 | OneFlow社区“Go big or go home. ”是美国人的一句习语&#xff0c;经常会在赛场上听到&#xff0c;NBA球迷应该很熟悉&#xff0c;翻译过来就是“要不变强大&#xff0c;要不滚回家”。在1960年初期的计算机行业&#xff0c;IBM正站在这样一个十字路…

CentOS Linux内核升级全过程

首先说明&#xff0c;下面带#号的行都是要输入的命令行&#xff0c;且本文提到的所有命令行都在终端里输入。接下来&#xff0c;让我们一起开始精彩的Linux内核升级之旅吧&#xff01;一、准备工作启动Linux系统&#xff0c;并用根用户登录&#xff0c;进入终端模式下。1、查看…

Windows程序设计------字体不等宽引出的问题及其细节知识

在写Windows程序设计的Typer程序时&#xff0c;我并不是在每一个使用HDC的地方都重新创建选中字体&#xff0c;而是在一开始选中之后&#xff0c;就没有再删除它&#xff0c;代码如图&#xff1a; 结果我的字体不是等宽字体&#xff01; 起先我以为是没有设置WM_INPUTLANGCHANG…

看闯关东原来知道古代已经十六进制了

闯关东第四集中夏掌柜说黄县口诀什么意思 1625 2125 31875 425 53125 6375 74375 85 95625 1625 116875 1275 138125 14875 159375 161 这个问题实际上是过去商品流通中的一种算法。过去的衡器十六两为一斤&#xff0c;也就是十六进制。为了计算方便&#xff0c;先人便选用了这…