opencv进阶11-LBPH 人脸识别(人脸对比)

news2024/9/24 9:23:25

人脸识别的第一步,就是要找到一个模型可以用简洁又具有差异性的方式准确反映出每个人脸的特征。识别人脸时,先将当前人脸采用与前述同样的方式提取特征,再从已有特征集中找出当前特征的最邻近样本,从而得到当前人脸的标签。

OpenCV 提供了三种人脸识别方法,分别是 LBPH 方法、EigenFishfaces 方法、Fisherfaces方法。本节主要对 LBPH 方法进行简单介绍。

LBPH(Local Binary Patterns Histogram,局部二值模式直方图)所使用的模型基于 LBP(Local
Binary Pattern,局部二值模式)算法。LBP
最早是被作为一种有效的纹理描述算子提出的,由于在表述图像局部纹理特征上效果出众而得到广泛应用。

基本原理

LBP 算法的基本原理是,将像素点 A 的值与其最邻近的 8 个像素点的值逐一比较:

  • 如果 A 的像素值大于其临近点的像素值,则得到 0。
  • 如果 A 的像素值小于其临近点的像素值,则得到 1。

最后,将像素点 A 与其周围 8 个像素点比较所得到的 0、1 值连起来,得到一个 8 位的二进制序列,将该二进制序列转换为十进制数作为点 A 的 LBP 值。

下面以图 23-6 中左侧 3×3 区域的中心点(像素值为 76 的点)为例,说明如何计算该点的LBP 值。计算时,以其像素值 76 作为阈值,对其 8 邻域像素进行二值化处理,

  • 将像素值大于 76 的像素点处理为 1。例如,其邻域中像素值为 128、251、99、213 的点,都被处理为 1,填入对应的像素点位置上。
  • 将像素值小于 76 的像素点处理为 0。例如,其邻域中像素值为 36、9、11、48 的点,都被处理为 0,填入对应的像素点位置上。

根据上述计算,可以得到图 23-6 中右图所示的二值结果。

在这里插入图片描述
完成二值化以后,任意指定一个开始位置,将得到的二值结果进行序列化,组成一个 8 位的二进制数。

例如,从当前像素点的正上方开始,以顺时针为序得到二进制序列“01011001”。最后,将二进制序列“01011001”转换为所对应的十进制数“89”,作为当前中心点的像素值,如图 23-7 所示。

在这里插入图片描述
对图像逐像素用以上方式进行处理,就得到 LBP 特征图像,这个特征图像的直方图被称为 LBPH,或称为 LBP 直方图。

为了得到不同尺度下的纹理结构,还可以使用圆形邻域,将计算扩大到任意大小的邻域内。圆形邻域可以用(P, R)表示,其中 P 表示圆形邻域内参与运算的像素点个数,R 表示邻域的半径。

例如,在图 23-8 中就分别采用了不同的圆形邻域。

  • 左侧使用的是(4, 1)邻域,比较当前像素与邻域内 4 个像素点的像素值大小,使用的半径是 1。

  • 右侧使用的是(8, 2)邻域,比较当前像素与邻域内 8 个像素点的像素值大小,使用的半径是 2。在参与比较的 8 个邻域像素点中,部分邻域可能不会直接取实际存在的某个位置上的像素点,而是通过计算构造一个“虚拟”像素值来与当前像素点进行比较。
    在这里插入图片描述
    人脸的整体灰度由于受到光线的影响,经常会发生变化,但是人脸各部分之间的相对灰度会基本保持一致。LBP 的主要思想是以当前点与其邻域像素的相对关系作为处理结果,正是因为这一点,在图像灰度整体发生变化(单调变化)时,从 LBP 算法中提取的特征能保持不变。
    因此,LBP 在人脸识别中得到了广泛的应用。

从上面的介绍可以看到,LBP 特征与 Haar 特征很相似,都是图像的灰度变化特征。

函数介绍

在 OpenCV 中,可以用函数 cv2.face.LBPHFaceRecognizer_create()生成 LBPH 识别器实例模型,然后应用 cv2.face_FaceRecognizer.train() 函数完成训练,最后用cv2.face_FaceRecognizer.predict()函数完成人脸识别。
下面分别介绍上述三个函数。

  1. 函数cv2.face.LBPHFaceRecognizer_create()
    函数 cv2.face.LBPHFaceRecognizer_create()的语法格式为:

retval = cv2.face.LBPHFaceRecognizer_create( [, radius[, neighbors[,
grid_x[, grid_y[, threshold]]]]])

其中全部的参数都是可选的,含义如下:

  • radius:半径值,默认值为 1。
  • neighbors:邻域点的个数,默认采用 8 邻域,根据需要可以计算更多的邻域点。
  • grid_x:将 LBP 特征图像划分为一个个单元格时,每个单元格在水平方向上的像素个数。
    该参数值默认为 8,即将 LBP 特征图像在行方向上以 8 个像素为单位分组。
  • grid_y:将 LBP 特征图像划分为一个个单元格时,每个单元格在垂直方向上的像素个数。
    该参数值默认为 8,即将 LBP 特征图像在列方向上以 8 个像素为单位分组。
  • threshold:在预测时所使用的阈值。如果大于该阈值,就认为没有识别到任何目标对象。
  1. 函数cv2.face_FaceRecognizer.train()
    函数 cv2.face_FaceRecognizer.train()对每个参考图像计算 LBPH,得到一个向量。每个人脸
    都是整个向量集中的一个点。该函数的语法格式为:

