基于OpenCV提供的人脸识别算法LBPH实现人脸识别

news2024/11/16 17:45:47

本文通过学习LBPH人脸识别算法,简要了解人脸识别技术的原理,实现人脸采集、训练人脸模型实现人脸识别。

文章目录

  • 一、 LBPH人脸识别算法概述
  • 二、 人脸识别技术原理
  • 三、 关键模块
  • 四、 实验准备
    • 1. 第三方库
    • 2. 新建相关文件夹
    • 3. 实验环境
  • 五、 人脸采集与检测实现
    • 1.人脸采集与检测FaceCollect.py代码
    • 2.程序执行效果
  • 六、 人脸模型训练实现
    • 1.训练人脸模型FaceTrain.py代码
    • 2.程序执行效果
  • 七、 人脸识别实现
    • 1.人脸识别FaceRecognition.py代码
    • 2.关于置信度confidence
    • 3.程序执行效果
  • 程序链接


一、 LBPH人脸识别算法概述

OpenCV库自带的人脸级联分级器具有很好的人脸检测和人脸追踪效果,它是一个基于Haar特征的Adaboost级联分类器。特别注意,OpenCV库虽然自带人脸级联分级器,但是识别效率一般。本项目使用的是OpenCV提供的人脸识别算法LBPH(Local Binary Pattern Histogram),即局部二进制模式直方图,它属于OpenCV拓展库opencv-contrib的一部分,需要另外单独安装opencv-contrib-python-4.1.2。
LBPH人脸识别算法思路如下:将检测到的人脸分为小单元如下图1所示,并将其与模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图,如图2所示,通过对直方图的比较,算法将能够识别图像的边缘和角,能够识别直方图中哪些代表人的主要特征,比如眼睛的颜色、嘴巴的形状等等,这个算法的基本理论也就是基于直方图的创建和比较。由于这种方法通过比较不同人脸图像LBP编码直方图达到人脸识别的目的,其优点是不会受到光照、缩放、旋转和平移的影响。
图1:图像和像素分解
提示:二进制是将中间的数值“90”与四周数值进行对比,大于为1,小于为0,然后绕四周逆时针得出二进制10001101
图2:以眼睛区域直方图示例
*参考文档:
1.使用LBPH算法理解人脸识别
2.LBPH人脸识别

二、 人脸识别技术原理

一个完整的人脸识别系统包含五个主要部分,即人脸采集(Face Collect)、人脸检测(Face Detection)、人脸配准(Face Alignment)、人脸特征提取(Face Feature Extraction)、人脸识别(Face Recognition)。
人脸识别的过程

人脸采集:

利用摄像机等采集设备拍摄人脸图像。

人脸检测:

人脸检测是检测出图像中人脸所在位置的一项技术,一般情况下就是用一个矩形框把人脸框出来。本项目使用Haar人脸识别分类器检测。

人脸配准:

人脸配准是根据输入的人脸图像,自动定位出人脸上五官关键点坐标的一项技术,一般有5点、68点、90点。

人脸特征提取:

人脸特征提取是将一张人脸图像转化为一串固定长度的数值的过程。
人脸特征提取过程示意图

人脸识别:

人脸识别是一种识别出输入人脸图对应身份的算法技术。输入一张人脸图像,通过与注册在库中N个身份对应的特征进行逐个比对,找出“一个”与输入特征相似度最高的特征。
人脸识别过程示意图

三、 关键模块

1.根据以上分析,本项目将实现人脸识别分为以下3个小任务,通过3个步骤来完成人脸采集与检测、人脸模型训练、人脸识别。
完成步骤
2.函数介绍
在OpenCV中,使用函数cv2.face.LBPHFaceRecognizer_create()生成LBPH人脸识别器实例模型,然后应用cv2.face_FaceRecognizer.train()函数完成训练,最后用cv2.face_FaceRecognizer.predict()函数完成人脸识别。

四、 实验准备

1. 第三方库

需要安装的第三方库

2. 新建相关文件夹

新建一个FaceRecognition工程文件夹,在里面Facedata文件夹、cv2data文件夹、Model文件夹
新建这3个文件夹
文件夹“树图”

