目录

介绍

对齐算法

算法的实现

向检测器添加人脸对齐

修改对齐算法

下一步


在这里,我们将简要说明如何在Raspberry Pi上安装MTCNN、TensorFlow和Keras。然后我们在视频文件上启动人脸检测以测试性能,然后简要说明如何在实时模式下运行检测。最后,我们看看如何使用运动检测器加快检测速度。

  • 下载源 - 152.7 KB
  • 下载帧 - 3.1 MB
  • 下载面孔 - 2.7 MB
  • 下载数据库 - 531.6 KB

介绍

人脸识别是人工智能(AI)的一个领域,深度学习(DL)在过去十年中取得了巨大成功。最好的人脸识别系统可以以与人类相同的精度识别图像和视频中的人物,甚至更好。人脸识别的两个主要基础阶段是人员验证和身份识别。

在本系列文章的前半部分(当前)中,我们将:

  • 讨论现有的AI人脸检测方法并开发程序来运行预训练的DNN模型
  • 考虑面部对齐并使用面部标志实现一些对齐算法
  • 在Raspberry Pi设备上运行人脸检测DNN,探索其性能,并考虑可能的方法来更快地运行它,以及实时检测人脸
  • 创建一个简单的人脸数据库并用从图像或视频中提取的人脸填充它

我们假设您熟悉DNN、Python、Keras 和 TensorFlow。

在上一篇文章中,我们实现了基于现代AI方法的通用面部识别系统的第一阶段——面部检测。在本文中,我们将讨论管道的第二阶段——面部对齐——基于OpenCV库中的透视变换函数。这不是强制性阶段。但是,它可以提高识别精度,并且一直用于现实生活中的面部识别软件。

对齐算法

简而言之,人脸对齐是一种将从图像或视频帧中提取的人脸图片转换为指定方向、位置和比例的算法。在人脸识别必须在现实生活中的图像和框架中,人脸可以在各种角度和各种比例因子下出现。下图显示了相对于相机视图处于不同位置的同一张脸。

1 – 脸向右旋转

2 – 脸向一侧倾斜

3 – 脸向左旋转

4 – 脸向下倾斜

人脸对齐的目标是将人脸拟合到相同大小的图像中,并标准化人脸视图:将人脸居中于图像内;相对于图像缩放面部,依此类推。

面部对齐可以使用各种算法,具体取决于有关面部及其位置的可用信息。我们将使用MTCNN模型,因为我们知道人脸的边界框在2D图像中并且有五个面部标志位置(关键点)。我们需要开发一种转换,使用面部的关键点将其带入标准视图。

幸运的是,我们不需要重新发明轮子。在计算机视觉中,这种变换被称为透视变换,用OpenCV库实现起来相对容易。我们只需要在源图像中选择四个点,在目标图像中选择四个匹配点。

看看下面的图片。在左侧,我们绘制了使用MTCNN算法找到的关键点。在右侧,我们显示了可以根据三个关键点的已知坐标计算的三个点:1、2 和 3。

点6位于点1和点2之间。点7和8与关键点1和2一起形成平行四边形。点1和7之间的距离与点2和8之间的距离相同,是点6和3之间距离的两倍。所以点3是平行四边形的中心。

算法的实现

让我们使用平行四边形的四个角来实现透视变换算法:

