Python实现人脸识别算法并封装为类库
引言
人脸识别技术在现代社会中应用广泛,从安全监控到智能门锁,再到社交媒体中的照片标记功能,都离不开这项技术。本文将详细介绍如何使用Python实现基本的人脸识别算法,并将其封装为一个类库,以便在多个项目中复用。
环境准备
安装依赖
首先,确保你的环境中安装了以下库:
- OpenCV
- dlib
- face_recognition
你可以使用以下命令安装这些库:
pip install opencv-python
pip install dlib
pip install face_recognition
代码实现
1. 创建类库文件
我们将创建一个名为 face_recognition_lib.py 的文件,内容如下:
import cv2
import face_recognition
import numpy as np
from PIL import Image, ImageDrawclass FaceRecognition:def __init__(self, image_paths):"""初始化FaceRecognition类。:param image_paths: 已知人脸图像的路径列表"""self.known_face_encodings, self.known_face_names = self.load_and_encode_faces(image_paths)def load_and_encode_faces(self, image_paths):"""加载并编码已知人脸图像。:param image_paths: 已知人脸图像的路径列表:return: 已知人脸的编码和名称"""known_face_encodings = []known_face_names = []for image_path in image_paths:# 加载图片image = face_recognition.load_image_file(image_path)# 编码人脸face_encoding = face_recognition.face_encodings(image)[0]# 获取文件名作为名字name = image_path.split('/')[-1].split('.')[0]# 添加到已知人脸列表known_face_encodings.append(face_encoding)known_face_names.append(name)return known_face_encodings, known_face_namesdef real_time_face_recognition(self):"""实现实时人脸识别。"""# 打开摄像头video_capture = cv2.VideoCapture(0)while True:# 读取一帧ret, frame = video_capture.read()# 将帧转换为RGBrgb_frame = frame[:, :, ::-1]# 检测人脸位置face_locations = face_recognition.face_locations(rgb_frame)# 编码人脸face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)# 遍历检测到的人脸for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):# 匹配已知人脸matches = face_recognition.compare_faces(self.known_face_encodings, face_encoding)name = "Unknown"# 计算欧氏距离face_distances = face_recognition.face_distance(self.known_face_encodings, face_encoding)best_match_index = np.argmin(face_distances)if matches[best_match_index]:name = self.known_face_names[best_match_index]# 在帧上绘制矩形和标签cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)font = cv2.FONT_HERSHEY_DUPLEXcv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)# 显示结果cv2.imshow('Video', frame)# 按q键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放摄像头video_capture.release()cv2.destroyAllWindows()# 示例用法
if __name__ == "__main__":# 已知人脸图像路径image_paths = ['path/to/known_face_1.jpg','path/to/known_face_2.jpg',# 添加更多已知人脸图像路径]# 初始化FaceRecognition类face_recognition = FaceRecognition(image_paths)# 启动实时人脸识别face_recognition.real_time_face_recognition()
2. 详细解释
初始化
class FaceRecognition:def __init__(self, image_paths):"""初始化FaceRecognition类。:param image_paths: 已知人脸图像的路径列表"""self.known_face_encodings, self.known_face_names = self.load_and_encode_faces(image_paths)
在类的初始化方法中,我们传入已知人脸图像的路径列表,并调用 load_and_encode_faces 方法来加载和编码这些图像。
加载和编码已知人脸
def load_and_encode_faces(self, image_paths):"""加载并编码已知人脸图像。:param image_paths: 已知人脸图像的路径列表:return: 已知人脸的编码和名称"""known_face_encodings = []known_face_names = []for image_path in image_paths:# 加载图片image = face_recognition.load_image_file(image_path)# 编码人脸face_encoding = face_recognition.face_encodings(image)[0]# 获取文件名作为名字name = image_path.split('/')[-1].split('.')[0]# 添加到已知人脸列表known_face_encodings.append(face_encoding)known_face_names.append(name)return known_face_encodings, known_face_names
load_and_encode_faces 方法遍历传入的图像路径列表,加载每张图像并对其进行编码。编码后的特征向量和对应的名字被存储在两个列表中,分别返回。
实时人脸识别
def real_time_face_recognition(self):"""实现实时人脸识别。"""# 打开摄像头video_capture = cv2.VideoCapture(0)while True:# 读取一帧ret, frame = video_capture.read()# 将帧转换为RGBrgb_frame = frame[:, :, ::-1]# 检测人脸位置face_locations = face_recognition.face_locations(rgb_frame)# 编码人脸face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)# 遍历检测到的人脸for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):# 匹配已知人脸matches = face_recognition.compare_faces(self.known_face_encodings, face_encoding)name = "Unknown"# 计算欧氏距离face_distances = face_recognition.face_distance(self.known_face_encodings, face_encoding)best_match_index = np.argmin(face_distances)if matches[best_match_index]:name = self.known_face_names[best_match_index]# 在帧上绘制矩形和标签cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)font = cv2.FONT_HERSHEY_DUPLEXcv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)# 显示结果cv2.imshow('Video', frame)# 按q键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放摄像头video_capture.release()cv2.destroyAllWindows()
real_time_face_recognition 方法打开摄像头并读取视频流。对于每一帧,我们将其转换为RGB格式,检测人脸位置并编码。然后,我们将编码后的人脸与已知人脸进行匹配,并在帧上绘制矩形和标签。按 q 键可以退出程序。
3. 使用类库
创建一个名为 main.py 的文件,内容如下:
from face_recognition_lib import FaceRecognition# 已知人脸图像路径
image_paths = ['path/to/known_face_1.jpg','path/to/known_face_2.jpg',# 添加更多已知人脸图像路径
]# 初始化FaceRecognition类
face_recognition = FaceRecognition(image_paths)# 启动实时人脸识别
face_recognition.real_time_face_recognition()
4. 运行示例
确保你的环境中安装了所需的库:
pip install opencv-python
pip install dlib
pip install face_recognition
然后运行 main.py:
python main.py
5. 代码运行接口
为了使类库更加通用和易于集成,我们可以添加一些额外的方法和配置选项。以下是改进后的类库文件 face_recognition_lib.py:
import cv2
import face_recognition
import numpy as np
from PIL import Image, ImageDrawclass FaceRecognition:def __init__(self, image_paths, tolerance=0.6, model='hog'):"""初始化FaceRecognition类。:param image_paths: 已知人脸图像的路径列表:param tolerance: 人脸匹配的阈值:param model: 人脸检测模型('hog' 或 'cnn')"""self.tolerance = toleranceself.model = modelself.known_face_encodings, self.known_face_names = self.load_and_encode_faces(image_paths)def load_and_encode_faces(self, image_paths):"""加载并编码已知人脸图像。:param image_paths: 已知人脸图像的路径列表:return: 已知人脸的编码和名称"""known_face_encodings = []known_face_names = []for image_path in image_paths:# 加载图片image = face_recognition.load_image_file(image_path)# 编码人脸face_encoding = face_recognition.face_encodings(image)[0]# 获取文件名作为名字name = image_path.split('/')[-1].split('.')[0]# 添加到已知人脸列表known_face_encodings.append(face_encoding)known_face_names.append(name)return known_face_encodings, known_face_namesdef real_time_face_recognition(self, camera_index=0):"""实现实时人脸识别。:param camera_index: 摄像头索引"""# 打开摄像头video_capture = cv2.VideoCapture(camera_index)while True:# 读取一帧ret, frame = video_capture.read()# 将帧转换为RGBrgb_frame = frame[:, :, ::-1]# 检测人脸位置face_locations = face_recognition.face_locations(rgb_frame, model=self.model)# 编码人脸face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)# 遍历检测到的人脸for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):# 匹配已知人脸matches = face_recognition.compare_faces(self.known_face_encodings, face_encoding, tolerance=self.tolerance)name = "Unknown"# 计算欧氏距离face_distances = face_recognition.face_distance(self.known_face_encodings, face_encoding)best_match_index = np.argmin(face_distances)if matches[best_match_index]:name = self.known_face_names[best_match_index]# 在帧上绘制矩形和标签cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)font = cv2.FONT_HERSHEY_DUPLEXcv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)# 显示结果cv2.imshow('Video', frame)# 按q键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放摄像头video_capture.release()cv2.destroyAllWindows()# 示例用法
if __name__ == "__main__":# 已知人脸图像路径image_paths = ['path/to/known_face_1.jpg','path/to/known_face_2.jpg',# 添加更多已知人脸图像路径]# 初始化FaceRecognition类face_recognition = FaceRecognition(image_paths, tolerance=0.6, model='hog')# 启动实时人脸识别face_recognition.real_time_face_recognition(camera_index=0)
6. 详细说明
初始化
def __init__(self, image_paths, tolerance=0.6, model='hog'):"""初始化FaceRecognition类。:param image_paths: 已知人脸图像的路径列表:param tolerance: 人脸匹配的阈值:param model: 人脸检测模型('hog' 或 'cnn')"""self.tolerance = toleranceself.model = modelself.known_face_encodings, self.known_face_names = self.load_and_encode_faces(image_paths)
我们在初始化方法中增加了 tolerance 和 model 参数,以便在实例化类时可以调整人脸匹配的阈值和检测模型。
实时人脸识别
def real_time_face_recognition(self, camera_index=0):"""实现实时人脸识别。:param camera_index: 摄像头索引"""# 打开摄像头video_capture = cv2.VideoCapture(camera_index)while True:# 读取一帧ret, frame = video_capture.read()# 将帧转换为RGBrgb_frame = frame[:, :, ::-1]# 检测人脸位置face_locations = face_recognition.face_locations(rgb_frame, model=self.model)# 编码人脸face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)# 遍历检测到的人脸for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):# 匹配已知人脸matches = face_recognition.compare_faces(self.known_face_encodings, face_encoding, tolerance=self.tolerance)name = "Unknown"# 计算欧氏距离face_distances = face_recognition.face_distance(self.known_face_encodings, face_encoding)best_match_index = np.argmin(face_distances)if matches[best_match_index]:name = self.known_face_names[best_match_index]# 在帧上绘制矩形和标签cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)font = cv2.FONT_HERSHEY_DUPLEXcv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)# 显示结果cv2.imshow('Video', frame)# 按q键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放摄像头video_capture.release()cv2.destroyAllWindows()
我们在 real_time_face_recognition 方法中增加了 camera_index 参数,以便可以选择不同的摄像头。同时,我们使用了 tolerance 和 model 参数来调整人脸匹配的阈值和检测模型。
7. 总结
通过上述步骤,我们成功实现了基于Python的人脸识别算法,并将其封装为一个类库。使用OpenCV和dlib库,我们可以轻松地加载和编码已知人脸,并在实时视频流中检测和识别人脸。希望这篇文章对你有所帮助!
相关文章:
Python实现人脸识别算法并封装为类库
引言 人脸识别技术在现代社会中应用广泛,从安全监控到智能门锁,再到社交媒体中的照片标记功能,都离不开这项技术。本文将详细介绍如何使用Python实现基本的人脸识别算法,并将其封装为一个类库,以便在多个项目中复用。…...
uniapp小程序分享使用canvas自定义绘制 vue3
使用混入结合canvas做小程序的分享 在混入里面定义一个全局共享的分享样式,在遇到特殊页面需要单独处理 utils/share.js import { ref } from vue; export default {onShow() {// 创建时设置统一页面的默认值uni.$mpShare {title: 分享的标题,path: /pages/home/…...
SpringCloud核心组件(四)
文章目录 NacosNacos 配置中心1.起源2.基本概念ProfileData IDGroup 3.基础配置a. bootstrap.ymlb. application.ymlc. nacos 中的配置 DataIDd.测试读取配置中心配置内容 4.配置隔离a.命名空间b.DataIDc.bootstrap.ymld.service 隔离 5.配置拆分a.配置拆分策略b.DataID 配置c.…...
如何把本地docker 镜像下载用到centos系统中呢?
如果需要将镜像下载到本地或在 CentOS 系统上使用该镜像,你可以按照以下步骤操作: 1. 拉取镜像 如果想将镜像从 Docker Hub 或其他镜像仓库下载到本地,可以使用 docker pull 命令。 如果使用的是本地构建的镜像(如 isc:v1.0.0&…...
Godot的开发框架应当是什么样子的?
目录 前言 全局协程还是实例协程? 存档! 全局管理类? UI框架? Godot中的异步(多线程)加载 Godot中的ScriptableObject 游戏流程思考 结语 前言 这是一篇杂谈,主要内容是对我…...
GitHub新手入门 - 从创建仓库到协作管理
GitHub新手入门 - 从创建仓库到协作管理 GitHub 是开发者的社交平台,同时也是代码托管的强大工具。无论是个人项目、开源协作,还是团队开发,GitHub 都能让你轻松管理代码、版本控制和团队协作。今天,我们将从基础开始,…...
作业25 深度搜索3
作业: #include <iostream> using namespace std; bool b[100][100]{0}; char map[100][100]{0}; int dx[4]{0,1,0,-1}; int dy[4]{1,0,-1,0}; int n,m; int sx,sy,ex,ey; int mink2147483647; void dfs(int,int,int); int main(){cin>>n>>m;for(…...
ubuntu20.04 colmap 安装2024.11最新
很多教程都很落后了,需要下载压缩包解压编译的很麻烦 现在就只需要apt install就可以了 apt更新 sudo apt update && sudo apt-get upgrade安装依赖 #安装依赖 sudo apt-get install git cmake ninja-build build-essential libboost-program-options-de…...
WebRTC视频 03 - 视频采集类 VideoCaptureDS 上篇
WebRTC视频 01 - 视频采集整体架构 WebRTC视频 02 - 视频采集类 VideoCaptureModule [WebRTC视频 03 - 视频采集类 VideoCaptureDS 上篇](本文) WebRTC视频 04 - 视频采集类 VideoCaptureDS 中篇 WebRTC视频 05 - 视频采集类 VideoCaptureDS 下篇 一、前…...
python os.path.basename(获取路径中的文件名部分) 详解
os.path.basename 是 Python 的 os 模块中的一个函数,用于获取路径中的文件名部分。它会去掉路径中的目录部分,只返回最后的文件名或目录名。 以下是 os.path.basename 的详细解释和使用示例: 语法 os.path.basename(path) 参数 path&…...
《FreeRTOS任务基础知识以及任务创建相关函数》
目录 1.FreeRTOS多任务系统与传统单片机单任务系统的区别 2.FreeRTOS中的任务(Task)介绍 2.1 任务特性 2.2 FreeRTOS中的任务状态 2.3 FreeRTOS中的任务优先级 2.4 在任务函数中退出 2.5 任务控制块和任务堆栈 2.5.1 任务控制块 2.5.2 任务堆栈…...
036集——查询CAD图元属性字段信息:窗体显示(CAD—C#二次开发入门)
提取CAD图元所有属性字段,通过窗体显示,效果如下:(curve改为entity) 代码如下: public void 属性查询() {List<Curve> ents Z.db.SelectEntities<Curve>();if (ents is null ||ents.Cou…...
Swift从0开始学习 函数和闭包 day2
一、函数 1.1函数定义 使用 func 来声明一个函数,使用名字和参数来调用函数。使用 -> 来指定函数返回值的类型。 示例:拼接字符串 //有参数和返回值的函数 func append1(name : String, description : String) -> String {return "\(name)…...
内网、公网(外网)划分
内网、公网(外网)划分 声明! 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章 笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其…...
【linux】centos7 换阿里云源
相关文章 【linux】CentOS 的软件源(Repository)学习-CSDN博客 查看yum配置文件 yum的配置文件通常位于/etc/yum.repos.d/目录下。你可以使用以下命令查看这些文件: ls /etc/yum.repos.d/ # 或者 ll /etc/yum.repos.d/备份当前的yum配置文…...
用OMS进行 OceanBase 租户间数据迁移的测评
基本概念 OceanBase迁移服务(,简称OMS),可以让用户在同构或异构 RDBMS 与OceanBase 数据库之间进行数据交互,支持数据的在线迁移,以及实时增量同步的复制功能。 OMS 提供了可视化的集中管控平台ÿ…...
【因果分析方法】MATLAB计算Liang-Kleeman信息流
【因果分析方法】MATLAB计算Liang-Kleeman信息流 1 Liang-Kleeman信息流2 MATLAB代码2.1 函数代码2.2 案例参考Liang-Kleeman 信息流(Liang-Kleeman Information Flow)是由 Liang 和 Kleeman 提出的基于信息论的因果分析方法。该方法用于量化变量之间的因果关系,通过计算信息…...
【Java基础知识系列】之Java类的初始化顺序
前言 类的初始化顺序 简单场景 代码示例 public class Person {private String name initName();private String initName() {System.out.println("【父类】初始化实例变量name");return "【父类】史蒂夫";}private int age;private static int staticVa…...
Swift 宏(Macro)入门趣谈(二)
概述 苹果在去年 WWDC 23 中就为 Swift 语言新增了“其利断金”的重要小伙伴 Swift 宏(Swift Macro)。为此,苹果特地用 2 段视频(入门和进阶)颇为隆重的介绍了它。 那么到底 Swift 宏是什么?有什么用&…...
vue elementui el-dropdown-item设置@click无效的解决方案
如图,直接在el-dropdown-item上面设置click,相应的method并没有被触发,查找资料发现需要在它的上级 el-dropdown 处使用 command 方法触发。 【template】 <el-dropdown placement"bottom-end" command"handleCommand&quo…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
shell脚本质数判断
shell脚本质数判断 shell输入一个正整数,判断是否为质数(素数)shell求1-100内的质数shell求给定数组输出其中的质数 shell输入一个正整数,判断是否为质数(素数) 思路: 1:1 2:1 2 3:1 2 3 4:1 2 3 4 5:1 2 3 4 5-------> 3:2 4:2 3 5:2 3…...
【Vue】scoped+组件通信+props校验
【scoped作用及原理】 【作用】 默认写在组件中style的样式会全局生效, 因此很容易造成多个组件之间的样式冲突问题 故而可以给组件加上scoped 属性, 令样式只作用于当前组件的标签 作用:防止不同vue组件样式污染 【原理】 给组件加上scoped 属性后…...
学习 Hooks【Plan - June - Week 2】
一、React API React 提供了丰富的核心 API,用于创建组件、管理状态、处理副作用、优化性能等。本文档总结 React 常用的 API 方法和组件。 1. React 核心 API React.createElement(type, props, …children) 用于创建 React 元素,JSX 会被编译成该函数…...
Java多线程从入门到精通
一、基础概念 1.1 进程与线程 进程是指运行中的程序。 比如我们使用浏览器,需要启动这个程序,操作系统会给这个程序分配一定的资源(占用内存资源)。 线程是CPU调度的基本单位,每个线程执行的都是某一个进程的代码的某…...
android关于pthread的使用过程
文章目录 简介代码流程pthread使用hello_test.cppAndroid.bp 编译过程报错处理验证过程 简介 android开发经常需要使用pthread来编写代码实现相关的业务需求 代码流程 pthread使用 需要查询某个linux函数的方法使用,可以使用man 函数名 // $ man pthread_crea…...
