戴口罩的人脸识别

上一次写技术文章是去年4月份了,时隔一整年终于又恬不知耻的上线了!

其实这中间有好多事都想要写,找实习,找工作,申博,考试等

但人的惰性太大了,停笔容易,但是想再拾起笔可真是太难了。

最近研究了一个新的方向,感觉还是挺有意思的,很想记下来一点感触。


去年年初疫情的爆发,迅速席卷了全球,由于管控措施的加强。现在大家出门基本上都要佩戴口罩了,如果在戴口罩的情况下对人脸进行识别,这就显得极为重要了。尤其是商场这些密集型场所,公共场合你叫顾客把口罩给摘下来,这也不太现实,人家肯定也不肯,心里肯定OS:妈得,劳资摘了口罩万一感染了你给我负责?那么如何在戴口罩的情况下对人脸进行识别呢?

深度学习人脸识别一般先进行人脸检测扣出人脸区域后,再进行特征点定位,然后根据定位特征点进行仿射变换来对齐人脸,最后将对齐后的人脸送入特征提取网络提取人脸特征,并用该特征进行人脸识别。

以上是普通人脸识别的流程,其实对应到戴口罩的情况下也是如此,只不过此处最大的难点 是如何检测到有障碍物遮挡的人脸区域

因为我们在做项目时,基本上都是用opencv或者dlib开源库来检测人脸,这些开源库是调用已经训练好的Haar特征模型来检测人脸的,如我们一般用openCV中haarcascade_frontalfac e_fault.xml的模型文件来做识别。现在要来检测戴口罩的人脸,显而易见,这些预训练Haar特征模型是很难准确的完成任务的。因此,我们需要重新训练这样一个戴口罩的人脸检测模型。我在网上查阅了相关资料,这位博主的科普文章有介绍到如何训练这样的模型,最后我检测过准确度还是挺高的。

戴口罩的人脸识别_第1张图片

效果大概就是这样的,其实这个就是调用了Opencv库里面的opencv_traincascade.exe做二分类训练的。

opencv_traincascade.exe:是OpenCV自带的一个工具,封装了haar特征提取LBP和HOG特征分类器

人脸区域能够检测出来,其实后面我个人觉得非常简单了。那我就把眼睛,眉毛,鼻子,嘴巴,下巴这些关键部位的特征点提取出来就行了。等等等等,你唬我呢?肯定有读者此刻在心里大骂我,口罩都把人眼睛下面的区域给遮住了,怎么还能检测到鼻子和嘴巴?我的解释就比较霸道了:我说它有鼻子它就有。各位您再想再细想...

哈哈哈哈哈好了不卖关子了,其实对于机器而言,什么才是鼻子?没有鼻孔的鼻子可以算作鼻子吗?答案是可以,原理如下图所示,其实我只要装傻,把鼻子遮挡住的那部分口罩当成一个绿鼻子,机器敢有意见吗?

戴口罩的人脸识别_第2张图片

事实上,调用dlib开源库来提取128个特征点,这个模型也是这么干的,自动补充特征点,如下图所示:

戴口罩的人脸识别_第3张图片

到这里,前两步都完成了。对了,我好像还忘了总结人脸识别的步骤,也就4步,如下所示:

  1. 戴口罩的人脸检测

  2. 戴口罩的人脸对齐

  3. 戴口罩的人脸编码

  4. 戴口罩人脸对应的身份识别

后面两步我就直接是用dlib开源库来帮我完成了,效果还是不错的,可能是我脸盘比较大哈,可见区域比较丰富,就能比较迅速的识别出来,效果图如下图所示:

戴口罩的人脸识别_第4张图片

核心代码如下所示:

        ret, frame = video_capture.read()

        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # opencv的图像是BGR格式的,而我们需要是的RGB格式的,因此需要进行一个转换。
        rgb_frame = frame[:, :, ::-1]
        if process_this_frame:
            face_locations = mask_detector.detectMultiScale(gray, 1.1, 5)
            face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)  # 获得人脸特征值
            face_names = []  # 存储出现在画面中人脸的名字
            for face_encoding in face_encodings:
                matches = face_recognition.compare_faces(known_encodings, face_encoding, tolerance=0.5)
                if True in matches:
                    first_match_index = matches.index(True)
                    name = known_names[first_match_index]
                else:
                    name = "unknown"
                face_names.append(name)

题外话

本次实验研究的数据集是来自武汉大学王中元老师团队收集的数据,感谢王老师团队的研究成果,大家也可以去多多关注这个Github项目。

虽然说现在很多大公司的戴口罩人脸识别技术已经是非常成熟了,还是想谈谈自己的看法,也是在知乎帖子上看到的一段话,我觉得很有意义,直接摘抄下来了。 @工科初学者

人脸识别如果根本没有足够特征怎么办,一方面必须要求被检测人的脸部图像清晰度很高,至少要600dpi以上,然后用级联网络逐级定位到人眼、眉毛、鼻子这个精确的区间,如果不能只定位这个区域,那么结果在最终分类时准确率会更低。+然后被检人需要频繁的转脸、皱眉、瞪眼、闭眼,将脑门批复,眼周围的皮肤褶皱的变形都计算进来,通过测量眼镜和周围皮肤的相对位移来得到向量,当然这样也是很不准确,但起码有一定的唯一性,不同人在这几种微表情中不可能完全一样。+还需要结合虹膜识别、头发识别等辅助手段一起进行判定。+最终得到的推荐置信度一定很低,大量样本的置信度非常相近导致无法判断身份唯一性,那人脸识别的意义也就没了。

你可能感兴趣的:(深度学习大本营,人脸识别,计算机视觉,目标检测,opencv)