论文阅读:VITON: An Image-based Virtual Try-on Network(基于图像的虚拟试衣网络)

基于图像的虚拟试衣:VITON:An Image-based Virtual Try-on Network(2018) [paper]VITON: An Image-based Virtual Try-on Network(2018) [code]VITON 效果 网络结构 人的量化表示 人姿态热图 人的姿态用18个关键点表示。为了利用空间布局,每个关键点都将进一步转换为热图,关键点周围11x11领域设置为1,其他位置区域设置为0。然后将热图堆叠到18通道的姿势热图中。 人体表示 衣服的外观高度取决于人身体不同部位的位置和形状,使用人体解析算法对人身体的不同部位进行分割,将分割图进一步转换为1通道的二进制掩码, 阅读详情

原文地址:【paper】VITON: An Image-based Virtual Try-on Network
代码地址:【code】gitbub地址(数据集已不再公开)

摘要

我们提出了一种基于图像的虚拟试穿网络(VITON),该网络能够不利用任何形式的3D信息,而是使用“从粗到细”的策略,将想要的衣物无缝地转移到人的相应区域。基于一种新提出的与服装无关的描述性的人物表示,我们的框架首先生成一个粗糙的合成图像,目标衣服叠加在相同姿势的同一个人身上。我们通过一个细化网络进一步增强初始模糊服装区域。这个网络的目的是为了解目标服装的细节利用程度,以及在何处应用到人物身上,从而合成一幅逼真的图像,其中目标衣服以清晰的视觉模式自然变形。在我们新收集的Zalando数据集上进行的实验表明,在基于图像的虚拟试穿任务中,它比最先进的生成模型更有前景。

1.引言

近年来,人们对时尚物品的网购需求不断增加。美国的在线服装和配饰销售额预计将从2016年的720亿达到2022年的1230亿。尽管网上时尚购物提供了便利,但消费者在网上购买服装时,会担心产品图片中的某件时尚物品穿在身上会是什么样子。因此,允许消费者虚拟试穿衣服不仅可以提高他们的购物体验,改变人们购买服装的方式,还可以为零售商节省成本。在此刺激下,不同的公司已经开发了各种虚拟试衣间/镜子,如TriMirror、Fits Me等。然而,他们背后的关键方法是使用3D设备进行身体数据测量,或者由深度相机直接捕获,或者使用训练数据从2D图像推断。虽然这些三维建模技术能够在人身上进行逼真的服装模拟,但安装硬软件和收集三维注释数据的高成本抑制了它们的大规模部署。

我们提出了一种基于图像的虚拟试穿方法,仅仅依靠普通的RGB图像,而不利用任何3D信息。我们的目标是通过将产品图像无缝叠加到一个穿着衣服的人的相应区域来合成一个照片般真实的新图像(如图1所示)。我们期望合成的图像在视觉上是较为真是的,满足以下要求:

  1. 人的身体部位和姿势与原始图像相同;
  2. 目标服装根据人的姿势和体形自然变形;
  3. 目标衣服的细节图案清晰可见,其中不仅包括颜色和纹理等低层次特征,还包括刺绣、标识等复杂图形。

由于衣服的非刚性特征,并且经常受到变形和遮挡的影响,在没有3D信息的情况下,对同时满足这些要求形成了巨大的挑战。
图1 由我们的方法生成的虚拟试衣结果。每一行显示的是同一个人在试穿不同的衣服。模型自然地将衣服渲染到一个人身上,同时保留她的姿势和服装的详细特征。
图1-由我们的方法生成的虚拟试衣结果。每一行显示的是同一个人在试穿不同的衣服。模型自然地将衣服渲染到一个人身上,同时保留她的姿势和服装的详细特征。

条件生成对抗性网络(gans)在图像生成、图像到图像的翻译和编辑任务方面取得了不错的成果,这似乎是解决这个问题自然想到的方法。特别的,它们最大限度地减少对抗性损失,从而使生成器产生的样本与鉴别器根据输入信号确定的真实样本无法区分。然而,它们只能粗略地转换对象类和属性等信息,而不能生成图形细节和适应几何变化。这限制了GAN在虚拟试穿这样的任务中的能力,在生成的图像中需要保留目标服装的细节和以及进行真实变形。

为了解决这些问题,我们提出了一个虚拟试衣网络(VITON) 。这是一个从粗到精的框架,可以无缝地将目标服装转移到2D 图像中衣服人员的相应区域,图2显示了 VITON 的框架。特别要说明的是,我们首先提出了了一个与服装无关的描述性的表示(clothing-agnostic representation),以描述一个人的不同特点。在此基础上,采用多任务编解码网络,生成穿着目标服装的,与输入人物同一姿态的粗糙合成图像,并生成相应的服装区域掩码(mask)。然后,该掩码被用作指导,对目标服装进行扭曲(变形),以考虑到变形的情况。此外,我们利用一个细化网络,该网络被训练来学习如何将扭曲的服装合成到粗略的图像中,从而使所需的衣服以自然的变形和详细的视觉模式被转移。为了验证我们的方法,我们在新收集的数据集上进行了一项用户研究,结果表明VITON产生了比最先进的方法更真实、更吸引人的虚拟试穿结果。
图2
图2-VITON架构总览。VITON分为两个阶段:(a)编码器-解码器生成阶段(第3.2节)。(2)细化阶段(第3.3节)。

