使用OpenCV工具包成功实现人脸检测与人脸识别,包括传统视觉和深度学习方法(附完整代码,模型下载......)

您所在的位置:网站首页 人脸定位跟踪软件下载免费 使用OpenCV工具包成功实现人脸检测与人脸识别,包括传统视觉和深度学习方法(附完整代码,模型下载......)

使用OpenCV工具包成功实现人脸检测与人脸识别,包括传统视觉和深度学习方法(附完整代码,模型下载......)

2024-07-11 12:21:16| 来源: 网络整理| 查看: 265

使用OpenCV工具包实现人脸检测与人脸识别(吐血整理!) OpenCV实现人脸检测OpenCV人脸检测方法基于Haar特征的人脸检测Haar级联检测器预训练模型下载Haar 级联分类器OpenCV-Python实现 基于深度学习的人脸检测传统视觉方法与深度学习方法对比 OpenCV实现人脸识别制作数据集加载数据集训练数据集单张图片测试

OpenCV实现人脸检测

要实现人脸识别功能,首先要进行人脸检测,判断出图片中人脸的位置,才能进行下一步的操作。

参考链接: 1、OpenCV人脸检测 2、【OpenCV-Python】32.OpenCV的人脸检测和识别——人脸检测 3、【youcans 的图像处理学习课】23. 人脸检测:Haar 级联检测器 4、OpenCV实战5:LBP级联分类器实现人脸检测 5、计算机视觉OpenCv学习系列:第十部分、实时人脸检测

OpenCV人脸检测方法

在OpenCV中主要使用了两种特征(即两种方法)进行人脸检测,Haar特征和LBP特征。用的最多的是Haar特征人脸检测,此外OpenCV中还集成了深度学习方法来实现人脸检测。

基于Haar特征的人脸检测 Haar级联检测器预训练模型下载

在OpenCV中,使用已经训练好的XML格式的分类器进行人脸检测。在OpenCV的安装目录下的sources文件夹里的data文件夹里或者在github上下载opencv源代码,在源代码的data文件夹里都可以找到模型文件: https://github.com/opencv/opencv/tree/4.x/data

haarcascade_eye.xml, 眼睛 haarcascade_eye_tree_eyeglasses.xml, 戴眼镜的眼睛 haarcascade_frontalcatface.xml, 正面猫脸 haarcascade_frontalcatface_extended.xml, 正面猫脸 haarcascade_frontalface_alt.xml, 正面人脸 haarcascade_frontalface_alt2.xml, 正面人脸 haarcascade_frontalface_alt_tree.xml, 正面人脸 haarcascade_frontalface_default.xml, 正面人脸 haarcascade_fullbody.xml, 人体 haarcascade_lefteye_2splits.xml, 左眼 haarcascade_license_plate_rus_16stages.xml, haarcascade_lowerbody.xml, haarcascade_profileface.xml, haarcascade_righteye_2splits.xml, 右眼 haarcascade_russian_plate_number.xml, haarcascade_smile.xml, 笑脸 haarcascade_upperbody.xml, 上身

Haar 级联分类器

基于 Haar 特征的级联分类器是 Paul Viola 在论文”Rapid Object Detection using a Boosted Cascade of Simple Features”中提出的一种目标检测方法。

Haar 级联分类器在每一级的节点中,使用 AdaBoost 算法学习一个高检测率低拒绝率的多层分类器。其特点是:

使用 Haar-like 输入特征,对矩形图像区域的和或者差进行阈值化。使用积分图像计算 45°旋转区域的像素和,加速 Haar-like 输入特征的计算。使用统计 Boosting 来创建二分类(人脸/非人脸)的分类器节点(高通过率,低拒绝率)。将弱分类器并联组合起来,构成筛选式级联分类器。 Haar级联分类器

各级的 Boosting 分类器对于有人脸的检测窗口都能通过,同时拒绝一小部分非人脸的检测窗口,并将通过的检测窗口传给下一个分类器。依次类推,最后一个分类器将几乎所有非人脸的检测窗口都拒绝掉,只剩下有人脸的检测窗口。因此,只要检测窗口区域通过了所有各级 Boosting 分类器,则认为检测窗口中有人脸。

