计算机视觉基础25—人脸检测和人脸识别

参考书目:《OpenCV计算机视觉基础教程》–夏帮贵。
代码编写:Jupyter Notebook。



1.人脸检测

# 人脸检测:在图像中完成人脸定位的过程;
# 人脸识别:在人脸检测的基础上进一步判断人的身份;

# 1.基于Haar的人脸检测
# 在haarcascades文件夹中包含训练好的Haar级联分类器文件;
# a.haarcascade_eye.xml:人眼检测;
# b.haarcascade_eye_tree_eyeglasses.xml:眼镜检测;
# c.haarcascade_frontalcatface.xml:猫脸检测;
# d.haarcascade_frontalface_alt.xml:人脸检测;
# e.haarcascade_frontalface_default.xml:人脸检测;
# f.haarcascade_profileface.xml:侧脸检测;

# 1.1 加载分类器
# 语法格式:faceClassifier = cv2.CascadeClassifier(filename)
# 参数说明:
# a.faceClassifier:返回的级联分类器对象;
# b.filename:级联分类器的文件名;

# 1.2 执行检测
# 语法格式:objects = faceClassifier.detectMultiScale(image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]])
# 参数说明:
# a.objects:返回的目标矩形,矩形中为人脸;
# b.image:输入图像,通常为灰度图像;
# c.scaleFactor:图像缩放比例;
# d.minNeighbors:构成目标矩形的最小相邻矩形个数;
# e.minSize:目标矩形的最小尺寸;
# f.maxSize:目标矩形的最大尺寸;

import cv2 as cv

img1 = cv.imread("women_football_team.jpg")
gray = cv.cvtColor(img1, cv.COLOR_BGR2GRAY)

# 加载人脸检测器
face = cv.CascadeClassifier("C:ProgramDataAnaconda3Libraryetchaarcascadeshaarcascade_frontalface_default.xml")

# 加载眼睛检测器
eye = cv.CascadeClassifier("C:ProgramDataAnaconda3Libraryetchaarcascadeshaarcascade_eye.xml")
faces = face.detectMultiScale(gray)

for x, y, w, h in faces:
    cv.rectangle(img1, (x, y), (x + w, y + h), (255, 0, 0), 2)
    roi_eye = gray[y : y + h, x : x + w]    # 根据人脸获得眼睛的检测范围
    eyes = eye.detectMultiScale(roi_eye)
    for (ex, ey, ew, eh) in eyes:
        cv.circle(img1[y : y + h, x : x + w], (int(ex + ew / 2), int(ey + eh / 2)), int(max(ew, eh) / 2), (0, 255, 0), 2)
        
cv.imshow("face_detect", img1)
cv.waitKey(0)

1

# 使用Haar级联分类器检测猫脸
import cv2 as cv

img1 = cv.imread("cats.JPG")
gray = cv.cvtColor(img1, cv.COLOR_BGR2GRAY)

# 加载猫脸检测器
face = cv.CascadeClassifier("C:ProgramDataAnaconda3Libraryetchaarcascadeshaarcascade_frontalcatface.xml")
faces = face.detectMultiScale(gray)

for x, y, w, h in faces:
    cv.rectangle(img1, (x, y), (x + w, y + h), (255, 0, 0), 2)
    
cv.imshow("catfaces", img1)
cv.waitKey(0)

2

# 使用Haar级联分类器检测摄像头视频中的人脸
import cv2 as cv

capture = cv.VideoCapture(0)

if not capture.isOpened:
    print("打开摄像头失败!")
    exit(0)

# 加载人脸检测器
face = cv.CascadeClassifier("C:ProgramDataAnaconda3Libraryetchaarcascadeshaarcascade_frontalface_default.xml")

# 加载眼睛检测器
eye = cv.CascadeClassifier("C:ProgramDataAnaconda3Libraryetchaarcascadeshaarcascade_eye.xml")

while True:
    ret, frame = capture.read()
    if frame is None:
        break
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    faces = face.detectMultiScale(gray)
    for x, y, w, h in faces:
        cv.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
        roi_eye = gray[y:y+h, x:x+w]
        eyes = eye.detectMultiScale(roi_eye)
        for (ex, ey, ew, eh) in eyes:
            cv.circle(frame[y:y+h, x:x+w], (int(ex + ew / 2), int(ey + eh / 2)), int(max(ew, eh) / 2), (0, 255, 0), 2)
    cv.imshow("faces", frame)
    key = cv.waitKey(0) & 0xFF
    if (key == 27) or ord("q"):
        break