提前将haar的人脸分类器放到cv2data文件夹

3. 实验环境

(1)摄像头设备。
(2) python3.7(文末提供的安装包是3.7版本的,如果是其他版本,请根据需要升级第三方库)。
备注:文末提供参考程序


五、 人脸采集与检测实现

第一步:采集和检测人脸

1.人脸采集与检测FaceCollect.py代码

实现效果见本程序后面

#导入库函数
import cv2
import numpy as np
import random
#请先看主函数
# 将捕获照片的大小裁剪为正方形
def getpaddingSize(shape):
    # 照片的长和宽
    h, w = shape
    longest = max(h, w)
    # 将最长的边进行处理
    result = (np.array([longest]*4, int) - np.array([h, h, w, w], int)) // 2
    return result.tolist()

# 图像去噪处理,使得训练出来的模型具备一定的泛化能力
def dealwithimage(img, h=64, w=64):
    top, bottom, left, right = getpaddingSize(img.shape[0:2])
    img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[0, 0, 0])
    img = cv2.resize(img, (h, w))
    return img

# 捕获人脸,要拍够100张人脸图像
def GetFace(name,face_id):
    # 0: 笔记本内置摄像头; 1: USB摄像头
    camera = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    # 获取分类器
    face_detector = cv2.CascadeClassifier(r'./cv2data/haarcascade_frontalface_default.xml')
    count = 1
    while True:
        # 默认获取100张图片作为训练数据集
        if(count<=100):
            print("It's processing %s image." % count)
            # 读取图片
            success,img = camera.read()
            # 图片灰度化
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            # 检测人脸
            faces = face_detector.detectMultiScale(gray,1.3,8)
            for (x, y, w, h) in faces:
                # 图像预处理,处理成64*64大小的图片
                face = gray[y:y+h, x:x+w]
                face = cv2.resize(face, (64, 64))
                # 图像去噪处理
                face = dealwithimage(face)
                # 保存图片
                cv2.imwrite("Facedata/User." + str(face_id) + '.' + str(count) + '.jpg', face)
                # 在图片上显示名字
                cv2.putText(img, name, (x, y-20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2)
                # 画一个矩形
                img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
                count+=1
            cv2.imshow('img', img)
            # 保持画面持续
            key = cv2.waitKey(30)&0xff
            # 按下Esc退出
            if key == 27:
                break
        else:
            break
    # 关闭摄像头
    camera.release()
    cv2.destroyAllWindows()
 #主函数
if __name__ == '__main__':
    # 请输入您的name和id
    name = input('Please input your name:')
    face_id = input('Please input face id:')  #ID很重要,训练分类的时候根据id来识别对应的模型
    GetFace(name,face_id)  

2.程序执行效果

程序打印下列内容,输入人脸身份(如lyx),其次输入身份ID(序号0,1,2…)。当用户输入名字和ID,按下回车键后,只要用户正对着摄像头计算机会自动采集人脸图像,直到采集到100张有效照片后自动退出,照片默认保存在根目录下的Facedata文件夹

执行窗口
Facedata文件夹内采集图像


六、 人脸模型训练实现

训练人脸模型对采集到的人脸数据集进行人脸特征提取并建立人脸模型,形成模型文件。

1.训练人脸模型FaceTrain.py代码

import os
import cv2
from PIL import Image
import numpy as np

# 人脸训练集路径
path = './Facedata/'
# 初始化识别器
# opencv-contrib-python和opencv-python库版本要一致,否则运行会报错
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 获取分类器
detector = cv2.CascadeClassifier(r'./cv2data/haarcascade_frontalface_default.xml')

# 获取图像及标签
def getImagesAndLabels(path):
    # join函数的作用
    imagePaths = [os.path.join(path, f) for f in os.listdir(path)]  
    faceSamples = []
    ids = []
    for imagePath in imagePaths:
        PIL_img = Image.open(imagePath).convert('L')   
        img_numpy = np.array(PIL_img, 'uint8')
        id = int(os.path.split(imagePath)[-1].split(".")[1])
        faces = detector.detectMultiScale(img_numpy)
        for (x, y, w, h) in faces:
            faceSamples.append(img_numpy[y:y + h, x: x + w])
            ids.append(id)
    return faceSamples, ids

# 主程序入口
if __name__ == "__main__":
    print('Training faces. It will take a few seconds. Waiting...')
    faces, ids = getImagesAndLabels(path)
    # 开始训练
    recognizer.train(faces, np.array(ids))         
    print('Training has finished!')
    # 保存文件,生成模型,模型名为“trainer20221230”
    recognizer.write(r'./Model/trainer20221230.yml')  
    print("{0} faces trained. Exiting Program.".format(len(np.unique(ids))))

2.程序执行效果

当出现如下所示的信息时,说明模型训练完成,模型文件默认保存在当前程序目录下的Model文件夹

Training faces. It will take a few seconds. Waiting...
Training has finished!
1 faces trained. Exiting Program.

训练生成人脸模型


七、 人脸识别实现

实现人脸识别

通过摄像头实时捕获人脸图像,进行人脸追踪,跟训练好的人脸模型trainer-20221230.yml进行特征匹配,从而进行人脸识别,对应的用户名字会实时显示在人脸图像上。

1.人脸识别FaceRecognition.py代码

import cv2
# 人脸识别函数
def Face():
    # 初始化识别器
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    # 加载训练好的模型文件
    recognizer.read('./Model/trainer-2021.yml')
    # 获取分类器
    faceCascade = cv2.CascadeClassifier(r'./cv2data/haarcascade_frontalface_default.xml')
    # 设置图片显示的字体
    font = cv2.FONT_HERSHEY_SIMPLEX
    idnum = 0  #用户ID
    # 用户需要在此添加自己的姓名(拼音),下标序号要与名字对应(ID从0开始,依次递增)
    names = ['lin','Jack']
    # 捕获图像
    camera = cv2.VideoCapture(0, cv2.CAP_DSHOW)
    # 设置格式
    minW = 0.1*camera.get(3)
    minH = 0.1*camera.get(4)
    print('请正对着摄像头...')
    confidence = 150.00  #设置置信度初始值
    score = 0  #设置匹配指数初始值
    name = "unknown"
    while True:
        # 读取图片
        success,img = camera.read()
        # 图片灰度化
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # 检测人脸
        faces = faceCascade.detectMultiScale(
            gray,
            scaleFactor=1.3,
            minNeighbors=5,
            minSize=(int(minW), int(minH))
        )
        for (x, y, w, h) in faces:
            # 画一个矩形
            cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
            # 图像预测 https://www.py.cn/jishu/jichu/26805.html
            #predict()函数返回两个元素的数组:第一个元素是所识别 个体的标签,第二个是置信度评分。
            #  图像预测predict函数,返回值一个是id,一个是置信度confidence,置信度值越小越好
            idnum, confidence = recognizer.predict(gray[y:y+h, x:x+w])
            # 设置匹配指数,200是根据confidence的结果估算出来的
            score =int( "{0}".format(round(200 - confidence)))
            # 匹配指数大于等于95即可验证通过人脸  
            if score > 95:
                name = names[idnum]
            else:
                name = "unknown"
            cv2.putText(img, str(name), (x+5, y-5), font, 1, (230, 250, 100), 1)
            cv2.putText(img, str(score), (x+5, y+h-5), font, 1, (255, 0, 0), 1)
        cv2.imshow('camera', img)
        # 保持画面持续
        key = cv2.waitKey(10)
        # 按Esc键退出
        if key==27 or score > 95:
            cv2.imwrite('./image.jpg', img)
            break
    # 关闭摄像头
    camera.release()
    cv2.destroyAllWindows()
    return name,confidence

if __name__ == '__main__':
    name,confidence = Face()
    score = "{0}".format(round(200 - confidence))
    print("您的名字是:", name)
    print("匹配指数:", score)

2.关于置信度confidence

LBPH中置信度评分用来衡量所识别人脸与原模型的差距,0 表示完全匹配,predict()函数返回两个元素的数组:第一个元素是所识别 个体的标签,第二个是置信度评分。其中由于本人采集人脸数据的干扰,confidence的值会在88-110以上(confidence想要接近0基本上概率为0),所以我设置了本项目score为200-confidence,反过来判断score的值大于我设定的阈值(95)那么就判定为人脸识别成功。

3.程序执行效果

在弹出图像窗口并在人脸图像上实时显示用户名和匹配指数。
人脸识别效果

程序链接

完成参考程序与第三方库:
链接:https://pan.baidu.com/s/1woGOnY8YWWfWSAQI6yldwg?pwd=lyx4
提取码:lyx4

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

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

相关文章

【自学Java】Java开发环境搭建

Java开发环境搭建 Java开发环境搭建 Java 的开发环境主要使用 JDK。我们这边介绍的 JDK 版本是 1.8。我们可以直接从 Oracle 官网上面下载。JDK 下载地址&#xff1a; https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html如下图&#xff1a; 由于在…

如何使用css实现三角形?

​ 一、前言 ​ 通常情况下&#xff0c;我们会使用图片或者svg去完成三角形效果图&#xff0c;但如果单纯使用css如何完成一个三角形呢&#xff1f; 实现过程似乎也并不困难&#xff0c;通过边框就可完成 二、实现过程 在以前也讲过盒子模型&#xff0c;默认情况下是一个矩形…

Faster RCNN网络源码解读(Ⅳ) --- Faster R-CNN主体代码执行流程解析

目录 一、Faster R-CNN框架图 二、结合代码 &#xff08;faster_rcnn_framework.py&#xff09; 2.1 FasterRCNNBase类 2.2 FasterRCNN类 一、Faster R-CNN框架图 我们获取一张图片后将其输入特征提取网络Backbone中得到特征图&#xff0c;将特征图输入到RPN中得到一系列的…

Maven的基本使用方法

Maven Maven是专门用于管理和构建Java项目的工具&#xff0c;它的主要功能有&#xff1a; 提供了一套标准化的项目结构 提供了一套标准化的构建流程&#xff08;编译&#xff0c;测试&#xff0c;打包&#xff0c;发布……&#xff09; 提供了一套依赖管理机制 标准化的项…

【JavaEE】Linux

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录一、Linux概述二、 云服务器安装Linux环境 Xshell登录三、Linux中常用指令介绍1. ls2. pwd 查看当前路径对应的绝对路径3. cd 切换当前的工作目录4. touch&#xff1a;创建一个空文件5. cat&#xff1a; 显示文件内…

23 种设计模式总结

title: 23 种设计模式总结 date: 2022-12-30 16:53:46 tags: 设计模式 categories:设计模式 cover: https://cover.png feature: false 文章目录1. 创建型1.1 单例模式&#xff08;Singleton Design Pattern&#xff09;1.1.1 概述与实现1.1.2 多例1.2 工厂模式&#xff08;Fa…

零信任与 K8s 环境实践

零信任的热度自然吸引了大量市场上的关注。尽管如此&#xff0c;零信任并不只是一个空洞的术语&#xff1a;它代表了对未来安全性的一些深刻变革的想法。那么&#xff0c;零信任具体是什么&#xff0c;为什么它会突然变得如此重要&#xff1f;零信任对 Kubernetes 用户来说具体…

【数据结构】顺序表(线性表)的实现

目录 一、什么是顺序表&#xff1f; 二、顺序表的动态实现 1、顺序表初始化 2、顺序表打印 3、顺序表检查空间 4、顺序表尾插 5、顺序表尾删 6、顺序表头插 7、顺序表头删 8、顺序表指定位置插入 9、顺序表指定位置删除 10、顺序表查找 11、顺序表销毁 三、源代码 1、SeqList.h…

hnu社交网络作业1

前言&#xff1a;上的是林剑新老师的课程&#xff0c;还是比较有意思的&#xff0c;此博客用来记录作业的学习情况&#xff0c;答案为老师提供的 一、对于图 1&#xff0c;请回答以下问题&#xff0c;并给出相应的计算过程&#xff1a; (1) 计算图 G 中每个顶点的 closeness 中…

Java重点源码回顾——HashMap1.7

1. 概述 public class HashMap<K,V>extends AbstractMap<K,V>implements Map<K,V>, Cloneable, SerializableHashMap在我们的日常使用中非常多&#xff0c;所以今天来阅读下它的源码&#xff0c;了解它具体的设计思想&#xff0c;能够帮助我们扩宽视野。 H…

vmware vcp证书怎么考?vmware vcp证书通过率如何

可为您提供行业领先的虚拟化技术培训和认证服务&#xff0c;这些认证不但会考察您的知识掌握情况和经验水平&#xff0c;还将与您的实际工作职责挂钩。VMware认证按照不同解决方案划分&#xff0c;可分为四条路径&#xff1a;数据中心虚拟化、网络虚拟化、云计算管理和自动化、…

微信小程序项目转uniapp踩坑日记

本文目录一、前言二、转换方式三、后语四、其他&#xff1a;node报错1、包默认C盘存放&#xff0c;而不是安装目录E盘2、正确的环境变量添加3、npm install 命令报错4、npm install -g express报错没有权限一、前言 由于想要把之前完成的微信小程序项目转换成uniapp项目&#…

git入门指南

文章目录Git入门指南前言什么是版本控制系统&#xff08;VCS&#xff09;版本控制系统Git1、概述2、目前比较流行的Git和SVN&#xff0c;区别是什么3、Git安装4、Git的工作区、暂存区、本地仓库、远程仓库5、git的分支6、git的标签7、 实际操作下git常用命令准备操作git cloneg…

Kafka Cluster 扩容 添加副本 重分配分区

Kafka Cluster 扩容 针对kafka集群&#xff0c;可以通过向群集添加新节点来扩展群集。新节点将仅服务于新主题或新分区&#xff0c;现有分区将不会自动重新平衡以使用新节点。如果需要对现有的TOPIC进行重新分配分区&#xff0c;需要运维人员手动进行干预。今天学习下如何对已…

CAPL学习之路-测试功能集函数(故障注入函数)

TestDisableMsg 禁止发送消息,除非调用函数TestSetMsgEvent 使用TestEnableMsg重新启用消息。此函数影响分配CANoe交互层或CANopen仿真的仿真节点 这个函数可以在测试用例中控制Simulation Setup界面仿真节点报文的发送与停止 testcase TCExample() {testDisableMsg(LightSt…

Linux模块代码、编译、加载、卸载一条龙

最近要写一个Linux的内核模块&#xff0c;记录一下内核模块的代码编写、编译、加载和卸载的基本流程&#xff0c;以作备忘&#xff0c;也希望能帮到有需要的同学。 模块代码 //代码来自https://yangkuncn.cn/kernel_INIT_WORK.html //init_works.c #include <linux/kernel…

Docker-compose快速部署PostgreSQL

Docker-compose快速部署PostgreSQL&#xff1a; 利用docker-compose编排工具部署&#xff1a; docker-compose.yml 文件 version: "3.1" services:postgresql:image: postgres:12-alpinecontainer_name: postgresqlenvironment:POSTGRES_DB: postgresPOSTGRES_USE…

Python--数据容器总结

一、数据容器的分类 数据容器可以从一下视角进行简单的分类&#xff1a; 是否支持下标索引 支持&#xff1a;列表、元组、字符串 --序列类型不支持&#xff1a;集合、字典 --非序列类型是否支持重复元素 支持&#xff1a;列表、元组、字符串 --序列类型不支持&#xff1a;集…

自动生成单测代码插件Squaretest

今天来介绍一款工具Squaretest&#xff0c;它是一款自动生成单元测试的插件&#xff0c;会用到它也是因为最近公司上了代码质量管控的指标&#xff0c;会考评各个项目的单元测试覆盖率&#xff0c;以及sonar扫描出来的各种问题。 很多老项目老代码&#xff0c;或者着急交付的项…

第十八讲:神州三层交换机DHCP中继服务的配置

当DHCP客户机和DHCP服务器不在同一个网段时&#xff0c;由DHCP中继传递DHCP报文。增加DHCP中继功能的好处是不必为每个网段都设置DHCP服务器&#xff0c;同一个DHCP服务器可以为很多个子网的客户机提供网络配置参数&#xff0c;即节约了成本又方便了管理。这就是DHCP中继的功能…