【传知代码】无监督动画中关节动画的运动表示(论文复现)

前言:在数字动画的广袤领域中,关节动画以其真实、流畅的运动表现,一直占据着举足轻重的地位。无论是电影中的震撼特效,还是游戏世界的角色互动,关节动画都以其细腻的运动表现,赋予虚拟世界以生动与活力。然而,随着技术的不断进步和观众对视觉体验要求的日益提高,如何更加高效、智能地生成和表示关节动画的运动,成为了我们面临的重要挑战。

本文所涉及所有资源均在传知代码平台可获取

目录

概述

演示效果

核心代码实现

写在最后


概述

        动画在教育和娱乐等多个领域得到了广泛的运用,同时也强调了动画在内容创意、故事叙述清晰度和用户体验方面的显著提升。过去,要达到这些动画效果,通常都需要接受过专门培训的技术人员、特定的硬件和软件,以及大量的实际操作。尽管目前仍需专业的知识和持续的努力,但在视觉和图形领域,通过对某些已知的对象类别进行数据驱动方法的培训,我们试图克服其中的某些局限性。

        近年来,有些工作试图通过运动转移进行无监督,以规避真实数据要求。通过采用图像重建为损失函数,并对运动与外观进行解耦,使训练有明显的进步。如果不需要领域知识和标记数据,只需要利用物体正在移动的视频来训练就可以了,因此可望实现面向更大范围物体范畴的动画制作。但仍有两大关键问题。一是怎样表达关节或者非刚性运动物体的各部位,包括其外形与姿态。二是给定物体的每一部分如何利用驱动视频的运动序列为其动画。以往尝试采用端对端框架先提取无监督关键点,再通过在驱动视频关键点中嵌入源图像特征进行对齐。在随后的工作中,进一步建模各关键点附近的移动情况,引入生成模块不仅综合出变形后的源图像区域,而且还对遮挡区域进行修复,从而渲染出最终的图像。这样便可实现多种创意应用,比如仅需要一幅源脸部图像便可产生以不同面部的录像为动力的几乎图片真实的动画。尽管边缘上的点更容易识别,但在帧之间跟踪这些关键点却很困难,因为边界上的任何点都是有效的候选点,很难建立帧之间的对应关系。另外,这几个无监督产生的关键点与语义中含义明确的对象部分不相对应,它们只指示位置与方向而非形状。由于这些限制,动画化关节对象(如人体)仍然具有挑战性。而这些方法都假定背景为静止状态,也就是不存在相机运动的情况,这就造成了在检测过程中有一个或者几个关键点漏掉了背景的运动信息。最后绝对运动转移把被驱动物体的外形传递给所产生的顺序以减少源身份保真度。这些问题制约着以往工作中对较为复杂的物体类别及运动特别是物体关节运动的处理应用。

        这项研究为解决挑战提出三个主要贡献。首先,它通过使用区域测量方式而非传统的回归方法,重新定义了基本的运动表示,这不仅使得模型收敛性更强,而且提升了对象与运动的表示稳定性和鲁棒性,同时还能更好地揭示物体底部的形状,从而优化运动分割效果。其次,模型通过预测参数来表达训练帧之间背景或相机的全局仿射变换,明确模拟与前景无关的运动,提高了模型对前景对象的关注度,增强了点的稳定性并改善了收敛速度。最后,通过在无监督区域内分离对象的形状和姿态,防止形状变异并优化动画表现。这个框架采用自监督机制,无需任何标签,并通过重建损失来进行优化。

        这些建议为无监督的运动转移技术带来了进一步的优化,尤其是在关节对象的高保真度动画制作上。为了构建一个更具挑战性的基准测试环境,作者设计了一个全新收集的TED演讲演讲者数据集。他们所构建的框架在无监督区域的数量方面表现出更高的可扩展性,并引发了更为深入的动态变化。与过去的无监督动画技术相比,这种方法在多种数据集上的表现都更为出色,涵盖了对话面部、太极视频以及动画像素的艺术形式。

图像动画方法可以大致分为监督无监督两类,每种方法都有其独特的挑战和局限性。这篇总结概述了这两类方法中的已有工作,为论文关注的无监督方法提供背景。

通过无监督区域检测实现的静止源图像动画图片如下:

