File size: 3,044 Bytes
1cdc47e
 
 
4e2aa43
1cdc47e
 
 
4e2aa43
 
 
 
 
 
1cdc47e
 
 
 
 
 
 
 
 
 
4e2aa43
1cdc47e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4e2aa43
1cdc47e
 
 
 
4e2aa43
 
1cdc47e
4e2aa43
1cdc47e
 
 
 
 
 
 
 
 
 
 
4e2aa43
1cdc47e
 
 
4e2aa43
 
 
 
 
 
1cdc47e
4e2aa43
 
 
1cdc47e
 
 
4e2aa43
1cdc47e
 
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
import numpy as np
import os
from datetime import datetime
import argparse

def define_human_connections():
    return [
        [0, 7], [7, 8], [8, 9], [9, 10],  # Core body
        [7, 14], [14, 15], [15, 16],      # Left arm
        [7, 11], [11, 12], [12, 13],      # Right arm
        [0, 1], [1, 2], [2, 3],           # Left leg
        [0, 4], [4, 5], [5, 6],           # Right leg
        [14, 11], [1, 4],                 # Structural connections
    ]

def npz_to_obj_sequence(npz_path, output_dir):
    os.makedirs(output_dir, exist_ok=True)
    data = np.load(npz_path)
    reconstruction = data['reconstruction'][0]
    
    num_frames = reconstruction.shape[0]
    connections = define_human_connections()
    
    scale = 150.0
    
    for frame_idx in range(num_frames):
        vertices = reconstruction[frame_idx]
        output_path = os.path.join(output_dir, f"frame_{frame_idx:04d}.obj")
        
        with open(output_path, 'w') as f:
            for v in vertices:
                x, y, z = v[0] * scale, v[2] * scale, v[1] * scale
                f.write(f"v {x:.8f} {y:.8f} {z:.8f}\n")
            for conn in connections:
                f.write(f"l {conn[0] + 1} {conn[1] + 1}\n")

def analyze_vertex_data(npz_path):
    data = np.load(npz_path)
    reconstruction = data['reconstruction'][0]
    x_min, x_max = reconstruction[:,:,0].min(), reconstruction[:,:,0].max()
    y_min, y_max = reconstruction[:,:,1].min(), reconstruction[:,:,1].max()
    z_min, z_max = reconstruction[:,:,2].min(), reconstruction[:,:,2].max()

def process_motion_capture(npz_file, output_dir):
    try:
        if not os.path.exists(npz_file):
            raise FileNotFoundError(f"Input file {npz_file} not found")
        
        # Use the provided output_dir with 'obj_sequence' subfolder
        obj_output_dir = os.path.join(output_dir, "obj_sequence")
        analyze_vertex_data(npz_file)
        npz_to_obj_sequence(npz_path=npz_file, output_dir=obj_output_dir)
        
    except Exception as e:
        print(f"Error processing motion capture data: {str(e)}")
        raise

def get_npz_paths(folder_path):
    if not os.path.isdir(folder_path):
        raise FileNotFoundError(f"Directory not found: {folder_path}")
    
    for file in os.listdir(folder_path):
        if file.endswith('.npz'):
            return os.path.join(folder_path, file)
    
    raise FileNotFoundError(f"No NPZ files found in directory: {folder_path}")

def arg_parse():
    parser = argparse.ArgumentParser('Convert NPZ to OBJ sequence.')
    parser.add_argument('--output-dir', type=str, default='../outputs/', help='Output directory for results')
    args = parser.parse_args()
    return args

if __name__ == "__main__":
    args = arg_parse()
    input_dir = os.path.join(os.path.abspath(args.output_dir), 'npz')
    os.makedirs(input_dir, exist_ok=True)
    
    try:
        npz_file = get_npz_paths(input_dir)
        process_motion_capture(npz_file, args.output_dir)
    except FileNotFoundError as e:
        print(f"Error: {str(e)}")