class Face_Align:    def __init__(self, size):self.size = sizedef align_point(self, point, M):(x, y) = pointp = np.float32([[[x, y]]])p = cv2.perspectiveTransform(p, M)return (int(p[0][0][0]), int(p[0][0][1]))def align(self, frame, face):(x1, y1, w, h) =  face['box'](l_eye, r_eye, nose, mouth_l, mouth_r) = Utils.get_keypoints(face)(pts1, pts2) = self.get_perspective_points(l_eye, r_eye, nose, mouth_l, mouth_r)s = self.sizeM = cv2.getPerspectiveTransform(pts1, pts2)dst = cv2.warpPerspective(frame, M, (s, s))f_aligned = copy.deepcopy(face)f_aligned['box'] = (0, 0, s, s)f_img = dstl_eye = self.align_point(l_eye, M)r_eye = self.align_point(r_eye, M)nose = self.align_point(nose, M)mouth_l = self.align_point(mouth_l, M)mouth_r = self.align_point(mouth_r, M)f_aligned = Utils.set_keypoints(f_aligned, (l_eye, r_eye, nose, mouth_l, mouth_r))return (f_aligned, f_img)class Face_Align_Nose(Face_Align):    def get_perspective_points(self, l_eye, r_eye, nose, mouth_l, mouth_r):(xl, yl) = l_eye(xr, yr) = r_eye(xn, yn) = nose(xm, ym) = ( 0.5*(xl+xr), 0.5*(yl+yr) )(dx, dy) = (xn-xm, yn-ym)(xl2, yl2) = (xl+2.0*dx, yl+2.0*dy)(xr2, yr2) = (xr+2.0*dx, yr+2.0*dy)s = self.sizepts1 = np.float32([[xl, yl], [xr, yr], [xr2, yr2], [xl2, yl2]])pts2 = np.float32([[s*0.25, s*0.25], [s*0.75, s*0.25], [s*0.75, s*0.75], [s*0.25,s*0.75]])return (pts1, pts2)

上面的代码包含两个类。基类Face_Align使用OpenCV库中的两个函数:getPerspectiveTransform和warpPerspective实现转换算法。第一个函数计算变换矩阵,第二个函数用矩阵变换图像。计算透视图矩阵的点必须由get_perspective_points方法提供。方法的具体实现是在继承的类Face_Align_Nose中实现的。

向检测器添加人脸对齐

现在我们可以将人脸对齐算法添加到上一篇文章中描述的视频人脸检测器中:

class VideoFD:    def __init__(self, detector):self.detector = detectordef detect(self, video, save_path = None, align = False, draw_points = False):detection_num = 0;capture = cv2.VideoCapture(video)img = Nonedname = 'AI face detection'cv2.namedWindow(dname, cv2.WINDOW_NORMAL)cv2.resizeWindow(dname, 960, 720)frame_count = 0dt = 0face_num = 0if align:fa = Face_Align_Nose(160)# Capture all frameswhile(True):    (ret, frame) = capture.read()if frame is None:breakframe_count = frame_count+1t1 = time.time()faces = self.detector.detect(frame)t2 = time.time()p_count = len(faces)detection_num += p_countdt = dt + (t2-t1)if (not (save_path is None)) and (len(faces)>0) :f_base = os.path.basename(video)for (i, face) in enumerate(faces):if align:(f_cropped, f_img) = fa.align(frame, face)else:(f_cropped, f_img) = self.detector.extract(frame, face)if (not (f_img is None)) and (not f_img.size==0):if draw_points:Utils.draw_faces([f_cropped], (255, 0, 0), f_img, draw_points, False)face_num = face_num+1dfname = os.path.join(save_path, f_base + ("_%06d" % face_num) + ".png") cv2.imwrite(dfname, f_img)if len(faces)>0:Utils.draw_faces(faces, (0, 0, 255), frame)if not (save_path is None):dfname = os.path.join(save_path, f_base + ("_%06d" % face_num) + "_frame.png")cv2.imwrite(dfname, frame)# Display the resulting framecv2.imshow(dname,frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakcapture.release()cv2.destroyAllWindows()    fps = frame_count/dtreturn (detection_num, fps)

让我们对视频文件启动人脸检测:

d = MTCNN_Detector(50, 0.95)
vd = VideoFD(d)
v_file = r"C:\PI_FR\video\5_2.mp4"save_path = r"C:\PI_FR\detect"
(f_count, fps) = vd.detect(v_file, save_path, True, False)print("Face detections: "+str(f_count))
print("FPS: "+str(fps))

