Centerface + Facenet实现视频人脸识别(附代码)

Centerface + Facenet实现视频人脸识别

Facenet的pytorch版本:GitHub地址:https://github.com/timesler/facenet-pytorch
CenterFace:GitHub地址:https://github.com/Star-Clouds/CenterFace

我是先跑通Centerface做人脸检测,发现效果还可以,然后跑人脸识别项目facenet,发现其中的人脸检测模型MTCNN效果好像没有centerface好,然后就用centerface替换了Facenet中的MTCNN人脸检测算法,发现效果确实更好一点。
两个项目跑通都比较容易,可以去网上找博客或者好好读读官方文档即可。当然,你可以用你自己喜欢的人脸检测和识别算法,自己组合,但前提是你首先得理解读懂别人的项目,然后才能开始改。
这里主要是对用Centerface做检测和Facenet做识别的新组合做解释。(项目是在Facenet原有基础上做改动)

项目结构介绍

改动后的项目结构和Facenet原有项目结构一致,不同的是将Centerface中的用于检测的脚本文件cnterface.py和与训练模型centerface.onnx复制到该项目下。我把centerface.py放到examples文件夹下,centerface.onnx放到models文件夹下。
在这里插入图片描述 在这里插入图片描述
data文件夹下是自己建的一些数据库,可以用爬虫脚本自动创建,后面会给出代码。
以DB1为例

  • DB1_images是存放的原始人脸数据,就是直接从网上下载的人脸图片;
  • crooped存放的是剪切后的人脸图片,大小为160*160(这是facenet项目中要求的大小,想改的话你可以去好好看看项目代码,找到在哪改,我没改)
  • features下保存的是人脸特征向量和人脸标签(就是你的名字)
  • test下保存的是用来测试的图片,你建好一个人脸数据库之后,总要拿一些新的图片看看效果嘛
  • test_results保存测试结果
    这样子把数据库标准化以后,对后续的操作非常方便。比如你要增加一个新的人脸数据库,或者向现有的书库中添加人脸(本项目中想做但还没做的,应该也不难,就是求出新人脸的特征向量,然后将新的人脸特征添加到对应数据库的文件中即可)
    在这里插入图片描述

项目重要脚本介绍

face_database.py
该脚本是用于创建人脸特征数据库的,即对一个人脸数据集,计算出每个人脸的特征向量并保存,用于后续识别。

from facenet_pytorch import MTCNN, InceptionResnetV1
import torch
from torch.utils.data import DataLoader
from torchvision import datasets
import numpy as np
import pandas as pd
import os
from centerface import CenterFace, FaceExtract


# creat a new database
# 要保证数据库中的图片只有当前人脸
def CreatNewDB(DB_images_path, feature_path, cropped_save_pth=None):
    # 定义了一个数据集
    # 读取路径下的所有文件夹,每一个文件夹为一个类别,有对应的标签index
    # 所有文件夹下的图片按顺序都存储在dataset中,dataset为可遍历对象,每张图片的格式为元祖(data,label)
    dataset = datasets.ImageFolder(DB_images_path)

    # dataset.class_to_idx将类别转化为数字索引
    dataset.idx_to_class = {
   i: c for c, i in dataset.class_to_idx.items()}
    # 定义一个数据加载器,一张图片表示为(data,label)的元祖
    loader = DataLoader(dataset, collate_fn=collate_fn, num_workers=workers)
    names = []
    for name in dataset.class_to_idx.keys():
        names.append(name)
    # 保存所有剪裁过后的人脸,用于求特征向量
    cropped_faces = []
    # 每个类别的人脸数
    num_each_class = 10
    # image为图片,index为name对应的标签
    j = 0
    for image, index in loader:
        centerface = CenterFace()
        w, h = image.size
        boxes, lms = centerface(image, h, w, threshold=0.6)
        print(f"{names[index]} 检测人脸数:{len(boxes)}")
        extractFace = FaceExtract()
        resnet = InceptionResnetV1(pretrained='vggface2').eval().to(device)

        # j表示一个name下的第几张图片

        # i表示第几个人脸框
        for i, box in enumerate(boxes):
            box, score = box[:4], box[4]
            # 存储cropped face,创建文件夹
            path = cropped_save_pth + dataset.idx_to_class[index]
            if not os.path.exists(path):
                os.makedirs(path)
            save_path = path + f'/{j}.jpg'
            # face为tensor
            face = extractFace(image, box=box, save_path=save_path)
            cropped_faces.append(face)
            # tensor([[...]])
            #face_embedding = resnet(face.unsqueeze(0)).detach()
            # 每张图片只保存一个人脸向量
            #embedings.append(face_embedding[0])
        j += 1
        # break
        if j % num_each_class == 0:
            j = 0

    aligned = torch.stack(cropped_faces).to(device)
    # 返回所有人脸的特征向量,每个向量的长度是512维
    embedings = resnet(aligned).detach().cpu()

    # 一个人有多个人脸,求平均特征向量
    # [tensor([...])]
    mean_embedings = []
    for i in range(len(dataset.idx_to_class)):
        emd = embedings[i * num_each_class:(i + 1) * num_each_class].mean(0)        # ???
        mean_embedings.append(emd)

    # dicts = [[(e1 - e2).norm().item() for e2 in mean_embedings] for e1 in mean_embedings]
    # print(pd.DataFrame(dicts, columns=names, index=names))
    if not os.path.exists(feature_path):
        os.makedirs(feature_path)
    # 将人脸特征向量和标签保存下来
    # 人脸特征向量和标签的index保持一致
    # names中的顺序应该和数据集类别的顺序相同
    torch.save(mean_embedings, feature_path + 'features.pt')
    torch.save(names, feature_path + 'names.pt')