2.相关工作

时尚分析
由于服装具有巨大的利润潜力,因此人们对其进行了广泛的研究。现有的方法主要集中在服装解析、服装属性识别、在线服装匹配、时尚推荐、视觉兼容性学习和时尚趋势预测等方面。与这些工作相比,我们主要关注在仅使用2D图像作为输入的虚拟试穿。我们的任务与最近的交互式搜索工作相比,也更具挑战性,因为虚拟试穿需要尽可能地保留目标服装图像的细节,包括完全相同的款式、刺绣、标志、文字等。

图像合成
GAN是用于图像合成的最流行的深度生成模型之一,并在图像生成和图像编辑等任务中表现出不错的结果。为了在生成的样本中加入想要的属性,研究人员还利用不同的信号,通过类标签、文本、属性等形式,作为先验条件来指导图像生成过程。最近有一些研究使用条件GANs研究了从图像到图像的转换问题,它将一个给定的输入图像转换为另一个具有不同表示的图像。例如,从其相应的边缘图、或语义标签图,产生一个RGB图像,或者反过来也行。最近,Chen和Kolton使用回归损失训练了一个CNN,作为GANs的替代方案来完成这项任务,而没有进行对抗性训练。这些方法能够产生照片般真实的图像,但在发生几何变化时,其成功率有限。为此,我们提出了一个细化网络,关注服装区域并处理在虚拟试穿中的服装变形。

在时尚应用的图像合成方面,Yoo等人以产品图像为条件生成了一个穿衣服的人物,而不考虑人物的姿势。Lassner等人介绍了一个穿着衣服的人物生成模型,但不清楚如何控制生成结果中的衣服。另个一相关的工作是FashionGAN,它将一个人身上的衣服替换成由文本描述指定的新衣服。相比之下,我们关注的是用目标衣服精确替换参考图像中的服装衣服,并通过一个新颖的从粗到细的框架解决这个问题。

虚拟试穿
在虚拟试穿方面已经有了大量的工作,大部分是在计算机图形学方面进行的。Guan等人提出了DRAPE,这是在不同形状和姿势的三维人体上,模拟二维服装进行设计。Hilsmann和P . Eisert根据运动模型对服装进行动态重新贴图,以便在虚拟镜像环境中实现实时可视化。Sekine等人介绍了一个虚拟试衣系统,通过用深度图像推断用户的身体形状来调整2D服装图像。最近,Pons-Moll等人利用衣着身体的多部分三维模型进行服装捕捉和重定位。Yang等人从单视图的二维图像中恢复了服装的三维网格,并进一步将其重新定位到其他人体上。在我们的工作中,与依靠三维测量来进行精确的衣服模拟相比,我们专注于直接从二维图像中合成一个感知上正确的照片图像,这在计算上更有效率。在计算机视觉中,有限的工作探索了虚拟试穿的任务。最近,Jetchev和Bergmann提出了一个条件类比的GAN来交换衣服。然而,在测试过程中,他们需要目标衣服和原始衣服在人物身上的图像,这使得它在实际场景中不可行。此外,在没有提供任何人物表征或明确考虑变形的情况下,它不能产生照片般真实的虚拟试穿结果。

3.VITON

VITON的目标是,给定一个穿着衣服的人物图像 I 和目标衣服 c ,合成一个新的图像 I’ ,其中 c 被自然转移到该人物的相应区域,其身体部位和姿势信息被保留下来。高质量合成的关键是要学习从衣服图像到身体上的衣服的适当转换。一个直接的方法是利用具有固定姿势的,穿着不同衣服的人的训练数据和衣服的产品图像,然而,这通常很难获得。
在实际的虚拟试穿场景中,在测试时只有一张人物参考图像和一张所需的衣服图像可用。因此,我们采用同样的设置来进行训练,给定一个穿着衣服 c 的人的参考图像 I 和 c 的衣服图像作为输入(在下文中我们将用c 来指代衣服图像)。现在的问题是,给定衣服图像c 和人物的信息,如何学习一个生成器,不仅在训练中产生 I ,而且更重要的是在测试时能够有泛化能力,即合成一个具有任意所需服装的,感知上令人信服的图像。
为此,我们首先介绍了一个与服装无关的人物表示(clothing-agnostic person representation)(第3.1节)。然后,我们以人物表示和目标服装图像为条件,用一个编码器-解码器架构来合成参考图像(第3.2节)。由此产生的粗略结果被进一步改进,然后用一个精细的网络来解释详细的视觉模式和变形(第3.3节)。图2说明了整个流程的框架。

3.1 人物表示

虚拟试穿的一个主要技术挑战是对目标服装图像进行变形以适应人的姿势。为此,我们引入了一个与服装无关的人物表征,它包含一组特征(图3),包括姿势、身体部位、面部和头发,作为约束合成过程的先验知识。

