-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathvideo2mocap.py
189 lines (142 loc) · 5.36 KB
/
video2mocap.py
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import os
import sys
import shutil
import subprocess
from absl import flags
from utils import logging
# ----------------------------------------------------------------------------
# define flags
flags.DEFINE_string("mayapy_exe", "mayapy.exe", "Path to mayapy.exe")
flags.DEFINE_string("python2_exe", "python.exe", "Path to python.exe (2)")
flags.DEFINE_string("python3_exe", "python3.exe", "Path to python.exe (3)")
flags.DEFINE_string("video_path", None, "Path to source video")
flags.DEFINE_string("output_dir", None, "Output dir for characters")
flags.DEFINE_boolean("keep_temp", 0, "Keep temp dir for debugging")
# ----------------------------------------------------------------------------
# static variables
ROOT_DIR = os.path.abspath(os.path.dirname(__file__))
APP_DIR = os.path.join(ROOT_DIR, "3rdparty")
FFMPEG_EXE = os.path.join(APP_DIR, "ffmpeg", "bin", "ffmpeg.exe")
HMR_DIR = os.path.join(APP_DIR, "hmr")
OPEN_POSE_DIR = os.path.join(APP_DIR, "openpose")
OPEN_POSE_EXE = os.path.join(OPEN_POSE_DIR, "bin", "OpenPoseDemo.exe")
# ----------------------------------------------------------------------------
def makedirs(path):
"""
:param str path:
"""
if not os.path.exists(path):
os.makedirs(path)
# ----------------------------------------------------------------------------
def video2mocap(
video_path,
output_dir,
keep_temp=False,
mayapy_exe="mayapy.exe",
python2_exe="python.exe",
python3_exe="python3.exe"
):
"""
Convert a video to maya scenes containing a animated human ik skeleton.
Step 1:
OpenPose is used to get the bounding boxes of the characters in the
video. This data is stored in a json file generated for each frame.
Step 2:
FFmpeg is used to convert the video into individual image files. These
images are needed for the next step. The images are stored as in a png
file format.
Step 3:
HMR is used to export a json file for each of the frames and the 3D
matrices that are found in each of the images. The OpenPose json file
is used to crop the image to only look at a single person at the same
time.
Step 4:
Maya standalone is used to read the json file and generate an animated
human ik skeleton for each character found.
:param video_path:
:param output_dir:
:param keep_temp:
:param mayapy_exe:
:param python2_exe:
:param python3_exe:
:return:
"""
# log settings
logger.info("---- VIDEO > MOCAP ----")
logger.info("---- SETTINGS ----")
logger.info("Video: {}".format(video_path))
logger.info("Output: {}".format(output_dir))
logger.info("Keep temp directory: {}".format(keep_temp))
logger.info("---- PYTHON ----")
logger.info("Python 2: {}".format(python2_exe))
logger.info("Python 3: {}".format(python3_exe))
logger.info("Python Maya: {}".format(mayapy_exe))
# create temp dir
temp_dir = os.path.join(output_dir, "temp")
logger.info("---- TEMP ----")
logger.info("Directory: {}".format(temp_dir))
makedirs(temp_dir)
# run openpose
open_pose_json_dir = os.path.join(temp_dir, "openpose_data")
open_pose_command = [
OPEN_POSE_EXE,
"--video", video_path,
"--write_json", open_pose_json_dir
]
logger.info("---- OPEN POSE ----")
logger.info("Command: {}".format(" ".join(open_pose_command)))
subprocess.check_call(open_pose_command, cwd=OPEN_POSE_DIR)
# run ffmpeg
images_dir = os.path.join(temp_dir, "images_data")
images_path = os.path.join(images_dir, "image%04d.png")
ffmpeg_command = [
FFMPEG_EXE,
"-i", video_path, images_path
]
logger.info("---- FFMPEG ----")
logger.info("Directory: {}".format(images_path))
logger.info("Command: {}".format(" ".join(ffmpeg_command)))
makedirs(images_dir)
subprocess.check_call(ffmpeg_command)
# run hmr
hrm_json_path = os.path.join(temp_dir, "hmr_data.json")
hmr_command = [
python3_exe,
"-m", "export",
"--img_dir", images_dir,
"--json_dir", open_pose_json_dir,
"--log_dir", output_dir,
"--output_path", hrm_json_path
]
logger.info("---- HMR ----")
logger.info("Command: {}".format(" ".join(hmr_command)))
subprocess.check_call(hmr_command, cwd=HMR_DIR)
# run mayapy
maya_command = [
mayapy_exe,
"-m", "export_maya",
"--json_path", hrm_json_path,
"--output_dir", output_dir,
]
logger.info("---- MAYA ----")
logger.info("Command: {}".format(" ".join(maya_command)))
subprocess.check_call(maya_command, cwd=ROOT_DIR)
# remove temporary files
if not keep_temp:
shutil.rmtree(temp_dir)
# ----------------------------------------------------------------------------
if __name__ == '__main__':
# convert data
config = flags.FLAGS
config(sys.argv)
# get logger
logger = logging.get_logger(config.output_dir)
# convert
video2mocap(
config.video_path,
config.output_dir,
config.keep_temp,
config.mayapy_exe,
config.python2_exe,
config.python3_exe,
)