监督图像动画:在训练过程中,监督方法需要对动画对象有一定的先验知识,这些通常以地标、语义分割或参数化的3D模型的方式存在。由于缺少视觉上可见且可交互操作的特征信息,这种基于图像的方法无法满足对目标识别和跟踪任务的要求。这些技术方法受到标记数据需求的制约,只适合于那些拥有大量标记数据的特定对象类别,如面部和人体。因此,为了获得更多可用于不同应用中的视觉信息,我们提出一种基于深度学习的人脸重建算法。在早期的面部重塑过程中,人们采用了3D的可塑模型,并利用图像技术来实现动画和渲染效果。为了提升渲染的品质,神经网络后续被采纳,这在某些情况下可能涉及到多个身份的图像。

在监督方法中,动画被视为从图像到图像或从视频到视频的转化过程,这一问题仅限于对单一对象实例进行动画处理,不论其面部特征还是身体构造。针对这一挑战,本文提出了一种基于局部特征和全局信息相结合的方法来解决该问题,并设计出相应算法。虽然这些策略已经取得了某些积极的成果,但在更宽泛的目标类别中进行泛化依然是一个具有挑战性的任务。因为不同种类的对象可能是由不同类型和数量的模型构成的复杂系统。除此之外,它们通常不只是传达了动作信息,还传达了驱动目标的外形。

无监督图像动画:无监督方法旨在克服监督方法的局限性,通过消除对动画对象形状或地标的标记数据的需求。这一类别包括基于视频生成的动画方法,其根据初始帧和动画类别标签预测未来帧 。值得注意的是,Menapace等人引入了可玩的视频生成,允许在每个时间戳选择动作 。另一组无监督方法专注于将动画从驱动视频重新定向到源帧。X2Face构建了输入面的规范表示,生成了一个基于驱动视频的变形场 。Monkey-Net学习无监督关键点以生成动画,随后的工作,包括第一阶段运动模型(FOMM),通过考虑每个关键点的局部仿射变换来增强动画质量。从经验上看,这些无监督方法通常在动画对象的边界上提取关键点,对于人体等关节对象,内部运动建模不足,导致动画不自然。

论文贡献:该论文提出了一种新颖的无监督方法,旨在解决以往方法在对关节对象进行动画处理时的局限性。主要关注的是克服内部表示无法捕捉完整对象部分、形状和姿态的问题。值得注意的是,提出的区域运动表示灵感来自于运动历史图像的构建,利用主要成分进行形状分析。总的来说,该论文通过引入一种新的表示法,增强了对关节对象的理解,特别是解决了与形状和姿态捕捉相关的挑战。这种创新的方法为更为逼真和通用的无监督动画技术打开了新的可能性。

演示效果

在变分自编码器(VAE)等无监督学习模型中,Reconstruction Loss通常用于衡量模型解码器部分输出的重构数据与原始输入数据之间的差异。这种差异可以通过多种方式进行量化,其是机器学习和深度学习中用于衡量模型重构原始数据能力的一个指标。具体来说,它用于评估模型在尝试从压缩或编码后的表示中恢复原始数据时的性能。图片如下:

接下来对一些相关模型进行讲解:

一阶运动模型:FOMM 主要包括两个部分:运动估计和图像生成,其中运动估计进一步包含粗糙运动估计和密集运动预测。粗糙运动被建模为分离对象部分之间的稀疏运动,而密集运动则生成整个图像的光流和置信度图。我们用S和D分别表示源帧和驱动帧,这两者来自同一视频。首先从S和D估计各个对象部分的粗糙运动。每个对象部分的运动由仿射变换表示,Ak ∈ R^2x3,到一个抽象的共同参考帧R;X可以是S或D。针对K个不同的部分估计运动。编码器-解码器关键点预测网络输出K个热图,M1到MK,这些热图对输入图像进行建模,然后经过softmax,使得Mk ∈ [0,1]^HW,满足∑Mk(z) = 1,其中z是图像中的像素位置。这样,仿射变换的平移分量(即Ak的最后一列)可以使用softargmax进行估计。

        在FOMM 中,剩余的仿射参数通过每个像素进行回归,形成4个附加通道。用于索引仿射矩阵。这个模型被称为基于回归的模型,因为仿射参数由网络预测并进行池化以计算。D和S之间的每个部分k的运动然后通过公共参考帧计算。

