Skip to content

Commit 6be9791

Browse files
committed
forked custom scene replication script and adjusted boploader for xyzibd
1 parent 0525d04 commit 6be9791

File tree

2 files changed

+131
-11
lines changed

2 files changed

+131
-11
lines changed

blenderproc/python/loader/BopLoader.py

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -122,32 +122,64 @@ def load_bop_scene(bop_dataset_path: str, scene_id: int, model_type: str = "", c
122122
"""
123123

124124
bop_path, bop_dataset_name = _BopLoader.setup_bop_toolkit(bop_dataset_path)
125-
125+
126126
# This import is done inside to avoid having the requirement that BlenderProc depends on the bop_toolkit
127127
# pylint: disable=import-outside-toplevel
128128
from bop_toolkit_lib import dataset_params, inout
129-
129+
130130
# pylint: enable=import-outside-toplevel
131131

132132
if source_frame is None:
133133
source_frame = ["X", "-Y", "-Z"]
134134

135135
model_p = dataset_params.get_model_params(bop_path, bop_dataset_name, model_type=model_type if model_type else None)
136+
137+
# TODO: uncomment to enable debug output
138+
"""
139+
print("------- Model Params -------")
140+
for k,v in model_p.items():
141+
print(f"[{k}]: {v}")
142+
print("----------------------------")"""
143+
136144
try:
137145
split_p = dataset_params.get_split_params(bop_path, bop_dataset_name, split=split,
138146
split_type=cam_type if cam_type else None)
147+
139148
except ValueError as e:
140149
raise RuntimeError(f"Wrong path or {split} split does not exist in {bop_dataset_path}.") from e
150+
151+
# TODO: uncomment to enable debug output
152+
"""
153+
print("------- Split Params -------")
154+
for k,v in split_p.items():
155+
if v is not None and "xyzibd" in v:
156+
rel_v_path = v.split("xyzibd")[1]
157+
else:
158+
rel_v_path = v
159+
print(f"[{k}]: {rel_v_path}")
160+
161+
if rel_v_path is not None and "scene_gt.json" in rel_v_path:
162+
print("found it")
163+
break
164+
print("----------------------------")"""
165+
166+
# add actual paths by hand, since dataset_params.get_split_params provides no acceess to internal structure
167+
if bop_dataset_name == "xyzibd":
168+
split_p["scene_gt_tpath"] = os.path.join(bop_path, bop_dataset_name, "train", "{scene_id:06d}", "scene_gt.json")
169+
split_p["scene_camera_tpath"] = os.path.join(bop_path, bop_dataset_name, "train", "{scene_id:06d}", "scene_camera.json")
170+
141171
sc_gt = inout.load_scene_gt(split_p['scene_gt_tpath'].format(**{'scene_id': scene_id}))
142172
sc_camera = inout.load_json(split_p['scene_camera_tpath'].format(**{'scene_id': scene_id}))
143-
173+
144174
assert object_model_unit in ['m', 'dm', 'cm', 'mm'], (f"Invalid object model unit: `{object_model_unit}`. "
145175
f"Supported are 'm', 'dm', 'cm', 'mm'")
146176
scale = {'m': 1., 'dm': 0.1, 'cm': 0.01, 'mm': 0.001}[object_model_unit]
147177
if mm2m is not None:
148178
warnings.warn("WARNING: `mm2m` is deprecated, please use `object_model_unit='mm'` instead!")
149179
scale = 0.001
150-
180+
181+
182+
camera_poses = []
151183
for i, (cam_id, insts) in enumerate(sc_gt.items()):
152184
cam_K, cam_H_m2c_ref = _BopLoader.get_ref_cam_extrinsics_intrinsics(sc_camera, cam_id, insts, scale)
153185

@@ -162,8 +194,13 @@ def load_bop_scene(bop_dataset_path: str, scene_id: int, model_type: str = "", c
162194
_BopLoader.set_object_pose(cur_objs[-1], inst, scale)
163195

164196
cam_H_c2w = _BopLoader.compute_camera_to_world_trafo(cam_H_m2w_ref, cam_H_m2c_ref, source_frame)
197+
camera_poses.append(cam_H_c2w)
165198
# set camera intrinsics
166-
CameraUtility.set_intrinsics_from_K_matrix(cam_K, split_p['im_size'][0], split_p['im_size'][1])
199+
if bop_dataset_name == "xyzibd":
200+
# Quick and dirty fix for xyzibd
201+
CameraUtility.set_intrinsics_from_K_matrix(cam_K, split_p['im_size']['xyz'][0], split_p['im_size']['xyz'][1])
202+
else:
203+
CameraUtility.set_intrinsics_from_K_matrix(cam_K, split_p['im_size'][0], split_p['im_size'][1])
167204

168205
# set camera extrinsics as next frame
169206
frame_id = CameraUtility.add_camera_pose(cam_H_c2w)
@@ -176,10 +213,11 @@ def load_bop_scene(bop_dataset_path: str, scene_id: int, model_type: str = "", c
176213
# Copy object poses to key frame (to be sure)
177214
for cur_obj in cur_objs:
178215
_BopLoader.insert_key_frames(cur_obj, frame_id)
216+
217+
return cur_objs, camera_poses
179218

180-
return cur_objs
181-
182-
219+
220+
183221
def load_bop_intrinsics(bop_dataset_path: str, split: str = "test", cam_type: str = "") -> Tuple[np.ndarray, int, int]:
184222
"""
185223
Load and set the camera matrix and image resolution of a specified BOP dataset
@@ -217,6 +255,7 @@ def load_bop_intrinsics(bop_dataset_path: str, split: str = "test", cam_type: st
217255
return cam_p['K'], split_p['im_size'][0], split_p['im_size'][1]
218256

219257

258+
220259
class _BopLoader:
221260
CACHED_OBJECTS = {}
222261
@staticmethod
@@ -256,10 +295,10 @@ def compute_camera_to_world_trafo(cam_H_m2w_ref: np.array, cam_H_m2c_ref: np.arr
256295
"""
257296

258297
cam_H_c2w = np.dot(cam_H_m2w_ref, np.linalg.inv(cam_H_m2c_ref))
259-
260-
print('-----------------------------')
298+
# TODO: uncomment
299+
"""print('-----------------------------')
261300
print(f"Cam: {cam_H_c2w}")
262-
print('-----------------------------')
301+
print('-----------------------------')"""
263302

264303
# transform from OpenCV to blender coords
265304
cam_H_c2w = change_source_coordinate_frame_of_transformation_matrix(cam_H_c2w, source_frame)
@@ -371,3 +410,4 @@ def load_mesh(obj_id: int, model_p: dict, bop_dataset_name: str, scale: float =
371410
cur_obj.set_cp("bop_dataset_name", bop_dataset_name)
372411

373412
return cur_obj
413+
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import blenderproc as bproc
2+
from pathlib import Path
3+
import argparse
4+
import os
5+
6+
# This script loads a BOP dataset scene and rerenders it with freestyle edges
7+
# Then write the results back using the BOP folder structure
8+
9+
def normalize_path(path_str: str) -> Path:
10+
"""
11+
Normalize a filesystem path in an OS-agnostic way.
12+
13+
- Expands user (~) and environment variables.
14+
- Converts relative paths to absolute.
15+
- Normalizes slashes and resolves ".." and "." segments.
16+
"""
17+
if not path_str:
18+
return None
19+
return Path(path_str).expanduser().resolve()
20+
21+
parser = argparse.ArgumentParser()
22+
parser.add_argument('bop_parent_path', nargs='?', help="Path to the bop datasets parent directory")
23+
parser.add_argument('bop_dataset_name', nargs='?', help="Main BOP dataset")
24+
parser.add_argument('output_dir', nargs='?', help="Path to where the final files will be saved ")
25+
args = parser.parse_args()
26+
27+
# Normalize paths to ensure compatibility across different operating systems
28+
args.bop_parent_path = normalize_path(args.bop_parent_path)
29+
args.output_dir = normalize_path(args.output_dir)
30+
31+
bproc.init()
32+
33+
# load specified bop objects into the scene
34+
35+
render_id = 0
36+
while True:
37+
print(f"Rendering scene id {render_id}...")
38+
try:
39+
bop_objs, camera_poses = bproc.loader.load_bop_scene(
40+
bop_dataset_path = os.path.join(args.bop_parent_path, args.bop_dataset_name),
41+
object_model_unit = "mm",
42+
scene_id = render_id,
43+
split = 'train')
44+
45+
# set shading
46+
print("----------Object Info----------")
47+
for j, obj in enumerate(bop_objs):
48+
obj.set_shading_mode('auto')
49+
print(j, obj.get_name())
50+
print("-------------------------------")
51+
52+
# Set light source
53+
light_point = bproc.types.Light()
54+
light_point.set_energy(1000)
55+
light_point.set_location([0, 0, -0.8])
56+
57+
# activate depth rendering
58+
bproc.renderer.enable_depth_output(activate_antialiasing=False)
59+
bproc.renderer.set_max_amount_of_samples(50)
60+
61+
bproc.renderer.set_render_devices(desired_gpu_device_type=["HIP", "CUDA"])
62+
# render the cameras of the current scene
63+
data = bproc.renderer.render(verbose=True)
64+
65+
# Render the edges
66+
data["edges"] = bproc.renderer.render_edges(
67+
target_objects=bop_objs, camera_poses=camera_poses
68+
)
69+
70+
# Write data to bop format
71+
bproc.writer.write_bop(os.path.join(args.output_dir, 'bop_data'),
72+
dataset=args.bop_dataset_name,
73+
depths = data["depth"],
74+
colors=data["colors"],
75+
edges=data["edges"],
76+
save_world2cam=False) # world coords are arbitrary in most real BOP datasets
77+
render_id += 1
78+
except Exception as e:
79+
print(f"Finished rendering all scenes. Stopped at scene id {render_id}.")
80+
break

0 commit comments

Comments
 (0)