在实际应用中输入图片的尺寸较大,需要进行多区域、多尺度的检测。多区域是要遍历图片的不同位置,多尺度是为了检测图片中不同大小的人脸。 在 Haar 级联分类人脸检测器中,主要利用了人脸的结构化特征: 1)与脸颊相比,眼部颜色较深 2)与眼睛相比,鼻梁区域较为明亮 3)眼睛、嘴巴、鼻子的位置较为固定 通过这 5 个矩形区域的明暗关系,就可以形成对人脸的各个部分的判别特征。例如在下图中,第一个特征检测眼部和上脸颊之间的强度差异,第二个特征检测双眼的间距。 在这里插入图片描述 Haar 人脸检测正脸检测识别率很高,但对侧脸的检测性能较差。

OpenCV-Python实现

使用 Haar 级联检测器检测图片中的人脸的步骤:

(1)创建一个 CascadeClassifier 级联分类器对象,从 .xml 文件加载级联分类器模型。 (2)读取待检测的图片。 (3)使用 detectMultiScale() 方法检测图片,返回检测到的面部或眼睛的边界矩形。 (4)将检测到的边界矩形绘制到检测图片上。 OpenCV 中定义了级联分类器类 cv::CascadeClassifier。在 Python 语言中,使用接口函数 cv2.CascadeClassifier() 从文件创建分类器。成员函数 cv.CascadeClassifier.detectMultiScale() 用于执行对图像进行目标检测。

import cv2 cv2.CascadeClassifier.detectMultiScale(image[, scaleFactor=1.1, minNeighbors=3, flags=0, minSize=Size(), maxSize=Size()]) → objects

参数说明:

filename:加载分类器模型的文件路径和名称,字符串。加载的级联分类器模型文件,扩展名为 .xml。image:待检测的输入图像,CV_8U 格式。scaleFactor:搜索窗口的缩放比例,默认值为1.1。minNeighbors:表示构成检测目标的相邻矩形的最小个数,默认值为 3。flags:版本兼容标志,默认值为 0。minSize:检测目标的最小尺寸,元组 (h,w)。maxSize:检测目标的最大尺寸,元组 (h,w)。

返回值

objects:返回值,检测目标的矩形边界框 ,是形如 (N,4) 的Numpy数组。每行有 4个元素 (x, y, width, height) 表示矩形框的左上顶点坐标 (x,y) 和宽度 width、高度 height。

使用Haar 级联检测器检测图片中的人脸:

import numpy as np import cv2 as cv if __name__ == '__main__': # (6) 使用 Haar 级联分类器 预训练模型 检测人脸 # 读取待检测的图片 img = cv.imread("../data/single.jpg") print(img.shape) # 加载 Haar 级联分类器 预训练模型 model_path = "../data/haarcascade_frontalface_alt2.xml" face_detector = cv.CascadeClassifier(model_path) # # 使用级联分类器检测人脸 faces = face_detector.detectMultiScale(img, scaleFactor=1.1, minNeighbors=1, minSize=(30, 30), maxSize=(300, 300)) print(faces.shape) # (17, 4) print(faces[0]) # (x, y, width, height) # 绘制人脸检测框 for x, y, width, height in faces: cv.rectangle(img, (x, y), (x + width, y + height), (0, 0, 255), 2, cv.LINE_8, 0) # 显示图片 cv.imshow("faces", img) cv.waitKey(0) cv.destroyAllWindows()

单个人脸检测 使用Haar 级联检测器检测图片中的人眼: 人眼检测的方法与人脸检测方法相同,只是使用了不同的预训练模型,例如 haarcascade_eye.xml。 由于眼睛比人脸的尺寸小,因此减小了检测函数 detectMultiScale() 的参数 minSize=(20, 20)。 此外scaleFactor和minNeighbors也会影响到检测出的人眼个数。

import cv2 as cv if __name__ == '__main__': # (7) 使用 Haar 级联分类器 预训练模型 检测人眼 # 读取待检测的图片 img = cv.imread("./data/single.jpg") print(img.shape) # 加载 Haar 级联分类器 预训练模型 model_path = "./data/haarcascade_eye.xml" eye_detector = cv.CascadeClassifier(model_path) # # 使用级联分类器检测人脸 eyes = eye_detector.detectMultiScale(img, scaleFactor=1.1, minNeighbors=10, minSize=(10, 10), maxSize=(80, 80)) # 绘制人脸检测框 for x, y, width, height in eyes: cv.rectangle(img, (x, y), (x + width, y + height), (0, 0, 255), 2, cv.LINE_8, 0) # 显示图片 cv.imshow("Haar_Cascade", img) # cv.imwrite("../images/imgSave3.png", img) cv.waitKey(0) cv.destroyAllWindows()