姿势热图
人物姿势的变化会导致服装不同的变形,因此我们用最先进的姿势估计器对姿势信息进行清晰的建模。一个人的计算姿势被表示为18个关键点的坐标。为了利用它们的空间布局,每个关键点被进一步转化为热图,在关键点周围的11×11的邻域中,用1和0填充其他地方。来自所有关键点的热图被进一步堆叠成一个18通道的姿势热图。

人体表示
服装的外观很大程度取决于人物体形,因此如何转换目标衣服取决于不同身体部位(如手臂或躯干)的位置和身体形状。因此,我们用一个最先进的人体分析器来计算人体分割图,其中不同的区域代表人体的不同部位,如手臂、腿等。我们进一步将分割图转换为一个单通道的二进制掩码,其中“1”表示人体(除了脸和头发),其他地方为“0”。这个直接来自 I 的二进制掩码被降维到一个较低分辨率的图(如图3所示的16×12),以避免在身体形状和目标衣服冲突时出现伪影。
图3
图3- 一个与服装无关的人物表示。给定一个参考图像 I ,我们提取人物的姿势、身体形状、脸部和头发区域,并将这些信息作为我们的生成器的部分输入。

面部和头发部分
为了保持人的身份,我们加入了脸部、肤色、发型等物理属性。我们使用人类解析器来提取人的面部和头发区域的RGB通道,以便在生成新图像时加入身份信息。

最后,我们将这三个特征图调整到相同的分辨率,然后将它们串联起来,形成一个与衣服无关的人的表示 p ,这样 p ∈R^(m×n×k),其中m=256和n=192表示特征图的高度和宽度,k=18+1+3=22表示通道的数量。该表征包含了关于人的丰富信息,在此基础上进行卷积以建立其关系模型。请注意,我们的表示比以前的工作更详细。

3.2 多任务编码-解码生成器

给定的与服装无关的表示p和目标服装图像c,我们提出通过重构来合成参考图像I,这样就可以学习从c到p的相应区域的自然转移。特别地,我们利用了一个多任务编码器-解码器框架,该框架生成了一个穿着衣服的人的图像,同时也生成了该人衣服的二进制掩码(mask)。除了引导网络关注服装区域外,预测的服装掩码将被进一步利用来完善生成的结果,这一点将在第3.3节中讨论。编码器-解码器是一种通用的U型网结构,具有跳过连接,通过绕过连接直接在各层之间分享信息的特点。

从形式上看,让GC来表示由编码器-解码器生成的近似的函数值。它以串联的c和p为输入,产生一个4通道的输出(I′,M)=GC(c,p),其中前3个通道代表合成图像I′,最后一个通道M代表服装区域的分割掩码,如图2顶部所示。我们希望学习一个生成器,使I′接近参考图像I,M接近M0(M0是人体解析器在I上预测的伪真值服装掩码)。一个简单的方法是用L1损失来训练网络,当目标是像M0这样的二进制掩码时,它可以产生不错的结果。然而,当期望的输出是彩色图像时,L1损失往往会产生模糊的图像。继[22, 27, 7]之后,我们利用了一种感知损失,它模拟了由视觉感知网络计算的合成图像的相应特征图和真实图像之间的距离。编码器-解码器的损失函数现在可以写成感知损失和L1损失之和:
公式1
其中第一项中的Фi(y)是视觉感知网络Ф中第 i 层的图像y的特征图,该网络是在ImageNet上预先训练的VGG19[42]网络。对于大于1的层,我们利用VGG模型的’conv1 2’、‘conv2 2’、‘conv3 2’、‘conv4 2’、‘conv5 2’,而对于第0层,我们直接使用RGB像素值。超参数λi控制第i层对总损失的贡献。感知损失使合成图像与真实图像的RGB值及其在视觉感知模型中不同层的激活相匹配,使合成网络能够学习真实的模式。公式1中的第二项是回归损失,用来预测的服装掩码M与M0相同。

通过最小化公式1,编码器-解码器学习了如何在人物表示的条件下转移目标服装。虽然合成的人物符合原始图像中的姿势、身体部位和身份(如图5第三列所示),但目标衣服的细节,如文字、标志等会消失。这可能是由于目前的生成器对合成过程的控制能力有限。它们通常优化合成的图像,使其看起来像真实的图像,而不知道在哪里以及如何生成细节。为了解决这个问题,VITON使用一个细化网络和预测的服装掩码M来改善粗糙的结果I′。

3.3 细化网络

VITON中的细化网络GR被训练成,利用变形的目标衣服的现实细节,来渲染粗糙的模糊区域。
服装变形
我们直接借用目标服装图像 c 的信息来填补粗糙样本生成区域中的细节。然而,直接粘贴衣服图像是不合适的,因为衣服的变形是以人的姿势和身体形状为条件的。因此,我们通过估计薄板样条(TPS)变换和形状上下文匹配来进行衣服变形,如图4所示。更具体地说,我们提取c的前部掩码( foreground mask),并用公式1估计该掩码与人的衣服掩码 M 之间的形状上下文TPS变化。这些计算出来的TPS参数被进一步应用于将目标服装图像 c 转化为一个扭曲的版本 c’ 。结果,扭曲的服装图像符合人的姿势和体形信息,并完全保留了目标物品的细节。这个想法类似于最近用于人脸合成的2D/3D纹理变形方法,其中2D面部关键点和3D姿势估计被用来进行变形。相比之下,由于缺乏准确的服装项目注释,我们依赖于基于形状上下文的变形。注意到用形状上下文匹配来估计TPS的一个潜在的替代方法是,像[23]那样通过一个连体网络来学习TPS参数。然而,这对非刚性衣服来说特别具有挑战性,我们根据经验发现,直接使用上下文形状匹配可以为虚拟试穿提供更好的变形结果。
在这里插入图片描述
图4-衣服变形图像 给定目标衣服图像和第一阶段预测的服装掩码,我们使用形状上下文匹配来估计TPS变换,并生成一个扭曲的服装图像。

