自学内容网 自学内容网

python opencv4

四、人脸识别操作

        import face_recognition 

        使用 HOG 特征或 CNN(卷积神经网络)进行人脸检测,提取人脸的特征向量(128维),并用于比较不同人脸之间的相似度

1、检测人脸 face_locations

        face_recognition.face_locations(img, number_of_times_to_upsample=1, model='hog')

number_of_times_to_upsample`:图像上采样的次数,用于提高检测精度。

model:使用的模型,可以是 'hog'(默认)或 'cnn'。

返回一个列表,每个元素是一个 (top, right, bottom, left) 的元组,表示人脸的位置。

# 获取人脸图片
img = cv2.imread('images/p3.png')
# 检测人脸信息
face_list = face_recognition.face_locations(img, model='hog')
print(face_list)
# 根据坐标进行裁剪脸部图片
for face in face_list:
    y, w, h, x = face
    cv2.rectangle(img, (x, y), (w, h), (0, 255, 0), 2)
    qie_img = img[y:h, x:w]
    # 保存图片
    cv2.imwrite('../../save_images/p3.png', qie_img)
cv2.imshow('img', img)
cv2.imshow('qie_img', qie_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

2、提取脸部特征 face_encodings

        face_recognition.face_encodings(img, known_face_locations=None, num_jitters=1, model='small')

known_face_locations:人脸位置的列表,如果为 None,则自动检测人脸位置。

num_jitters:对每个人脸进行多次编码以提高精度。

model:使用的模型,可以是 'small''large'(默认)。

返回一个列表,每个元素是一个 128 维的特征向量。

img1 = cv2.imread('face_train_images/1.jpg')
face01 = face_recognition.face_encodings(img1, num_jitters=1)
print(face01)

3、欧几里得距离 linalg.norm

        numpy 库的函数

        测量两个点之间直线距离的方式,机器学习中的数据点距离计算;在人脸识别等任务中,欧几里得距离用于计算特征向量之间的相似度。

距离越小,相似度越高,相同身份的概率更大:欧几里得距离越小说明两个特征向量之间的差异越小,两个图像可能是同一个人或者相似度很高;距离小于某个设定的阈值,则系统会认为这两个面孔属于同一个人。

距离阈值:距离大于阈值,则认为是不同的身份。

img1 = cv2.imread('face_train_images/1.jpg')
img2 = cv2.imread('face_train_images/2.jpg')
face01 = face_recognition.face_encodings(img1, num_jitters=1)
face02 = face_recognition.face_encodings(img2, num_jitters=1)
# 计算欧几里得距离
v = np.linalg.norm(face01[0]-face02[0])
print(v)
if v < 0.4:
    print("同一个人")
else:
    print("不是同一个人")

4、人脸匹配程度 compare_faces

        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,值越小表示匹配要求越高。

返回布尔值列表,表示待检测人脸特征向量是否与已知人脸特征向量匹配。

img1 = cv2.imread('../../face_train_images/1.jpg')
img2 = cv2.imread('../../face_train_images/2.jpg')
# 转灰度
g_img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
g_img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# 双边滤波
b_img1 = cv2.bilateralFilter(g_img1, 9, 75, 75)
b_img2 = cv2.bilateralFilter(g_img2, 9, 75, 75)
# 灰度转BGR
a_img1 = cv2.cvtColor(b_img1, cv2.COLOR_GRAY2BGR)
a_img2 = cv2.cvtColor(b_img2, cv2.COLOR_GRAY2BGR)
# 提取人脸特征向量
face01 = face_recognition.face_encodings(a_img1, num_jitters=1)
face02 = face_recognition.face_encodings(a_img2, num_jitters=1)[0]
# 计算是否匹配
test = face_recognition.compare_faces(face01, face02, 0.5)
print(test)
v = np.linalg.norm(face01-face02)
print(v)

5、视频中的人脸检测

i = 0
while True:
    ret, frame = c.read()
    # c.read() 返回一个元组,第一个元素为布尔值,第二个元素的数组
    if ret:
        # 显示图片数组信息
        cv2.imshow('frame', frame)
        # 间隔 0.5 秒刷新图片
        cv2.waitKey(20)
        i += 500
        # 调用人脸识别判断是否获取到内容
        face_list = face_recognition.face_locations(frame)
        if face_list is not None and 3500 < i < 5500:
            print("检测到人脸")
            break
        elif face_list is not None and i <= 3500:
            continue
        else:
            print("未检测到人脸")

6、视频人脸与图像匹配

import cv2
import face_recognition
import os
import numpy as np

# 初始化视频捕捉
c = cv2.VideoCapture(0)


def load_known_faces(directory):
    known_faces = {}
    for filename in os.listdir(directory):
        img_path = os.path.join(directory, filename)
        img = cv2.imread(img_path)
        face_encodings = face_recognition.face_encodings(img)
        if face_encodings:
            known_faces[filename] = face_encodings[0]
    return known_faces


def recognize_face(frame, known_faces):
    face_locations = face_recognition.face_locations(frame)
    if not face_locations:
        return None, None

    face_encodings = face_recognition.face_encodings(frame, face_locations)

    for face_encoding in face_encodings:
        for name, known_encoding in known_faces.items():
            distance = np.linalg.norm(face_encoding - known_encoding)
            if distance < 0.3:
                return name, distance
    return None, None


known_faces = load_known_faces('图片路径')

while True:
    ret, frame = c.read()
    if not ret:
        break

    cv2.imshow('frame', frame)

    # 按下 'q' 开始人脸识别
    if cv2.waitKey(20) == ord('q'):
        name, distance = recognize_face(frame, known_faces)
        if name:
            print(f"该人脸信息存在: {name}, 距离: {distance}")
            break
        else:
            print("该人脸信息不存在,将此照片存储")
            cv2.imwrite("图片路径\\renwutest.png", frame)
            break

    # 使用 esc 直接退出程序
    if cv2.waitKey(1) == 27:
        break

c.release()
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('frame', frame)
        # 按 q 开始使用视频图片验证是否匹配
        if cv2.waitKey(20) == 113:
            # 获取人脸特征信息
            face_list = face_recognition.face_locations(frame)
            if len(face_list) > 0:
                print("检测到人脸")
                face0 = face_recognition.face_encodings(frame)

                # 遍历目录,查找存储的人脸图片信息
                path_list = os.listdir('图片路径')
                iss = 0
                for i in path_list:
                    # 获取检测人脸与目录人脸对比信息
                    img1 = cv2.imread(f"图片路径\\{i}")
                    face1 = face_recognition.face_encodings(img1)
                    iss = np.linalg.norm(face0[0] - face1[0])
                    if iss < 0.3:
                        print(f"{iss},该人脸信息存在,{i}")
                        break
                if iss < 0.3:
                    break
                else:
                    print("该人脸信息不存在,将此照片存储")
                    cv2.imwrite("图片路径\\renwutest.png", frame)
                    break

        # 使用 esc 直接退出程序
        if cv2.waitKey(1) == 27:
            break
 


原文地址:https://blog.csdn.net/h0039490/article/details/143520587

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!