单个人脸人眼检测 scaleFactor=1.1, minNeighbors=10 单个人脸人眼检测 scaleFactor=1.1, minNeighbors=5

使用 Haar 级联检测器同时检测人脸和人眼 为了提高检测效率,可以先检测人脸,再在人类窗口内检测人眼,不仅可以提高检测效率,而且可以提高检测精度。

import cv2 as cv if __name__ == '__main__': # (8) 使用 Haar 级联分类器 预训练模型 检测人脸和人眼 # 读取待检测的图片 img = cv.imread("./data/multiface1.jpeg") print(img.shape) # 加载 Haar 级联分类器 预训练模型 face_path = "./data/haarcascade_frontalface_alt2.xml" # 人脸检测器 face_detector = cv.CascadeClassifier(face_path) # eye_path = "./data/haarcascade_eye.xml" # 人眼检测器 eye_detector = cv.CascadeClassifier(eye_path) # # 使用级联分类器检测人脸 faces = face_detector.detectMultiScale(img, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), maxSize=(300, 300)) print(faces.shape) # (15, 4) # 绘制人脸检测框 for x, y, width, height in faces: cv.rectangle(img, (x, y), (x + width, y + height), (0, 0, 255), 2, cv.LINE_8, 0) # 在人脸区域内检测人眼 roi = img[y:y + height, x:x + width] # 提取人脸 # 检测人眼 eyes = eye_detector.detectMultiScale(roi, scaleFactor=1.1, minNeighbors=1, minSize=(2, 2), maxSize=(80, 80)) # 绘制人眼 for ex, ey, ew, eh in eyes: cv.rectangle(img, (x+ex, y+ey), (x+ex+ew, y+ey+eh), (255, 0, 0), 2) # 显示图片 cv.imshow("Haar_Cascade", img) # cv.imwrite("../images/imgSave4.png", img) cv.waitKey(0) cv.destroyAllWindows()

可以看到对于比较正常的人脸检测效果还是不错的(需要手动调整detectMultiScale()方法的参数),但是对于侧脸、歪脸、小脸的检测效果就不太理想了,而且对于眼睛的检测只能画框,不能实现关键点检测,现在在考虑利用这个人眼检测转换成关键点来做人脸对齐,后面再看看效果。

基于深度学习的人脸检测

OpenCV的深度神经网络(Deep Neural Network,DNN)模块提供了基于深度学习的人脸检测器。DNN模块中使用了广受欢迎的深度学习框架,包括Caffe、TensorFlow、Torch和Darknet等。 OpenCV提供了两个预训练的人脸检测模型:Caffe和TensorFlow模型。 Caffe模型需要加载以下两个文件:

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

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

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

在OpenCV源代码的“\samples\dnn\face_detector”的文件夹中提供了模型配置文件,但未提供模型训练文件。可运行该文件夹中的download_models.py文件下载上述两个训练模型文件。或直接在官方链接https://github.com/spmallick/learnopencv/find/master(这个链接太难下了)下载,在这个链接下载:OpenCV学堂/OpenCV课程资料https://gitee.com/opencv_ai/opencv_tutorial_data(关键时刻靠Gitee) (在搜索框中输入Age进行搜索,不然找不到)  在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

使用预训练的模型执行人脸检测时主要包含下列步骤: (1) 调用cv2.dnn.readNetFromCaffe()或cv2.dnn.readNetFromTensorflow()函数加载模型,创建检测器。 (2) 调用cv2.dnn.blobFromImage()函数将待检测图像转换为图像块数据。 (3) 调用检测器的setInput()方法将图像块数据设置为模型的输入数据。 (4) 调用检测器的forward()方法执行计算,获得预测结果。 (5) 将可信度高于指定值的预测结果作为检测结果,在原图中标注人脸,同时输出可信度作为参考。

单张图片检测

