【一起学】实时人脸识别项目(10)视频流匹配人脸代码

用 Python 实现视频流中逐帧识别匹配的人脸

本文通过实际代码案例,详细解析如何利用face_recognition库根据人脸特征点匹配实现视频中寻人的效果,帮助读者快速掌握相关技术要点。

环境搭建 

在开始之前,请确保你的开发环境中已安装face-recognition和opencv库。可以通过以下命令安装:

pip install face-recognition opencv-python

代码实现与解析

完整代码
import face_recognition
import cv2


input_movie = cv2.VideoCapture('presentation.mp4')
if not input_movie.isOpened():
    print("error")
    exit()
length = int(input_movie.get(cv2.CAP_PROP_FRAME_COUNT))

fourcc = cv2.VideoWriter.fourcc(*'XVID')

output_movie = cv2.VideoWriter('output.avi', fourcc, 60, (1920,1080))

trump_image = face_recognition.load_image_file('trump.jpg')
trump_face_encoding = face_recognition.face_encodings(trump_image)[0]

obama_image = face_recognition.load_image_file('obama.jpg')
obama_face_encoding = face_recognition.face_encodings(obama_image)[0]

known_faces = [
    trump_face_encoding,
    obama_face_encoding
]

face_locations = []
face_encodings = []
face_names = []
frame_number = 0

while True:
    ret,frame = input_movie.read()
    frame_number +=1

    if not ret:
        break
    rgb_frame = frame[:, :, ::-1]
    face_locations = face_recognition.face_locations(rgb_frame)
    face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)

    face_names = []

    for face_encoding in face_encodings:
        match = face_recognition.compare_faces(known_faces, face_encoding, tolerance=0.5)

        name = None
        if match[0]:
            name = "Trump"
        elif match[1]:
            name = 'Obama'

        face_names.append(name)

    for (top, right, bottom, left), name in zip(face_locations, face_names):
        if not name:
            continue

        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
        cv2.rectangle(frame, (left, bottom - 25), (right, bottom), (0, 0, 255), cv2.FILLED)
        font = cv2.FONT_HERSHEY_DUPLEX
        cv2.putText(frame, name, (left + 6, bottom - 6), font, 0.5, (255, 255, 255), 1)

    print('writing frame {}/{}'.format(frame_number, length))
    output_movie.write(frame)

input_movie.release()
output_movie.release()
cv2.destroyAllWindows()
代码解读
1 视频读取与输出设置
input_movie = cv2.VideoCapture('presentation.mp4')
if not input_movie.isOpened():
    print("error")
    exit()
length = int(input_movie.get(cv2.CAP_PROP_FRAME_COUNT))

fourcc = cv2.VideoWriter.fourcc(*'XVID')
output_movie = cv2.VideoWriter('1.avi', fourcc, 60, (1920,1080))

使用 OpenCV 的cv2.VideoCapture方法打开输入视频文件 "presentation.mp4"。通过input_movie.isOpened()方法检查视频是否成功打开,若未打开则输出错误信息并退出程序。接着,通过length = int(input_movie.get(cv2.CAP_PROP_FRAME_COUNT))获取视频的总帧数,以便后续在处理过程中能够实时显示进度。

2 加载已知人脸图像并提取特征
trump_image = face_recognition.load_image_file('trump.jpg')
trump_face_encoding = face_recognition.face_encodings(trump_image)[0]

obama_image = face_recognition.load_image_file('obama.jpg')
obama_face_encoding = face_recognition.face_encodings(obama_image)[0]

known_faces = [
    trump_face_encoding,
    obama_face_encoding
]

在进行视频中人脸的识别之前,需要先加载已知的人脸图像,并提取其特征。这里分别加载了 "trump.jpg" 和 "obama.jpg" 两张图片,分别代表特朗普和奥巴马。使用方法face_recognition.load_image_file加载图片,然后通过方法提取图片中人脸的特征编码。这些特征编码是后续进行人脸比对的关键依据,将它们存储到known_faces列表中,以便在视频帧中检测到人脸时进行比对识别。

视频帧处理与人脸检测识别
while True:
    ret,frame = input_movie.read()
    frame_number +=1

    if not ret:
        break
    rgb_frame = frame[:, :, ::-1]
    face_locations = face_recognition.face_locations(rgb_frame)
    face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)

进入循环,逐帧读取视频。通过input_movie.read()方法读取每一帧,ret表示读取是否成功,frame是读取到的帧图像。若读取失败(即视频结束),则退出循环。

为了提高人脸检测的速度,先将每一帧图像从 BGR 格式转换为 RGB 格式库要求输入为 RGB 格式),接着,使用face_recognition.face_locations方法在图像中检测人脸的位置,得到人脸的坐标框。最后,使用face_recognition.face_encodings方法提取当前帧中检测到的人脸的特征编码,以便后续与已知人脸特征进行比对。

for face_encoding in face_encodings:
    match = face_recognition.compare_faces(known_faces, face_encoding, tolerance=0.5)

    name = None
    if match[0]:
        name = "Trump"
    elif match[1]:
        name = 'Obama'

    face_names.append(name)

对于当前帧中检测到的每一个人脸特征编码,使用face_recognition.compare_faces方法与已知的人脸特征列表known_faces进行比对。tolerance参数指定了比对的容差阈值,值越小,比对越严格。根据比对结果,确定当前人脸对应的名称,若与第一个已知人脸特征匹配,则名称为 "Trump";若与第二个已知人脸特征匹配,则名称为 "Obama";若都不匹配,则名称为None。将识别到的名称存储到face_names列表中,与人脸坐标框一一对应。 

for (top, right, bottom, left), name in zip(face_locations, face_names):
    if not name:
        continue

    cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
    cv2.rectangle(frame, (left, bottom - 25), (right, bottom), (0, 0, 255), cv2.FILLED)
    font = cv2.FONT_HERSHEY_DUPLEX
    cv2.putText(frame, name, (left + 6, bottom - 6), font, 0.5, (255, 255, 255), 1)

遍历人脸坐标框和对应的名称,若名称不为空(即识别到了已知人物),则在原始帧图像上绘制矩形框来标记人脸位置,矩形框的颜色为红色(BGR 格式下的 (0, 0, 255))。同时,在矩形框下方绘制一个填充的矩形区域,用于显示人物名称,字体颜色为白色((255, 255, 255)),字体大小为 0.5,字体类型为cv2.FONT_HERSHEY_DUPLEX 这样,识别到的人物名称就会清晰地显示在人脸下方。

print('writing frame {}/{}'.format(frame_number, length))
output_movie.write(frame)

在处理完每一帧后,输出当前帧的处理进度(当前帧数与总帧数的比例)。然后,通过output_movie.write(frame)方法将绘制了识别结果的帧写入到输出视频文件中。 

4 资源释放
input_movie.release()
output_movie.release()
cv2.destroyAllWindows()

当所有帧都处理完成并写入输出视频后,释放输入视频和输出视频的资源,关闭所有 OpenCV 创建的窗口,以确保程序正常结束,避免资源泄漏等问题。

结果

通过运行上述代码,我们可以得到一个新的视频文件 "output.avi",其中在原始视频的基础上,对检测到的特朗普和奥巴马人脸进行了标注。


作者每周更新栏目文章,和读者一起从原理剖析到代码实践,完整实现实时人脸识别项目。

若您对文章内容有疑问,或发现文章中存在错误,请您指出,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值