在下图中,我们显示了相同位置的人脸,但现在它们与使用我们的算法对齐。

您可以看到现在所有图片的大小都相同。然而,对齐算法并没有做得很好。当人脸向左或向右旋转时,算法会失败并严重扭曲人脸。这是因为鼻尖与其他点不在同一平面上。当面旋转到一边时,点3不再是平行四边形的中心。

修改对齐算法

让我们尝试使用其他人脸地标修改对齐算法。在下图中,我们引入了一个新点——9。

点9计算为点4和5之间的中间点。我们仍然使用四个点——1、2、8、7——作为透视变换的基础。但是现在点7和8的计算是基于点9的坐标。我们假设点6和9位于平行四边形的中线上。下面的代码实现了这个算法:

class Face_Align_Mouth(Face_Align):    def get_perspective_points(self, l_eye, r_eye, nose, mouth_l, mouth_r):(xl, yl) = l_eye(xr, yr) = r_eye(xml, yml) = mouth_l(xmr, ymr) = mouth_r(xn, yn) = ( 0.5*(xl+xr), 0.5*(yl+yr) )(xm, ym) = ( 0.5*(xml+xmr), 0.5*(yml+ymr) )(dx, dy) = (xm-xn, ym-yn)(xl2, yl2) = (xl+1.1*dx, yl+1.1*dy)(xr2, yr2) = (xr+1.1*dx, yr+1.1*dy)s = self.sizepts1 = np.float32([[xl, yl], [xr, yr], [xr2, yr2], [xl2, yl2]])pts2 = np.float32([[s*0.3, s*0.3], [s*0.7, s*0.3], [s*0.7, s*0.75], [s*0.3, s*0.75]])return (pts1, pts2)

在视频检测器中使用新类Face_Align_Mouth并使用相同的视频文件启动它,我们得到以下对齐的人脸。

您会看到现在没有面部扭曲,并且所有面部都正确对齐。请注意,并非所有对齐的人脸看起来都在镜头前。例如,旋转后的面看起来仍然略微旋转。不幸的是,我们无法在2D图像中重建旋转人脸的前视图。

尽管如此,相对于最终图像,所有面部关键点现在都具有相同的坐标。这正是我们想要的对齐算法——将面部归一化为相同的图像坐标。这种方法确保从数据库中的人脸提取的特征和通过相机输入的人脸属于同一空间。

下一步

在本系列的下一篇文章​​​​​​​中,我们将在Raspberry Pi设备上运行我们的面部检测器。

https://www.codeproject.com/Articles/5306640/Hybrid-Edge-AI-Face-Alignment

