face_recognition 介绍
face_recognition
是一个非常流行的 Python 库,专门用于人脸识别任务。它基于 dlib 库和 HOG(Histogram of Oriented Gradients)特征以及深度学习模型,提供了简单易用的接口来进行人脸检测、面部特征点定位和人脸识别。face_recognition
库由 Adam Geitgey 开发,旨在简化人脸识别任务,容易上手。
主要功能
-
人脸检测:
-
检测图像中的人脸位置。
-
支持使用 HOG 特征或 CNN(卷积神经网络)进行人脸检测。
-
-
面部特征点定位:
-
检测人脸上的关键特征点(如眼睛、鼻子、嘴巴等)。
-
-
人脸识别:
-
提取人脸的特征向量(128维),并用于比较不同人脸之间的相似度。
-
支持从图像或视频中识别特定的人脸。
-
它和opencv关系
face_recognition
和 OpenCV 是两个独立的计算机视觉库,但它们在功能上有一些重叠,并且经常一起使用来完成复杂的视觉任务。下面简要介绍两者的联系:
联系
-
图像预处理:通常情况下,我们会先使用 OpenCV 对图像进行预处理,比如调整大小、灰度化、去噪等。这些预处理步骤有助于提高后续人脸识别的准确率。
-
人脸检测与识别:预处理后的图像可以传递给
face_recognition
库来执行人脸检测和识别。face_recognition
可以高效地完成这些任务,并返回人脸位置、面部特征点等信息。 -
结果可视化:再次利用 OpenCV 来对识别结果进行可视化处理,例如在图像上画出人脸框、标注识别到的名字等。
检测人脸
face_recognition.face_locations(img, number_of_times_to_upsample=1, model='hog')
-
功能:检测图像中的人脸位置。
-
参数
-
img
:图像的 NumPy 数组。 -
number_of_times_to_upsample
:图像上采样的次数,用于提高检测精度。 -
model
:使用的模型,可以是'hog'
(默认)或'cnn'
。
-
-
返回:一个列表,每个元素是一个
(top, right, bottom, left)
的元组,表示人脸的位置
import face_recognition import cv2 #加载图片 image = cv2.imread("../face_train_images/ldh.jpg") #读取人脸位置 face_locations = face_recognition.face_locations(image) print(face_locations) for (top, right, bottom, left) in face_locations: # 画出人脸区域 cv2.rectangle(image, (left, top), (right, bottom), (0, 255, 0), 2) # 显示结果 cv2.imshow("Detected Faces", image) cv2.waitKey(0) cv2.destroyAllWindows()
import cv2
import face_recognition
#读取人脸图片
img=cv2.imread("image/p3.png")
#检测人脸,返回人脸的坐标信息
face_List=face_recognition.face_locations(img)
print(face_List)
#获取人脸坐标
for x in face_List:
cv2.rectangle(img,(x[3],x[0]),(x[1],x[2]),(0,255,0),1)
qie_img=img[x[0]:x[2],x[3]:x[1]]
#保存图片
cv2.imwrite("save_image/save_p3.png",qie_img)
cv2.imshow("a",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
切割人脸
import face_recognition import cv2 #加载图片 image = cv2.imread("../face_train_images/ldh.jpg") #读取人脸位置 face_locations = face_recognition.face_locations(image) print(face_locations) for (top, right, bottom, left) in face_locations: # 画出人脸区域 cv2.rectangle(image, (left, top), (right, bottom), (0, 255, 0), 2) qg_image = image[top:bottom,left:right] # 显示结果 cv2.imshow("Detected Faces", qg_image) cv2.waitKey(0) cv2.destroyAllWindows()
提取人脸特征
`face_recognition.face_encodings(img, known_face_locations=None, num_jitters=1, model='small')`
-
功能:提取图像中人脸的特征向量。
-
参数
-
img
:图像的 NumPy 数组。 -
known_face_locations
:人脸位置的列表,如果为None
,则自动检测人脸位置。 -
num_jitters
:对每个人脸进行多次编码以提高精度。 -
model
:使用的模型,可以是'small'
或'large'
(默认)。
-
-
返回:一个列表,每个元素是一个 128 维的特征向量。
import face_recognition import cv2 #加载图片 image = cv2.imread("../face_train_images/ldh.jpg") #读取人脸位置 face_locations = face_recognition.face_locations(image) #提取人脸特征码 face_encodings = face_recognition.face_encodings(image)[0] print(face_encodings)
计算人脸的欧几里得距离
import face_recognition import cv2 import numpy as np #加载图片 image1 = cv2.imread("../face_train_images/ldh.jpg") #读取人脸位置 face_locations1 = face_recognition.face_locations(image1) #提取人脸特征码 face_encodings1 = face_recognition.face_encodings(image1)[0] #加载图片 image2 = cv2.imread("../face_train_images/4.jpg") #读取人脸位置 face_locations2 = face_recognition.face_locations(image2) #提取人脸特征码 face_encodings2 = face_recognition.face_encodings(image2)[0] # 计算两个人脸编码之间的欧几里得距离。 distance = np.linalg.norm(face_encodings1 - face_encodings2) print(distance)
欧几里得距离
欧几里得距离(Euclidean distance)是一种测量两个点之间直线距离的方式,常用于数学、物理学和计算机科学中的各种应用,包括机器学习中的数据点距离计算。它是基于欧几里得几何的概念,通常用于计算空间中两点之间的距离。
应用
-
数据分析: 欧几里得距离常用于计算数据点之间的距离,例如在聚类算法(如K均值聚类)中。
-
计算机视觉: 在人脸识别等任务中,欧几里得距离用于计算特征向量之间的相似度。
-
优化: 在路径规划和优化问题中,计算两点之间的欧几里得距离可以帮助寻找最短路径。
欧几里得距离的意义
-
距离越小,相似度越高:
-
特征向量相似:当欧几里得距离越小说明两个特征向量之间的差异越小,即这两个人脸在特征空间中很接近。因此,这两个图像可能是同一个人或者相似度很高。
-
相同身份的概率大:在许多人脸识别系统中,如果计算出的距离小于某个设定的阈值,则系统会认为这两个面孔属于同一个人。
-
-
距离阈值:
-
匹配判断:通常,系统会设置一个阈值来判断两个特征向量是否属于同一身份。如果计算出的距离小于这个阈值,则认为两张图片中的人脸是相同的;如果距离大于阈值,则认为是不同的身份。
-
误识别率:设置的阈值会影响系统的误识别率(假阳性和假阴性率)。距离阈值的选择需要根据具体应用场景进行调整。
-
计算人脸匹配程度
face_recognition.compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6)
-
功能:比较已知人脸特征向量和待检测人脸特征向量,判断是否匹配。
-
参数
-
known_face_encodings
:已知人脸特征向量的列表。 -
face_encoding_to_check
:待检测的人脸特征向量。 -
tolerance
:匹配的阈值,范围是 0.0 到 1.0,值越小表示匹配要求越高。
-
-
返回:一个布尔值列表,表示待检测人脸特征向量是否与已知人脸特征向量匹配
import face_recognition
import cv2
#提取已知人脸图片
known_image = image1 = cv2.imread("../face_train_images/ldh.jpg")
#提取提取已知人脸图片的人脸特征码
face_encodings1 = face_recognition.face_encodings(known_image)[0]
#提取未知人脸图片
unknown_image = image1 = cv2.imread("../face_train_images/1.jpg")
#提取未知人脸图片的人脸特征码
face_encodings2 = face_recognition.face_encodings(unknown_image)
#计算是否匹配
results = face_recognition.compare_faces([face_encodings1], face_encodings2[0],tolerance=0.5)
print(results)
注意:
提取提取已知人脸图片的人脸特征码要获取下标未 0 的数值
提取未知人脸图片的人脸特征码 不获取小标
在计算匹配的时候传入到函数的参数,已知人脸图片的人脸特征码 获取放入到列表中,未知获取下标未0
图片预处理
如果对图片进行,
import face_recognition import cv2 import numpy as np #加载图片 image1 = cv2.imread("../face_train_images/ldh.jpg") # 使用 OpenCV 进行图像预处理 gray_image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY) #使用高斯滤波去除噪声 gs_img1 =cv2.GaussianBlur(gray_image1,(3,3),0) image1 = cv2.cvtColor(gs_img1,cv2.COLOR_GRAY2BGR) #读取人脸位置 face_locations1 = face_recognition.face_locations(image1) #提取人脸特征码 face_encodings1 = face_recognition.face_encodings(image1)[0] #加载图片 image2 = cv2.imread("../face_train_images/1.jpg") # 使用 OpenCV 进行图像预处理 gray_image2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY) #使用高斯滤波去除噪声 gs_img2 =cv2.GaussianBlur(gray_image2,(3,3),0) image2 = cv2.cvtColor(gs_img2,cv2.COLOR_GRAY2BGR) #读取人脸位置 face_locations2 = face_recognition.face_locations(image2) #提取人脸特征码 face_encodings2 = face_recognition.face_encodings(image2)[0] # 计算两个人脸编码之间的欧几里得距离。 distance = np.linalg.norm(face_encodings1 - face_encodings2) print(distance) #比对两张照片是否是同一个个人-欧几里得
import cv2
import numpy as np
import face_recognition
#读取人脸库原图的图片
img1=cv2.imread("face_train_images/1.jpg")
#灰度图像
g_img1=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
#双边滤波去噪
b_img1=cv2.bilateralFilter(g_img1,20,1,30)
#把图像转换为BGR
a_img1=cv2.cvtColor(b_img1,cv2.COLOR_GRAY2BGR)
#提取人脸特征
face01=face_recognition.face_encodings(a_img1)[0]
print(face01)
#读取人脸库原图的图片
img2=cv2.imread("face_train_images/3.jpg")
g_img2=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
#双边滤波去噪
b_img2=cv2.bilateralFilter(g_img2,20,1,30)
#把图像转换为BGR
a_img2=cv2.cvtColor(b_img2,cv2.COLOR_GRAY2BGR)
#提取人脸特征向量
face02=face_recognition.face_encodings(a_img2)[0]
#计算欧几里得距离
v=np.linalg.norm(face01-face02)
print(v)
#阈值根据实际情况做调整
if v<0.5:
print("是一个人")
else:
print("不是一个人")
import cv2
import numpy as np
import face_recognition
#读取人脸库原图的图片
img1=cv2.imread("face_train_images/1.jpg")
#灰度图像
g_img1=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
#双边滤波去噪
b_img1=cv2.bilateralFilter(g_img1,20,40,50)
#把图像转换为BGR
a_img1=cv2.cvtColor(b_img1,cv2.COLOR_GRAY2BGR)
#提取人脸特征
face01=face_recognition.face_encodings(a_img1)[0]
print(face01)
#读取人脸库原图的图片
img2=cv2.imread("face_train_images/3.jpg")
g_img2=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
#双边滤波去噪
b_img2=cv2.bilateralFilter(g_img2,20,40,50)
#把图像转换为BGR
a_img2=cv2.cvtColor(b_img2,cv2.COLOR_GRAY2BGR)
#提取人脸特征向量
face02=face_recognition.face_encodings(a_img2)[0]
iss=face_recognition.compare_faces([face01],face02,tolerance=0.5)
print(iss)
#视频人脸检测
import cv2
#开启摄像头
c=cv2.VideoCapture(0)
while(True):
ret,frame=c.read()
if ret:
#显示图片
cv2.imshow("a",frame)
if cv2.waitKey(30)==27:
break
if cv2.waitKey(30)==113:
# 保存人脸
iss = cv2.imwrite("save_images_renlian/renlian01.png", frame)
#iss = cv2.imwrite("D:\\images\\renlian01.png", frame)
# 新建的存放保存的图片要用英文路径,例如:D:\\images\\renlian01.png
if iss == True:
print("收集人脸成功")
else:
print("收集人脸失败")
cv2.destroyAllWindows()
#视频人脸比对识别
import cv2
import face_recognition
import os
import numpy as np
# 开启摄像头
c = cv2.VideoCapture(0)
while (True):
ret, frame = c.read()
if ret:
# 显示图片
cv2.imshow("a", frame)
if cv2.waitKey(30) == 27:
break
if cv2.waitKey(30) == 113:
# 检测人脸
face_list = face_recognition.face_locations(frame)
if len(face_list) > 0:
print("检测到人脸")
# 遍历目录,查找人脸
path = os.listdir("save_images_renlian")
#path = os.listdir("D:\\images")
print(path)
for i in path:
# 获取人脸特征
img=cv2.imread(f"save_images_renlian/{i}")
#img = cv2.imread(f"D:\\images\\{i}")
en1=face_recognition.face_encodings(img)[0]
en2=face_recognition.face_encodings(frame)[0]
iss=np.linalg.norm(en1-en2)
print(iss)
if iss<0.5:
print("是同一个人")
else:
print("不是同一个人")
cv2.destroyAllWindows()