File size: 5,459 Bytes
7ca9b42 eaf5641 7ca9b42 eaf5641 7ca9b42 88c4250 50f8e9f 7ca9b42 50f8e9f 7ca9b42 50f8e9f 7ca9b42 eaf5641 7ca9b42 eaf5641 7ca9b42 eaf5641 7ca9b42 aadbdeb 7ca9b42 aadbdeb 7ca9b42 eaf5641 7ca9b42 eaf5641 7ca9b42 eaf5641 7ca9b42 eaf5641 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
import time
import shutil
import gradio as gr
import os
import cv2
import json
import torch
import argparse
import numpy as np
from lib.data import get_meanpose
from lib.network import get_autoencoder
from lib.util.motion import preprocess_mixamo, preprocess_test, postprocess
from lib.util.general import get_config
from lib.operation import rotate_and_maybe_project_world
from itertools import combinations
from lib.util.visualization import motion2video
from PIL import Image
def load_and_preprocess(path, config, mean_pose, std_pose):
motion3d = np.load(path)
# length must be multiples of 8 due to the size of convolution
_, _, T = motion3d.shape
T = (T // 8) * 8
motion3d = motion3d[:, :, :T]
# project to 2d
motion_proj = motion3d[:, [0, 2], :]
# reformat for mixamo data
motion_proj = preprocess_mixamo(motion_proj, unit=1.0)
# preprocess for network input
motion_proj, start = preprocess_test(motion_proj, mean_pose, std_pose, config.data.unit)
motion_proj = motion_proj.reshape((-1, motion_proj.shape[-1]))
motion_proj = torch.from_numpy(motion_proj).float()
return motion_proj, start
def image2video():
# 指定包含PNG图像的目录
image_directory = './an-frames'
# 输出视频的路径
output_video_path = './adv.mp4'
# 视频的帧率(每秒中的帧数)
fps = 24
# 获取所有PNG图像的文件名并按顺序排序
images = sorted([img for img in os.listdir(image_directory) if img.endswith(".png")])
# 确定视频的分辨率
first_image_path = os.path.join(image_directory, images[0])
first_frame = cv2.imread(first_image_path)
height, width, layers = first_frame.shape
size = (width, height)
# 创建视频写入器
out = cv2.VideoWriter(output_video_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, size)
# 依次读取图像并写入视频
for img_name in images:
img_path = os.path.join(image_directory, img_name)
frame = cv2.imread(img_path)
# 确保帧的大小与视频的分辨率匹配
if (frame.shape[1], frame.shape[0]) != size:
frame = cv2.resize(frame, size)
out.write(frame)
# 关闭视频写入器
out.release()
print(f"Video saved to {output_video_path}")
def handle_motion_generation(npy1,npy2):
path1 = './data/a.npy'
path2 = './data/b.npy'
np.save(path1,npy1)
np.save(path2,npy2)
config_path = './configs/transmomo.yaml' # 替换为您的配置文件路径
description_path = "./data/mse_description.json"
checkpoint_path = './data/autoencoder_00200000.pt'
out_dir_path = './output' # 替换为输出目录的路径
config = get_config(config_path)
ae = get_autoencoder(config)
ae.load_state_dict(torch.load(checkpoint_path, map_location=torch.device('cpu')))
# ae.cuda()
ae.eval()
mean_pose, std_pose = get_meanpose("test", config.data)
# print("loaded model")
description = json.load(open(description_path))
chars = list(description.keys())
os.makedirs(out_dir_path, exist_ok=True)
path1 = './data/1.npy'
path2 = './data/2.npy'
out_path1 = os.path.join(out_dir_path, "adv.npy")
x_a, x_a_start = load_and_preprocess(path1, config, mean_pose, std_pose)
x_b, x_b_start = load_and_preprocess(path2, config, mean_pose, std_pose)
# x_a_batch = x_a.unsqueeze(0).cuda()
# x_b_batch = x_b.unsqueeze(0).cuda()
x_a_batch = x_a.unsqueeze(0)
x_b_batch = x_b.unsqueeze(0)
x_ab = ae.cross2d(x_a_batch, x_b_batch, x_a_batch)
x_ab = postprocess(x_ab, mean_pose, std_pose, config.data.unit, start=x_a_start)
np.save(out_path1, x_ab)
motion_data = x_ab
height = 512 # 视频的高度
width = 512 # 视频的宽度
save_path = './an.mp4' # 保存视频的路径
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] # 关节颜色
bg_color = (255, 255, 255) # 背景颜色
fps = 25 # 视频的帧率
# print(motion_data.shape)
# 调用函数生成视频
motion2video(motion_data, height, width, save_path, colors, bg_color=bg_color, transparency=False, fps=fps)
image2video()
first_frame_image = Image.open('./an-frames/0000.png')
return './adv.mp4'
# 创建 Gradio 界面并展示视频而不是图片
with gr.Blocks() as demo:
gr.Markdown(
'''
This space displays how to perform Transmomo(Motion Retargeting):
## How to use this Space?
- Upload a npy, as the motion source of generated video.
- Upload a npy, as the structure source of generated video.
- You will receive the result of the Motion Retargeting after 1-2 minutes.
- Click the 'clear' button to clear all the files.
## Examples
- You can get the test examples from our [Roop Dataset Repo.](https://huggingface.co/datasets/SJTU-TES/momo)
'''
)
with gr.Row():
file1 = gr.File(file_types=[".npy"], label="Upload Motion Source .npy file")
file2 = gr.File(file_types=[".npy"], label="Upload Structure Source .npy file")
with gr.Row():
generate_btn = gr.Button("Generate Animation")
output_video = gr.Video(label="Generated Animation",width = 500)
generate_btn.click(
fn=handle_motion_generation,
inputs=[file1, file2],
outputs=output_video
)
if __name__ == "__main__":
demo.launch()
|