(三)混合边缘AI人脸对齐相关推荐

  1. (二)混合边缘AI人脸检测

    目录 介绍 人脸检测方法 MTCNN检测器 图像中的人脸检测 视频中的人脸检测 下一步 下载源 - 152.7 KB 下载帧 - 3.1 MB 下载面孔 - 2.7 MB 下载数据库 - 531.6 ...

  2. (五)为边缘AI人脸识别创建人脸数据库

    目录 介绍 数据库中有什么 创建数据库 填充数据库 下一步 在这里,我们将解释用于人脸识别的简单人脸数据库的结构,开发用于将人脸添加到人脸数据库的实用程序的Python代码,并提供下载人脸以创建数据库 ...

  3. (一)开始使用混合边缘AI进行面部识别

    目录 介绍 人脸检测和对齐 人脸识别 本系列文章 工具和假设 下一步 在这里,我们陈述使用AI和边缘设备进行人脸识别的问题.然后列出主要步骤:检测.对齐.特征提取.识别.最后,简要概述该系列并说明我们 ...

  4. (十)用于面部识别的混合边缘人工智能:下一步

    目录 介绍 DNN的困境 结论 下一步 在这里,我们陈述了从头开始开发AI人脸识别系统的任务,并在它是更好的解决方案时提出了一些实际示例.然后我们给出基础阶段并提供有关如何开发系统主要成分的资源的参考 ...

  5. 原创 | 一文了解边缘计算和边缘AI

    这个9月,AI芯片独角兽地平线发布了自诩最强边缘 AI 芯片地平线「旭日3」,一时间引起轰动.相比第二代芯片,「旭日3」的AI性能上得到很大提升,只需在 2.5W 的功耗下,能够达到等效 5TOPS ...

  6. 一文了解边缘计算和边缘AI

    这个9月,AI芯片独角兽地平线发布了自诩最强边缘 AI 芯片地平线「旭日3」,一时间引起轰动.相比第二代芯片,「旭日3」的AI性能上得到很大提升,只需在 2.5W 的功耗下,能够达到等效 5TOPS ...

  7. 重磅!清华商汤开源CVPR2018超高精度人脸对齐算法LAB

    清华&商汤开源超高精度人脸对齐算法LAB 同时发布含10000张人脸的多属性人脸关键点数据集 该算法来自CVPR2018论文<Look at Boundary: A Boundary-A ...

  8. 人脸对齐算法调研(Face Alignment)

    人脸对齐算法调研(Face Alignment) 转载自 https://zhuanlan.zhihu.com/p/101250334 一.人脸对齐的定义与作用(引用): https://blog.c ...

  9. 3d人脸对齐代码matlab,重磅!清华商汤开源CVPR2018超高精度人脸对齐算法LAB

    清华&商汤开源超高精度人脸对齐算法LAB 同时发布含10000张人脸的多属性人脸关键点数据集 该算法来自CVPR2018论文<Look at Boundary: A Boundary-A ...

最新文章

  1. 基于单片机的水壶自动加热系统_基于烟雾检测火灾自动报警系统
  2. python序列类型唯一的映射类型_python2.x学习笔记(8)-映射和集合类型
  3. 局部变量和常量的性能分析
  4. python mysql批量更新_Python批量删除mysql中千万级大量数据的脚本分享
  5. 单独组件_阿里P8年薪百万大牛-教你打造一个Android组件化开发框架
  6. 好文荐读 | 阿里巴巴为什么不用 ZooKeeper 做服务发现?
  7. html 图片导出excel,用JavaScript导出图片到Excel
  8. 安卓案例:初试谷歌图表
  9. Flink AggOperatorWholeWin 全窗口聚合函数
  10. HDU-1429 胜利大逃亡(续)
  11. android调用本地js文件上传,原生JS实现前端本地文件上传
  12. Lomboz插件安装
  13. Unity SRP从零搭建一套图形渲染管线
  14. 缺少tlqcu_qcu1.conf文件
  15. 用计算机怎么管理小米路由器,小米路由器电脑怎么设置_小米路由器怎么用电脑设置?-192路由网...
  16. 详解ico图标制作方法
  17. 聂微东:《暗时间》读书笔记与读后感 - 博客 - 伯乐在线
  18. html中图片太大了,css背景图片太大的坏处与解决方法
  19. 雅思在线模拟测试软件,上海雅思在线模拟测试
  20. mysql charset=utf-8_mysql数据库charset=utf-8

热门文章

  1. Java读取文件中的arraylist_java – 从文件中读取ArrayList作为对象?
  2. python项目上线_django之项目部署上线
  3. java.lang.object 下载_java.lang.Object
  4. 分式混合运算20道题_FAG剖分式调心滚子轴承的性能
  5. spark 设置主类_最近Kafka这么火,聊一聊Kafka:Kafka与Spark的集成
  6. python书籍pdf文档密码-Python玩转PDF的各种骚操作
  7. 高清电脑手机壁纸任你选,每天不重样!
  8. 承包你所有壁纸需求,高图网图片,美到窒息
  9. 有哪些网站社区可以看原创平面设计大师作品?
  10. 电商购物APP UI 模板素材,充满时尚感的设计