Skip to content

Commit

Permalink
new version now it should prepare and assemble a list of broken objec…
Browse files Browse the repository at this point in the history
…ts, testing
  • Loading branch information
freerafiki committed Jun 7, 2023
1 parent dbdb681 commit b814e73
Show file tree
Hide file tree
Showing 12 changed files with 328 additions and 149 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# AAFR (Ali Alagrami Fresco Reconstruction)

The AAFR is a framework


# Feature Lines Extraction

FeatureLine is used to extract feature lines as per the paper (Gumhold, Stefan & Wang, Xinlong & MacLeod, Rob. (2001). Feature Extraction from Point Clouds. Proceedings of 10th international meshing roundtable. 2001. )
Expand Down
39 changes: 33 additions & 6 deletions assemble_fragments.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,60 @@ def main(args):
module_name = f"configs.{args.cfg}"
cfg = importlib.import_module(module_name)

print("\nWill try to assemble:")
for i, broken_objects in enumerate(cfg.data_list):
category = broken_objects["category"]
fracture = broken_objects["fracture"]
name = f"{category}_{fracture}"
print(f"{i}) {name}")

print('\n')
print('-' * print_line_length)
category = broken_objects["path_obj1"].split("/")[-3]
fracture = broken_objects["path_obj1"].split("/")[-2]
print()
for i, broken_objects in enumerate(cfg.data_list):

print('#' * print_line_length)
category = broken_objects["category"]
fracture = broken_objects["fracture"]
name = f"{category}_{fracture}"
print(f'Current broken object: {fracture} ({category})')
fr_ass = fragment_reassembler(broken_objects, cfg.pipeline_parameters, cfg.name, show_results = True, save_results=True)
fr_ass = fragment_reassembler(broken_objects, cfg.variables_as_list, cfg.pipeline_parameters, name, show_results = True, save_results=True)
print('-' * print_line_length)
# load object and move them (challenge_R_T) to have something to solve (without R and T they are loaded in the correct position)
fr_ass.load_objects()

# set output directory, save fragments and information there
fr_ass.set_output_dir(cfg.output_dir)
fr_ass.save_fragments(cfg.name)
fr_ass.save_info()

# 3.1) breaking curves
print('-' * print_line_length)
fr_ass.detect_breaking_curves()
fr_ass.save_breaking_curves()

# 3.2) segmentation
print('-' * print_line_length)
fr_ass.segment_regions()
fr_ass.save_segmented_regions()

# 3.3) registration
print('-' * print_line_length)
fr_ass.register_segmented_regions()
fr_ass.save_registration_results()

# if we have ground truth, evaluate it
if 'solution' in broken_objects.keys():
print('-' * print_line_length)
fr_ass.evaluate_against_gt()
fr_ass.save_evaluation_results()

print('#' * print_line_length)

pdb.set_trace()
return 1

if __name__ == '__main__':

parser = argparse.ArgumentParser(description='Reassembling broken objects')
parser.add_argument('--cfg', type=str, default='base', help='config file (.py)')
parser.add_argument('--cfg', type=str, default='assemble_cfg', help='config file (.py)')
args = parser.parse_args()
main(args)
Binary file modified configs/__pycache__/base.cpython-36.pyc
Binary file not shown.
47 changes: 47 additions & 0 deletions configs/assemble_cfg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# parameters for the pipeline
pipeline_parameters = {
# angles and translation parameters for initial "challenge" position
'challenge_R_T' : [[0.2, 0.2, 0.1], [-0.5, -0.5, -0.5]],
'processing_module' : "standard",
'registration_module' : "teaser",
'evaluation_metrics' : ["rms"]
}

# data_list
num_of_points = 15000 # resampling to n points
# see paper for details (graph creation)
to = 100
tb = 0.1
dil = 0.01
thre = 0.93
N = 15
variables_as_list = [num_of_points, num_of_points, N, to, to, to, tb, tb, tb, dil, thre]

import os, pdb, json
name = f'drinkbottle_{num_of_points}'
output_dir = os.path.join('3dvr_results', name)
os.makedirs(output_dir, exist_ok=True)

# list of broken objects (for now pairs)
data_folder = 'data'
data_list = []

for category_folder in os.listdir(data_folder):
cat_ff = os.path.join(data_folder, category_folder)
for fracture_folder in os.listdir(cat_ff):
objects_folder = os.path.join(cat_ff, fracture_folder, 'objects')
p_o1 = os.path.join(objects_folder, 'obj1_challenge.ply')
p_o2 = os.path.join(objects_folder, 'obj2_challenge.ply')
solution_folder = os.path.join(cat_ff, fracture_folder, 'solution')
broken_obj_dict = {
"path_obj1": p_o1,
"path_obj2": p_o2,
"category": category_folder,
"fracture": fracture_folder
}
if os.path.exists(solution_folder):
with open(os.path.join(solution_folder, 'solution.json'), 'r') as sj:
solution = json.load(sj)
broken_obj_dict['solution'] = solution

data_list.append(broken_obj_dict)
45 changes: 0 additions & 45 deletions configs/base.py

This file was deleted.

21 changes: 21 additions & 0 deletions configs/prepare_cfg.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# configuration file

r : [0.2, 0.2, 0.1]
t : [-0.5, -0.5, -0.5]

voxel_size : 15000
move_to_origin : False

output_folder : 'data'

