微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过在Swift中实时跟踪用户的脸部,为实时视频添加类似Snap的效果

如何解决通过在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,我的眼睛和嘴巴也会受到一些影响。

这是我尝试过的。我声明了一些全局变量,并在Apple的绘图代码添加了一些逻辑,以尝试帮助选择左眉上的CGPoint。


    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吗?

一旦有了,我就已经想出了如何隐藏面部标志的方法,这样,只有我的效果才可见,并且我的效果将实时跟踪左眉。要隐藏显示的面部检测线,只需注释掉苹果对的呼叫即可:


// self.updateLayerGeometry()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。