基于PCA的运动估计:准确的运动估计是实现高质量图像动画的主要要求。与FOMM不同,我们采用了不同的运动表示方式,即所有运动直接从热图Mk中测量。我们像以前一样计算平移,而x和y方向的平面旋转和缩放则通过热图Mk的主成分分析(PCA)进行计算。

        这里使用奇异值分解(SVD)方法来计算PCA,将热图的协方差分解为酉矩阵Uk和V_k以及奇异值的对角矩阵S_k。我们称这种方法为基于PCA的方法,与基于回归的方法相对。尽管这两者在此使用相同的区域表示和编码器,但由于我们创新的前景运动表示,编码的区域之间存在显著的差异,将前景映射到有意义的对象部分,例如关节。

背景运动估计:背景占据图像的大部分。因此,即使在帧之间有微小的背景运动,例如由于摄像机运动引起的运动,也会对动画质量产生负面影响。FOMM未将背景运动单独处理,因此必须使用关键点对其进行建模。这带来了两个负面影响:(i)需要额外的网络容量,因为关键点用于模拟背景而不是前景;(ii)过度拟合训练集,因为这些关键点集中在背景的特定部分上,而这些部分可能在测试集中不存在。因此,我们使用编码器网络额外预测背景仿射变换。由于我们的框架是无监督的,背景网络可能将前景的某些部分包

        含到背景运动中。实际上,这并没有发生,因为对于网络来说,使用前景的更适当的基于PCA的运动表示要比使用S和D编码前景运动更简单。从经验上讲,我们证明了所提出的运动表示可以在完全无监督的情况下分离背景和前景。

        与FOMM 类似,我们将目标图像分为两个阶段进行渲染:像素级的光流生成器将粗糙运动转换为密集光流,然后根据光流对源的编码特征进行变形,随后对缺失区域进行修补。密集光流预测器的输入是一个HxWx(4K+3)张量,每个区域有四个通道,每个区域有三个用于根据区域的仿射变换变形的源图像通道,一个用于区域的热图的高斯近似,另外三个通道用于根据背景的仿射变换变形的源图像。与FOMM不同,后者使用常数方差,我们从热图中估计协方差。其图像生成如下:

        这种模型在背景运动略有变化时会变得复杂。当有轻微的背景运动时,该模型会自动适应通过将一些可用关键点分配给模拟背景来进行调整。我们还通过使用相同的网络预测置信度图C来处理源图像中缺失的部分。最后,S通过编码器传递,然后通过光流变形生成的特征图乘以置信度图。一个解码器然后重建驱动图像D。在测试时,FOMM 有两种动画模式:标准模式和相对模式。在标准动画中,逐帧计算源和驱动之间的运动。对于相对动画,为了生成帧t,首先计算D1和Dt之间的运动,然后应用于s。 

        通过上述改进,我们提出的方法克服了以前方法在处理关节对象时无法捕捉完整对象部分、形状和姿势的局限性。我们的基于PCA的运动表示以及背景运动估计模块提供了更高的稳定性和区域分布的改善,同时能够更好地适应不同数量的区域。我们的方法在多个数据集和任务上都取得了令人满意的定量和定性结果,为未来在这一领域的改进提供了有力的基准。

我们在几个基准数据集上评估我们的方法,这些数据集用于对人脸、身体和动画卡通进行动画。每个数据集都有单独的训练和测试视频。这些数据集包括:

VoxCeleb:包含不同名人的采访视频。我们提取正方形的面部区域并将其缩小到256×256,遵循FOMM 的方法。每个视频的帧数范围从64到1024。

TaiChiHD:包含执行太极动作的全身视频。我们在两个分辨率上评估该数据集:256×256和一个新的512×512子集,删除了分辨率不足以支持该大小的视频。

MGif:一个包含2D卡通动物的.gif文件数据集,通过Google搜索收集。

