【OpenCV-Python】——Haar人脸检测深度学习人脸检测EigenFaces/FisherFaces/LBPH人脸识别

news2025/2/28 12:47:27

目录

前言:

1、人脸检测

1.1 基于Haar的人脸检测

1.2 基于深度学习的人脸检测

2、人脸识别

2.1 EigenFaces人脸识别

2.2 FisherFaces人脸识别

2.3 LBPH人脸识别

总结:


前言:

人脸检测是人脸定位的过程;人脸识别是在人脸检测的基础上进一步判断人的身份。

1、人脸检测

1.1 基于Haar的人脸检测

OpenCV源代码中的"data\haarcascades"文件夹中包含训练好的Haar级联分类器文件:包含人眼、眼镜、猫脸、人脸(alt和default)、侧脸检测等文件。

①cv2.CascadeClassifier()函数用于加载分类器:

faceClassifier=cv2.CascadeClassifier(filename)
faceClassifier是返回的级联分类器对象。参数是文件名

②级联分类器的detectMultiScale()方法用于执行检测:

objects=faceClassifier.detectMultiScale(image,scaleFactor,minNeighbors,
                                        flags,minSize,maxSize)

objects是返回的目标矩形,矩形中是人脸。image通常输入的是灰度图。后面的都是可选参数(flags在高版本中省略):图像缩放比例、构成目标矩形的最少相邻矩形个数、目标矩形的最小尺寸、目标矩形的最大尺寸。

检测图像中的人脸示例:

import cv2
img=cv2.imread('friends.png')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
face=cv2.CascadeClassifier("./haarcascade_frontalface_default.xml")#加载人脸识别器
eye=cv2.CascadeClassifier("./haarcascade_eye.xml")  #加载眼镜识别器
faces=face.detectMultiScale(gray)  #执行人脸识别
for x,y,w,h in faces:
    cv2.rectangle(img,(x,y),(x+w,y+h), (0,255,0),2)  #绘制矩形标注人脸
    roi_eye=gray[y:y+h,x:x+w]  #根据人脸获得眼睛的检测范围
    eyes=eye.detectMultiScale(roi_eye)  #在人脸范围内检测眼睛
    for (ex,ey,ew,eh) in eyes:   #标注眼睛
        cv2.circle(img[y:y+h,x:x+w],(int(ex+ew/2),int(ey+eh/2)),
                    int(max(ew,eh)/2),(0,0,255),2)
