智能家居人脸识别系统--python (附源码)

开发工具与环境

选择使用Visual Studio Code作为主要的开发工具。
安装其他相关的工具和库,face_recognition和cv2: OpenCV ,它们分别用于面部识别和视频捕捉和图像处理。

整体架构流程

该程序采用模块化设计,其各模块函数功能如下:

load_target_images: 加载目标人物的图像并生成面部编码。
initialize_camera: 初始化摄像头并设置参数。
recognize_faces: 主要的面部识别和标注逻辑,包含一个无限循环,处理每一帧视频。
cleanup: 释放资源,关闭摄像头和窗口。
主程序main:调用上述函数,执行面部识别流程。

这种结构清晰易懂,便于后续维护和扩展。

其核心模块recognize_faces流程图如下:
在这里插入图片描述

核心数据结构

  • 面部特征编码 (face_encoding)
    数据类型: numpy.ndarray
    用途: 存储一个面部的128维特征向量,该特征向量用于表示面部的独特特征。
    face_recognition.face_encodings(image) 函数会返回一个包含所有检测到的面部特征编码的列表。每个编码是一个长度为128的浮点数数组,代表面部的独特特征。

  • 视频帧 (frame)
    数据类型: numpy.ndarray
    用途: 存储从摄像头捕捉到的单帧图像。
    video_capture.read()函数会返回两个值:ret 是一个布尔值,表示是否成功读取帧;frame是捕获到的图像,通常是一个三维数组,表示图像的高、宽和颜色通道(BGR格式)。

  • 面部位置 (face_locations)
    数据类型: list of tuple
    用途: 存储在图像中检测到的所有面部的位置,每个位置由一个包含四个整数的元组表示。
    face_recognition.face_locations(image)函数会返回一个包含所有检测到的面部位置的列表。每个位置由四个值组成的元组 (top, right, bottom, left),表示面部在图像中的位置。

  • 面部距离 (face_distance)
    数据类型: list of float
    用途: 存储一个面部特征编码与目标面部特征编码之间的距离。
    face_recognition.face_distance(known_face_encodings, face_encoding_to_check) 函数会返回一个列表,包含每个已知面部特征编码与待检查的面部特征编码之间的距离。距离越小,表示两个面部特征越相似。

核心算法解释

target_face_encoding1 = face_recognition.face_encodings(target_image1)[0]

对加载的目标图像target_image1进行面部编码,并提取该图像中的第一个面部特征编码。

  1. face_recognition.face_encodings(target_image1):
    函数作用: face_recognition.face_encodings是face_recognition库中的一个函数,用于从给定的图像中检测并提取面部特征编码。
    参数:
    target_image1: 这是之前加载的目标图像,以 NumPy 数组的形式表示。该图像包含了需要识别的目标人物的面部。
    返回值: 该函数返回一个列表,列表中的每个元素都是一个面部特征编码(长度为128的浮点数数组)。每个编码表示图像中一个检测到的面部。
    如果图像中有多个面部,这个列表会包含多个编码。
    如果图像中没有检测到面部,列表会是空的。

  2. [0]:
    作用: 索引操作,用于提取列表中的第一个元素。
    原因: 通常情况下,每张图像只包含一个目标面部。因此,我们只需要提取第一个(也是唯一一个)面部特征编码。如果图像中可能包含多个面部,这种操作需要小心,确保选择的是正确的面部特征编码。

  3. target_face_encoding1
    作用: 将提取到的第一个面部特征编码赋值给变量target_face_encoding1。
    用途:target_face_encoding1用于在后续的面部识别过程中,与实时捕获的视频帧中的面部特征编码进行比较,以确定视频帧中的面部是否与目标人物匹配。
    这行代码的核心在于将图像中检测到的面部特征编码提取出来,为后续的识别操作做准备。

ret, frame = video_capture.read()