学习合成
将变形的服装 c’ 合成到粗糙的合成图像 I’ 上,希望能将 c’ 与服装区域无缝结合,并在手臂或头发在身体前面的情况下正确处理遮挡。因此,我们学习如何用细化网络进行合成。如图2的底部所示,我们首先将 c’ 和粗糙的输出 I’ 连接起来,作为细化网络GR的输入。然后,细化网络产生一个单通道的组合掩码α∈(0,1)m×n,表示从两个来源,即变形的服装项目c′和粗糙的图像I′中各利用了多少信息。VITONˆI的最终虚拟试穿输出是 c’ 和 I’ 的组合。
在这里插入图片描述
其中,⊙代表元素矩阵乘法。为了学习最佳的组合掩码,我们尽量减少生成的结果 I’ 和参考图像 I之间的差异,其感知损失Lpercas公式1为:
在这里插入图片描述
其中Ф表示视觉感知网络VGG19。这里我们只用’conv3 2’, ‘conv4 2’, 'conv5 2’来计算这个损失。由于视觉感知网络的低层更关心图像的详细像素级信息,而不是其内容,I和I’之间的小位移(通常由不完美的扭曲引起)将导致低层(‘conv1’和’conv2’)的特征图之间的较大不匹配,然而,这在虚拟试穿中是可接受的。因此,通过只使用较高的层,我们鼓励模型忽略不完善的变形的影响,因此它能够选择变形的目标服装图像并保留更多的细节。

我们用L1准则和总变异(TV)准则进一步规范GR生成的组合掩码输出,细化网络的全部目标函数就变成了:
在这里插入图片描述
其中λwarp和λT V分别表示L1准则和TV准则的权重。最小化负的L1项鼓励我们的模型利用更多来自扭曲的服装图像的信息,呈现更多的细节。总变异正则||∇α|||对生成的合成掩码α的梯度进行均衡,使其在空间上变得平滑,这样可以使扭曲区域到粗糙结果的过渡看起来更加自然。
在这里插入图片描述
图5-我们方法中不同步骤的输出 通过学习合成掩码(composition mask),进一步提高了编码解码器产生的粗糙合成结果的细节和以及进行变形。

图5直观地显示了我们的方法在不同步骤中产生的结果。考虑到目标服装和人的表现,编码器-解码器产生了一个粗糙的结果,其中保留了人的姿势、体形和脸部,而目标服装上的图形和纹理等细节则不见了。基于服装掩码,我们的细化阶段对目标服装图像进行扭曲,并预测出一个组成掩码,以确定哪些区域应该在粗略的合成图像中被替换。因此,从目标服装图像中 "复制 "的重要细节(第一个例子中的材料,第二个例子中的文字,以及第三个例子中的图案)被 "粘贴 "到人物的相应服装区域。

4.实验

4.1 Zalando 数据集

在[21]中使用的数据集是进行虚拟试穿实验的一个很好的选择,但它并不公开可用。因此,我们从与[21]相同的网站(www.zalando.de)收集了我们自己的数据集–Zalando(现在也不公开了)。我们首先抓取了大约19,000个正面视角的女性和顶部服装图像对,然后删除了没有解析结果的噪声图像,得到了16,253对图像。剩下的图像被进一步分成训练集和测试集,分别有14,221和2,032对。需要注意的是,在测试过程中,这个人应该像现实世界的场景一样,穿着与目标不同的服装,所以我们在这2,032个测试对中随机地混合了一下服装图像来进行评估。

4.2 实验细节

训练设置
根据最近使用编码器-解码器结构的工作,我们使用Adam优化器,其中β1=0.5,β2=0.999,固定学习率(learning rate)为0.0002。我们对编码-解码器生成器器进行了15K步的训练,对细化网络进行了6K步的训练,两者的batch size都是16。合成样本的分辨率为256×192。
编码解码器
我们粗糙阶段的网络包含6个卷积层,分别用于编码和解码。所有的编码层由跨度(stride )为2的4×4空间滤波器组成,其滤波器的数量分别为64、128、256、512、512、512。对于解码器,所有层都采用类似的4×4空间滤波器,跨度(stride )为1/2,其通道数分别为512、512、256、128、64、4。 激活函数和批量归一化的选择与[20]相同。为了提高性能,在编码器和解码器之间加入了跳过连接。 λi在公式1中的选择是为了适当地调整每个项的损失[6]。
细化网络
该网络是一个四层的全卷积模型。前三层中的每一层都有3×3×64的滤波器,然后是Leaky ReLUs,最后一层用1×1的空间滤波器输出组成的掩码,然后是一个sigmoid激活函数,将输出内容扩展到(0,1)之间。公式4中的λi与公式1相同,λwarp= 0.1,λT V= 5e - 6。
运行时间
VITON中每个组件的运行时间为:人体解析(159ms),姿势估计(220ms),编码器解码器(27ms),TPS(180ms),细化网络(20ms)。除TPS以外的结果是在K40 GPU上获得的。我们期望在GPU上实现TPS时能进一步加速。

