引言:近段时间,一个让梦娜丽莎图像动起来的项目火遍了朋友圈。而今天我们就将实现让图片中的人物随着视频人物一起产生动作。
很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!??¤
QQ群:704929215
其中通过在静止图像中动画对象产生视频有无数的应用跨越的领域兴趣,包括电影制作、摄影和电子商务。更准确地说,是图像动画指将提取的视频外观结合起来自动合成视频的任务一种源图像与运动模式派生的视频。
近年来,深度生成模型作为一种有效的图像动画技术出现了视频重定向。特别是,可生成的对抗网络(GANS)和变分自动编码器(VAES)已被用于在视频中人类受试者之间转换面部表情或运动模式。
根据论文FirstOrder Motion Model for Image Animation可知,在姿态迁移的大任务当中,Monkey-Net首先尝试了通过自监督范式预测关键点来表征姿态信息,测试阶段估计驱动视频的姿态关键点完成迁移工作。在此基础上,FOMM使用了相邻关键点的局部仿射变换来模拟物体运动,还额外考虑了遮挡的部分,遮挡的部分可以使用image inpainting生成。
而今天我们就将借助论文所分享的源代码,构建模型创建自己需要的人物运动。具体流程如下。
实验前的准备
首先我们使用的python版本是3.6.5所用到的模块如下:
- imageio模块用来控制图像的输入输出等。
- Matplotlib模块用来绘图。
- numpy模块用来处理矩阵运算。
- Pillow库用来加载数据处理。
- pytorch模块用来创建模型和模型训练等。
- 完整模块需求参见requirements.txt文件。
模型的加载和调用
通过定义命令行参数来达到加载模型,图片等目的。
(1)首先是训练模型的读取,包括模型加载方式:
def load_checkpoints(config_path, checkpoint_path, cpu=False):
with open(config_path) as f:
config = yaml.load(f)
generator = OcclusionAwareGenerator(**config[ model_params ][ generator_params ],
**config[ model_params ][ common_params ])
if not cpu:
generator.cuda()
kp_detector = KPDetector(**config[ model_params ][ kp_detector_params ],
**config[ model_params ][ common_params ])
if not cpu:
kp_detector.cuda()
if cpu:
checkpoint = torch.load(checkpoint_path, map_location=torch.device( cpu ))
else:
checkpoint = torch.load(checkpoint_path)
generator.load_state_dict(checkpoint[ generator ])
kp_detector.load_state_dict(checkpoint[ kp_detector ])
if not cpu:
generator = DataParallelWithCallback(generator)
kp_detector = DataParallelWithCallback(kp_detector)
generator.eval()
kp_detector.eval()
return generator, kp_detector
(2)然后是利用模型创建产生的虚拟图像,找到最佳的脸部特征:
def make_animation(source_image, driving_video, generator, kp_detector, relative=True, adapt_movement_scale=True, cpu=False):
with torch.no_grad():
predictions = []
source = torch.tensor(source_image[np.newaxis].astype(np.float32)).permute(0, 3, 1, 2)
if not cpu:
sourcesource = source.cuda()
driving = torch.tensor(np.array(driving_video)[np.newaxis].astype(np.float32)).permute(0, 4, 1, 2, 3)
kp_source = kp_detector(source)
kp_driving_initial = kp_detector(driving[:, :, 0])
for frame_idx in tqdm(range(driving.shape[2])):
drivingdriving_frame = driving[:, :, frame_idx]
if not cpu:
driving_framedriving_frame = driving_frame.cuda()
kp_driving = kp_detector(driving_frame)
kp_norm = normalize_kp(kp_sourcekp_source=kp_source, kp_drivingkp_driving=kp_driving,