从摄像头捕捉一帧视频图像。

  1. video_capture.read():
    函数作用: read()方法是 OpenCV 中 VideoCapture类的一部分,用于从视频流(通常是摄像头)中读取一帧图像。
    返回值:
    ret: 一个布尔值,表示读取是否成功。如果成功读取到一帧图像,则 ret为True,否则为False。
    frame: 读取到的视频帧,是一个 NumPy 数组,表示捕获的图像。它的作用是存储读取到的图像帧,是一个多维数组。通常情况下,这个数组的形状是 (height, width, 3),表示图像的高度、宽度和颜色通道(BGR格式)。
  2. 在使用 read()方法之前,需要初始化摄像头。例如:
    video_capture = cv2.VideoCapture(0) 这里,0通常表示默认的摄像头设备。如果有多个摄像头,可以传递不同的索引值来选择不同的设备。
  3. ret, frame = video_capture.read() 是一个用于从摄像头捕获视频帧的重要函数调用。ret表示捕获是否成功,frame存储捕获到的视频帧图像。该方法是实时视频处理和计算机视觉应用中非常常见的操作,用于获取摄像头的实时图像进行进一步处理。
face_locations = face_recognition.face_locations(frame)

检测图像帧中的所有面部位置。

face_recognition.face_locations(frame):
函数作用: 该函数用于在给定的图像(frame)中检测所有人脸的位置。
参数:
frame: 这是一个包含图像数据的NumPy数组,通常是从视频捕获设备读取的一帧图像。
返回值: 该函数返回一个列表,每个列表项是一个元组,表示检测到的一个面部的位置。每个返回的元组包含四个整数,分别表示面部在图像中的位置。具体格式如下:
(top, right, bottom, left)
top: 面部边界的上边缘的y坐标。
right: 面部边界的右边缘的x坐标。
bottom: 面部边界的下边缘的y坐标。
left: 面部边界的左边缘的x坐标。

frame 是从摄像头捕获的一帧图像,通常是一个三维的NumPy数组,形状为 (height, width, 3),表示图像的高度、宽度和颜色通道(BGR格式)。

face_recognition.face_locations(frame) 函数用于检测图像中的所有面部位置,并返回这些位置的坐标。每个面部位置由一个元组 (top, right, bottom, left) 表示,指示面部在图像中的具体位置。这些信息可以用于在图像上绘制面部边界框,或进行进一步的面部识别处理。

face_encodings = face_recognition.face_encodings(frame, face_locations)

在给定图像帧(frame)中的特定面部位置(face_locations)提取面部特征编码。

分解与解释:
face_recognition.face_encodings(frame, face_locations):
函数作用: 该函数用于在指定的面部位置提取面部特征编码(128维的向量),这些特征编码可以用于面部比较和识别。
参数:
frame: 包含图像数据的NumPy数组,通常是从视频捕获设备读取的一帧图像。
face_locations: 一个列表,包含图像中所有检测到的面部位置。每个位置用一个元组表示,格式为 (top, right, bottom, left)。
返回值: 返回一个列表,每个列表项是一个面部特征编码(长度为128的浮点数数组),对应于 face_locations 中的每个面部位置。每个面部特征编码是一个128维的浮点数数组,表示该面部的特征。这个编码是通过预训练的深度学习模型生成的,可以用于面部识别。

详细过程:
先输入图像和面部位置:frame 是从摄像头捕获的一帧图像。face_locations 是之前检测到的图像中所有面部的位置,每个位置用 (top, right, bottom, left) 表示。
然后调用 face_recognition.face_encodings 函数:该函数会处理输入的图像,并在指定的面部位置提取特征编码。返回的面部特征编码是一个128维的浮点数数组,可以用于面部比较和识别。这些编码可以在后续的步骤中与已知面部的编码进行比较,以实现面部识别功能。

face_distance1 = face_recognition.face_distance([target_face_encoding1], face_encoding) 

