首页 > 编程语言 >用OpenCv-Python自带的LBPH识别器实现简单人脸识别(上)

用OpenCv-Python自带的LBPH识别器实现简单人脸识别(上)

时间:2023-04-02 16:25:13浏览次数:48  
标签:人脸识别 Python LBPH cv2 jpg 图像 test path ID

用OpenCv-Python自带的LBPH识别器实现简单人脸识别(上)

引言:

本文开发环境为: Windows10 + phchram + Anaconda5.2 (Python3.6)+ Opencv4.5.5,用opencv-contrib原生的API完成了人脸识别的功能,其可以任意添加人脸ID数据,但其效果比较差(勉强能用),如果日后有时间的话,给大家出一期(挖坑)利用基于paddle人脸识别教程。

特别注意:上篇只是一个大致流程和核心API的讲解,其含有大量细节未补充,如果有copy需求,请看下篇!

一、环境搭建

此处不做赘述,只提一点,Opencv需要下载opencv_contrib_python这个包,这个contrib是opencv的拓展版,包括了opencv的主要模块和一些拓展的算法,注意:下载一个contrib就可以,不要把两个2个都安装。

二、思路解析

我们完成人脸识别,需要哪些步骤?

(1)数据的收集

毫无疑问,第一步是人脸数据的采集,我们要得到这个人的面部数据和其对应的ID,我们需要写一个函数去采集这些东西,我们需要2个参数,一个是int类型的ID号码,一个是字符串类型的名字,至于为什么不能直接输入名字,我们后面会讲到

def get_data(id,face_name):
  • 1

下面介绍一下核心的API

#这个函数可以帮助我们去找到图像中的人脸部分,返回值是一个包含4个元素的列表,分别是x,y坐标,以及宽度和高度。
face_xy = face_detector.detectMultiScale(src)
#我们得到face的坐标之后,可以直接截取下来,然后resize一下,保存下来,方便我们日后的训练
src = src[X:x+w,y:y+h]
#保存图像,里面填写地址和要保存的图像
cv2.imwrite()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

经过这步,我们会得到size固定的人脸图片,类似这样的文件名字:

1.NAME.1.jpg,1.NAME.2.jpg,1.NAME.3.jpg,1.NAME.4.jpg ... 
  • 1

其中第一个数字,是我们这个人的ID,第二个是我们的姓名,第三个则是代表我们这个ID号的照片序号,如ID为1的第1张照片。

(2)模型的训练

我们得到了ID和图像信息之后,需要构建一个训练器trainer,其中,我们需要的核心API如下:

recognizer.train(images, np.array(ids))
  • 1

他需要我们导入2个数组,一个是图像数组,一个是ID数据,比如说,我们现在要训练2个ID,每个ID包括2张图片,那么输入的参数就应该长这样:

#由于字数原因,我就简写,这个图像矩阵就是uint8_t的灰度矩阵,0-255之间取值
images = [图像1矩阵,图像2矩阵,图像3矩阵,图像4矩阵]
 #这个就是序号的矩阵,需要和前面的图像一一对应!
ids = [1,1,2,2]								   
  • 1
  • 2
  • 3
  • 4

那么问题来了,我们如何让图像与序号对应,一个一个写?当然可以,但如果图像很多呢,显然不太现实,所以我们需要专门写一个函数来帮助我们来,绑定这个ID和图像,还记得我们前面的命名规则吗?我们可以用OS库轻松的将其分离开来,如何利用append插入数组,完成数据的绑定。

下面我们来介绍核心API,使用他需要导入OS库

1.拼接路径,我直接放效果: os.path.join(path,f)

test_path = os.path.join('data/','test.jpg')
print(test_path)
#输出:
$data/test.jpg
  • 1
  • 2
  • 3
  • 4

2.显示路径下所有文件的信息:os.listdir(path)

test_path = os.listdir(path)
print(test_path)
#输出:路径下所有文件
$['1.HQS.1.jpg', '1.HQS.10.jpg', '1.HQS.100.jpg']	
  • 1
  • 2
  • 3
  • 4

3.分割函数: os.path.spilt()

test_path = 'data/1.HQS.1.jpg'
test = os.path.split(test_path)
print(test)
#输出一个数组
$('data', '1.HQS.1.jpg')
#可以[1]取文件的名称,然后spilt('.'),以.为分割符继续分割,然后[0]取我们的ID
test_path = 'data/1.HQS.1.jpg'
test = os.path.split(test_path)[1].split('.')[0]
print(test)
#输出
$1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

之后就简单许多,我们只需要遍历文件夹里的人脸数据,然后把图像和ID append到我们的列表里,便可以完成图像与ID的对应。

我们得到了对应ID列表和图像列表之后,就可以开始训练了,训练很简单,opencv给我们提供了识别器,以下为核心API介绍:

recognizer = cv2.face.LBPHFaceRecognizer_create()	#加载识别器
recognizer.train(faces, np.array(ids))				#导入数据,开始训练
recognizer.write('trainer/trainer.yml')				#保存数据
  • 1
  • 2
  • 3

至此,模型训练完毕,接下来就是部署了。

(3)模型的部署

经过我们的训练,我们可以得到一个权重文件yml,我们只需要建立一个识别器对象,读取yml的路径,然后使用.predict,就可以返回2个参数,一个是置信度,一个是ID编号,置信度越高,可信几率越低,下面我们看看具体的步骤:

1.读取图像,转化灰度图

