[深度学习 - 实战项目] yoloV5人脸侦测&arcFace人脸识别&silentFace静态活体检测
yoloV5&arcFace人脸识别
yoloV4&V5已经出来几个月了啊。
刚接触yolo的时候,是大三下的时候,那时候导师给了个项目,就是侦测人体加上骨架提取的一个项目。我当时也没只是想先搞个毕业设计出来。然后就查资料,找到了yoloV3,下了源码。在linux系统上跑了起来。
当时最大的感受就是,我这破笔记本电脑也能跑得掉,这代码真牛逼。
然后到现在的yoloV4、V5,可以看出来网络结构基本没变。仅仅在一些小组件上优化:优化了数据集、优化了子结构/激活函数、加了一些技巧在拼接上、重新设计了IOU损失,然后性能和精度就提高了。换句话说,单单看yolo的网络,我们还没把它的潜能全部发挥出来。可以说,在神经元单元的利用率还很低。
之前做过MTCNN&arcface的人脸识别项目,所以就下载了yoloV5,把MTCNN那部分替换了一下。
附上我修改后的代码https://github.com/ooooxianyu/yoloV5-arcface_forlearn
最下面更新了silentFace静态活体检测 有兴趣的可以看一看。
2021.01.29 更新:
最近比较闲,没事就去github翻仓库看项目。发现一个人脸识别的项目。
https://github.com/JDAI-CV/FaceX-Zoo
Retinaface 人脸检测 + InsightFace 人脸识别 + PFLD 人脸关键点检测,把各种做人脸项目的功能都封装好了,而且写了许多readme做解释,非常棒的一个仓库。有兴趣可以直接跳转过去看。
而且项目虽然封装好了,但是也提供了增强训练的地方。很nice!!!做人脸项目的朋友不要错过噢 😀
1. yoloV5
首先是下载官方源码,https://github.com/ultralytics/yolov5;
使用官方源码和它的权重做预训练模型,训练人脸侦测。
我这里使用celebA的数据集,就找了1500张照片。
然后要自己做标签。
主要注意一下几点:
① 标签和照片在一个目录下新建新目录,分别为“/labels”,“/images”,用来存放图片数据和标签数据。
② 标签和图片同名,一张图片一个标签。
③ 修改yaml配置文件;
train: D:/AIstudyCode/data/CelebA/images/train/
val: D:/AIstudyCode/data/CelebA/images/test/
# number of classes
nc: 1
# class names
names: ['face']
④ 标签的格式为: 类别 中心点偏移量 x y 宽高 w h;(下面为标签制作的代码)
# 制作标签
from PIL import Image,ImageDraw
anno_box_path = r"D:/AIstudyCode/data/CelebA/Anno/list_bbox_celeba.txt"
label_dir = "D:/AIstudyCode/data/CelebA/labels"
img_dir = "D:/AIstudyCode/data/CelebA/Img/img_celeba.7z/img_celeba.7z/img_celeba"
count = 0
epoch = 1
box_file = open(anno_box_path,"r")
i = 0
for line in box_file:
if i < 2:
i += 1
continue
i += 1
print(line)
imgname = line[0:6]
#print(imgname)
img_strs = line.split()
x1, y1, w, h = int(img_strs[1]), int(img_strs[2]), int(img_strs[3]), int(img_strs[4])
x2, y2 = x1+w, y1+h
img = Image.open(f"{img_dir}/{img_strs[0]}")
img_w, img_h = img.size
# ****************************
dw = 1. / (int(img_w))
dh = 1. / (int(img_h))
x = ((x1 + x2) / 2.0 - 1)*dw
y = ((y1 + y2) / 2.0 - 1)*dh
w = (x2 - x1)*dw
h = (y2 - y1)*dh
# x = x * dw
# w = w * dw
# y = y * dh
# h = h * dh
# ****************************
label_txt = open(f"{label_dir}/{imgname}.txt", "w")
label_txt.write(f"0 {x} {y} {w} {h}\n")
label_txt.flush()
label_txt.close()
if i == 1562:
exit()
训练速度还是很快的哈,我用渣渣的1050Ti,训练了一个多小时,效果已经很好了。需要更好的效果,可以加大样本,训练时间再长一点。
2. arcface
arcface前面说过了一些,也用的官方代码和权重包,所以也没什么好说的。
主要要说的就是,跟yoloV5结合一起使用的部分。
先是要从数据库中,获取已有照片的特征表。(用来做识别)
model 为Arcface模型,dir为数据库的目录。
输出字典,(图片名:特征图1024)
def get_featuresdict(model, dir):
list = os.listdir(dir)
person_dict = {}
for i,each in enumerate(list):
image = load_image(f"pic/{each}")
data = torch.from_numpy(image)
data = data.to(torch.device("cuda"))
output = model(data) # 获取特征
output = output.data.cpu().numpy()
fe_1 = output[0]
fe_2 = output[1]
feature = np.hstack((fe_1, fe_2))
person_dict[each] = feature
return person_dict
然后,修改yoloV5里面detect部分代码。
for *xyxy, conf, cls in det: # x1 y1 x2 y2 cls class
face_img = im0[int(xyxy[1]):int(xyxy[3]),int(xyxy[0]):int(xyxy[2])] # 裁剪侦测到的人脸部分
face_img = cv2.resize(face_img,(128, 128)) # 缩放至128*128
face_img = cv2.cvtColor(face_img,cv2.COLOR_BGR2GRAY)
face_img = np.dstack((face_img, np.fliplr(face_img)))
face_img = face_img.transpose((2, 0, 1))
face_img = face_img[:, np.newaxis, :, :]
face_img = face_img.astype(np.float32, copy=False)
face_img -= 127.5
face_img /= 127.5
face_data = torch.from_numpy(face_img)
face_data = face_data.to(torch.device("cuda"))
# 获取特征
_output = arcface_model(face_data)
_output = _output.data.cpu().numpy()
fe_1 = _output[0]
fe_2 = _output[1]
_feature = np.hstack((fe_1, fe_2))
# label = '%s %.2f' % (names[int(cls)], conf)
label = "none"
list = os.listdir(dir)
max_f = 0
t = 0
# 比较数据库中每一张图片的余弦相似度
for i, each in enumerate(list):
t = cosin_metric(features[each],_feature)
# print(each, t)
if t>max_f:
max_f = t
max_n = each
# print(max_n,max_f)
if (max_f>0.5):
label = max_n[:-4]
plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
3. 测试(我的娜娜女神)
测试视频都是在B站找的,欧阳娜娜的视频。
测试在我这渣渣电脑上跑是0.05秒左右/每帧。效果也还可以。
存在几个问题,因为我数据库每个人只准备一张图片。(网上找的正脸照片)所以视频中很多侧脸照有时候不能够识别出来。
第二个问题就是余弦相似度的阈值问题,正常来讲两个不一样的人余弦相似度都不会太高(例如下图欧阳娜娜和陈立农)但是我后面找了欧阳娜娜姐妹三个人的volg来测试,发现有的时候,阈值设置高了容易识别不出来,阈值设置低了就容易识别错误。
所以数据库实际上可以准备多角度多张照片,准备单人的数据库目录。
结合单个人多张照片余弦相似度,求平均或者制定其他规则,可以得到更加准确的识别。我这边只准备了四张图片如下。
==============================================================================================
4. silentFace活体检测
更新:silentFace活体检测:https://github.com/smisthzhu/Silent-Face-Anti-Spoofing直接参考这篇。
做完人脸识别,我还不满足哈,我想。要是我家安防门有人直接那我照片不就解锁了。这可不行。于是乎,查资料。这个咋解决。
❗❗❗❗❗做个活体检测不就行了吗。然后就查了很多活体检测,什么张张嘴,摇摇头,不不不,这都不是我想要的。总不能我过个人脸识别门禁还得规定动作吧。
刚好前几天在机器之心公众号上看到这个。静默活体检测:https://mp.weixin.qq.com/s/01X6UyoPGwASTDWgC6X6qQ,于是找了找代码跑了跑,觉得效果还行。于是拼装进我原来的代码里。具体的我修改后也上传到GitHub上。(就是简单的拼装一下)
github下载下来可以通过配置open_rf控制是否开启真假脸检测。
效果:(没剪头发,没刮胡子,献丑了)
说下感受哈:检测的速度非常慢,效果的话实际来看其实预测会预测错误。所以我设置只有预测为真脸且预测率大于0.9才判定为真脸。
静默识别原文说明:RGB静默活体对摄像头型号和使用场景鲁棒性受限,所以实际使用体验会有一定差异。
所以效果看看就好吧我觉得。
更多推荐
所有评论(0)