通过在Swift中实时跟踪用户脸部,为实时视频添加快照效果

通过在Swift中实时跟踪用户脸部,为实时视频添加快照效果,swift,face-detection,apple-vision,Swift,Face Detection,Apple Vision,我希望在实时跟踪用户面部的基础上,为实时视频添加一个快照效果。我的设计想要放置来自眉毛、眼睛或嘴唇的粒子流。我已经有了一个灵活的效果库,可以将所需的流放置在屏幕上的任何选择点上,可以实时更新 苹果提供了一个Swift演示项目,我在以下链接下载了该项目: 如果您下载并运行该项目而不做任何更改,它将向您显示一个覆盖图,其中包含实时跟踪人脸的面部地标,如左右眉毛、眼睛、鼻子、嘴唇等 没有太多关于坐标系、图层绘制等的文档,使我能够提取对应于面部地标(例如左眉毛上的点)的CGPoint值 我在分析苹果演

我希望在实时跟踪用户面部的基础上,为实时视频添加一个快照效果。我的设计想要放置来自眉毛、眼睛或嘴唇的粒子流。我已经有了一个灵活的效果库,可以将所需的流放置在屏幕上的任何选择点上,可以实时更新

苹果提供了一个Swift演示项目,我在以下链接下载了该项目:

如果您下载并运行该项目而不做任何更改,它将向您显示一个覆盖图,其中包含实时跟踪人脸的面部地标,如左右眉毛、眼睛、鼻子、嘴唇等

没有太多关于坐标系、图层绘制等的文档,使我能够提取对应于面部地标(例如左眉毛上的点)的CGPoint值

我在分析苹果演示中使用的绘图代码方面取得了一些进展,但在获得所需坐标方面的成功有限

左眉毛似乎由一个由线连接的路径上的6个点组成的数组。我只想得到一个CGPoint,它指示左眉毛上一个点的当前位置


    var sampleLeftEyebrowPoint = false
    var mostRecentLeftEyebrowPoint = CGPoint()

苹果提供了一个名为addPoints的例程

对于打开和关闭的地标,都会调用addPoints

每个人脸标志都会调用该例程。由于眉毛不是闭合路径,因此它对应于以下类型:openLandmarkRegions。嘴巴和眼睛对应于稍有不同的类型closedLandmarkRegions,因为它们是起点和终点相同的闭合路径


fileprivate func addPoints(in landmarkRegion: VNFaceLandmarkRegion2D, to path: CGMutablePath, applying affineTransform: CGAffineTransform, closingWhenComplete closePath: Bool) 

这条路是开放的还是封闭的其实并不重要。我所关心的是在任何地标上获得一个有效的CG点。最终,我会对眼睛和嘴巴产生一些影响,只要我知道如何为一个面部标志点获得一个有效的CG点

这就是我试过的。我声明了一些全局变量,并在Apple绘图代码中添加了一些逻辑,以帮助识别左眉上的CG点


    var sampleLeftEyebrowPoint = false
    var mostRecentLeftEyebrowPoint = CGPoint()

由于addPoints是为所有地标上的循环调用的,所以我必须尝试找出对应于左眉毛的循环


    var sampleLeftEyebrowPoint = false
    var mostRecentLeftEyebrowPoint = CGPoint()

在addPoints中,苹果有一行代码,他们使用任何给定地标上的点:


            let points: [CGPoint] = landmarkRegion.normalizedPoints
我在该行代码之后添加了此代码段:


if sampleLeftEyebrowPoint
{
                
mostRecentLeftEyebrowPoint = points[1]               
mostRecentLeftEyebrowPoint = mostRecentLeftEyebrowPoint.applying(affineTransform)

sampleLeftEyebrowPoint = false
          
}

请注意,点[1]是眉毛上的第二个点,即中间点之一

注意,我对Apple在逻辑中应用的单点应用了相同的仿射变换

在这个Apple例程中,我使用一些逻辑将SampleLeft眉毛点设置为true,以确定左眉毛当前是否正在循环:


    fileprivate func addIndicators(to faceRectanglePath: CGMutablePath, faceLandmarksPath: CGMutablePath, for faceObservation: VNFaceObservation)

在这个例行程序中,苹果在开放的地标上有一个for循环,如下所示。我添加了一些逻辑来设置SampleLeft眉毛点,以便addPoints中的逻辑能够识别左眉毛当前正在工作,以便可以设置


            for openLandmarkRegion in openLandmarkRegions where openLandmarkRegion != nil {
                if openLandmarkRegion == landmarks.leftEyebrow
                {
                    sampleLeftEyebrowPoint = true
                }

我得到的最重要的点似乎在某种程度上与我想要的CG点相关,但并不完全相关。X坐标似乎在跟踪,但需要一些缩放。但是Y坐标看起来是倒转的,可能还有别的事情

有没有人能提供一个例程,让我得到与MOSTRECentLeftMaybookPoint对应的所需CGPoint

一旦我有了这些,我已经知道了如何隐藏面部标志,这样只有我的效果才可见,并且我的效果会实时跟踪左眉毛。要隐藏显示的人脸检测线,只需注释掉Apple调用:


// self.updateLayerGeometry()