None = cv2.face_FaceRecognizer.train( src, labels )

式中各个参数的含义为:

  • src:训练图像,用来学习的人脸图像。
  • labels:标签,人脸图像所对应的标签。
    该函数没有返回值。
  1. 函数cv2.face_FaceRecognizer.predict()
    函数 cv2.face_FaceRecognizer.predict()对一个待测人脸图像进行判断,寻找与当前图像距离最近的人脸图像。与哪个人脸图像最近,就将当前待测图像标注为其对应的标签。当然,如果待测图像与所有人脸图像的距离都大于函数 cv2.face.LBPHFaceRecognizer_create()中参数
    threshold 所指定的距离值,则认为没有找到对应的结果,即无法识别当前人脸。
    函数 cv2.face_FaceRecognizer.predict()的语法格式为:

label, confidence = cv2.face_FaceRecognizer.predict( src )

式中参数与返回值的含义为:

  • src:需要识别的人脸图像。
  • label:返回的识别结果标签。
  • confidence:返回的置信度评分。置信度评分用来衡量识别结果与原有模型之间的距离。
    0 表示完全匹配。通常情况下,认为小于 50 的值是可以接受的,如果该值大于 80 则认为差别较大。

示例:完成一个简单的人脸识别程序

import cv2
import numpy as np
images=[]
images.append(cv2.imread("face\\face2.png",cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("face\\face3.png",cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("face\\face4.png",cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("face\\face5.png",cv2.IMREAD_GRAYSCALE))
labels=[0,0,1,1]
#print(labels)
recognizer = cv2.face.LBPHFaceRecognizer.create()
recognizer.train(images, np.array(labels))
predict_image=cv2.imread("face\\face4.png",cv2.IMREAD_GRAYSCALE)

label,confidence= recognizer.predict(predict_image)
print("label=",label)
print("confidence=",confidence)

其中的图片是我随便到网上下载的明星的图片。总体识别度不高,而且如果识别不到会直接返回0.这个在深度的时候也会有这个问题。需要调整判断逻辑。

返回结果:

label= 1
confidence= 0.0

先熟悉了解下,后续在集中对比下几个人脸识别的算法的区别及更合适的应用场景。

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

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

相关文章

Linux知识点 -- Linux多线程(二)

Linux知识点 – Linux多线程(二) 文章目录 Linux知识点 -- Linux多线程(二)一、线程互斥1.背景概念2.多线程访问同一个全局变量3.加锁保护4.问题5.锁的实现 二、线程安全1.可重入与线程安全2.常见情况3.可重入与线程安全的联系 三…

【力扣每日一题】2023.8.17 切披萨的方案数

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我们一个二维数组来表示一个披萨,其中‘A’表示披萨上的苹果。 让我们切k-1刀,把披萨切成 k 份&#xff0…

Eslint error, configuration for rule “import/no-cycle“ is invalid

可以参考stackoverflow.comEslint error, configuration for rule "import/no-cycle" is invalid他的意思是有个∞符号不支持,解决方案,把 eslint-plugin-import 的版本增加到 ^2.22.1,重新下载依赖包如:

【分布式共识】Raft算法 选举一个领导者

Raft算法是通过一切以领导者为准的方式,实现一系列值的共识和各节点日志的一致 在分布式系统中,节点可能出现宕机、网络故障等,所以在3个节点的分布式系统中,如何选举出一个Leader节点。比如我们部署一个ZK集群。 成员 Leader领…

《Linux运维总结:Centos7.6之OpenSSH7.4p1升级版本至9.4p1》

Centos通过yum升级OpenSSH 在官方支持更新的CentOS版本,如果出现漏洞,都会通过更新版本来修复漏洞。这时候直接使用yum update就可以升级版本。 yum -y update openssh 但是,CentOS更新需要有一段时间,不能在漏洞刚出来的时候就有…

SpringBoot实现热部署/加载

在我们修改完项目代码后希望不用重启服务器就能把项目代码部署到服务器中(也就是说修改完项目代码后不用重启服务器修改后的项目代码就能生效)。 一、实现devtools原理 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-…

内网渗透神器CobaltStrike之凭据的导出与存储(八)

简介 Cobalt Strike 是一个流行的渗透测试工具&#xff0c;主要用于模拟高级持续性威胁&#xff08;APT&#xff09;的攻击。它提供了许多功能来操作、持久化和操纵受害者机器。其中&#xff0c;凭据的导出和存储是渗透测试中的一个重要步骤。 凭据导出: Cobalt Strike 通过其…

Vue前端封装一个任务条的组件进行使用

任务条 样式 代码 父组件 <articleSteps :tabs"tabs" :tabs-active-name"tabsActiveName" /><div class"drawer__footer"><el-button v-if"tabsActiveName 1 || tabsActiveName 2" click"backClick">…

面试了几十家,整理出这份车载测试面试题

年前有朋友找工作&#xff0c;跟我说简历改了车载后&#xff0c;收到的打招呼翻了几倍&#xff0c;如今车载测试前景非常广阔&#xff0c;因为越来越多的汽车厂商正在开发新的可智能化的汽车&#xff0c;他们需要测试这些汽车的性能&#xff0c;安全性以及可靠性。 车载测试技…

面试时,如何向HR解释自己频繁跳槽?

有数据显示&#xff0c;现在的职场人&#xff0c;跳槽越来越频繁&#xff0c;95后平均7个月就离职。 对于面试官来说&#xff0c;一个跳槽过于频繁的人总是存在潜在风险&#xff0c;比如抗压力差、稳定性不好、心不定这山望着那山高、职业规划不清晰等等。 我一直强调一个观点…

WXSS的全局样式和局部样式

什么是WXSS? WXSS中的样式和css差不多&#xff0c;是用于给WXML页面来设置样式的&#xff0c;但是WXSS中扩展了rpx尺寸单位和import样式导入 rpx:根据不同的屏幕自动进行适配&#xff0c;把设备屏幕的宽度等分为750份(设备的总宽度750rpx) import: 用于进行样式的导入 通过inp…

get Error: aborted,net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK) 问题解决

先说结论&#xff1a;由于磁盘空间满导致部分数据接口无法正常反馈结果。 今天前线业务人员忽然说&#xff0c;有个页面刷新后白屏。经过验证确实有这种情况。页面上用开发者工具查看请求和报错信息&#xff0c;发现一个请求所有字典数据的接口没有反馈数据&#xff0c…

无人机精细化巡检方案制定:提高效率与准确性的关键

在当前技术日新月异的时代&#xff0c;无人机在多个领域的应用已成为行业标配。但如何制定出一套有效、细致的无人机巡检方案&#xff0c;确保其最大效能&#xff0c;成为许多组织与公司的核心议题。其中&#xff0c;复亚智能在此领域已展现出了卓越的实力与深入的见解。 1. 精…

【LeetCode-困难题】42. 接雨水

题目 题解一&#xff1a;暴力双重for循环&#xff08;以行计算水量&#xff09; 1.先找出最高的柱子有多高&#xff08;max 3&#xff09; 2.然后第一个for为行数&#xff08;1&#xff0c;2&#xff0c;3&#xff09; 3.第二个for计算每一行的雨水量&#xff08;关键在于去除…

06 mysql all查询 和 主键查询 和 非索引列查询

前言 本文主要调试一下 mysql 的如下两种查询语句 我们也来深入的看一下, 究竟如下两个普通的查询, mysql 做了什么事情 1. select * from user where id 991; 2. select * from user; 3. select * from user where name jerry991; 环境介绍 测试表 user schema 如下…

极限学习机(ELM)的原理和matlab代码实现

单隐含层前馈神经网络(Single - hidden Layer Feedforward Neural Network,SLFN)以其良好的学习能力在许多领域得到了广泛的应用。然而,传统的学习算法(如 BP算法等)固有的一些缺点,成为制约其发展的主要瓶颈。前馈神经网络大多采用梯度下降方法,该方法主要存在以下几个方面的缺…

机器人操作系统【02】:如何在 ROS2 中对点云数据进行建模

一、说明 RViz和Gazebo中RADU的模拟进展顺利。在上一篇文章中&#xff0c;我们学习了如何启动机器人并使用远程节点进行操作。在本文中&#xff0c;我们将添加两个视觉传感器。首先&#xff0c;一个图像摄像机&#xff0c;用于在机器人四处移动时查看机器人的实时馈送。其次&am…

Nginx高可用集群

目录 一.简介二.案例1.实现思路2.配置文件修改3.实现效果故障转移机制 一.简介 以提高应用系统的可靠性&#xff0c;尽可能地减少中断时间为目标&#xff0c;确保服务的连续性&#xff0c;达到高可用的容错效果。例如“故障切换”、“双机热备”、“多机热备”等都属于高可用集…

03:TIM定时器

目录 一:TIM 1:介绍 2:定时器的分类 3:基本定时器 4:通用定时器 5:高级定时器 6:定时器的基本结构 二:定时中断功能 A:定时器定时器中断 1:连接图 ​编辑 2:步骤 3:函数介绍 4:代码 三:外部时钟功能 A:定时器外部时钟 1:连接图 2:函数介绍 3:外部时钟代码 一…

【FreeRTOS】【应用篇】任务创建

前言 从本篇开始&#xff0c;将不再太过于关心 FreeRTOS 的内核细节&#xff0c;把重心转移到对 FreeRTOS 的应用上来。 本篇代码大部分参考野火的 FreeRTOS 教程。 一、静态任务和动态任务创建的区别 1. 概念解析 在 FreeRTOS 中&#xff0c;我们可以选择两个不同的函数进…