计算当前检测到的面部特征编码与目标面部特征编码之间的距离(即相似度)。
分解与解释:
face_recognition.face_distance([target_face_encoding1], face_encoding):
函数作用: 该函数用于计算两个面部特征编码之间的距离。距离越小,表示两个面部越相似。
参数:
[target_face_encoding1]: 一个列表,包含一个已知目标面部的特征编码。即目标面部的128维浮点数数组。
face_encoding: 当前检测到的面部特征编码,也是一个128维浮点数数组。
返回值: 返回一个包含距离值的NumPy数组。因为第一个参数是一个列表,所以返回的数组中每个元素表示face_encoding与列表中对应元素的距离。在这个例子中,返回的数组只有一个元素,即目标面部编码与当前面部编码的距离。
距离的意义:距离表示两个面部特征编码的相似度。通常来说,距离越小,表示两个面部越相似。距离越大,表示两个面部越不相似。

源代码

程序代码:

# 导入必要的库
import face_recognition
import cv2
import time  # 此处未使用,可以移除
from scipy.spatial import distance  # 此处未使用,可以移除

# 加载目标人群的图像并学习如何识别它们
def load_target_images():
    target_image1 = face_recognition.load_image_file("target_person1.jpg")
    target_face_encoding1 = face_recognition.face_encodings(target_image1)[0]
    
    target_image2 = face_recognition.load_image_file("target_person2.jpg")
    target_face_encoding2 = face_recognition.face_encodings(target_image2)[0]

    return target_face_encoding1, target_face_encoding2

# 初始化摄像头
def initialize_camera():
    video_capture = cv2.VideoCapture(0)
    video_capture.set(3, 620)  # 设置视频宽度
    video_capture.set(4, 240)  # 设置视频高度
    
    fps = 10  # 设置帧率为10帧每秒
    video_capture.set(cv2.CAP_PROP_FPS, fps)
    
    return video_capture

# 面部识别和标注
def recognize_faces(video_capture, target_face_encoding1, target_face_encoding2):
    while True:
        # 抓取一帧视频
        ret, frame = video_capture.read()
        
        # 将视频帧中的所有脸部位置找出来
        face_locations = face_recognition.face_locations(frame)
        face_encodings = face_recognition.face_encodings(frame, face_locations)
        
        # 在这个视频帧中的每个脸部上循环
        for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
            # 计算面部与目标面部的距离
            face_distance1 = face_recognition.face_distance([target_face_encoding1], face_encoding)
            face_distance2 = face_recognition.face_distance([target_face_encoding2], face_encoding)
            
            # 默认框颜色设置为蓝色
            box_color = (255, 0, 0)  # 蓝色框
            
            # 设置一个阈值
            if face_distance1[0] < 0.49:
                name = "Target 1"
            elif face_distance2[0] < 0.49:
                name = "Target 2"
            else:
                name = "Unknown"
            
            # 画框并标注结果
            cv2.rectangle(frame, (left, top), (right, bottom), box_color, 2)
            cv2.rectangle(frame, (left, bottom - 35), (right, bottom), box_color, cv2.FILLED)
            font = cv2.FONT_HERSHEY_DUPLEX
            cv2.putText(frame, name, (left + 6, bottom - 6), font, 0.5, (255, 255, 255), 1)
        
        # 显示结果图像
        cv2.imshow('Video', frame)
        
        # 按'q'退出循环
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

# 释放摄像头和关闭窗口
def cleanup(video_capture):
    video_capture.release()
    cv2.destroyAllWindows()

# 主程序
def main():
    target_face_encoding1, target_face_encoding2 = load_target_images()
    video_capture = initialize_camera()
    recognize_faces(video_capture, target_face_encoding1, target_face_encoding2)
    cleanup(video_capture)

if __name__ == "__main__":
    main()

注意,我们需要将待识别人脸照片放在和主程序同一文件夹下,路径不要有中文出现。

target_image1 = face_recognition.load_image_file("target_person1.jpg")

这里的target_person1.jpg是我要识别的照片文件名,可以根据需要添加多张待识别的人脸照片。

最后运行主程序,弹出识别窗口,将主机摄像头打开进行识别,若主机无自带摄像头可以购买外设摄像头。

感谢您的阅读,如有问题欢迎与作者联系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值