diff --git a/data/cloth3d_io.py b/data/cloth3d_io.py index c25f5c8..862ff25 100644 --- a/data/cloth3d_io.py +++ b/data/cloth3d_io.py @@ -236,7 +236,7 @@ def read_posed_garment_frame(folder, id, garment, frame, map=None, mask=None, sh verts[mask, :] = verts[mask, :] - np.squeeze(shape_offsets)[mask, :] if deorient: - R = scipy.spatial.transform.Rotation.from_euler(pose[:3]).inv() + R = scipy.spatial.transform.Rotation.from_euler('xyz', pose[:3]).inv() # R = scipy.spatial.transform.Rotation.from_euler([0,0,-zrot]) verts = R.apply(verts) @@ -244,13 +244,12 @@ def read_posed_garment_frame(folder, id, garment, frame, map=None, mask=None, sh # can i cache map? -def read_posed_garment(folder, id, garment, map=None, mask=None, shape=None, shapedirs=None, poses=None, unshape=False, deorient=False): - pc16_path = os.path.join(folder, id, garment + '.pc16') - verts = readPC2(pc16_path, True) +# NOT WORKING WELL +def read_posed_garment(folder, id, garment, mask=None, shape=None, shapedirs=None, poses=None, unshape=False, deorient=False): + body_posed = readPC2(os.path.join(folder, id, 'Body_posed.pc16'), True)['V'] + offsets = readPC2(os.path.join(folder, id, garment + '_offsets_dynamic.pc16'), True)['V'] + verts = (body_posed + offsets) * mask[:, None] - if map is None: - map = sio.loadmat(os.path.join(folder, id, garment + '_map.mat'))['map'].reshape((-1)) - verts = verts[:, map, :] if unshape: shape_offsets = np.tensordot(shape, shapedirs, axes=[[1], [2]]) @@ -258,7 +257,7 @@ def read_posed_garment(folder, id, garment, map=None, mask=None, shape=None, sha if deorient: for i in range(verts.shape[0]): - R = scipy.spatial.transform.Rotation.from_euler(poses[:3, i]).inv() + R = scipy.spatial.transform.Rotation.from_euler('xyz', poses[:3, i]).inv() # R = scipy.spatial.transform.Rotation.from_euler([0,0,-zrot]) verts[i] = R.apply(verts[i]) @@ -304,6 +303,16 @@ def read_posed_body(folder, id, poses=None, deorient=False): return verts + +def read_curvatures(h5file, id, frames, neighbourhood=None): + frames_filtered = [frame for frame in frames if frame.split()[0] == id] + garment = frames_filtered[0].split()[2] + curvatures_all = [] + for frame_nr in range(len(frames_filtered)): + curv = h5file.get_node(f'/{id}/{frame_nr}/{garment}/curvature_raw').read() + curvatures_all.append(curv) + return np.array(curvatures_all) + # import os # import sys # import numpy as np diff --git a/data/convert_to_uv.py b/data/convert_to_uv.py index 0425716..f9e5baf 100644 --- a/data/convert_to_uv.py +++ b/data/convert_to_uv.py @@ -13,6 +13,7 @@ import numpy as np import scipy as sp import trimesh as tm import cmapy as cm +import tables as tb import scipy.io as sio import scipy.interpolate as spi import matplotlib.pyplot as plt @@ -22,7 +23,8 @@ import plotly.express as ex import plotly.graph_objects as go sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/..') -from data.cloth3d_io import read_garment_mask, read_garment_template, read_posed_garment_frame, loadInfo, read_posed_body_frame, read_posed_body, read_posed_garment +from data.cloth3d_io import read_garment_mask, read_garment_template, read_posed_garment_frame, loadInfo, read_posed_body_frame, read_posed_body, read_posed_garment, read_curvatures +from data.utils import save_to_h5file os.environ["CUDA_VISIBLE_DEVICES"] = "6" @@ -119,6 +121,8 @@ def convert_to_uv_batch(res, m2uv, uv_map, verts, neighbours=15, mask=None, meth rbf_dest_current = np.nonzero(rbf_dest_current) rbf_dest_current = np.array(rbf_dest_current).T + out = [] + for i in range(batch): print('processing frame: ' + str(i)) @@ -138,8 +142,10 @@ def convert_to_uv_batch(res, m2uv, uv_map, verts, neighbours=15, mask=None, meth if garment_uv_mask is not None: result *= garment_uv_mask[:,:,np.newaxis] - - np.savez_compressed(os.path.join(folder, 'uv_posed_no_orient', id + '_' + str(i) + '.npz'), uv_posed_no_orient=result) + + out.append(result) + + return out def convert_to_uv_batch_label(res, m2uv, uv_map, values, neighbours=15, mask=None, method='rbf', garment_uv_mask=None, garment_uv_mask_border=None): @@ -323,25 +329,16 @@ def get_shapedirs(): shapedirs.append(male['shapedirs'][to_keep, :]) return shapedirs + if __name__ == '__main__': parser = argparse.ArgumentParser() - parser.add_argument("-f", "--folder", help = "end of range", default='/home/workspace/data/dataset/test_skirt_ready_2') - parser.add_argument("-x", "--extras", help = "end of range", default='/home/workspace/data/dataset/test_skirt_ready_2_extras') + parser.add_argument("-f", "--folder", help = "end of range", default='/home/workspace/data/dataset/cloth3d/train') parser.add_argument("-s", "--start", help = "start of range", default=0) - parser.add_argument("-e", "--end", help = "end of range", default=30000) + parser.add_argument("-e", "--end", help = "end of range", default=1000) parser.add_argument("-n", "--name", help = "end of range", default='lhunor') - parser.add_argument("-sk", "--skirt", help = "end of range", default=1) + parser.add_argument("-sk", "--skirt", help = "end of range", default=0) args = parser.parse_args() - # smpl = SMPL('FeatureLines/superSMPL') - - folder = args.folder - extras_folder = args.extras - - os.makedirs(extras_folder, exist_ok=True) - - print("skirt" if args.skirt == 1 else "not skirt") - F = np.load("custom_utils/smpl_faces" + ("_skirt" if args.skirt == 1 else "") + ".npy") uv_map = np.load('custom_utils/stretched_uv_map_' + ("skirt" if args.skirt == 1 else "3") + '.npy') m2uv = np.load('custom_utils/m2uv' + ("_skirt" if args.skirt == 1 else "") + '.npy', allow_pickle=True).item() @@ -369,49 +366,64 @@ if __name__ == '__main__': rbf_dest[uv_map_discreet_unique[:, 0], uv_map_discreet_unique[:, 1]] = 0 rbf_dest[np.invert(uv_mask[:,:,0])] = 0 - is_skirt = True if args.skirt == 1 else False - skirt_modifier = '_skirt' if is_skirt else '' + ######################################################################################### + + use_no_orient = False + no_shape = False + is_skirt = True if args.skirt == 1 else False folder = args.folder + neighbourhood = 25 frames_file = 'frames_all.txt' + data_to_convert = ['mesh_posed', 'mesh_static', 'mesh_curvature', 'body_posed'] # 'mesh_unposed', + + print("skirt" if args.skirt == 1 else "not skirt") + print(f'params: -f {args.folder} -s {args.start} -e {args.end} -n {args.name} -skirt {args.skirt}') + + skirt_modifier = '_skirt' if is_skirt else '' + orient_mod = '_no_orient' if use_no_orient else '' + shape_mod = '_no_shape' if no_shape else '' frames = [] with open(os.path.join(folder, frames_file), 'r') as f: lines = f.readlines() lines = [line.strip() for line in lines] - frames = lines#[int(args.start):int(args.end)] - ids = [frame.split('_')[0] for frame in frames] - - print(f'params: -f {args.folder} -s {args.start} -e {args.end} -n {args.name} -skirt {args.skirt}') - - # ids = os.listdir(os.path.join(local_folder, 'pose_shape')) - # ids = [id.split('_')[0] for id in ids] + frames = lines + ids = [frame.split()[0] for frame in frames] ids = sorted(list(set(ids)))[int(args.start):int(args.end)] shapedirs = get_shapedirs() - use_no_orient = True - no_shape = False - data_to_convert = ['mesh_posed', 'mesh_unposed', 'mesh_static', 'mesh_curvature', 'body_posed'] + root = '/'.join(folder.split('/')[:-1]) + type = folder.split('/')[-1] + h5file = tb.open_file(os.path.join(root, f'{type}_extras.h5'), mode='a') + for id in tqdm.tqdm(ids): + info = loadInfo(os.path.join(folder, id, 'info.mat')) - garments = info['outfit'] + garments = list(info['outfit'].keys()) assert info['poses'].shape[1] <= 300 + # put all this in a function and call for all garments + + # also masking is not the same as just filling the empty values with neighbouring + # values, at least the plots are different + garment = garments[0] mask = read_garment_mask(folder, id, garment) if 'mesh_posed' in data_to_convert: - mesh_posed = read_posed_garment(folder, id, garment, mask=mask, shape=info['shape'], poses=info['poses'], use_no_orient=use_no_orient, no_shape=no_shape) + mesh_posed_frame = read_posed_garment_frame(folder, id, garment, 0, mask=mask, shape=info['shape'], pose=info['poses'][:,0], deorient=use_no_orient, unshape=no_shape) + mesh_posed = read_posed_garment(folder, id, garment, mask=mask, shape=info['shape'], poses=info['poses'], deorient=use_no_orient, unshape=no_shape) if 'mesh_unposed' in data_to_convert: - mesh_unposed = read_unposed_garment(folder, id, garment, mask=mask, shape=info['shape'], no_shape=no_shape) + mesh_unposed = read_unposed_garment(folder, id, garment, mask=mask, shape=info['shape'], unshape=no_shape) if 'mesh_static' in data_to_convert: mesh_static = read_garment_template(folder, id, garment, mask) if 'mesh_curvature' in data_to_convert: - mesh_curvature = compute_curvature(mesh_posed, F) + mesh_curvature = read_curvatures(h5file, id, frames, neighbourhood=None) if 'body_posed' in data_to_convert: body_posed = read_posed_body(folder, id, info['poses'], use_no_orient) @@ -442,33 +454,35 @@ if __name__ == '__main__': start = time.perf_counter() - uv_verts_static, garment_uv_mask, garment_uv_mask_border = convert_to_uv(uv_res, m2uv, uv_map, verts_static, neighbours=3, mask=mask, method='rbf', garment_uv_mask=None) - uv_verts_static = uv_verts_static.astype(np.float32) + uv_static, uv_mask, garment_uv_mask_border = convert_to_uv(uv_res, m2uv, uv_map, mesh_static, neighbours=3, mask=mask, method='rbf', garment_uv_mask=None) + uv_static = uv_static.astype(np.float32) if 'mesh_posed' in data_to_convert: - uv_posed = convert_to_uv_batch(uv_res, m2uv, uv_map, gt[:, :, :], neighbours=3, mask=mask, method='rbf', garment_uv_mask=garment_uv_mask, garment_uv_mask_border=garment_uv_mask_border).astype(np.float32) + uv_posed = convert_to_uv_batch(uv_res, m2uv, uv_map, mesh_posed[:, :, :], neighbours=3, mask=mask, method='rbf', garment_uv_mask=uv_mask, garment_uv_mask_border=garment_uv_mask_border).astype(np.float32) if 'mesh_unposed' in data_to_convert: - uv_unposed = convert_to_uv_batch(uv_res, m2uv, uv_map, mesh_unposed[:, :, :], neighbours=3, mask=mask, method='rbf', garment_uv_mask=garment_uv_mask, garment_uv_mask_border=garment_uv_mask_border).astype(np.float32) + uv_unposed = convert_to_uv_batch(uv_res, m2uv, uv_map, mesh_unposed[:, :, :], neighbours=3, mask=mask, method='rbf', garment_uv_mask=uv_mask, garment_uv_mask_border=garment_uv_mask_border).astype(np.float32) if 'mesh_curvature' in data_to_convert: - uv_curvature = convert_to_uv_batch_label(uv_res, m2uv, uv_map, curvature[:, :], neighbours=3, mask=mask, method='nearest', garment_uv_mask=garment_uv_mask, garment_uv_mask_border=garment_uv_mask_border).astype(np.float32) + uv_curvature = convert_to_uv_batch_label(uv_res, m2uv, uv_map, mesh_curvature[:, :], neighbours=3, mask=mask, method='nearest', garment_uv_mask=uv_mask, garment_uv_mask_border=garment_uv_mask_border).astype(np.float32) if 'body_posed' in data_to_convert: uv_body_posed = convert_to_uv_batch(uv_res, m2uv, uv_map, body_posed[:, :, :], neighbours=3, mask=None, method='rbf', garment_uv_mask=None, garment_uv_mask_border=garment_uv_mask_border).astype(np.float32) print(time.perf_counter() - start) - - if 'mesh_static' in data_to_convert: - # np.save(os.path.join(folder, id, garment + '_offsets_static_uv.npy'), uv_verts_static) - # np.save(os.path.join(folder, id, 'mask_uv.npy'), garment_uv_mask) + # mesh_static + save_to_h5file(h5file, id, 0, garment, uv_static, 'uv_static', 'float32') + save_to_h5file(h5file, id, 0, garment, uv_mask, 'uv_mask', 'float32') if 'mesh_posed' in data_to_convert: - mesh_posed = read_posed_garment(folder, id, garment, mask=mask, shape=info['shape'], poses=info['poses'], use_no_orient=use_no_orient, no_shape=no_shape) + for i in range(uv_posed.shape[0]): + save_to_h5file(h5file, id, i, garment, uv_posed[i, :, :, :], 'uv_posed' + orient_mod + shape_mod, 'float32') if 'mesh_unposed' in data_to_convert: - mesh_unposed = read_unposed_garment(folder, id, garment, mask=mask, shape=info['shape'], no_shape=no_shape) + for i in range(uv_unposed.shape[0]): + save_to_h5file(h5file, id, i, garment, uv_unposed[i, :, :, :], 'uv_unposed' + orient_mod + shape_mod, 'float32') if 'mesh_curvature' in data_to_convert: - mesh_curvature = compute_curvature(mesh_posed, F) + for i in range(uv_curvature.shape[0]): + save_to_h5file(h5file, id, i, garment, uv_curvature[i, :, :, :], 'uv_curvature', 'uint8') if 'body_posed' in data_to_convert: - # for i in range(uv_body_posed.shape[0]): - # np.savez_compressed(os.path.join(folder, id, 'uv_body_posed', garment + '_' + str(i) + '.npz'), uv_body=uv_body[i, :, :, :]) + for i in range(uv_body_posed.shape[0]): + save_to_h5file(h5file, id, i, garment, uv_body_posed[i, :, :, :], 'uv_body_posed', 'float32') # start = time.perf_counter() diff --git a/data/curvatures.py b/data/curvatures.py index ff72902..45d59ab 100644 --- a/data/curvatures.py +++ b/data/curvatures.py @@ -114,14 +114,6 @@ class Cache: mask = read_garment_mask(self.folder, id, garment) - if self.include_neighbours: - k_neighbors = np.argsort(dist[mask, :][:, mask], axis=-1)[:, :self.neighbourhood] - self.cache[id].k_neighbors = k_neighbors - G = tm.graph.vertex_adjacency_graph(m) - for i in range(v.shape[0]): - for k in range(25): - assert nx.has_path(G, i, k_neighbors[i, k]), f'No path between {i} and {k_neighbors[i, k]}' - _, faces = _maskFaces(np.zeros((14475,3)), F, mask) v = read_posed_garment_frame(folder, id, garment, 0)[mask,:] m = tm.Trimesh(v, faces, process=False, validate=False) @@ -132,6 +124,14 @@ class Cache: faces = np.concatenate((faces, outliers_faces), axis=0) m = tm.Trimesh(v, faces, process=False, validate=False) + if self.include_neighbours: + k_neighbors = np.argsort(dist[mask, :][:, mask], axis=-1)[:, :self.neighbourhood] + self.cache[id].k_neighbors = k_neighbors + G = tm.graph.vertex_adjacency_graph(m) + for i in range(v.shape[0]): + for k in range(25): + assert nx.has_path(G, i, k_neighbors[i, k]), f'No path between {i} and {k_neighbors[i, k]}' + self.cache[id].mask = mask self.cache[id].faces = faces @@ -162,7 +162,6 @@ def calculate_dist(folder, neighbourhood, frames): def generate_curvatures(folder, neighbourhood, frames): - # ids = os.listdir(folder)[int(args.start):int(args.end)] # frames = frames[int(args.start):int(args.end)] os.makedirs(os.path.join('/'.join(folder.split('/')[:-1]), 'backup', f'mesh_curvature_raw'), exist_ok=True) @@ -176,9 +175,6 @@ def generate_curvatures(folder, neighbourhood, frames): frame_nr = int(frame.split()[1]) garment = frame.split()[2] - # bodies = readPC2(os.path.join(folder, id, 'Body_posed.pc16'), True)['V'] - # offsetss = readPC2(os.path.join(folder, id, garment + '_registered.pc16'), True)['V'] - # mask = np.load(os.path.join(folder, 'mesh_mask', f'{id}.npy')).astype(bool) mask = cache[id].mask faces = cache[id].faces v = read_posed_garment_frame(folder, id, garment, frame_nr)[mask,:] @@ -193,7 +189,6 @@ def generate_curvatures(folder, neighbourhood, frames): curvature = np.array(cloud.points["curvature(" + str(neighbourhood+1) + ")"]) out = np.zeros((14475), dtype=np.float32) out[mask] = curvature - np.savez_compressed(os.path.join('/'.join(folder.split('/')[:-1]), 'backup', f'mesh_curvature_raw', f'{id}_{frame_nr}_{garment}.npz'), mesh_curvature_raw=out) group = h5file.get_node(f'/{id}/{frame_nr}/{garment}') @@ -204,7 +199,6 @@ def generate_curvatures(folder, neighbourhood, frames): carray = h5file.create_carray(group, "curvature_raw", atom=tb.Float32Atom(), shape=out.shape, filters=filters) carray[:] = out - return None @@ -282,24 +276,13 @@ def visualize_curvature_labels(folder, frames): faces = cache[id].faces verts = read_posed_garment_frame(folder, id, garment, frame_nr)[mask, :] curv = h5file.get_node(f'/{id}/{frame_nr}/{garment}/curvature_mesh_global').read()[mask] - - # m = tm.Trimesh(verts, faces, process=False, validate=False) - - # outliers = np.array([len(v) for v in m.vertex_neighbors]) == 0 - # outliers = np.nonzero(outliers)[0] - # outliers_n_neighbours = get_closest_n_points(verts, outliers, 2) - # outliers_faces = np.concatenate((outliers[:, np.newaxis], outliers_n_neighbours), axis=-1) - # faces = np.concatenate((faces, outliers_faces), axis=0) colors = np.array([cm.color('jet', 1 - i) for i in np.linspace(0, 1, int(curv.max()))]) colors_binned = np.zeros((curv.shape[0], 3)) for i in range(1, int(curv.max())+1): # print(np.count_nonzero(curv == i)) colors_binned[curv == i, :] = colors[i-1] - # colors_binned = colors_binned[mask, :] - # m = tm.Trimesh(verts, faces, process=False, validate=False, vertex_colors=colors_binned) - # m.show() x = verts meshes = [go.Mesh3d( x=x[:,0], diff --git a/data/utils.py b/data/utils.py index bc3908f..e7d6392 100644 --- a/data/utils.py +++ b/data/utils.py @@ -1,4 +1,4 @@ - +import tables as tb class Frame: def __init__(self, id, frame_nr, garment): @@ -12,3 +12,23 @@ class Frame: def __eq__(self, other): return (self.id, self.frame_nr) == (other.id, other.frame_nr) + +def save_to_h5file(h5file, id, frame_nr, garment, data, name, type): + filters = tb.Filters(complevel=9, complib='blosc2') + group = h5file.get_node(f'/{id}/{frame_nr}/{garment}') + + if type == 'float32': + atom = tb.Float32Atom() + elif type == 'uint8': + atom = tb.UInt8Atom() + elif type == 'bool': + atom = tb.BoolAtom() + else: + raise Exception('Unknown type') + + if f'{name}' in group: + array = h5file.get_node(f'/{id}/{frame_nr}/{garment}/{name}') + array[:] = data + else: + carray = h5file.create_carray(group, name, atom=atom, shape=data.shape, filters=filters) + carray[:] = data \ No newline at end of file