capture.release()
cv.destroyAllWindows()

2.人脸识别

# 1.特征脸(EigenFaces)人脸识别
# EigenFaces使用主要成分分析(Principal Component Analysis,PCA)方法将人脸数据从高维处理成低维后,
# 获得人脸数据的主要成分信息,进而完成人脸识别;

# 基本步骤:
# a.调用cv2.face.EigenFaceRecognizer_create()创建识别器;
# b.调用识别器的train()方法,以便使用已知图像进行训练模型;
# c.调用识别器的predict()方法,以便使用未知图像进行识别,确认其身份;

# 1.1 创建识别器
# 语法格式:recognizer = cv2.face.EigenFaceRecognizer_create([num_components[, thresholod]])
# 参数说明:
# a.recognizer:返回的EigenFaces识别器对象;
# b.num_components:分析时的分量个数;默认值:0,表示根据实际输入决定;
# c.threshold:人脸识别时采用的阈值;

# 1.2 训练模型
# 语法格式:recognizer.train(src, labels)
# 参数说明:
# a.src:用于训练的已知图像数组;图像必须为灰度图像,且大小相同;
# b.labels:标签数组;

# 1.3 人脸识别预测
# 语法格式:label, confidence = recognizer.predict(testing)
# 参数说明:
# a.testing:未知人脸图像,必须为灰度图像,且与训练图像大小相同;
# b.label:返回的标签值;
# c.confidence:返回的可信度,表示未知人脸和模型已知人脸之间的距离;0表示完全匹配,低于5000则认为是可靠的匹配结果;
import cv2 as cv
import numpy as np

img1 = cv.imread("facerecognition/1_1.jpg", 0)
img2 = cv.imread("facerecognition/1_2.jpg", 0)
img3 = cv.imread("facerecognition/2_1.jpg", 0)
img4 = cv.imread("facerecognition/2_2.jpg", 0)
img5 = cv.imread("facerecognition/3_1.jpg", 0)
img6 = cv.imread("facerecognition/3_2.jpg", 0)

train_images = [img1, img2, img3, img4, img5, img6]
labels = np.array([0, 0, 1, 1, 2, 2])

recognizer = cv.face.EigenFaceRecognizer_create()
recognizer.train(train_images, labels)

testimg1 = cv.imread("facerecognition/7.jpg", 0)
testimg2 = cv.imread("facerecognition/2_3.jpg", 0)
testimg3 = cv.imread("facerecognition/3_3.jpg", 0)

label1, confidence1 = recognizer.predict(testimg1)
label2, confidence2 = recognizer.predict(testimg2)
label3, confidence3 = recognizer.predict(testimg3)

print("匹配标签:", label1)
print("可信度:", confidence1)    # 注意,该可信度高于5000,识别结果不可靠;

print("匹配标签:", label2)
print("可信度:", confidence2)

print("匹配标签:", label3)
print("可信度:", confidence3)
# 结果输出:
匹配标签: 0
可信度: 6330.208283003789
匹配标签: 1
可信度: 472.850776831913
匹配标签: 2
可信度: 4813.318969729076
# 2.人鱼脸(FisherFaces)人脸识别
# FisherFaces使用线性判别分析(Linear Discriminant Analysis,LDA)实现人脸识别;
# 基本步骤:
# a.调用cv2.face.FisherFaceRecognizer_create()函数创建FisherFaces识别器;
# b.调用cv2.train()方法,以便使用已知图像训练模型;
# c.调用cv2.predict()方法,以便识别未知图像,确认身份;
import cv2 as cv
import numpy as np

img1 = cv.imread("facerecognition/1_1.jpg", 0)
img2 = cv.imread("facerecognition/1_2.jpg", 0)
img3 = cv.imread("facerecognition/2_1.jpg", 0)
img4 = cv.imread("facerecognition/2_2.jpg", 0)
img5 = cv.imread("facerecognition/3_1.jpg", 0)
img6 = cv.imread("facerecognition/3_2.jpg", 0)

train_images = [img1, img2, img3, img4, img5, img6]
labels = np.array([0, 0, 1, 1, 2, 2])

recognizer = cv.face.FisherFaceRecognizer_create()
recognizer.train(train_images, labels)