4.3 比较方法

为了验证我们框架的有效性,我们与以下替代方法进行了比较。
有人物代表的GANs (GANs with Person Representation(PRGAN))
现有的以姿势或身体形状信息为条件的GANs方法不能直接进行比较,因为它们不是为虚拟试穿任务设计的。为了实现公平的比较,我们将[51, 32]的输入丰富到与我们的模型相同(22通道表示,p + 目标服装图像c),并采用他们的GAN结构来合成参考图像。
条件类比GAN(Conditional Analogy GAN (CAGAN))
CAGAN将虚拟试穿任务表述为一个图像类比问题–它在训练Cycle-GAN时将原始衣服和目标衣服一起作为一个条件[50]。然而,在测试时,它还需要参考图像中原始服装的产品图像,这使得它在实际场景中不可行。但为了完整起见,我们与这种方法进行了比较。请注意,为了公平起见,我们修改了他们的编码器-解码器发生器,使其具有与我们相同的结构,从而也能生成256×192的图像。其他实现细节与[21]相同。
级联细化网络(Cascaded Refinement Network(CRN))
CRN利用一个级联的细化模块,每个模块从其前一个模块的输出和输入的下采样版本,生成一个高分辨率的合成图像。在没有对抗性训练的情况下,CRN使用CNN网络对目标图像进行回归。为了与CRN进行比较,我们将我们的生成器的相同输入送入CRN,并输出256×192的合成图像。
编码-解码生成器
我们只用第一阶段的网络来产生目标的虚拟试穿效果,而不使用TPS变化和细化网络。
非参数化的变化合成
在不使用我们的编码-解码器生成器的粗糙输出的情况下,我们使用形状上下文匹配来估计TPS变换,并将变形的服装粘贴在人物如下上。[51]中也提出了一个类似的思想。
前三种最先进的方法与我们的编码器-解码器生成器直接进行了比较,没有明确地对变形进行建模,而最后一种非参数变形合成方法被采用,来证明基于粗糙结果的学习合成的重要性。

4.4 定性结果

图6展示了不同方法在视觉上的比较。CRN和编码-解码器产生了模糊和粗糙的结果,而不知道在哪里以及如何渲染目标服装的细节。带有对抗性训练的方法会产生更多的边缘模糊,但也会造成不理想的伪影。非参数基线直接将扭曲的目标图像粘贴到人身上,而不考虑原始衣服和目标服装之间的不一致,这导致了不自然的图像。与这些方法相比,VITON准确而无缝地生成了详细的虚拟试穿结果,证实了我们框架的有效性。
在这里插入图片描述
图6-不同方法的定性比较我们的方法有效地将目标衣物给一个人穿上。

然而,在最后一行的领口周围有一些伪影,这是因为我们的模型不能确定哪些靠近脖子的区域应该是可见的(例如,在最终结果中,脖子上的标签应该被隐藏起来,更多讨论见补充材料)。此外,在没有提供任何产品图片的情况下,裤子也是由我们的模型生成的。这表明我们的模型隐含地学习了不同时尚物品之间的共现性。如果以类似于脸部和头发的方式处理裤子区域(即提取裤子区域并将其作为编码器的输入),VITON也能够保持原始的裤子。更多结果和分析见补充材料。
人物表示分析
为了研究姿势和身体形状在人物表示中的有效性,我们将它们从表示中单独删除,并与我们的完整表示进行比较。采样的粗糙结果如图7所示。我们可以看到,对于一个具有复杂姿势的人来说,仅仅使用体形信息是不足以处理遮挡和姿势模糊的情况。体形信息对于将目标衣服调整到合适的尺寸也是至关重要的。这证实了所提出的与服装无关的人物表示确实比先前的工作更全面和有效。
失败的例子
图8展示了我们的方法的两个失败案例,一个是由于很少见到的姿势(例如左图)或当前和目标服装形状的巨大不匹配(右手臂在右边)。
在这里插入图片描述图8-失败的例子

在户外照片上的结果
除了用有约束的图像进行实验外,我们还利用COCO数据集中的未处理的图像,通过裁剪人体区域并在其上运行我们的方法。图9显示了样本结果,这表明我们的方法在虚拟试穿等应用中具有潜力。
在这里插入图片描述
图9-在户外照片上的结果 将我们的方法应用在COCO数据集上

4.5 定量结果

