DragGAN 最关键的实现部分Motion supervision和Point tracking详解

DragGAN

DragGAN的底层是StyleGAN v2

所以如果你不了解StyleGAN的话,请先去看原文或者StyleGAN的讲解。

在StyleGAN中,图片是由一个个的潜在变量w控制生成的,在DragGAN中,通过改变这些潜在变量w来改变物体的拽动。

实现过程

整个过程分为两步, Motion supervision 和 Point tracking
在这里插入图片描述

1 Motion Supervision

作者提出一种loss,不需要额外的网络来做Motion Supervision。

关键思想是,生成器的中间特征是非常具有表达性的,一个简单的损失就足以监督运动。

我们把第6层(第1层就是分辨率最小的那个feature map)的特征图拿出来,当作这里的feature map F。作者说,这一层(第6层)在分辨率和表达性上的权衡,比其他的层都要好。

首先把Fresize到最终得到的图像一样的分辨率(通过双线性插值 Bilinear interpolation)

如下图所示:
在这里插入图片描述

作者的想法就是,把红色圆形区域中的small patch(像素点),移动到蓝色的圆形区域中。这样就完成了一步的移动。
L = ∑ i = 0 n ∑ q i ∈ Ω 1 ( p i , r 1 ) ∥ F ( q i ) − F ( q i + d i ) ∥ 1 + λ ∥ ( F − F 0 ) ⋅ ( 1 − M ) ∥ 1 , ( 1 ) \mathcal{L}=\sum_{i=0}^{n}\sum_{q_{i}\in\Omega_{1}(p_{i},r_{1})}\|\mathbf{F}(q_{i})-\mathbf{F}(q_{i}+d_{i})\|_{1}+\lambda\|(\mathbf{F}-\mathbf{F}_{0})\cdot(1-\mathbf{M})\|_{1}, \qquad (1) L=i=0nqiΩ1(pi,r1)F(qi)F(qi+di)1+λ(FF0)(1M)1,(1)

p p p是原点, t t t是目标点。因为我们可以设多个移动点对(包括原点和目标点),所以会有一个下标 i i i

其中 Ω 1 ( p i , r 1 ) \Omega_{1}(p_{i},r_{1}) Ω1(pi,r1)是以 p i p_i pi为圆心,以 r 1 r_1 r1为半径的圆形区域。

q q q是指图像中的某一个像素点, F ( q ) F(q) F(q)是指像素点 q q q在 Feature Map中的值。

d i = t i − p i ∥ t i − p i ∥ 2 d_i=\frac{t_i-p_i}{\| t_i-p_i\|_2} di=tipi2tipi是从原点 p i p_i pi指向目标点 t i t_i ti的单位向量。

由于 q i + d i q_{i}+d_{i} qi+di的分量不是整数,我们通过双线性插值得到 F ( q i + d i ) \mathbf{F}(q_{i}+d_{i}) F(qi+di)。重要的是,当使用这种损失执行反向传播时,梯度并不是反向传播到 F ( q i ) \mathbf{F}(q_i) F(qi)。这将促使 p i p_i pi转移到 p i + d i p_i+d_i pi+di,反之亦然。

我们这个移动是通过多步来实现的,而 F 0 F_0 F0是最开始的feature map。

M M M是二进制掩码,值为0代表这个区域不需要被改变,数值为1表示我们需要改变的区域。比如当我们的 λ \lambda λ远大于前一项的范数时。当某个像素的 M M M为0时,第二项的数值远大于第一项,所以这个loss函数就会迫使这个像素保持原样;同理,当某个像素的 M M M为1时,第二项就变为0,只需要关注第二项即可。

这个loss不是直接用来改变第6层的Feature Map的,而是直接改变潜在变量 w w w的。

作者通过实验发现,前6层的 w w w才会影响空间属性,而后面的 w w w只会影响物体的外观。因此,作者只更新前6层的 w w w,固定其他层的 w w w。这种选择性优化可以让图片中的物体在保持外观不练的情况下产生我们想要的微小的移动。

2 Point tracking

只有Motion supervision还不够精准的控制,而且我们的目标是更新每个handle point p i p_i pi使其跟踪物体上相应的点

通常通过光流估计模型或粒子视频方法[Harley et al. 2022]来执行点跟踪。同样,这些附加模型可能会显著影响效率,并且在GAN中存在Alias artifacts(伪影)时可能会遭受累积误差。因此,我们提出了一种针对GAN的新的点跟踪方法。关键在于GAN的判别特征很好地捕捉了密集的对应关系,因此可以通过在特征块中进行最近邻搜索来有效地进行跟踪。


补充知识

"Alias artifacts"是指在生成对抗网络(GAN)中出现的一种伪影或伪像,通常是由于GAN模型的训练不充分或者过拟合等问题导致的。这些伪影通常表现为图像中出现重复模式、噪点、失真等问题,从而降低了生成图像的质量和真实感。为了减少alias artifacts的出现,可以采用一些技巧,如增加训练数据、调整GAN模型的超参数、使用正则化技术等。