# 基于深度学习的人脸检测(脸-眼_视频) import cv2 import numpy as np # dnnnet = cv2.dnn.readNetFromCaffe("deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel") dnnnet = cv2.dnn.readNetFromTensorflow("./data/opencv_face_detector_uint8.pb", "./data/opencv_face_detector.pbtxt") img = cv2.imread("./data/multiface1.jpeg") h, w = img.shape[:2] blobs = cv2.dnn.blobFromImage(img, 1.0, (300, 300), [104., 117., 123.], False, False) dnnnet.setInput(blobs) detections = dnnnet.forward() faces = 0 for i in range(0, detections.shape[2]): confidence = detections[0, 0, i, 2] if confidence > 0.6: 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, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) cv2.imshow('faces',img) cv2.waitKey(0) cv2.destroyAllWindows()

在这里插入图片描述 相比之下,还是深度学习模型的效果更胜一筹。

视频检测

import cv2 import numpy as np # win7系统在代码中所有的cv2.VideoCapture要加cv2.CAP_DSHOW,不然会报错 capture = cv2.VideoCapture(0, cv2.CAP_DSHOW) frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH) frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT) fps = capture.get(cv2.CAP_PROP_FPS) dnnnet = cv2.dnn.readNetFromTensorflow("./data/opencv_face_detector_uint8.pb", "./data/opencv_face_detector.pbtxt") if capture.isOpened() is False: print('CAMERA ERROR !') exit(0) while capture.isOpened(): ret, frame = capture.read() if ret is True: # cv2.imshow('FRAME', frame) # 显示捕获的帧 h, w = frame.shape[:2] blobs = cv2.dnn.blobFromImage(frame, 1.0, (300, 300), [104., 117., 123.], False, False) dnnnet.setInput(blobs) detections = dnnnet.forward() faces = 0 for i in range(0, detections.shape[2]): confidence = detections[0, 0, i, 2] if confidence > 0.6: 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(frame, (x1, y1), (x2, y2), (255, 0, 0), 2) cv2.putText(frame, text, (x1, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) cv2.imshow('faces', frame) k = cv2.waitKey(1) if k == ord('q'): break else: break capture.release() cv2.destroyAllWindows()

把手机放在摄像头前进行检测,可以看到有些人脸还是检测不出来,后面可以考虑加入活体检测。

传统视觉方法与深度学习方法对比

针对同一段视频文件,速度与检测总数统计比较 在这里插入图片描述

OpenCV实现人脸识别

参考链接: 1、opencv的人脸面部识别(主要代码参考) 2、【OpenCV-Python】33.OpenCV的人脸检测和识别——人脸识别 自己根据博主的代码做了适当的修改,符合自己项目的要求

OpenCV 有三种人脸识别的算法:

特征脸(Eigenfaces)人脸识别 是通过 PCA(主成分分析)实现的,它识别人脸数据集的主成分,并计算出待识别图像区域相对于数据集的发散程度(0-20k),该值越小,表示差别越小,0值代表完全匹配。低于4k-5k都是相当可靠的识别。 EigenFaces人脸识别的基本步骤如下: (1) 调用cv2.face.EigenFaceRecognizer_create()方法创建EigenFace识别器。 (2) 调用识别器的train()方法以便使用已知图像训练模型。 (3) 调用识别器的predict()方法以便使用未知图像进行识别,确认其身份。 cv2.face.EigenFaceRecognizer_create()函数的基本格式如下:

recognizer = cv2.face.EigenFaceRecognizer_create([num_components[, threshold]]) # recognizer为返回的EigenFaces识别器对象 # num_components为分析时的分量数量, 默认为0, 表示根据实际输入决定 # threshold为人脸识别时采用的阈值

EigenFaces识别器的train()方法的基本格式如下:

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

EigenFaces识别器的predict()方法的基本格式如下:

label, confidence = recoginer.predict(testimg) # label为返回的标签值 # confidence为返回的可信度, 表示未知人脸和模型中已知人脸之间的距离, 0表示完全匹配, 低于5000可认为是可靠的匹配结果 # test_img为未知人脸图像, 图像必须为灰度图且大小要与训练图像相同

