在android中检测人脸地标点

Posted

技术标签:

【中文标题】在android中检测人脸地标点【英文标题】:Detecting face landmarks points in android 【发布时间】:2016-11-20 23:57:18 【问题描述】:

我正在开发应用程序,在该应用程序中,我需要在诸如镜子凸轮或化妆凸轮之类的凸轮上获取面部标志点。我希望它也可用于 ios。请指导我找到一个强大的解决方案。 我用过 Dlib 和 Luxand。

DLIB:https://github.com/tzutalin/dlib-android-app

卢森堡:http://www.luxand.com/facesdk/download/

Dlib 很慢,大约有 2 秒的延迟(请查看 git 页面上的演示视频),luxand 还可以,但它是付费的。我的首要任务是使用开源解决方案。 我也使用了谷歌的视觉,但他们没有提供太多的面部标志点。 因此,请给我一个解决方案以使 dlib 快速工作或保持跨平台优先的任何其他选项。 提前致谢。

【问题讨论】:

您需要什么地标?我的项目在 Android Vision 方面取得了相当大的成功(还没有看 iOS!)。我之前看过 OpenCV,它只是比 Android Vision 慢很多——但值得一试。 【参考方案1】:

如果您采取一些捷径,您可以让 Dlib 在 Android (20-30 fps) 上实时检测面部标志。这是一个很棒的图书馆。

初始化

首先,您应该遵循 Evgeniy 回答中的所有建议,特别是确保您只初始化一次 frontal_face_detectorshape_predictor 对象,而不是每帧。如果您从文件中反序列化 frontal_face_detector 而不是使用 get_serialized_frontal_faces() 函数,则 frontal_face_detector 的初始化速度会更快。 shape_predictor 需要从一个 100Mb 的文件初始化,并且需要几秒钟。序列化和反序列化函数被编写为跨平台并对数据执行验证,这很健壮,但速度很慢。如果您准备对字节顺序做出假设,您可以编写自己的反序列化函数,该函数会快得多。该文件主要由 136 个浮点值的矩阵组成(其中大约 120000 个,意味着总共 16320000 个浮点数)。如果将这些浮点数量化为 8 位或 16 位,则可以节省大量空间(例如,您可以将最小值和 (max-min)/255 存储为每个矩阵的浮点数并分别量化)。这将文件大小减少到大约 18Mb,并且在几百毫秒而不是几秒钟内加载。使用量化值导致的质量下降对我来说似乎可以忽略不计,但 YMMV。

人脸检测

您可以将相机帧缩小到 240x160(或其他任何尺寸,保持宽高比正确),以加快人脸检测速度。这意味着您无法检测到较小的面孔,但这可能不是问题,具体取决于您的应用程序。另一种更复杂的方法是自适应裁剪和调整用于人脸检测的区域大小:首先检查高分辨率图像(例如 480x320)中的所有人脸,然后在前一个位置周围裁剪 +/- 一个人脸宽度的区域,按比例缩小如果需要的话。如果您在前一帧未能检测到人脸,则在下一帧恢复为检测整个区域。

人脸追踪

为了更快的人脸跟踪,您可以在一个线程中连续运行人脸检测,然后在另一个线程中跟踪检测到的人脸并使用跟踪的矩形执行人脸特征检测。在我的测试中,我发现人脸检测需要 100 到 400 毫秒,具体取决于我使用的手机(大约 240x160),并且在那段时间我可以在中间帧上进行 7 或 8 个人脸特征检测。如果人脸移动很多,这可能会有点棘手,因为当你得到一个新的人脸检测(从 400 毫秒前开始)时,你必须决定是从新检测到的位置继续跟踪,还是从被跟踪的位置开始跟踪。以前的检测。 Dlib 包含一个correlation_tracker,但不幸的是,我无法让它以每帧约 250 毫秒的速度运行,并且缩小分辨率(甚至大幅降低)并没有太大的区别。修补内部参数可以提高速度,但跟踪效果不佳。我最终使用了基于预览帧的色度 UV 平面的 CAMShift 跟踪器,根据检测到的面部矩形生成颜色直方图。 OpenCV 中有一个 CAMShift 的实现,但也很容易自己实现。

希望这会有所帮助,这主要是先挑选低垂的果实进行优化,然后继续前进,直到您对它足够快感到满意为止。在 Galaxy Note 5 上,Dlib 以大约 100 毫秒的时间进行面部+特征检测,即使没有所有这些额外的复杂性,这对于您的目的可能已经足够了。