#这个没啥好说的,你可以单张图片预测,也可以开启摄像头或者视频,这里以单张图片举例
test = cv2.imread('data/1.HQS.1.jpg')
gray = cv2.cvtColor(test, cv2.COLOR_BGR2GRAY)  # 转换为灰度图像
  • 1
  • 2
  • 3

2.加载检测器,裁取人脸图像

读取到图片之后,我们需要把图片中的人脸裁出来,然后resize拉一下,方便预测

#加载分类器,路径填自己的
face_detector = cv2.CascadeClassifier('G:/opencv/build/etc/haarcascades/haarcascade_frontalface_default.xml')
#这个函数之前我们介绍过
face = face_detector.detectMultiScale(gray)
#裁出人脸部分,if是为了防止没有检测到人脸导致程序卡死
if face is not None:
    for x, y, w, h in face:
        cv2.rectangle(img, (x, y), (x+w, y+h), color=(0, 0, 255), thickness=2)
        gray = gray[y:y + h, x:x + w]
        gray = cv2.resize(gray,dsize=(500,500))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.加载识别器,将图像对比

我们得到人脸图片之后,就可以开始预测了,下面介绍一下核心API

/****************************************************
分类器预测函数.predict,输入参数是图片,输出有2个,一个是ID序号
就是我们模型训练时候的那个ids里的内容,还有一个就是置信度,这个置
信度越高表明可信度越低,没错,是反比的关系,下面我们随便举一个例子
来讲。
****************************************************/
#假设我们以及把人脸照片传了进去,他预测完了之后,返回2个值
#id列表
names = ['name1','name1']
id,ture = recogizer.predict(gray)
#根据置信度判断,并且在图像上画图
if (confidence > 50):
	cv2.putText(test,'unknow', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
else:
	cv2.putText(img,str(names[id-1]), (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
cv2.imshow('result', test)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

结语:

上篇至此完结,下篇会有完整的代码,如果觉得有错误的地方,欢迎大家讨论交流。

转载声明:原文链接

标签:人脸识别,Python,LBPH,cv2,jpg,图像,test,path,ID
From: https://www.cnblogs.com/index-12/p/17280678.html

相关文章

  • 用OpenCv-Python自带的LBPH识别器实现简单人脸识别(下)
    介绍本文附录了通过LBPH实现简单人脸识别的源代码,分类效果并不是很好,供个人学习使用。人脸录入.pyimportcv2cap=cv2.VideoCapture(0)flag=1num=0while(cap.isOpened()):ret_flag,Vshow=cap.read()cv2.imshow("Capture_Test",Vshow)k=cv2.w......
  • javascript VS python 变量作用域
    js中函数内部默认是可以读取到外部声明的变量,python不可以,必须使用关键字globalglobal必须在函数内部使用,用以内化函数外部变量。在函数外部是无法声明全局变量的,或者说所谓的全局变量在函数内部是不好使的,这还叫什么全局变量?应该叫局外变量。而global是内部跟局外变量建立一种......
  • 孤狼老师-接口测试自动化(Python版完整版)-日志记录&测试报告
            此时,由于每次执行方法前,都会执行一遍setup,故每次都要初始化一次LoggerHelper方法,每次都会加载一次配置文件,优化LoggerHelper:        针对多个接口用例,使用如下方式:   ......
  • Python使用rtlsdr
    1.打开命令行  也可以在Spyder中的控制台中2.安装rtlsdrpipinstallpyrtlsdr3.下载驱动动态库https://ftp.osmocom.org/binaries/windows/rtl-sdr/因为python是64位的,所以驱动也要下载64位的 下载最新的即可4.这三个就是我们需要的驱动  5.将三个驱动复制......
  • 【Linux Centos】如何卸载自带的python和yum以及卸载后如何重新安装yum
    【LinuxCentos】如何卸载自带的python和yum以及卸载后如何重新安装yum注意如果不是必要情况,请不要卸载服务器自带的python,因为yum等命令都会用到python库,卸载以后可能造成不良后果。如果只是觉得系统python版本不合适,想安装新版本,建议安装anaconda或miniconda,在不同的环境中使......
  • python从入门到实践第16章 下载数据1
    第一步获取csv格式文件需要python爬虫的相关知识 第二步 先打印第一行观察标签importcsvfilename='data/sitka_weather_2014.csv'withopen(filename)asf:reader=csv.reader(f)header_row=next(reader)print(header_row)['AKST','MaxTempe......
  • Python遍历时删除元素问题(附深拷贝与浅拷贝介绍)
    问题有时候,我们希望用Python遍历一个列表(或其他可迭代对象),如果其中有我们不需要的元素就把它删除并继续遍历。如以下代码段,我们本希望打印1、3,可最后却只打印了1。a=[1,2,3]foriina:ifi==2:a.remove(i)else:print(i)分析其实,之所以......
  • python面向对象进阶
    面向对象进阶类型判断issubclasstypeisinstance反射反射的四个函数importlib类的其他成员__str____repr____format____del____dict__和__slots____item__系列__init____new____call____doc____iter__和__next____ente......
  • [oeasy]python0123_中文字符_文字编码_gb2312_激光照排技术_王选
    中文编码GB2312回忆上次内容上次回顾了日韩各有编码格式日本有假名五十音一字节可以勉强放下 有日本汉字字符数量超过20000+  韩国有谚文数量超过500一个字节放不下 有朝鲜汉字字符数量超过20000+......
  • Python异常 ValueError的问题详解
    导读这篇文章主要介绍了Python异常ValueError的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教Python异常ValueErrorValueError:invalidliteralforint()withbase10:'*'试图将一个与数字无关的类型转化为整数,会抛出该异常。......