TED-talks:这是一个为本文收集的新数据集,用于演示我们模型的泛化性能。我们从视频中裁剪了人体的上半身部分,将其缩小到384×384。每个视频的帧数范围从64到1024。
由于视频动画是一个相对较新的问题,目前还没有许多有效的评估方法。对于定量指标,先前的研究 使用视频重建精度作为图像动画质量的代理。我们采用相同的指标:

        我们展示了我们的方法在具有非关节对象(如人脸)的数据集上达到了与FOMM 相媲美的结果。当与VoxCeleb上的FOMM 进行比较时,我们的方法表现相当。然而,当考虑到关节对象(例如TaiChiHD和TED-talks中的人体)时,FOMM 未能正确检测和动画化关节的身体部位,例如手。我们的方法即使在极端情况下也可以以驾驶姿势渲染它们,从而在我们的方法中显示出更高的偏好。

        这里,对于FOMM,我们使用标准方法,而我们的方法使用动画解缠。结果显示,在大多数情况下,我们的方法在动画质量方面都有明显的改进,特别是在肢体方面。我们通过类似于的用户偏好研究对动画质量进行了定量评估。AMT用户被呈现源图像、驱动视频以及我们的方法和FOMM的输出,并被询问他们更喜欢其中的哪一个视频。每项研究中被评估的视频共有2500个偏好,由50名用户分别进行评估。结果进一步支持了表2中的重建分数。当动画对象不是关节时(VoxCeleb),该方法提供了与先前工作可比较的结果,例如我们的方法获得52%的偏好。然而,当身体被动画(TaiChiHD和TED-talks)时,FOMM未能正确检测和动画化关节的身体部位,例如手。我们的方法即使在极端情况下也可以以驾驶姿势渲染它们,从而在我们的方法中显示出更高的偏好。由于通过重建指标无法展示通过解缠实现动画的好处,我们进行了额外的用户研究,以比较我们的方法与标准动画和通过解缠实现的动画。由于动画通过解缠可以更好地保持对象的形状,用户更倾向于选择它。在TED-talks数据集的情况下,这一点尤为明显,因为对象的形状在这种情况下更为不同。

        动画技术在教育和娱乐中占据着重要的地位。然而,以往的动画方法通常需要专业培训、专业硬件和大量努力。近年来,数据驱动的方法成为解决这些问题的尝试,其中无监督动画框架受到广泛关注。然而,这些框架在处理关节对象方面的表现不佳,其表示方法限制了其在动画领域的应用。出了一种全新的PCA-Based区域运动表示方法,通过主成分分析,更容易使网络学习到区域运动,同时鼓励学习语义丰富的对象部分。此外,引入了背景运动估计模块,有力地解耦了前景和背景的运动,为动画质量的提升提供了新的途径,图像演示如下:

核心代码实现

使用 ArgumentParser 解析命令行参数,包括配置文件路径 --config、运行模式 --mode(默认为 “train”)、日志目录 --log_dir(默认为 ‘log’)、检查点路径 --checkpoint、设备编号 --device_ids、是否输出模型架构 --verbose,将参数解析结果保存在 opt 对象中。

parser = ArgumentParser()
parser.add_argument("--config", required=True, help="path to config")
parser.add_argument("--mode", default="train", choices=["train", "reconstruction", "animate"])
parser.add_argument("--log_dir", default='log', help="path to log into")
parser.add_argument("--checkpoint", default=None, help="path to checkpoint to restore")
parser.add_argument("--device_ids", default="0", type=lambda x: list(map(int, x.split(','))),help="Names of the devices comma separated.")
parser.add_argument("--verbose", dest="verbose", action="store_true", help="Print model architecture")
opt = parser.parse_args()

使用 yaml.load 读取配置文件,其中配置了模型参数、数据集参数等。配置信息保存在 config 字典中:

with open(opt.config) as f:config = yaml.load(f)

创建生成器 generator、判别器 discriminator 和关键点检测器 kp_detector,模型的参数从配置文件中获取:

generator = OcclusionAwareGenerator(**config['model_params']['generator_params'],**config['model_params']['common_params'])
discriminator = MultiScaleDiscriminator(**config['model_params']['discriminator_params'],**config['model_params']['common_params'])
kp_detector = KPDetector(**config['model_params']['kp_detector_params'],**config['model_params']['common_params'])

如果 GPU 可用,将模型移动到指定的 GPU 设备上:

if torch.cuda.is_available():generator.to(opt.device_ids[0])discriminator.to(opt.device_ids[0])kp_detector.to(opt.device_ids[0])

创建日志目录,如果不存在的话,创建日志目录,如果不存在的话:

if not os.path.exists(log_dir):os.makedirs(log_dir)
if not os.path.exists(os.path.join(log_dir, os.path.basename(opt.config))):copy(opt.config, log_dir)

根据命令行参数中的 --mode 的值,选择运行训练、重建还是动画生成,分别调用相应的函数:train、reconstruction 或 animate:

if opt.mode == 'train':print("Training...")train(config, generator, discriminator, kp_detector, opt.checkpoint, log_dir, dataset, opt.device_ids)
elif opt.mode == 'reconstruction':print("Reconstruction...")reconstruction(config, generator, kp_detector, opt.checkpoint, log_dir, dataset)
elif opt.mode == 'animate':print("Animate...")animate(config, generator, kp_detector, opt.checkpoint, log_dir, dataset)

整个代码实现了一个端到端的图像动画生成流程,用户可以通过命令行参数选择不同的模式,并在配置文件中指定模型和数据集的参数。训练模型时,通过调用 train 函数,进行模型的训练;重建时,通过调用 reconstruction 函数,进行图像的重建;动画生成时,通过调用 animate 函数,生成动画。

写在最后

        在深入探讨无监督动画中关节动画的运动表示后,我们不难发现这一领域不仅蕴含着深厚的理论基础,也展现出了广泛的应用前景。通过无监督学习技术,我们能够从海量的无标签数据中提取出关节动画的运动特征,进而生成更加自然、真实的动画效果。无监督学习在关节动画运动表示中的应用将有着更加广阔的前景。随着技术的不断进步和算法的不断优化,无监督学习将能够更加准确地提取出运动特征,生成更加自然、真实的动画效果。同时,随着计算机图形学和虚拟现实技术的不断发展,关节动画也将在更多领域得到应用,如电影制作、游戏开发、虚拟现实体验等。这些应用将为我们带来更加丰富多彩的视觉体验,也将进一步推动无监督学习在关节动画运动表示中的研究和应用。

详细复现过程的项目源码、数据和预训练好的模型可从该文章下方附件获取。

【传知科技】关注有礼     公众号、抖音号、视频号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/17054.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Excel某列中有不连续的数据,怎么提取数据到新的列?

这里演示使用高级筛选的例子: 1.设置筛选条件 在D2单元格输入公式:COUNTA(A4)>0 这里有两个注意事项: *. 公式是设置在D2单元格,D1单元格保持为空, **. 为什么公式中选A4单元格,A列的第一个数据在A3…

CPU数据传送控制方式

引入 为了实现CPU与I/O设备信息交换的同步 无条件传送 示例1: 示例2: 程序查询方式 引入 工作过程 单个外设 多个外设 特点 中断传送方式 工作过程 特点 DMA 概述 DMAC功能 总线请求信号HOLD 总线请求响应信号HOLDA 工作过程 小结

景源畅信:新手做抖音运营难不难?

在这个信息爆炸的时代,社交媒体平台如抖音已经成为了人们日常生活中不可或缺的一部分。随着抖音的兴起,越来越多的人开始尝试进入这个领域,希望通过抖音运营实现自己的价值。然而,对于新手来说,抖音运营是否真的容易呢…

文心智能体大赛:情深智导

情深智导 概述限制澄清个性化 预览体验 概述 情深向导,致力于为您和您的孩子提供科学、个性化的情感支持与指导。无论您在家庭教育上遇到什么困惑,或是想了解孩子的内心世界,我都会在您身边,与您共同探索,助力亲子关系…

keepalived交叉编译

前言 Keepalived可以实现对服务器的健康检查,当主服务器出现故障时,自动将服务切换到备份服务器上,确保服务的连续性,避免单点故障。它还可以管理一个虚拟 IP 地址,在主备服务器之间进行灵活切换,对外提供…

使用 Python 编程语言进行供应链分析

前言 要分析一家公司的供应链,我们需要供应链不同阶段的数据,如有关采购、制造、运输、库存管理、销售和客户人口统计的数据。我为这项任务找到了一个理想的数据集,其中包括一家时尚和美容初创公司的供应链数据。 1. 相关数据集 让我们导入…