我们还根据Inception Score和用户研究,将VITON与其他方法进行定量比较。
Inception Score
Inception Score(IS)通常被用来定量评估图像生成模型的合成质量。产生视觉上多样化和语义上有意义的图像的模型会有较高的评分,这个指标与人类对图像数据集(如CIFAR10)的评价有很好的相关性。
用户感知研究
虽然Inception Score可以作为图像合成质量的一个指标,但它不能反映出目标服装的细节是否被自然地转移,或者在合成的图像中是否保留了人的身体和姿势。因此,与[6,9]类似,我们在Amazon Mechanical Turk(AMT)平台上进行了一项用户研究。在每次试验中,给用户一个人像、一个目标服装图像和两个由两种不同方法产生的虚拟试穿结果(都是256×192)。然后用户被要求选择在虚拟试穿情况下更真实和准确的方法。每个AMT工作包含5个这样的试验,时间限制为200秒。这是一种被评为比其他方法更好的人类评价指标。
表1中总结了定量比较的情况。请注意,人物的得分评估了虚拟试穿的结果,即有人穿着目标衣服的合成图像是否真实。然而,我们没有这样的真实图像,即同一个人以同样的姿势穿着目标衣服(IS衡量一个集合的特征,所以我们使用测试集中的所有参考图像来估计真实数据的IS)。
在这里插入图片描述
表1-在Zanlando数据集上的定量评价
根据这个表格,我们得出以下结论。(a) 像Inception Score这样的自动测量方法不适合于评价像虚拟试穿这样的任务。原因有两个方面。首先,这些评价倾向于让由对抗性训练或直接粘贴图像产生的更清晰的图像内容得更高分,因为它们在Inception模型中的神经元激活值比光滑图像的激活值高。这甚至会导致非参数基线比真实图像的IS更高。此外,他们没有也不知道我们的任务是什么,不能测量虚拟试穿系统的预期属性。例如,CRN的IS最低,但在用户研究中排名第二。类似的现象也在[27,6]中观察到。(b) 人们更倾向于使用人像表示法(PRGAN, CRN, EncoderDecoder, VITON)。CAGAN和Non-parametric直接将原始人像作为输入,所以它们不能处理原始衣服和目标衣服不一致的情况,例如,在穿着长袖衬衫的人身上渲染短袖T恤;(c)通过将粗糙的结果与扭曲的服装图像合成,VITON的表现比每个单独的组件更好。与最先进的生成模型相比,VITON还获得了更高的用户评价分数,并输出了更多照片般真实的虚拟试穿效果。
为了更好地了解研究的噪音,我们按照[6,32]在AMT上进行限时(0.25s)的真假测试,结果显示17.18%的生成图像被评为真实,11.46%的真实图像被评为生成。

5.结论

我们提出了一个虚拟试穿网络(VITON),它能够仅依靠RGB图像将图像中的衣服转移到一个人身上。首先用一个多任务编码器-解码器生成一个粗糙的样本,其条件是一个详细的与服装无关的人的代表。粗糙的结果通过一个细化网络进一步细化,该网络学习了最佳的构成。我们在一个新收集的数据集上进行了实验,在数量和质量上都取得了不错的结果。这表明我们基于二维图像的合成方法可以作为昂贵的三维方法的替代品。

都看到这里了,点个赞再走吧~

虚拟试衣:Virtual Try-on Network系列工作 虚拟试衣:Virtual Try-on Network系列工作 前言:原先在知乎上用Markdown+LaTex编辑的插件失效了,稍微修正了下长公式,短的符号就不一一修改了。最佳浏览体验见:http://grayxu.cn/2019/07/30/VITON/ 介绍 本文主要讲在2D虚拟试衣这个任务上两个效果比较好的工作。主要是两篇文章,一篇是VITON: An Image-based Virtual Try-on Network发于CVPR 2018,另一篇是Toward Characterist.. 阅读详情

相关推荐

基于图像的虚拟试衣:Image Based Virtual Try-On Network from Unpaired Data