testimg1 = cv.imread("facerecognition/7.jpg", 0)
testimg2 = cv.imread("facerecognition/2_3.jpg", 0)
testimg3 = cv.imread("facerecognition/3_3.jpg", 0)

label1, confidence1 = recognizer.predict(testimg1)
label2, confidence2 = recognizer.predict(testimg2)
label3, confidence3 = recognizer.predict(testimg3)

print("匹配标签:", label1)
print("可信度:", confidence1)    # 注意,识别结果不可靠;

print("匹配标签:", label2)
print("可信度:", confidence2)

print("匹配标签:", label3)
print("可信度:", confidence3)
匹配标签: 2
可信度: 3496.186604323862
匹配标签: 1
可信度: 102.56612713281567
匹配标签: 2
可信度: 1102.977592421783
# 3.局部二进制编码直方图(LBPH,Local Binary Patterns Histograms)
# 基本原理:
# a.取像素x周围(领域)的8个像素与其比较,像素值比像素x大的取0,否则取1;
# 将8个像素对应的0、1连接得到一个8位二进制数,将其转换为十进制数,作为像素x的LBP值;
# b.对图像的所有像素按相同的方法进行处理,得到整个图像的LBP图像,该图像的直方图就是图像的LBPH;

# LBPH人脸识别的步骤:
# a.调用cv2.face.LBPHFaceRecognizer_create()函数创建LBPH识别器;
# b.调用识别器的train()方法,以便训练模型;
# c.调用识别器的predict()方法,以便识别未知图像,确认身份;

# 3.1 创建LBPH识别器
# 语法格式:recognizer = cv2.face.LBPHRecognizer_create([, radius[, neighbors[, grid_x[, grid_y[, threshold]]]]])
# 参数说明:
# a.recognizer:返回的LBPH识别器对象;
# b.radius:邻域的半径大小;
# c.neighbors:邻域内像素点的数量,默认值:8;
# d.grid_x:将LBP图像划分为多个单元格时,水平方向上的单元格数量,默认值:8;
# e.grid_y:将LBP图像划分为多个单元格时,垂直方向上的单元格数量,默认值:8;
# f.threshold:人脸识别时采用的阈值;

# 3.2 训练模型
# 语法格式:recognizer.train(src, labels)
# 参数说明:
# a.src:用于训练的已知图像数组,所有图像必须为灰度图像,且大小相同;
# b.labels:标签数组;

# 3.3 人脸识别
# 语法格式:label, confidence = recognizer.predict(testimg)
# 参数说明:
# a.testimg:未知人脸图像;
# b.label:返回的识别标签值;
# c.confidence:返回的可信度,0表示完全匹配,低于50认为是非常可靠的匹配结果;
import cv2 as cv
import numpy as np

img1 = cv.imread("facerecognition/1_1.jpg", 0)
img2 = cv.imread("facerecognition/1_2.jpg", 0)
img3 = cv.imread("facerecognition/2_1.jpg", 0)
img4 = cv.imread("facerecognition/2_2.jpg", 0)
img5 = cv.imread("facerecognition/3_1.jpg", 0)
img6 = cv.imread("facerecognition/3_2.jpg", 0)

train_images = [img1, img2, img3, img4, img5, img6]
labels = np.array([0, 0, 1, 1, 2, 2])

recognizer = cv.face.LBPHFaceRecognizer_create()
recognizer.train(train_images, labels)

testimg1 = cv.imread("facerecognition/7.jpg", 0)
testimg2 = cv.imread("facerecognition/2_3.jpg", 0)
testimg3 = cv.imread("facerecognition/3_3.jpg", 0)
testimg4 = cv.imread("facerecognition/3_2.jpg", 0)

label1, confidence1 = recognizer.predict(testimg1)
label2, confidence2 = recognizer.predict(testimg2)
label3, confidence3 = recognizer.predict(testimg3)
label4, confidence4 = recognizer.predict(testimg4)

print("匹配标签:", label1)
print("可信度:", confidence1)    # 注意,识别结果不可靠;

print("匹配标签:", label2)
print("可信度:", confidence2)

print("匹配标签:", label3)
print("可信度:", confidence3)

print("匹配标签:", label4)
print("可信度:", confidence4)
# 结果输出:
匹配标签: 0
可信度: 48.09836604698404
匹配标签: 1
可信度: 28.451521738224358
匹配标签: 2
可信度: 72.14613446383872
匹配标签: 2
可信度: 0.0

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇
下一篇>>