p i : = arg min ⁡ q i ∈ Ω 2 ( p i , r 2 ) ∥ F ′ ( q i ) − f i ∥ 1 . ( 2 ) p_i:=\operatorname*{arg\,min}_{q_{i}\in\Omega_{2}(p_{i},r_{2})}\|\mathbf{F}^{\prime}(q_{i})-f_{i}\|_{1}. \qquad(2) pi:=qiΩ2(pi,r2)argminF(qi)fi1.(2)
其中 p i p_i pi表示第 i i i个关键点的位置, Ω 2 ( p i , r 2 ) \Omega_2(p_i,r_2) Ω2(pi,r2)表示以 p i p_i pi为中心、半边长为 r 2 r_2 r2的正方向区域, F ′ ( q i ) \mathbf{F}^{\prime}(q_{i}) F(qi)表示在StyleGAN2模型的第6个块之后提取出来的特征图, f i f_i fi表示第 i i i个关键点在最开始的feature map中位置。公式的意思是,在方形区域 Ω 2 ( p i , r 2 ) \Omega_2(p_i,r_2) Ω2(pi,r2)内搜索一个最近邻 q i q_i qi,使得 F ′ ( q i ) \mathbf{F}^{\prime}(q_{i}) F(qi) f i f_{i} fi之间的 L 1 L1 L1距离最小。找到 q i q_i qi后,将其作为新的 p i p_i pi来更新目标跟踪。

我自己对Point Tracking的理解:

就是在我们通过Motion supervision更新了feature map之后,得到了一个新的feature map F ′ F^{\prime} F。我们不能够确保关键点 p i p_i pi在这个新的feature map F ′ F^{\prime} F上的位置,所以Point Tracking要做的就是在新的feature map F ′ F^{\prime} F上找到这个关键点新的位置。

有人可能会问,刚刚的Motion supervision更新了feature map的时候不是就往目标方向前进了一个单位的距离吗?这个只是损失函数的公式,我们不能确保它一定能过完全更新到那个地方,也就是说我们不能确定损失函数最后可以降为0

Discussions

Mask

在这里插入图片描述

我们的方法允许用户输入一个二进制掩膜,表示可移动区域。我们在图8中展示了它的效果。当给狗头部覆盖掩膜时,其他区域几乎不动,只有头部移动。没有掩膜时,操作将移动整个狗的身体。这也表明,基于点的操作通常有多种可能的解决方案,GAN将倾向于从训练数据中学习到的图像流形中找到最接近的解决方案。掩膜函数可以帮助减少不确定性并保持某些区域固定。

很强的泛化能力

到目前为止,我们展示的基于点的操作都是“内部分布”的操作,即可以使用训练数据集图像分布内的自然图像来满足操作要求。在图9中,我们展示了一些超出训练数据分布的操作。可以看出,我们的方法具有一定的外推能力,可以创建训练图像分布之外的图像,例如,一个非常张开的嘴巴和一个大轮子。在某些情况下,用户可能希望始终将图像保持在训练分布中,并防止其达到这样的超出分布的操作。实现这一目标的一种潜在方法是向潜在编码𝒘添加额外的正则化,但这不是本文的主要关注点。

在这里插入图片描述

Limitations

尽管具有一定的外推能力,但我们的编辑质量仍受训练数据多样性的影响。如图14(a)所示,创建偏离训练分布的人体姿势可能会导致伪影。此外,纹理较少的区域中的关键点有时会在跟踪中偏移更多,如图14(b)©所示。因此,我们建议在可能的情况下选择纹理丰富的关键点。

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在H5中使用人脸识别,可以使用HTML5的getUserMedia API获取摄像头视频流并交给人脸识别库进行处理。常见的人脸识别库有FaceAPI.js、OpenCV.js、TensorFlow.js等。 以下是一个简单的使用FaceAPI.js和Vue.js实现人脸识别的例子: 1. 首先在HTML中定义一个video元素和一个canvas元素,用于显示摄像头视频流和人脸识别结果: ```html <template> <div> <video ref="video" autoplay></video> <canvas ref="canvas"></canvas> </div> </template> ``` 2. 在Vue.js的mounted钩子函数中获取摄像头视频流并将其绑定到video元素上: ```javascript <script> import * as faceapi from 'face-api.js' export default { mounted() { navigator.mediaDevices.getUserMedia({ video: true }) .then(stream => { const video = this.$refs.video video.srcObject = stream video.play() }) .catch(error => { console.log(error) }) } } </script> ``` 3. 在Vue.js的mounted钩子函数中使用FaceAPI.js进行人脸识别并将结果绘制到canvas元素上: ```javascript <script> import * as faceapi from 'face-api.js' export default { mounted() { navigator.mediaDevices.getUserMedia({ video: true }) .then(stream => { const video = this.$refs.video video.srcObject = stream video.play() const canvas = this.$refs.canvas const displaySize = { width: video.width, height: video.height } faceapi.matchDimensions(canvas, displaySize) setInterval(async () => { const detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()) .withFaceLandmarks() .withFaceExpressions() const resizedDetections = faceapi.resizeResults(detections, displaySize) canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height) faceapi.draw.drawDetections(canvas, resizedDetections) faceapi.draw.drawFaceLandmarks(canvas, resizedDetections) faceapi.draw.drawFaceExpressions(canvas, resizedDetections) }, 100) }) .catch(error => { console.log(error) }) } } </script> ``` 注意,由于人脸识别需要不断地对视频流进行处理,因此在例子中使用了setInterval函数来定时进行人脸识别并将结果绘制到canvas元素上。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值