data_list : [
[
"/media/lucap/big_data/datasets/pairwise/ali/DrinkBottle/fractured_62/piece_0.obj",
"/media/lucap/big_data/datasets/pairwise/ali/DrinkBottle/fractured_62/piece_1.obj"
],
[
"/media/lucap/big_data/datasets/pairwise/ali/DrinkBottle/fractured_70/piece_0.obj",
"/media/lucap/big_data/datasets/pairwise/ali/DrinkBottle/fractured_70/piece_1.obj",
]
]

1 change: 1 addition & 0 deletions helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from copy import copy, deepcopy
random.seed(0)
np.random.seed(0)

def down_sample_to(obj,num):
if len(obj.points) < num:
print("num should be less than number of voxels in the objects, no down sampling will happen !")
Expand Down
4 changes: 0 additions & 4 deletions pipline_modules/standard.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,11 +231,8 @@ def run(Obj_url, pipline_variables, folder_path=''):
border_nodes = [node for branch in valid_nodes for node in branch]

dilated_border = dilate_border(Obj,border_nodes,dilation_size)


dilated_faces = get_sides(isolated_islands_pruned_graph, dilated_border)

pdb.set_trace()
print("got faces")

node_face = {}
Expand Down Expand Up @@ -280,7 +277,6 @@ def run(Obj_url, pipline_variables, folder_path=''):

return Obj,Objects


def load_obj(Obj_url, small, large, N):
if Obj_url.split("_")[-1] == "0.obj":
#print("big object")
Expand Down
95 changes: 95 additions & 0 deletions prepare_challenge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import numpy as np
from helper import down_sample_to
import open3d as o3d
import json
import argparse
import yaml
import os

def read_obj(path, voxel_size):

if path.endswith('.ply'):
pcd1 = o3d.io.read_point_cloud(path)
voxel_percentage = down_sample_to(pcd1,voxel_size)
#print("my number is -> ",voxel_percentage)
downpcd1 = pcd.voxel_down_sample(voxel_size=voxel_percentage)
elif path.endswith('.obj'):
mesh = o3d.io.read_triangle_mesh(path)
downpcd1 = mesh.sample_points_uniformly(number_of_points=voxel_size)
else:
print("we only support .ply or .obj at the moment!\nFound", cfg['path_obj1'])
return None, -1

return downpcd1, 0

def main(args):

print('Config file:', args.cfg)
with open(args.cfg, 'r') as yaml_file:
cfg = yaml.safe_load(yaml_file)

for obj_pair in cfg['data_list']:

print('Preparing:')
path_obj1 = obj_pair[0]
path_obj2 = obj_pair[1]
print(path_obj1)
print(path_obj2)

pcd1, ok1 = read_obj(path_obj1, voxel_size = cfg['voxel_size'])
pcd2, ok2 = read_obj(path_obj2, voxel_size = cfg['voxel_size'])

if ok1 == 0 and ok2 == 0:

# moving to origin if we need it (see config file, default False)
if cfg['move_to_origin']:
c1 = np.mean(np.asarray(pcd1.points), axis=1)
pcd1.translate(-c1)
c2 = np.mean(np.asarray(pcd2.points), axis=1)
pcd1.translate(-c2)

r = np.asarray(cfg['r'])
t = np.asarray(cfg['t'])
rot_mat = o3d.geometry.get_rotation_matrix_from_xyz(r)
trsf_mat = np.eye(4)
trsf_mat[:3, :3] = rot_mat
trsf_mat[:3, 3] = t
r_inv = np.linalg.inv(rot_mat)
t_inv = -t
gt = np.eye(4)
gt[:3, :3] = r_inv
gt[:3, 3] = t_inv

pcd2.transform(trsf_mat)

category = path_obj1.split("/")[-3]
fracture = path_obj1.split("/")[-2]
output_dir = os.path.join(cfg['output_folder'], category, fracture)

output_pcds = os.path.join(output_dir, 'objects')
output_sol = os.path.join(output_dir, 'solution')
os.makedirs(output_pcds, exist_ok=True)
os.makedirs(output_sol, exist_ok=True)
solution = {
'T' : trsf_mat.tolist(),
'r' : rot_mat.tolist(),
't' : t.tolist(),
'GT': gt.tolist(),
'gt_r': r_inv.tolist(),
'gt_t': t_inv.tolist()
}
with open(os.path.join(output_sol, 'solution.json'), 'w') as osj:
json.dump(solution, osj, indent=3)
o3d.io.write_point_cloud(os.path.join(output_pcds, 'obj1_challenge.ply'), pcd1)
o3d.io.write_point_cloud(os.path.join(output_pcds, 'obj2_challenge.ply'), pcd2)
print('Saved in', output_dir)
else:
print('something went wrong! please check config file and input paths.')
print('FINISHED')

if __name__ == '__main__':

parser = argparse.ArgumentParser(description='Preparing challenge (moving objects)')
parser.add_argument('--cfg', type=str, default='base', help='config file (.yaml)')
args = parser.parse_args()
main(args)
2 changes: 1 addition & 1 deletion register_seg_parts.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def main():
transf_icp.append(np.eye(4))
chamfer_distances.append(MIN_PCD_SIZE)

else:ORIGINAL
else:
target = copy(pcd_part1)
source = copy(pcd_part2)
icp_sol, teaser_sol, num_corrs = register_fragments(source, target)
Expand Down
Loading

0 comments on commit b814e73

Please sign in to comment.