cv2.imshow('face',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 检测图像中的猫脸示例:

import cv2
img=cv2.imread('cat.png')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
face=cv2.CascadeClassifier("./haarcascade_frontalcatface.xml")#加载猫脸识别器
faces=face.detectMultiScale(gray)  #执行猫脸识别
for x,y,w,h in faces:
    cv2.rectangle(img,(x,y),(x+w,y+h), (255,0,0),2)  #绘制矩形标注猫脸
cv2.imshow('face',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 检测摄像头视频中的人脸示例:

import cv2
face_detector=cv2.CascadeClassifier("./haarcascade_frontalface_alt.xml")#cv2自带人脸识别器
cap=cv2.VideoCapture(0)#打开摄像头
while True:
    ret, frame = cap.read(0)#从摄像头中读取一帧数据,frame存储了此一帧数据
    gray = cv2.cvtColor(frame,code=cv2.COLOR_BGR2GRAY)#数据压缩——将获取到的数据灰度处理,减小内存增加处理速度
    faces = face_detector.detectMultiScale(gray)#算法返回下x,y,h,w四个参数
    for x,y,h,w in faces:
        #cv2.circle(frame,center = (x+w//2,y+h//2),radius = w//2, color =[0,0,255],thickness=2)
        cv2.rectangle(frame,(x,y),(x+w,y+h), color =[0,255,0],thickness=2)
        cv2.imshow('img',frame)
    key = cv2.waitKey(1000//24)#1000ms显示24张图片,最多等待1000//24毫秒,直到从键盘上按下一个按键或等待时间结束,key中保存了我们按下那个按键
    if key ==ord('q'):
        break
cap.release()#释放摄像头
cv2.destroyAllWindows()

1.2 基于深度学习的人脸检测

Opencv的深度神经网络(DNN)模块提供了基于深度学习的人脸检测器,DNN模块使用了Caffe、TensorFlow、Torch和Darknet等广受欢迎的深度学习框架。Opencv提供了Caffe、TensorFlow两个预训练的人脸检测模型。

①Caffe模型需要加载以下两个文件:

deploy.prototxt:定义模型结构的配置文件
res10.300x300_ssd_iter_140000_fb16.caffemodel:包含实际层权重的训练模型文件

②TensorFlow模型需要加载以下两个文件:

opencv_face_detector.pbtxt:定义模型结构的配置文件
opencv_face_detector_uint8.pb:包含实际层权重的训练模型文件

步骤:首先调用cv2.dnn.readNetFromCaffe()或cv2.dnn.readNetFromTensorFlow()函数加载模型,创建检测器;调用cv2.dnn.blobFromImage()函数将待检测图像转换为图像块数据;调用检测器的setInput()方法将图像块数据设置为模型的输入数据;调用检测器的forward()方法执行计算获得预测结果;将可信度高于指定值的预测结果作为检测结果,在原图像中标注人脸,同时输出可信度以作参考。

import cv2
import numpy as np
from matplotlib import pyplot as plt
dnnet=cv2.dnn.readNetFromCaffe("deploy.prototxt",#加载训练好的模型
                                "    " ) #缺少训练模型文件
img=cv2.imread("friends.png")
h,w=img.shape[: 2]
blobs=cv2.dnn.blobFromImage(img,1.0,(300,300),#创建图像的块数据
                            [104.,117.,123.],False,False)
dnnet.setInput(blobs)   #将块数据设置为输入数据
detections=dnnet.forward()  #执行计算,获得预测结果
faces=0
for i in range(0,detections.shape[2]):  #迭代,输出可信度高的人脸识别结果
    confidence=detections[0,0,i,2]    #获得可信度
    if confidence >0.8:               #输出可信度高于80%的结果
        faces += 1
        box = detections[0,0,i,3:7]*np.array([w,h,w,h])  #获得人脸在图像中的坐标
        x1,y1,x2,y2=box.astype("int")
        y=y1-10 if y1-10 >10 else y1+10    #计算可信度输出位置
        text="%.3f"%(confidence*100)+'%'
        cv2.rectangle(img,(x1,y1),(x2,y2),(255,0,0),2) #标注人脸范围
        cv2.putText(img,text,(x1+20,y),
                    cv2.FONT_HERSHEY_SIMPLEX,0.9,(0,0,255),2)  #输出可信度
cv2.imshow('faces',img)
cv2.waitKey(0)
cv2.destroyAllWindows()


2、人脸识别

Opencv提供了3种人脸识别方法:特征脸(EigenFaces)、人鱼脸(FisherFaces)和局部二进制编码直方图(Local Binary Patterns Histograms,LBPH)。

2.1 EigenFaces人脸识别

EigenFaces使用主要成分分析(PCA)方法将人脸数据从高维处理成低维后,获得人脸数据的主要成分信息,进而完成人脸识别。

步骤:首先调用cv2.face.EigenFaceRecognizer_create()方法创建EigenFaces识别器;然后调用识别器的train()方法以便使用已知图像训练模型;调用识别器的predict()方法以便使用未知图像进行识别,确认其身份。

①cv2.face.EigenFaceRecognizer_create()函数:

recognizer=cv2.face.EigenFaceRecognizer_create(num_components,threshold)
recognizer是返回的识别器对象;
参数都是可选参数:
num_components是分析时的分量个数;默认是0,表示根据实际输入决定;
threshold是人脸识别时采用的阈值

②EigenFaces识别器train()方法:

recognizer.train(src,labels)
src是用于训练的已知图像数组。所有图像都要是灰度图,且大小要相同;
labels是标签数组,与已知图像数组中的人脸一一对应,同一个人的脸标签应设置为相同值

③EigenFaces识别器predict()方法:

label,confidence=recognizer.predict(testimg)
testimg是未知的人脸图像,必须是灰度图,且与训练图像大小相同;
label是返回的标签值;
confidence是返回的可信度,表示未知人脸和模型中已知人脸之间的距离。
            0表示完全匹配,低于5000可认为是可靠的匹配结果。
import cv2
import numpy as np
img1=cv2.imread('face1.png',0)#打开图像,灰度图(0)——img1和img2是杨幂;img3和img4是关晓彤
img2=cv2.imread('face2.png',0)
img3=cv2.imread('face3.png',0)
img4=cv2.imread('face4.png',0)
print(img1.shape) #(161,157)
img2=cv2.resize(img2,(161,157))#训练图像需要大小相同
img3=cv2.resize(img3,(161,157))
img4=cv2.resize(img4,(161,157))

train_imgs=[img1,img2,img3,img4] #创建训练图像数组
labels=np.array([0,0,1,1])  #创建标签数组,0和1表示训练图像数组中人脸的身份(杨幂0和关晓彤1)
recognizer=cv2.face.EigenFaceRecognizer_create()  #创建EigenFaces识别器
recognizer.train(train_imgs,labels)  #执行训练操作
testimg=cv2.imread('testface1.png',0)  #打开测试图像(杨幂)
testimg=cv2.resize(testimg,(161,157))  #测试图像大小也要与训练图像相同
label,confidence=recognizer.predict(testimg)  #识别人脸
print('匹配标签:',label)  #输出识别结果
print('可信度:',confidence)

训练图像:        

测试图像和输出结果:  

2.2 FisherFaces人脸识别

FisherFaces使用线性判别分析(LDA)方法实现人脸识别。

步骤使用格式与EigenFaces相同:首先调用cv2.face.FisherFaceRecognizer_create()方法创建FisherFaces识别器;然后调用识别器的train()方法以便使用已知图像训练模型;调用识别器的predict()方法以便使用未知图像进行识别,确认其身份。

 所以代码就需要该一行创建识别器的代码:(这次测试下testface2关晓彤)

recognizer=cv2.face.FisherFaceRecognizer_create() 

 测试图像和输出结果:    

2.3 LBPH人脸识别

LBPH算法处理图像的基本原理:取像素x周围(邻域)的8个像素与其比较,像素值比像素x大的取0,小的取1。将8个像素对应的0、1连接得到一个8位二进制数,将其转换为十进制,作为像素x的LBP值。对所有像素同样操作得到整个LBP图像,该图像的直方图就是LBPH。

基本步骤与上面两个相似,只不过①创建识别器函数参数有所不同。②且predict()中confidence低于50可认为是非常可靠的匹配对象(不是5000了)。

cv2.face.LBPHFaceRecognizer_create(radius,neighbors,grid_x,grid_y,threshold)
参数都是可选参数:
radius是邻域的半径大小;
neighbors是邻域内像素点的数量,默认为8;
grid_x/grid_y是将LBP图像划分成多个单元格时,水平/垂直方向上的单元格的数量,默认是8
threshold是人脸识别时采用的阈值

 代码也只需改变创建识别器那一行即可,还是测试关晓彤,输出匹配结果标签和可信度:

recognizer=cv2.face.LBPHFaceRecognizer_create() 

可信度没低于50,说明结果不是非常可靠,可能是由于训练图像太少的缘故。


总结:

由于是初学者可能很多地方没有总结完全或者有误,后续深入学习后会不断回来该删,也欢迎各位朋友指正!下次学习机器学习和深度学习基础

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

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

相关文章

macOS 下载汇总(系统、应用和教程) 2023 持续更新中

macOS Ventura 13, macOS Monterey 12, macOS Big Sur 11, macOS Catalina 10.15, macOS Mojave 10.14, macOS High Sierra 10.13, macOS Sierra 10.12 请访问原文链接:https://sysin.org/blog/macOS/,查看最新版。原创作品,转载请保留出处。…

VMware Aria Suite 8.12 - 云管理解决方案 (下载索引)

VMware Aria Suite 8.12 - 云管理解决方案 (下载索引) 请访问原文链接:https://sysin.org/blog/vmware-aria-suite/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org 云管理套包 VMware Aria Suite(以前…

网络基础知识(2)——简单说说IP地址

Internet 依靠 TCP/IP 协议,在全球范围内实现不同硬件结构、不同操作系统、不同网络系统的主机之间的互联。在 Internet 上,每一个节点都依靠唯一的 IP 地址相互区分和相互联系,IP 地址用于标识互联网中的每台主机的身份,设计人员…

Windows 20个经典cmd命令,值得收藏

本文重点介绍Windows系统常用工具和服务的快捷启动命令。相比鼠标多次点击打开窗口,输入命令回车一键打开更为快捷高效。喜欢请点赞收藏,关注我获取最新原创分享~ 一、Windows启动命令使用方式 快捷键 【徽标R】打开命令窗口 输入命令,点击【…

ARM 栈帧(一)

ARM 栈帧 本系列均以 corter-A7(armv7-a) 为例 在 ARM 中,通常为满减栈(Full Descending FD), 也就是说,堆栈指针指向堆栈内存中最后一个填充的位置,并且随着每个新数据项被压入堆栈而递减。 栈的本质 要理解栈的本…

基于NXP+FPGA的大容量固态存储板实现方案

1 概述 近年来 ,大容量数据存储设备受到软硬件等发展的限制主 要还是采用机械硬盘叠加组合而用。机械硬盘以磁盘片作为载 体 ,采用机械马达 ,存在抗振性能低、低温性能差、噪声大等缺点。 固态硬盘是以半导体作为存储介质及控制载体 &…

使用马哈鱼SQLFLow 1 分钟获取复杂 SQL 语句的血缘关系

数据血缘关系在企业的数据治理中是非常重要的一个环节,关于数据血缘在企业数据治理中的重要作用,可以参考这篇文章。SQL 语言在数据处理中被广泛使用,SQL 语句中包含了丰富的数据血缘关系,关于什么是 SQL 中的数据血缘&#xff0c…

死锁与活锁

1 死锁概述 死锁主要是由于资源使用不当引发的。OS中存在很多不同类型的软硬件资源,而可以引发死锁的资源 主要是需要互斥访问的、不可被抢占的资源,即临界资源。下面先来简单了解下资源的分类。 资源分类 按照资源是否可重复使用划分,可以分…

Spring ( 三 ) SpringIoC

3.SpringIoC Spring 核心 是 通过IoC 降低 项目中的类之间的耦合 IoC Inversion of Control 控制反转: 应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。 ​ 这样控制权就由应用转移到了外部容器,控制权的转移…

【Linux从入门到精通】一文带你理解进程概念

我们通过对上篇文章冯诺依曼体系结构对硬件进行讲解后, 本篇文章会对进程进行深入讲解。同时会讲解PCB(进程控制块)。希望本篇文章内容会对你有所帮助。 文章目录 一、再次理解操作系统 1、1 操作系统的作用 1、2 操作系统的管理 二、进程基本…

基于Kubernetes集群构建大中型企业CICD应用平台(5)--Integrate工具

5.1、jenkins介绍 持续集成、持续部署的工具很多,其中Jenkins是一个开源的持续集成平台。 Jenkins涉及到将编写完毕的代码发布到测试环境和生产环境的任务,并且还涉及到了构建项目等任务。 Jenkins需要大量的插件保证工作,安装成本较高&am…

Java Web开发:Spring Boot和Spring Cloud的应用和实践

一、介绍 Java Web开发是当今互联网时代中的一项重要技术,随着互联网的发展和应用场景的不断扩大,Java Web开发技术也得到了广泛的应用。而Spring Boot和Spring Cloud作为Java Web开发中最常用的技术之一,已经成为了很多开发者必备的技能。本…

使用Vue3和Typescript实现可复用的路由标签页和面包屑导航组件

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: 三十天精通 Vue 3 文章目录 一、为什么需要可复用的路由标签页和面包屑导航组件1.1 前端应用导航的问题1.2 解决问题的方法二、Vue3和Typescript基础知识回…

shell脚本中数组的运用以及排序算法

shell脚本中数组的运用 一、数组的介绍1、概念2、定义方法3、数组包括的数据类型 二、关于数组的操作1、获取数组长度2、获取数组各个元素的下标3、获取数组列表或单个元素4、对数组切片输出5、对数组里的元素替换6、删除单个元素或数组7、数组追加元素8、向函数传入数组的值 三…

Learning C++ No.20 【红黑树实战】

引言: 北京时间:2023/5/12/20:30,今天周五,周五不摆烂从我做起,虽然刚睡醒,但是今天如果论学习时长,那可能是许久以来最长的一天,从早上6:40晨跑回来坐在凳子上,一坐久坐…

在 I/O 看未来 | 开发者集合!官方学习资源已更新,即 课 解锁新技能!

看完 Google I/O 2023 的精彩内容 你是否已跃跃欲试,准备充电学习? 马上跟随 Google 开发者在线课程 刷新知识储备和开发技能 将技术热爱落地为实践应用! "解码 Google I/O 洞见科技未来" 征文活动 也向身为技术爱好者的你发出召唤…

【Wi-Fi】802.11/802.11b/802.11g/802.11n/802.11a/802.11ac/802.11ax/802.11be

WiFi发展历史 IEEE 802.11 Protocol Release Date Frequency Band Bandwidth Max Throughput 802.11-1997 1997 2.4GHz 22MHz 2Mbps 802.11b 1999 2.4GHz 22MHz 11Mbps 802.11a 1999 5GHz 20MHz 54Mbps 802.11g 2003 2.4GHz 20MHz 54Mbps 802.11n (W…

Kubernetes❀实战入门

Kubernetes❀实战入门 4. 实战入门4.1 Namespace4.1.1 **查看**4.1.2 **创建**4.1.3 **删除**4.1.4 **配置方式** 4.2 Pod4.2.1 创建并运行4.2.2 查看pod信息4.2.3 访问Pod4.2.4 删除指定Pod4.2.5 配置操作 4.3 Label4.3.1 命令方式4.3.2 配置方式 4.4 Deployment4.4.1待操作。…

第二章 介绍Productions - 互操作性制作简介

文章目录 第二章 介绍Productions - 互操作性制作简介介绍Productions设置Production的消息流 第二章 介绍Productions - 互操作性制作简介 互操作性产品的目的是使能够连接系统,以便可以在它们之间转换和路由消息。要连接系统,需要开发、配置、部署和管…

( 位运算 ) 693. 交替位二进制数 ——【Leetcode每日一题】

❓693. 交替位二进制数 难度:简单 给定一个正整数,检查它的二进制表示是否总是 0、1 交替出现:换句话说,就是二进制表示中相邻两位的数字永不相同。 示例 1: 输入:n 5 输出:true 解释&#…