Image Based Virtual Try-on Network from Unpaired Data Image-Based-Virtual-Try-on-Network-from-Unpaired-Data 摘要 本文提出了一种新的基于图像的虚拟试穿方法(Outfit-VITON),该方法可帮助可视化从各种参考图像中选择的衣物组成如何在查询图像中的人身上形成凝聚力的衣服。我们的算法具有两个独特的属性。首先,它不昂贵,因为它只需要一大套穿着各种服装的人的(独立的)(真实的和分类的)图像(没有真实的3

studyeboy的专栏 3195

虚拟换衣 VITON 论文笔记

VITON 应该是第一篇专注于图像的换衣论文了,发表于2018年的CVPR,后续的很多虚拟换衣的工作都是基于这篇文章,可以说是图像换衣领域的开山之作了。 该算法目的很明确,就是给定两张图像,一张是包含穿着任意衣服的人的图像,另一张是一件衣服的图像,算法就会生成一张这

落队的飞行兵 6264

虚拟试衣:在DeepFashion数据集上使用VITON或CP-VTON模型进行虚拟试衣任务

VITON(Virtual Try-On Network)和CP-VTON(Cloth-Parsing Virtual Try-On Network)是两种常用的虚拟试衣模型。姿势估计网络用于提取用户的姿势信息,试穿模块将提取的姿势信息与给定的衣物进行匹配,生成虚拟试穿效果。CP-VTON模型是基于VITON模型的改进版本,它在衣物分割和姿势估计方面做了优化,从而提供更好的虚拟试衣效果。在使用VITON或CP-VTON模型进行虚拟试衣任务时,你可以根据具体的需求和数据集进行相应的调整和优化。

PzBlockchain的博客 1066

数据集 VITON-HD (High-Resolution VITON-Zalando Dataset) 虚拟换装 >> DataBall

VITON-HD 数据集是用于高分辨率(即 1024x768)虚拟试穿服装的数据集。具体来说,它由 13,679 个正面女性和顶级服装图像对组成。

DATABALL 的博客 1216

虚拟试衣:使用VITON或CP-VTON模型在DeepFashion数据集上进行虚拟试衣任务

欢迎来到我们的博客!在这篇文章中,我们将深入探讨虚拟试衣技术,使用VITON和CP-VTON模型在DeepFashion数据集上进行虚拟试衣任务。虚拟试衣技术旨在为用户提供一个在线平台,使他们能够在购买之前预览衣物的外观和合适程度。这可以帮助提高购物体验,同时减少退货率。我们将会用Python语言编写代码,并将一步步地解释每个部分。

斌擎科技 1208

提取数据matlab代码-VITON:论文“基于图像的虚拟试穿网络”的代码和数据集

提取数据matlab代码VITON:基于映像的虚拟试穿网络 CVPR 2018论文“ VITON:基于图像的虚拟试穿网络”的代码和数据集 人像提取 本文使用的人物表示由2D姿态估计器和人工解析器提取: 数据集 由于版权问题,该数据集不再公开可用。 对于已经下载数据集的用户,请注意使用或分发它是非法的! 测试 第一阶段 在上下载预训练的模型。 将它们放在model/文件夹下。 运行test_stage1.sh进行推断。 结果在results/stage1/images/ 。 results/stage1/index.html可视化结果。 第二阶段 运行matlab脚本shape_context_warp.m以提取TPS转换控制点。 然后, test_stage2.sh将进行细化并生成最终结果,该results/stage2/images/位于results/stage2/images/ 。 results/stage2/index.html可视化结果。 火车 准备数据 进入prepare_data 。 首先运行extract_tps.m 。 这将需要一些时间,您可以尝试并行运行它,也可以

VITON: An Image-based Virtual Try-on Network虚拟试衣网络论文翻译

引用论文: Han, X., Wu, Z., Wu, Z., Yu, R., Davis, L.S.: Viton: An image-based virtual try-on network. arXiv preprint arXiv:1711.08447 (2017) CVPR 2018 Github:https://github.com/zaoqiweixaio/VITON 话说想要跑通VI...

weixin_41971682的博客 2302

datasets-for-test_of_VITON-HD.zip

test datasets file for VITON-HD

【虚拟试衣论文笔记】C-VTON: Context-Driven Image-Based Virtual Try-On Network

论文地址:https://openaccess.thecvf.com/content/WACV2022/papers/Fele_C-VTON_Context-Driven_Image-Based_Virtual_Try-On_Network_WACV_2022_paper.pdf 项目地址:https://github.com/benquick123/C-VTON 作者提出了一个上下文驱动的虚拟试穿网络 (C-VTON),即使在具有挑战性的姿势配置和存在自我遮挡的情况下,也能令人信服地将选定的服装区..

bikahuli的博客 5158

public datasets@wibo-数据集

这个数据集是来自网络的公共数据集

StarRocks FE启动异常

服务器断电,StarRocks FE 启动失败。

qq_15138049的博客 1113

推荐项目:C-VTON - 软件驱动的图片虚拟试穿网络

推荐项目:C-VTON - 软件驱动的图片虚拟试穿网络 在数字化时尚领域中,图像虚拟试穿技术为提升用户体验和顾客满意度带来了重大突破。C-VTON(Context-Driven Image-Based Virtual Try-On Network)是一个创新的解决方案,它解决了在处理多样性和复杂性的输入图像时产生的问题,如不同的姿势和自我遮挡。该项目的目标是生成逼真且视觉上令人信服的试穿效果,进一...

gitblog_00061的博客 487

【机器学习实战中阶】音乐流派分类-自动化分类不同音乐风格

数据下载地址:https://www.kaggle.com/datasets/andradaolteanu/gtzan-dataset-music-genre-classification/data背景音乐。专家们长期以来一直在尝试理解声音以及是什么使一首歌曲与另一首不同。如何可视化声音。是什么使一个音调与另一个不同。这个数据集希望能提供实现这些目标的机会。内容原始流派 - 包含10种流派,每种流派有100个音频文件,每个文件长度为30秒(著名的GTZAN数据集,声音的MNIST)

2145

虚拟换装知识脉络

近年来,随着电商的兴起,大量的关于虚拟试衣的论文被发表。本文梳理一下相关脉络。

祥瑞的技术博客 1901

车载导航测试,面试常见问题

车载导航测试是汽车软件测试的重要组成部分,涉及验证导航系统的功能、性能、可靠性和用户体验。在面试中,面试官通常会考察候选人的测试思维、问题解决能力和实际经验。以下我将从常见问题类别入手,逐步介绍面试中的高频问题,并提供结构化分析。通过以上结构化准备,你能在面试中自信应对车载导航测试相关问题。用户体验测试关注界面友好性和交互流畅性,安全测试则涉及功能安全和数据隐私。功能测试聚焦于导航核心功能的正确性,如路线规划、位置定位和地图显示。面试官会考察你如何识别、报告和跟踪缺陷,以及熟悉测试工具。

m0_69889939的博客 527

Memory SystemsCache, DRAM, Disk翻译学习DRAM部分(二)

DRAM 的发展史

qq_33473931的博客 995

基于图像的虚拟换装:Morphing architectures for pose-based image generation of people in clothing

项目的重点是变形操作的特征化与实现,解决卷积神经网络中的信息失准问题。我们将所研究的方法应用到一个换衣服的任务中,将其建模为一个条件图像生成问题。尽管对抗性方法在生成性任务中很流行,但我们将此项目的范围限制为监督方法,因此有助于变形操作的学习。尽管在三维建模的深度学习领域取得了令人兴奋的进展,但我们将这个项目的范围限制在二维图像上。 ...

studyeboy的专栏 2772

Playwright Java环境配置避坑指南:浏览器路径、类加载与离线部署

Playwright作为现代端到端测试框架,其Java SDK突破了传统Selenium的Driver管理模式,将Chromium/Firefox/WebKit内核视为可编程运行时资源。其核心原理在于SDK与浏览器二进制分离——Maven仅管理Java字节码,而浏览器需独立下载、校验与沙箱加载。这一设计带来显著技术价值:跨平台一致性、进程隔离安全性及多浏览器并行能力;典型应用场景涵盖Spring Boot集成测试、金融级离线CI/CD、Kubernetes容器化部署及Air-Gapped封闭环境。然而,因J

weixin_32956805的博客 678

Virtual Try-On with Pose-Garment Keypoints Guided Inpainting-基于姿态服装关键点引导的虚拟试穿修复

虚拟试穿是一项支持在线服装购物的重要技术,它为消费者提供了一种虚拟体验,让他们在不穿衣服的情况下试穿衣服。近年来,基于图像的虚拟试戴受到越来越多的研究关注。然而,现有的虚拟试穿方法的合成结果往往存在服装形状失真和图案细节缺失的问题。本文针对基于图像的虚拟试衣任务,提出了一种姿态-服装关键点引导的绘制方法,该方法能够生成高保真度的试衣图像,并能很好地保留服装的形状和图案。在我们的方法中,从源图像中提取人体姿态和服装关键点,并构造成图形来预测目标姿态下的服装关键点。

weixin_45984209的博客 874

Avellaneda & Stoikov模型实战解析:如何动态调整做市策略参数

本文深入解析Avellaneda & Stoikov模型在动态调整做市策略参数中的应用,重点探讨库存状态、剩余时间、风险系数和订单深度等核心参数的实战技巧。通过加密货币市场的实际案例,展示如何根据市场波动和流动性动态调整参数,提升做市策略的盈利能力和风险控制水平。

weixin_29070861的博客 202

opencode : 无法将“opencode“项识别为 cmdlet、函数、脚本文件或可运行程序的名称 解决方案

opencode命令识别问题与openclawcodexgemini确保的路径在 PATH 中。这个知识对所有 npm 全局工具通用。

一键难忘的博客 4521

【亲测免费】 VITON-HD:高分辨率虚拟试衣技术的革命性突破

VITON-HD是由KAIST的研究团队开发的一款高分辨率虚拟试衣系统,该系统在CVPR 2021上首次亮相,并迅速引起了广泛关注。VITON-HD的核心目标是通过先进的图像处理技术,将目标衣物无缝地“穿”在人物图像上,生成高分辨率(1024x768)的虚拟试衣效果图。这一技术的突破不仅提升了用户体验,还为在线购物、时尚设计等领域带来了新的可能性。 ## 项目技术分析 VITON-HD的技术架...

gitblog_01026的博客 803

Unity之ASE+ShaderGraph+VFX入门到精通 目录

这里是ASE+ShaderGraph+VFX从入门到精通专栏的目录,不停更新中,有问题随时留言或者私信。

TxNet 2841

AI一键换衣神器 终于把老黄的黑皮夹克给换了

下载 VITON-HD 数据集后,将 vitonhd_test_tagged.json 移动到测试文件夹中。我们使用 detectorron2 来获取密集姿态图像,请参阅 此处 了解更多详细信息。下载 DressCode 数据集后,放置图像密集目录和标题文本文件,如下所示。您可以从 VITON-HD 下载 VITON - HD 数据集。对于 DressCode 数据集,通过类别参数输入要生成图像的类别,我们在这里 提供预先计算的密集姿势图像和服装标题。在此处 下载用于人工解析的检查点。

文浩Marvin的博客 1482

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

StableVITON模型论文及训练报错记录

StableVITON模型论文概述以及项目运行过程报错记录

m0_73835785的博客 1446

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

超110篇!CVPR 2021最全GAN论文汇总梳理!

戳我,查看GAN的系列专辑~!下述论文已分类打包好!超110篇,事实上仍有一些GAN论文未被包含入内……可见GAN在CVPR 2021仍十分火热。后台回复2021GAN(长按红字、选...

idol24的博客 6939

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

上一篇: viton-gan踩坑记录
Pomprogram
博客等级 码龄9年 18粉丝 2原创
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值