【讨论】:

我对通过量化浮点数来减少 .dat 文件大小非常感兴趣。你能指导我一些示例代码或类似的东西吗?我真的很感激 @s1ddok 当然,这里有一些以压缩格式序列化 shape_predictor 的代码:pastebin.com/UqNq5qDV,下面是以相同格式反序列化它的代码:pastebin.com/UT3w8CmS 我将序列化代码添加到 face_landmark_detection_ex.cpp生成打包文件。这未经最新版本的 dlib btw 测试 非常感谢,我试图编译它,但我得到了一堆is a private member of 'dlib::shape_predictor' 错误:( 你认为有可能解决这个问题吗? 另外,idxncnr 变量的默认值是什么?他们没有在 sn-p 中贴花 编辑形状预测器标题的定义以公开变量。默认值只是零【参考方案2】:

对于大多数情况,Dlib 足够快。由于现代智能手机正在生成高分辨率图像 (10MP+)

是的,人脸检测在 3-5MP 图像上可能需要 2 秒以上的时间,但它会尝试找到 80x80 像素大小的非常小的人脸。我真的很确定,在高分辨率图像上你不需要这么小的人脸,这里的主要优化是在找到人脸之前减小图像的大小。

找到人脸区域后,下一步——人脸地标检测速度极快,一张人脸耗时

dlib-android 端口目前没有以正确的方式使用 dlib 的检测器。以下是如何使 dlib-android 端口更快地工作的建议列表: https://github.com/tzutalin/dlib-android/issues/15

它非常简单,您可以自己实现。我预计性能提升约 2 倍至 20 倍

【讨论】:

该链接似乎很有帮助。让我试试这些,然后回复你。感谢您的帮助。【参考方案3】:

除了 OpenCV 和 Google Vision,还有广泛可用的 Web 服务,例如 Microsoft Cognitive Services。优点是它将完全独立于平台,您已将其列为主要设计目标。我还没有亲自在实现中使用过它们,但是基于玩过他们的演示一段时间,它们看起来非常强大;它们非常准确,可以根据您想知道的内容提供很多细节。 (顺便说一下,其他供应商也提供类似的解决方案)。

这样的两个主要潜在缺点是可能增加网络流量和 API 定价(取决于您使用它们的频率)。

在定价方面,微软目前每月免费提供多达 5,000 笔交易,所增加的交易量仅占一美分的几分之一(取决于流量,您实际上可以获得大量交易的折扣),但如果您是例如,每月进行数百万笔交易,费用可能会以惊人的速度开始增加。这实际上是一个相当典型的定价模式;在您选择供应商或实施此类解决方案之前,请确保您了解他们将如何向您收费,您最终可能支付多少费用,以及如果您扩大用户群,您可以支付多少费用。根据您的流量和业务模式,它可能非常合理或成本过高。

增加的网络流量可能会或可能不会成为问题,具体取决于您的应用程序的编写方式以及您发送的数据量。如果您可以异步进行处理并保证相当快速的 Wi-Fi 访问,那显然不会成为问题,但不幸的是,您可能拥有也可能没有这种奢侈。

【讨论】:

谢谢@EJoshuaS 但我希望它在设备中,所以请给我任何选项来检查设备而不是网络。再次感谢您提供的有用信息。【参考方案4】:

我目前正在使用 Google Vision API,它似乎能够开箱即用地检测地标。在此处查看 FaceTracker:

google face tracker

此解决方案应按原样检测面部、幸福以及左右眼。对于其他地标,您可以在 Face 上调用 getLandmarks,它应该根据他们的文档返回您需要的所有内容(以为我没有尝试过):Face reference

【讨论】:

我已经尝试过演示,但无法在相机预览上精确地绘制面部标志点。让我知道您是否成功地精确绘制了面部点并分享代码块。非常感谢。

以上是关于在android中检测人脸地标点的主要内容,如果未能解决你的问题,请参考以下文章

使用OpenCV Android SDK从摄像头帧实时检测人脸

如何在 android 中提高 OpenCV 人脸检测性能?

在android中使用人脸检测裁剪图像

Android(玻璃)无法在 onFaceDetection 中检测人脸

在实时人脸检测 Android 中的 Live CameraPreview 上围绕人脸绘制矩形

Android 人脸检测替代方案