# add a new face to existing database
def AddNewFace2DB():
    a = 1


# 将一个list的sample组成一个mini-batch的函数
def collate_fn(x):
    return x[0]


if __name__ == "__main__":
    # os.name返回当前操作系统名字,nt为Windows,posix为linux
    # 线程数
    workers = 0 if os.name == 'nt' else 4
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print(f"Running on {device}")

    DB = 3
    DB_path = f"../data/DB{DB}_images_school/"
    cropped_path = f"../data/DB{DB}_images_cropped/"
    feature_path = f"../data/DB{DB}_features/"
    CreatNewDB(DB_path, feature_path, cropped_path)

test_new_face.py
该脚本用于识别测试集中的人脸。实现了三个函数:detect_one用于识别单张图片,detect_multi识别一个数据集,detect_videos用于视频人脸识别。

from facenet_pytorch import MTCNN, InceptionResnetV1
import torch
from PIL import ImageDraw, Image, ImageFont
from torchvision import datasets
from torch.utils.data import DataLoader
import os
import time
import cv2
import numpy as np
from centerface import CenterFace, FaceExtract


# mtcnn = MTCNN(keep_all=True)

# 识别单张图片
def detect_one(img, names, embeddings):
    # 定义检测和识别人脸模型
    centerface = CenterFace(landmarks=True)
    extractFace = FaceExtract()
    resnet = InceptionResnetV1(pretrained='vggface2').eval()

    # 自定义字体格式
    fontStyle = ImageFont.truetype("SIMYOU.TTF", 24)

    # Image对象读大小
    w, h = img.size
    boxes, lms = centerface(img, h, w, threshold=0.5)

    # face = mtcnn(img)
    # boxes, prob = mtcnn.detect(img)  # 人脸检测器,直接返回人脸的位置坐标和概率

    frame_draw = img.copy()
    draw = ImageDraw.Draw(frame_draw)
    print("检测人脸数目:", len(boxes))
    for i, box in enumerate(boxes):
        # 人脸框,分数
        box, score = box[:4], box[4]
        x1, y1, x2, y2 = box
        draw.rectangle(box, outline=(255, 0, 0), width=2)

        # 人脸提取,返回的是标准化后的tensor
        face = extractFace(frame_draw, box=box)
        # 增加tensor维度,resnet输入参数为4维
        face_embedding = resnet(face
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
可部署到云主机(Heroku,AWS……)! 使用dlib最先进的面部识别功能构建而成,具有深度学习功能。该模型在Wild标记的Labeled Faces中具有99.38%的准确度 。 这提供了一个简单的命令行工具,允许从命令行对图像文件夹进行面部识别! 1、找到图片中出现的所有面孔 2、获取每个人的眼睛,鼻子,嘴巴和下巴的位置和轮廓。 3、应用数字化妆 4、识别每张照片中出现的人物。 5、可以将此库与其他Python库一起使用来进行实时人脸识别。 使用要求 Python 3.3+或Python 2.7 macOS或Linux(Windows未正式支持,但可能有效) 人脸检测 在照片中找到面孔 在照片中找到面孔(使用深度学习) 使用GPU(使用深度学习)批量查找图像中的面孔 使用网络摄像头模糊实时视频中的所有人脸(需要安装OpenCV) 面部特征 识别照片中的特定面部特征 应用(可怕的丑陋)数字化妆 面部识别 根据已知人物的照片查找并识别照片中的未知面部 识别并在照片中的每个人周围绘制框 通过数字面部距离比较面部而不仅仅是真/假匹配 使用网络摄像头识别实时视频中的人脸 - 简单/慢速版本(需要安装OpenCV) 使用网络摄像头识别实时视频中的人脸 - 更快的版本(需要安装OpenCV) 识别视频文件中的面部并写出新的视频文件(需要安装OpenCV) 用相机识别Raspberry Pi上的脸部 运行Web服务以通过HTTP识别面部(需要安装Flask) 使用K近邻分类器识别面部
本文的视频人脸检测识别方法的基本设计思想是,在给出一段视频文件以及这个视频文件的字幕和剧本之后,可以自动的对视频中的人物进行检测和识别,不需要任何的训练样本。视频人脸检测识别方法主要由四个部分组成:字幕剧本融合部分,人脸检测部分,样本集自动生成部分和基于深度学习的人脸识别部分。本文将深度学习算法引入到了视频人脸识别中来,有两方面的重要意义,一方面,视频人脸识别要求算法具备一定的抗干扰能力,并且能够保证一定的实时性,本文的实验与分析表明,深度学习算法具备这方面的要求;另一方面,从深度学习算法特性的角度来说,深度学习算法最大的缺点就是构造深度模型需要大量的样木,这很大程度上限制了深度学习算法的应用,然而本文所设计的基于视频人脸检测模块可以轻松的产生数万、数十万的样本,从而满足了深度学习算法的大样本集要求。 基于深度学习模型的人脸识别部分是整个系统的重点,这一部分主要有两方面的意义:一,经历了视频人脸的检测部分之后,虽然视频人脸集合中人脸的纯度有了很大的提升,但是依然会存在一些杂质,因此必须通过识别模块来进一步的过滤掉人脸集合中的杂质;二,通过视频所得到的帧文件中,经常会出现多张人脸同时出现的情况,在这种情况下,视频人脸的检测部分是无法将说话者与人脸进行对应的,必须通过识别模块才能区分出一个帧中的多个人脸。 基于深度学习模型的人脸识别部分主要包含三个模块:数据预处理模块、深度学习模块和识别模块。数据预处理模块主要由数据整合和构造数据立方体两个部分组成。深度学习模块通过两个具体过程来实现:RBM调节和深度模型的反馈微调。RBM的调节过程是自下而上的各个层间的调节过程,以这种方式来初始化整个深度模型的系统权值,而深度模型的反馈微调,首先进行自下而上的识别模型转换,然后再进行自上而下的生成模型转换,最后通过不同层次之间的不断调节,使生成模型可以重构出具有较低误差的原样本,这样就得到了此样本的本质特征,即深度模型的最高抽象表示形式。经过深度学习模型的处理,可以得到降维之后的样本特征,在此基础上运用识别模块,本文中所采用的识别方法是人工神经网络的识别方法。
Python是一种高级编程语言,并且非常适合进行人工智能领域的开发。MTCNN (多任务级联卷积神经网络) 是一种用于人脸检测、对齐和识别的深度学习模型。Facenet是一种基于卷积神经网络的人脸识别模型,该模型可以将两张不同的人脸图片转换为同一向量空间中的两个不同点。SVM(Support Vector Machine)是一种监督式学习算法,它的主要目标是将训练集中的不同类别数据分隔开来,以便将来被识别的新的样本能够被正确分类。 在这个项目中,我们使用Python编程语言和上述技术来实现人脸识别系统。首先,我们使用MTCNN对输入图像进行了人脸检测和对齐,即找到并将人脸图像转换为标准大小,然后使用Facenet来将图像转换为向量表示。 接下来,我们使用支持向量机 (SVM)算法对向量进行分类并预测所属人脸的标签。如果已知标签,则可以将标签与输出进行比对,从而确认识别结果是否正确。 在实际项目中,我们面对的是不同的人脸照片,这些照片具有各种不同的外观和表情。为了提高识别准确性,我们引入了数据增强技术,例如旋转、缩放、剪切等操作,从而增加了机器学习模型的训练数据量。此外,我们还通过t-SNE降维可视化技术来研究不同人脸图像在高维特征空间的不同分布,从而更好地理解人脸识别模型的工作原理。 总的来说,Python基于MTCNN、Facenet、SVM等算法进行人脸识别项目实战,是一项非常有挑战性的任务。然而,随着深度学习技术的不断进步,越来越多的人脸识别项目可以得到解决。从这个意义上说,这项任务带给我们的启示是,通过深度学习算法和多种技术手段的结合,我们可以构建更加高效和智能的人脸识别系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值