打造坦克游戏:类方法的深入解析

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、引言:坦克游戏与类方法的结合 二、坦克类的属性与方法概述 1. 属性定义与初…

Modbus协议基础

文章目录 Modbus概述Modbus TCP/IP Modbus概述 Modbus是由Modicon(现为施耐德电气公司的一个品牌)在1979年发明的,是全球第一个真正用于工业现场的应用层总线协议。 为更好地普及和推动Modbus在基于以太网上的分布式应用,目前施…

Ubuntu 安装 LibreOffice

1. 删除预安装的LibreOffice Ubuntu 和其他的 Linux 发行版带有预安装的 LibreOffice。这可能不是最新的,这是因为发行版有特定的发行周期。在进行新安装之前,你可以通过以下命令删除 Ubuntu 及其衍生发行版中的的旧版本。 sudo apt remove –purge li…

vs code怎么补全路径,怎么快捷输入文件路径

安装插件: 链接:https://marketplace.visualstudio.com/items?itemNamejakob101.RelativePath 使用 按住 Ctrl Shift H,弹出窗口,输入文件补全,回车就可以了 排除文件 如果你的项目下文件太多,它会…

基础—SQL—图形化界面工具的DataGrip使用(2)

一、回顾与引言 (1) 上次内容,博客讲到了DDL语句的数据库操作、表操作、表字段的操作的相关语法,然而之前都是在MySQL的命令行当中去操作演示的。这种方式可以用,但是使用的话,第一,在我们日常…

编译原理 期末复习笔记整理(上)

资料借鉴: 【编译原理】期末复习 零基础自学_哔哩哔哩_bilibili 编译原理笔记 第一章 引论 1.编译原理逻辑过程: 词法分析 语法分析 语义分析 中间代码生成 编译代码生成 2.词法分析 任务: 输入源程序,对…

解决 fatal: Not a git repository (or any of the parent directories): .git 问题

解决方法:在命令行 输入 git init 然后回车就好了

全面解析Java.lang.ClassCastException异常

全面解析Java.lang.ClassCastException异常 全面解析Java.lang.ClassCastException异常:解决方案与最佳实践 🚀📚摘要引言1. 什么是Java.lang.ClassCastException?代码示例 2. 报错原因2.1 类型不兼容2.2 泛型类型擦除2.3 接口和实…

02 FreeRTOS 任务

1、创建任务函数 1.1 动态内存的使用 在之前我们如果要创建一个与学生有关的任务,我们会定义: //打印50个学生的信息 char name[50][100]; int age[50]; int sex[50]; //1表示男,0表示女 int score[50]; 如果之后要对其进行修改会非常麻烦&…

使用稀疏约束水平集算法对MR图像中的脑肿瘤进行分割| 文献速递-深度学习肿瘤自动分割

Title 题目 Brain tumor segmentation in MR images using a sparse constrained level set algorithm 使用稀疏约束水平集算法对MR图像中的脑肿瘤进行分割" 01 文献速递介绍 脑磁共振(MR)成像是成像患者脑结构的主要方法,从MR图像…

最后7天,高考翻盘秘籍等你开启!

高考,这场关乎未来的考试,对于每一个学生来说都是一次严峻的挑战。随着倒计时的进行,无数考生和家长的焦虑和期待达到了顶点。在这个最后7天的关键时期,我们为即将参加高考的学生及其家长提供一份复习秘籍,帮助你们抓住…

rfid资产管理系统如何帮助医院管理耗材的

RFID资产管理系统可以帮助医院管理耗材,提高耗材管理的效率和准确性。以下是它可以发挥作用的几个方面: 1. 实时跟踪和定位:使用RFID标签附加在耗材上,可以实时跟踪和定位耗材的位置。医院可以通过系统查询耗材的实时位置&#xf…

微服务八股-分布式事务-注册中心-服务保护

一、分布式事务 1.CAP和BASE 三者不能同时存在。 CP:由于网络分片的存在,如果要保证强一致性就不能写,此时不满足可用性 AP:由于网络分片的存在,如果要保证可用性,能读也能写,就不能保证强一致…

【讲解下Web前端三大主流的框架】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…