swift - 基于在 Swift 中实时跟踪用户面部,为实时视频添加类似 Snap 的效果
问题描述
我希望基于实时跟踪用户的面部,为实时视频添加类似 Snap 的效果。我的设计想要放置来自眉毛、眼睛或嘴唇的粒子流。我已经有一个灵活的效果库,可以将所需的流放置在屏幕上可以实时更新的任何选定点。
Apple 提供了我在此链接下载的 Swift 演示项目: https ://developer.apple.com/documentation/vision/tracking_the_user_s_face_in_real_time
如果您下载并运行该项目而不进行任何更改,它将显示一个包含面部标志的叠加层,例如左右眉毛、眼睛、鼻子、嘴唇等,实时跟踪人脸。
没有太多关于坐标系、图层绘制等的文档,无法让我提取与面部标志相对应的 CGPoint 值,例如左眉上的点。
我在分析 Apple 演示中使用的绘图代码方面取得了一些进展,但在获得所需坐标方面的成功有限。
左眉毛似乎由一条由线连接的路径上的 6 个点组成。我只想得到一个 CGPoint 来指示左眉毛上一个点的当前位置。
Apple 提供了一个名为 addPoints 的例程。
addPoints 为开放和封闭的地标调用。
为每个面部标志调用该例程。由于眉毛不是封闭路径,因此它对应于这种类型:openLandmarkRegions。嘴巴和眼睛对应一个稍微不同的类型,closedLandmarkRegions,因为它们是起点和终点相同的闭合路径。
fileprivate func addPoints(in landmarkRegion: VNFaceLandmarkRegion2D, to path: CGMutablePath, applying affineTransform: CGAffineTransform, closingWhenComplete closePath: Bool)
路径是打开还是关闭并不重要。我所关心的只是在任何地标上获得一个有效的 CGPoint。最终我也会对眼睛和嘴巴产生一些影响,只要我弄清楚如何为面部标志之一获取有效的 CGPoint。
这是我尝试过的。我声明了一些全局变量,并在 Apples 绘图代码中添加了一些逻辑,以帮助找出左眉上的 CGPoints。
var sampleLeftEyebrowPoint = false
var mostRecentLeftEyebrowPoint = CGPoint()
由于在所有地标上的循环中调用了 addPoints,因此我不得不尝试挑选出与左眉毛相对应的循环。
在 addPoints Apple 中有这行代码,他们使用任何给定地标上的点:
let points: [CGPoint] = landmarkRegion.normalizedPoints
我在那行代码之后添加了这个代码片段:
if sampleLeftEyebrowPoint
{
mostRecentLeftEyebrowPoint = points[1]
mostRecentLeftEyebrowPoint = mostRecentLeftEyebrowPoint.applying(affineTransform)
sampleLeftEyebrowPoint = false
}
请注意,points[1] 是眉毛上的第二个点,它是中间点之一。
请注意,我将相同的仿射变换应用于 Apple 在其逻辑中应用的单点。
我在这个 Apple 例程中将 sampleLeftEyebrowPoint 设置为 true,并使用一些逻辑来确定左眉当前是否正在循环:
fileprivate func addIndicators(to faceRectanglePath: CGMutablePath, faceLandmarksPath: CGMutablePath, for faceObservation: VNFaceObservation)
在该例程中,Apple 在开放的地标上有一个 for 循环,如下所示。我添加了一些逻辑来设置 sampleLeftEyebrowPoint,以便 addPoints 中的逻辑能够识别左眉当前正在工作,因此可以设置。
for openLandmarkRegion in openLandmarkRegions where openLandmarkRegion != nil {
if openLandmarkRegion == landmarks.leftEyebrow
{
sampleLeftEyebrowPoint = true
}
我获得的 mostRecentLeftEyebrowPoint 似乎在某种程度上与我想要的 CGPoint 相关,但并不完全相关。X 坐标似乎可以跟踪,但需要一些缩放。但是 Y 坐标似乎是倒置的,可能还有其他事情发生。
谁能提供一个例程,让我得到与 mostRecentLeftEyebrowPoint 对应的所需 CGPoint ?
一旦我有了这个,我已经想出了如何隐藏面部标志,这样只有我的效果是可见的,我的效果会实时跟踪左眉毛。要隐藏显示的人脸检测线,只需注释掉 Apples call to :
// self.updateLayerGeometry()
解决方案
推荐阅读
- java - 如何在 MyClass 的构造函数中将 MyClass 类型的实例添加到在 MyClass 中声明的 MyClass 数组?
- python - 从 txt 文件中读取列表中的数字,但只能读取逗号
- weblogic - 远程visualvm到weblogic集群中的服务器
- sql - 更新数据库中的 200 个表
- charts - 如何仅显示 Chartjs 中发生变化的数据点?
- python-3.x - 如何根据规则在两个不同的值之间刷/修改一个系列的值,而不是改变标记?
- python - tensorord中混淆矩阵和CNN的一些内核的可视化
- c# - 如何使用C#获取中文\日文\韩文Word文档中包含修订或跟踪更改的所有句子
- google-bigquery - 将结算数据导出到 BigQuery 不起作用
- php - 在 EC2 上使用 PHP 的 Dialogflow V2 Webhook