我是靠谱客的博主 健康纸鹤,这篇文章主要介绍基于opencv的人脸识别和检测1.环境配置,现在分享给大家,希望可以做个参考。

人脸识别作为一个热门项目,目前有多种方法实现,利用python和opencv来实现,是一个比较简单的项目。

1.环境配置

windows平台

python版本:3.8.6

pycharm版本:2019.1.2

Opencv版本:4.5.3

安装了python后,在命令行直接安装opencv库

复制代码
1
pip install opencv-python

然后再去opencv官网,下载软件源码,如果下载速度过慢,可以选择网盘下载

2.实现思路

1.读取图片

2.灰度转换

3.修改图片大小

4.确定识别范围(脸)

5.实现人脸检测

6.多个目标的同时检测

7.对视频流实现检测

8.收集数据(录有带有人脸图片)

10.训练数据

11.实现人脸识别

3.具体实现

1.读取图片

复制代码
1
2
3
4
5
6
7
8
9
10
#导入cv模块 import cv2 as cv #读取图片 img = cv.imread('face1.jpg') #显示图片 cv.imshow('show_img',img) #等待,0表示无限等待后关闭窗口 cv.waitKey(0) #释放内存 cv.destroyAllWindows()

cv的自带函数用起来很方便,imread,imshow函数等

2.灰度转换

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#导入cv模块 import cv2 as cv #读取图片 img = cv.imread('face2.jpg') #灰度转换,使用到了cvt函数,其中img为图片参数,第二个为转换的颜色参数 gray_img = cv.cvtColor(img,cv.COLOR_BGR2GRAY) #显示灰度图片 cv.imshow('gray_img',gray_img) #保存灰度图片 cv.imwrite('gray_face2.jpg',gray_img) #显示图片 cv.imshow('show_img',img) #等待 cv.waitKey(0) #释放内存 cv.destroyAllWindows()

3.修改图片大小

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#导入cv模块 import cv2 as cv #读取图片 img = cv.imread('face2.jpg') #修改尺寸,使用到resize函数,参数为图片名和修改后的大小 resize_img = cv.resize(img,dsize=(200,200)) #显示原图 cv.imshow('img',img) #显示修改后的 cv.imshow('resize_img',resize_img) #打印原图尺寸大小 print('未修改:',img.shape) #打印修改后的大小 print('修改后:',resize_img.shape) #等待关闭窗口 while True: if ord('g') == cv.waitKey(0): break #释放内存 cv.destroyAllWindows()

 这一步中,我们可以自主选择是否关闭窗口,采用一个if语句,如果我们按下g键,关闭窗口

4.确定识别范围(脸)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#导入cv模块 import cv2 as cv #读取图片 img = cv.imread('face2.jpg') #坐标,确定识别的起始像素点位置坐标,识别的高度和宽度 x,y,w,h = 100,100,100,100 #绘制矩形,使用到rectangle函数,参数img为绘制的矩形位置和大小,边框颜色(bgr),边框粗细 cv.rectangle(img,(x,y,x+w,y+h),color=(0,0,255),thickness=2) #绘制圆形,使用circle函数,参数为圆心,半径 cv.circle(img,center=(x+w,y+h),radius=100,color=(255,0,0),thickness=2) #显示 cv.imshow('re_img',img) while True: if ord('g') == cv.waitKey(0): break #释放内存 cv.destroyAllWindows()

5.实现人脸检测

调用opencv训练好的分类器和自带的检测函数检测人脸人眼等的步骤简单直接:

1.加载分类器,当然分类器事先要放在工程目录中去。分类器本来的位置是在*opencvsourcesdatahaarcascades(harr分类器,也有其他的可以用,也可以自己训练)

2.调用detectMultiScale()函数检测,调整函数的参数可以使检测结果更加精确。

3.把检测到的人脸等用矩形(或者圆形等其他图形)画出来。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#导入cv模块 import cv2 as cv #定义检测函数 def face_detect_demo(): #灰度转换 gary = cv.cvtColor(img,cv.COLOR_BGR2GRAY) #加载调用opencv自带分类器cv.CascadeClassifier,减少训练成本 face_detect = cv.CascadeClassifier('D:/Opencv453/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') #调用函数,后两个参数表示检测的矩形范围。 face = face_detect.detectMultiScale(gary,1.01,5,0,(100,100),(300,300)) #绘制检测范围 for x,y,w,h in face: cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2) cv.imshow('face_detect',img) #读取图像 img = cv.imread('face2.jpg') #检测函数 face_detect_demo() #等待 while True: if ord('g') == cv.waitKey(0): break #释放内存 cv.destroyAllWindows()

 这一步采用了opencv自带的分类器,Haar特征分类器就是一个XML文件,该文件中会描述人体各个部位的Haar特征值。包括人脸、眼睛、嘴唇等等。加载分类器的步骤如下:

加载分类器cv.CascadeClassifier

找到opencv的安装目录,如下图

在har下提供大量的分类器

我们先把路径复制,粘贴到

再把我们需要使用的分类器的名称复制

粘贴到

再把路径中的符号更改

同时使用到opencv中的face_detect.detectMultiScale函数

