赞
踩
该算法由3个阶段组成:
第一阶段是使用一种叫做PNet(Proposal Network)的卷积神经网络,获得候选窗体和边界回归向量。同时,候选窗体根据边界框进行校准。然后利用非极大值抑制去除重叠窗体。
第二阶段是使用R-Net(Refine Network)卷积神经网络进行操作,将经过P-Net确定的包含候选窗体的图片在R-Net中训练,最后使用全连接网络进行分类。利用边界框向量微调候选窗体,最后还是利用非极大值抑制算法去除重叠窗体。
第三阶段,使用Onet(Output Network)卷积神经网络进行操作,该网络比R-Net多一层卷积层,功能与R-Net类似,只是在去除重叠候选窗口的同时标定5个人脸关键点位置。
MTCNN网络在经过3个卷积网络处理之前,先进行了多尺度变换,将一幅人脸图像缩放为不同尺寸的图片,这样就构成了图像金字塔。然后这些不同尺度的图像作为3个阶段的输入数据进行训练,这样可以令MTCNN检测到不同尺寸的人脸。MTCNN三个阶段所做的事情如下图:
NTCNN训练比较复杂,在代码中无需训练,直接使用现有模型即可达到满意效果。
论文地址:https://arxiv.org/pdf/1801.07698.pdf
论文代码:https://github.com/deepinsight/insightface
数据集:训练数据集:分别采用CASIA、VGGFACE2、MS1MV2、DeepGlint-Face(包括MS1M-Deepglin和Asian-Deepglin)
人脸验证数据集:LFW、YTF、CFP-FP、AGEDB-30
大姿态和大年龄数据集:CPLFW、CALFW
大规模图像数据集:MegaFace,IJB-B,IJB-C,Trillion-Pairs,iQIYI-VID(视频)
我们将特征向量L2归一化,权重L2归一化,他俩的夹角为θ,计算cos(θj),求反余弦arccos(θyi)得到特征xi与真实权值Wyi之间的夹角θyi,添加角度间隔m,再求余弦cos(θyj+m),将所有的log乘以特征尺度s,然后将logit送到softmax函数得到各类别概率。再用Ground Truth OneHot Vector一起算出交叉熵损失。
也就是DCNN特征和最后一个完全连接层之间的点积等于特征和权重归一化后的余弦距离。我们利用arc-cosine函数来计算当前特征和目标权重之间的角度。然后,在目标角上加上一个附加的角度间隔,用余弦函数重新计算逻辑回归的反向传播过程。然后,我们用一个固定的特征范数重新缩放。
同样的,提供现有模型,自己无需训练,目前支持resnet50,resnet18和mobilenet_v2模型。resnet50和resnet18参数量比较大,计算量较大,适合在PC服务器部署 ;而mobilenet_v2模型计算量较小,适合嵌入式,开发板,Android等终端部署。
├── common # 配置文件(设置检测模型,特征提取模型)、log
├── core
│ ├── alignment # 人脸校准算法
│ ├── detection # 人脸检测模型
│ ├── feature # 人脸特征提取模型
│ ├── face_detector.py # 人脸检测(支持MTCNN)
│ ├── face_feature.py # 人脸特征提取模型
│ ├── face_matcher.py # 人脸匹配算法
│ ├── face_recognizer.py # 人脸识别
│ └── face_register.py # 人脸注册
├── data # 人脸识别相关数据
├── face_search.py # 1:N人脸搜索Demo
├── register.py # 1:N人脸搜索人脸数据库注册Demo
├── README.md # 说明文档
└── requirements.txt # 项目依赖文件
Python依赖环境,使用pip安装即可
可能会有缺少依赖,需要自己补充
tornado
numpy
scikit-learn
pybaseutils
matplotlib
tqdm
toolz
tornado
#默认人脸数据库,图像存放在portrait = "./data/database/portrait"
#默认人脸数据库,特征文件保存在database='./data/database/database-resnet50.json'
python register.py
运行结果如下:
>>>>>>>>>>>>>开始注册人脸<<<<<<<<<<<<<<
file=./data/database/portrait\1.jpg-刘亦菲_1.jpg.jpg, 注册人脸:ID=1.jpg-刘亦菲
file=./data/database/portrait\1.jpg-刘德华_1.jpg.jpg, 注册人脸:ID=1.jpg-刘德华
file=./data/database/portrait\1.jpg-刘恺威_1.jpg.jpg, 注册人脸:ID=1.jpg-刘恺威
file=./data/database/portrait\1.jpg-刘诗诗_1.jpg.jpg, 注册人脸:ID=1.jpg-刘诗诗
file=./data/database/portrait\1.jpg-古力娜扎_1.jpg.jpg, 注册人脸:ID=1.jpg-古力娜扎
save database:./data/database\database11.17-resnet50.json
>>>>>>>>>>>>>完成注册人脸<<<<<<<<<<<<<<
如果需要注册新人 ,请参考如下步骤:
1.采集一张新人的个人照片,以张三的照片为例子
2.照片保存在人脸数据库中(data/database/portrait)中,图片按照[ID-XXXX.jpg]命名,如:张三-image.jpg,作为人脸识别的底图
3.然后运行register.py,完成人脸数据库的人脸注册
#待识别人脸图片存放在项目目录data/test_image
python face_search.py
import cv2 import traceback from core import face_recognizer from pybaseutils import image_utils class Example1(face_recognizer.FaceRecognizer): def __init__(self, database): """ @param database: 人脸数据库的路径 """ super(Example1, self).__init__(database=database) def start_capture(self, video_file, save_video=None, detect_freq=1, vis=True): """ start capture video :param video_file: *.avi,*.mp4,... :param save_video: *.avi :param detect_freq: :return: """ video_cap = image_utils.get_video_capture(video_file) width, height, numFrames, fps = image_utils.get_video_info(video_cap) if save_video: self.video_writer = image_utils.get_video_writer(save_video, width, height, fps) count = 0 while True: if count % detect_freq == 0: # 设置抽帧的位置 if isinstance(video_file, str): video_cap.set(cv2.CAP_PROP_POS_FRAMES, count) isSuccess, frame = video_cap.read() if not isSuccess: break frame, face_info = self.search_face_task(frame, thickness=4, fontScale=2.0, delay=10, vis=True) if save_video: self.video_writer.write(frame) count += 1 video_cap.release() def detect_image_dir(self, image_path, out_dir=None, vis=True): """ @param image_dir: @param out_dir: @param vis: @return: """ try: res = self.search_face_task(image_path, vis=vis) return res except: traceback.print_exc() def search_face_task(self, bgr, thickness=2, fontScale=1.5, delay=0, vis=False): """ 1:N人脸搜索任务 :param bgr: BGR image :return: """ face_info = self.detect_search(bgr, max_face=-1, vis=False) image = self.draw_result("Recognizer", image=bgr, face_info=face_info, thickness=thickness, fontScale=fontScale, delay=delay, vis=vis) return image
# -*-coding: utf-8 -*- import torch import os root = os.path.dirname(os.path.dirname(__file__)) det_thresh = 0.5 # 人脸检测阈值,小于该阈值的检测框会被剔除 rec_thresh = 0.5 # 人脸识别阈值,小于该阈值的人脸识别结果为unknown,表示未知 # 人脸检测模型,目前支持RFB和MTCNN人脸检测 DETECTOR = { # "net_name": "RFB", "net_name": "MTCNN", } # 人脸识别(特征提取)模型配置文件,目前支持resnet50,resnet18和mobilenet_v2模型 FEATURE = { "net_name": "resnet50", # "net_name": "resnet18", # "net_name": "mobilenet_v2", "input_size": (112, 112), "embedding_size": 512 } # 人脸数据库图像路径,用于注册人脸 portrait = "./data/database/portrait" # 人脸数据库特征路径database(注册人脸后生成的特征文件) database = os.path.join(os.path.dirname(portrait), "database-{}.json".format(FEATURE['net_name'])) # 运行设备 # device = "cpu" device = "cuda:0" if torch.cuda.is_available() else "cpu"
python main.py
运行后直接使用postman测试即可
支持参数:imageUrl(图片url)、imageBase64(图片base64格式)、imageFile(本地图片文件)
接口返回格式:
{
"code": 0,
"message": "成功",
"success": true,
"result": {
"face_num": "关晓彤"
}
}
评论区留言
数据集中每人有五张图片
中外公众人物数据集(400人左右):
中外明星数据集(400人左右):
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。