人鱼脸(FisherFaces)人脸识别 是从 PCA发展而来,使用线性判别分析(Linear Discriminant Analysis,LDA)方法实现人脸识别,采用更复杂的计算,容易得到更准确的结果。低于4k~5k都是相当可靠的识别。 FisherFaces人脸识别的基本步骤如下: (1) 调用cv2.face.FisherFaceRecognizer_create()方法创建FisherFaces识别器。 (2) 调用识别器的train()方法以便使用已知图像训练模型。 (3) 调用识别器的predict()方法以便使用未知图像进行识别,确认其身份。 在OpenCV中,cv2.face.EigenFaceRecognizer类和cv2.face.FisherFaceRecognizer类同属于cv2.face.BasicFaceRecognizer类、cv2.face.FaceRecognizer类和cv2.Algorithm类的子类,对应的xxx_create()、train()和predict()等方法的基本格式与用法相同。

局部二进制编码直方图(Local Binary Patterns Histograms,LBPH)人脸识别 将人脸分成小单元,并将其与模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图。它允许待检测人脸区域可以和数据集中图像的形状、大小不同,更方便灵活。参考值低于50则算是好的识别,高于80则认为比较差。 LBPH算法处理图像的基本原理如下: (1) 取像素x周围(邻域)的8个像素与其比较,像素值比像素x大的取0,否则取1。将8个像素对应的0、1连接得到一个8位二进制数,将其转换为十进制,作为像素x的LBP值。 (2) 对像素的所有像素按相同的方法进行处理,得到整个图像的LBP值,该图像的直方图就是图像的LBPH。 LBPH人脸识别的基本步骤如下; (1) 调用cv2.face.LBPHFaceRecognizer_create()方法创建LBPH识别器。 (2) 调用识别器的train()方法以便使用已知图像训练模型。 (3) 调用识别器的predict()方法以便使用未知图像进行识别,确认其身份。

cv2.face.LBPHFaceRecognizer_create()函数的基本格式如下:

recognizer = cv2.face.LBPHFaceRecognizer_create([radius[, neighbors[, grid_x[, grid_y[, threshold]]]]]) # recognizer为返回的LBPH识别器对象 # radius为邻域的半径大小 # neighbors为邻域内像素点的数量, 默认为8 # grid_x为将LBP图像划分为多个单元格时, 水平方向上的单元格数量, 默认为8 # grid_y为将LBP图像划分为多个单元格时, 垂直方向上的单元格数量, 默认为8 # threshold为人脸识别时采用的阈值

LBPH识别器的train()方法的基本格式如下:

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

LBPH识别器的predict()方法的基本格式如下:

label, confidence = recoginer.predict(testimg) # label为返回的标签值 # confidence为返回的可信度, 表示未知人脸和模型中已知人脸之间的距离, 0表示完全匹配, 低于50可认为是非常可靠的匹配结果 # test_img为未知人脸图像, 图像必须为灰度图且大小要与训练图像相同 制作数据集

不管使用哪种算法都需要有训练集。从视频或者动图创建训练集的效率比较高。可以从网上下载或者自己写一个摄像头捕获程序进行采集。本次实验直接从网上下载了一些明星的动图,然后将动图按帧分解,使用OpenCV中的Haar级联器检测人脸区域,然后将人脸区域全部存为200X200的灰度图,存入对应的文件夹中,创建训练集。

from PIL import Image import os import cv2 import numpy as np # GIF动图转图片 def gifSplit2Array(gif_path): import numpy as np img = Image.open(os.path.join(path, gif_path)) for i in range(img.n_frames): img.seek(i) new = Image.new("RGBA", img.size) new.paste(img) arr = np.array(new).astype(np.uint8) # image: img (PIL Image): yield arr[:, :, 2::-1] # 逆序(RGB 转BGR), 舍弃alpha通道, 输出数组供openCV使用 # 人脸检测 def face_generate(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) front_face_cascade = cv2.CascadeClassifier('./data/haarcascade_frontalface_alt2.xml') # 检测正脸 faces0 = front_face_cascade.detectMultiScale(gray, 1.02, 5) eye_cascade = cv2.CascadeClassifier('./data/haarcascade_eye_tree_eyeglasses.xml') # 检测眼睛 if faces0 is not None: for (x, y, w, h) in faces0: face_area = gray[y: y + h, x: x + w] # (疑似)人脸区域 quasi_eyes = eye_cascade.detectMultiScale(face_area, 1.03, 5, 0) # 在人脸区域检测眼睛 if len(quasi_eyes) == 0: continue quasi_eyes = tuple( filter(lambda x: x[2] / w > 0.18 and x[1] 0.18,尺寸过滤 ,且眼睛在脸的上半部 if len(quasi_eyes)


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