总共有5个参数

1.image表示的是要检测的输入图像(一般为灰度图,加快检测速度)

2.objects表示检测到的人脸目标序列,检测物体的矩形框向量组

3.scaleFactor表示每次图像尺寸减小的比例

4. minNeighbors表示每一个目标至少要被检测到n次才算是真的目标(因为周围的像素和不同的窗口大小都可以检测到人脸),

5.默认为0

6.minSize为目标的最小尺寸

7.minSize为目标的最大尺寸

改变上面的2,3,4参数,可以让检测到的人脸矩形框更准确

6.多个目标的同时检测

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#导入cv模块 import cv2 as cv #检测函数 def face_detect_demo(): #灰度转换 gary = cv.cvtColor(resize_img,cv.COLOR_BGR2GRAY) face_detect = cv.CascadeClassifier('D:/Opencv453/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml') face = face_detect.detectMultiScale(gary) for x,y,w,h in face: cv.rectangle(resize_img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2) cv.imshow('multi_face_detect',resize_img) img = cv.imread('duoren.jpg') resize_img = cv.resize(img,dsize=(2048,1024)) print('未修改:',img.shape) print('修改后:',resize_img.shape) #检测函数 face_detect_demo() #等待 while True: if ord('g') == cv.waitKey(0): break #释放内存 cv.destroyAllWindows()

此步导入多目标图片即可

7.对视频流实现检测

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#导入cv模块 import cv2 as cv #检测函数 def face_detect_demo(img): gary = cv.cvtColor(img,cv.COLOR_BGR2GRAY) face_detect = cv.CascadeClassifier('D:/Opencv453/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml') face = face_detect.detectMultiScale(gary) for x,y,w,h in face: cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2) cv.imshow('result',img) #读取摄像头,参数为0,调用默认摄像头 #cap = cv.VideoCapture(0) #读取视频,按帧数读取 cap = cv.VideoCapture("test1.mp4") #循环 while True: #调用cap.read函数 flag,frame = cap.read() if not flag: break face_detect_demo(frame) if ord('g') == cv.waitKey(1): break #释放内存 cv.destroyAllWindows() #释放摄像头 cap.release()

8.收集数据(录有带有人脸图片)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#导入模块 import cv2 #摄像头 cap=cv2.VideoCapture(0) falg = 1 num = 1 while(cap.isOpened()):#检测是否在开启状态 ret_flag,Vshow = cap.read()#得到每帧图像 cv2.imshow("Capture_Test",Vshow)#显示图像 k = cv2.waitKey(1) & 0xFF#按键判断 if k == ord('s'):#保存 cv2.imwrite("E:/PycharmProjects/facer/opencv/data/facedata/"+str(num)+".lumengyun"+".jpg",Vshow) print("success to save"+str(num)+".jpg") print("-------------------") num += 1 elif k == ord(' '):#退出 break #释放摄像头 cap.release() #释放内存 cv2.destroyAllWindows() #将人脸照片保存后,后续可以通过特征提取,识别人脸

 当然,也可以直接将数据把保存在待训练数据集data里

10.训练数据 

这一步就是将前面几步录入人脸数据进行训练,通过将人脸特征和人脸的ID对应起来,完成人脸识别,每张图片都有一个ID

在data里面的facedata作为我们的待训练数据,获取到facedata

使用函数getImageAndLabels,得到图片的特征faces和ID(ids)

再用cv2.face.LBPHFaceRecognizer_create()函数,得到训练对象。

FaceRecognizer类,里面有相关的一些人脸识别的算法及函数接口

LBP是一种特征提取方式,能提取出图像的局部的纹理特征,最开始的LBP算子是在3X3窗口中,取中心像素的像素值为阀值,与其周围八个像素点的像素值比较,若像素点的像素值大于阀值,则此像素点被标记为1,否则标记为0。这样就能得到一个八位二进制的码,转换为十进制即LBP码,于是得到了这个窗口的LBP值,用这个值来反映这个窗口内的纹理信息。LBPH是在原始LBP上的一个改进,在opencv支持下我们可以直接调用函数直接创建一个LBPH人脸识别的模型。

再利用我们recognizer对象.去训练整合(train)之前得到的图像特征和图像ID(faces,np.array(ids))

最后将训练后的数据(向量)保存到trainer.yml,以后进行人脸识别,直接调用这个文件就可以了

函数getImageAndLabels的实现原理

首先先建立数组来存储需要的人脸特征相关数据和ID相关数据

再把所有的信息通过路径存储在IMagePaths中

加载分类器

再对上面保存的所有信息,进行一个遍历读取   for imagePath in imagePaths:

首先

#打开图片,以灰度化方式打开。PIL_img=Image.open(imagePath).convert('L')

PIL有九种不同模式:1,L,P,RGB,RGBA,CMYK,YCbCr,I,F 

#图片以灰度表示后,就是用数字来表示,这时候对它进行向量化,将图像转换为数组,以黑白深浅 。img_numpy=np.array(PIL_img,'uint8')

#获取图片人脸特征 。faces = face_detector.detectMultiScale(img_numpy)

#获取每张图片的id和姓名  id = int(os.path.split(imagePath)[1].split('.')[0])

#这里要注意预防无面容照片

复制代码
1
2
3
for x,y,w,h in faces: ids.append(id) facesSamples.append(img_numpy[y:y+h,x:x+w])

 #打印脸部特征和id。print('id:', id),print('fs:', facesSamples)

最后将这些遍历的数据,全部都return到faces和ids中,得到全部训练后的数据集

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import os import cv2 import sys from PIL import Image import numpy as np def getImageAndLabels(path): facesSamples=[] ids=[] imagePaths=[os.path.join(path,f) for f in os.listdir(path)] #检测人脸 face_detector = cv2.CascadeClassifier('D:/Opencv453/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') #打印数组imagePaths print('数据排列:',imagePaths) #遍历列表中的图片 for imagePath in imagePaths: #打开图片,灰度化。PIL有九种不同模式:1,L,P,RGB,RGBA,CMYK,YCbCr,I,F PIL_img=Image.open(imagePath).convert('L') # PIL_img = cv2.resize(PIL_img, dsize=(400, 400)) # 向量化,将图像转换为数组,以黑白深浅 img_numpy=np.array(PIL_img,'uint8') #获取图片人脸特征 faces = face_detector.detectMultiScale(img_numpy) #获取每张图片的id和姓名 id = int(os.path.split(imagePath)[1].split('.')[0]) #预防无面容照片 for x,y,w,h in faces: ids.append(id) facesSamples.append(img_numpy[y:y+h,x:x+w]) #打印脸部特征和id #print('fs:', facesSamples) print('id:', id) #print('fs:', facesSamples[id]) print('fs:', facesSamples) #print('脸部例子:',facesSamples[0]) #print('身份信息:',ids[0]) return facesSamples,ids if __name__ == '__main__': #图片路径 path='./data/facedata/' #获取图像数组和id标签数组和姓名 faces,ids=getImageAndLabels(path) #获取训练对象 recognizer=cv2.face.LBPHFaceRecognizer_create() #recognizer.train(faces,names)#np.array(ids) recognizer.train(faces,np.array(ids)) #保存文件 recognizer.write('trainer/trainer.yml') #save_to_file('names.txt',names)

 此步是核心,决定人脸识别的准确与否,

11.实现人脸识别

将我们训练后存放在yml文件中的数据,导入到recognizer中,用这个文件来判断我们脸部特征是否符合,给出可执行评分

name = [] 存放我们训练数据图片文件名中,第一个.后面的字符,定义为名字

face_detect_demo中和上面的作用差不多,先把图片灰度化,然后加载分类器,然后进行检测,将整张图片中的人脸部分框起来,这部分就是我们得到的人脸照片。

得到的人脸照片,我们需要进行一个预测评分recoginzer.predict,得到的评分就是confidence

根据这个评分,来进行人脸识别,如果confidence过大,说明程序没有对这个人脸进行训练,无法通过验证,给出unknown提示

confidence未达到预警值,说明这个人脸被我们识别过,这是把上一步中训练识别得到的name打到矩形框上,给出人名。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import cv2 import numpy as np import os # coding=utf-8 import urllib import urllib.request import hashlib # 加载训练数据集文件 recognizer = cv2.face.LBPHFaceRecognizer_create() recoginzer.read('trainer/trainer.yml') # 名称 names = [] warningtime = 0 # 准备识别的图片 def face_detect_demo(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为灰度 face_detector = cv2.CascadeClassifier( 'D:/Opencv453/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') face = face_detector.detectMultiScale(gray, 1.1, 5, cv2.CASCADE_SCALE_IMAGE, (100, 100), (300, 300)) # face=face_detector.detectMultiScale(gray) for x, y, w, h in face: cv2.rectangle(img, (x, y), (x + w, y + h), color=(0, 0, 255), thickness=2) cv2.circle(img, center=(x + w // 2, y + h // 2), radius=w // 2, color=(0, 255, 0), thickness=1) # 人脸识别 ids, confidence = recoginzer.predict(gray[y:y + h, x:x + w]) # print('标签id:',ids,'置信评分:', confidence) if confidence > 80: global warningtime warningtime += 1 if warningtime > 100: warningtime = 0 cv2.putText(img, 'unkonw', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1) else: cv2.putText(img, str(names[ids - 1]), (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1) cv2.imshow('result', img) # print('bug:',ids) def name(): path = './data/facedata/' # names = [] imagePaths = [os.path.join(path, f) for f in os.listdir(path)] for imagePath in imagePaths: name = str(os.path.split(imagePath)[1].split('.', 2)[1]) names.append(name) cap = cv2.VideoCapture(0) name() while True: flag, frame = cap.read() if not flag: break face_detect_demo(frame) if ord(' ') == cv2.waitKey(10): break cv2.destroyAllWindows() cap.release() # print(names)

最后

以上就是健康纸鹤最近收集整理的关于基于opencv的人脸识别和检测1.环境配置的全部内容,更多相关基于opencv内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(69)

评论列表共有 0 条评论

立即
投稿
返回
顶部