3from mathutils
import Matrix
7 """! Save depth_M_color.txt file.
8 @param[in] prefix_data String corresponding to the folder where depth_M_color.txt file has to be saved.
9 @param[in] scene Scene handler.
10 @param[in] camera_name_color String corresponding to the name of the color camera to consider.
11 @param[in] camera_name_depth String corresponding to the name of the depth camera to consider.
16 d_M_c = w_M_d.inverted() @ w_M_c
19 filename = prefix_data +
"depth_M_color.txt"
21 print(f
"Saved: {filename}")
24 """! Return the object pose in the world frame w_M_o.
25 @param[in] object_name String corresponding to the name of the object to consider.
26 @return The 4-by-4 homogeneous matrix corresponding to w_M_object.
28 w_M_object = bpy.data.objects[object_name].matrix_world
29 w_M_object_normalized = w_M_object.copy()
30 w_R_object_normalized = w_M_object_normalized.to_3x3().normalized()
33 w_M_object_normalized[i][j] = w_R_object_normalized[i][j]
34 return w_M_object_normalized
37 """! Return the object pose in the camera frame as an homogenous matrices.
38 @param[in] camera_name String corresponding to the name of the camera to consider.
39 @param[in] object_name String corresponding to the name of the object to consider.
40 @return The 4-by-4 homogeneous matrix corresponding to c_M_o.
56 c_M_o = M @ w_M_c.inverted() @ w_M_o
62 """! Save pose in a .txt file.
63 @param[in] filename String corresponding to the file name that will contain the saved pose.
64 @param[in] pose Object pose to save as a 4-by-4 homogeneous matrix.
67 print(f
"Save: {filename}")
68 with open(filename,
'w')
as f:
69 f.write(str(pose[0][0]) +
" ")
70 f.write(str(pose[0][1]) +
" ")
71 f.write(str(pose[0][2]) +
" ")
72 f.write(str(pose[0][3]) +
" ")
75 f.write(str(pose[1][0]) +
" ")
76 f.write(str(pose[1][1]) +
" ")
77 f.write(str(pose[1][2]) +
" ")
78 f.write(str(pose[1][3]) +
" ")
81 f.write(str(pose[2][0]) +
" ")
82 f.write(str(pose[2][1]) +
" ")
83 f.write(str(pose[2][2]) +
" ")
84 f.write(str(pose[2][3]) +
" ")
87 f.write(str(pose[3][0]) +
" ")
88 f.write(str(pose[3][1]) +
" ")
89 f.write(str(pose[3][2]) +
" ")
90 f.write(str(pose[3][3]) +
" ")
96 """! Save homogeneous transformation from camera to object frames (cMo).
97 @param[in] prefix String corresponding to the folder name that will contain the saved poses.
98 @param[in] scene Scene handler.
99 @param[in] camera_name String corresponding to the name of the camera to consider.
100 @param[in] object_name String corresponding to the name of the object to track.
102 frame_number = scene.frame_current
103 print(
"\n\nCurrent Frame", scene.frame_current)
106 filename = prefix + camera_name_color +
"_%04d" % frame_number +
".txt"
110 """! Save camera intrinsics in xml.
111 @param[in] camera_name String corresponding to the name of the camera to consider.
113 cam_data = bpy.data.objects[camera_name].data
115 scene = bpy.context.scene
116 resolution_x_in_px = scene.render.resolution_x
117 resolution_y_in_px = scene.render.resolution_y
118 scale = scene.render.resolution_percentage / 100
119 sensor_width = cam_data.sensor_width
120 sensor_height = cam_data.sensor_height
121 pixel_aspect_ratio = scene.render.pixel_aspect_x / scene.render.pixel_aspect_y
122 if (cam_data.sensor_fit ==
'VERTICAL'):
125 s_u = resolution_x_in_px * scale / sensor_width / pixel_aspect_ratio
126 s_v = resolution_y_in_px * scale / sensor_height
130 pixel_aspect_ratio = scene.render.pixel_aspect_x / scene.render.pixel_aspect_y
131 s_u = resolution_x_in_px * scale / sensor_width
132 s_v = resolution_y_in_px * scale * pixel_aspect_ratio / sensor_height
135 w = resolution_x_in_px
136 h = resolution_y_in_px
139 u_0 = resolution_x_in_px*scale / 2
140 v_0 = resolution_y_in_px*scale / 2
142 return w, h, p_x, p_y, u_0, v_0
145 """! Save camera intrinsics in xml.
146 @param[in] filename Name of the file that will contain the intrinsics in xml format.
147 @param[in] camera_name Camera name.
148 @param[in] w, h Image size.
149 @param[in] p_x, p_y Ratio between the focal length and the size of the pixel.
150 @param[in] u_0, v_0 Coordinates of the principal point.
152 print(f
"Save: {filename}")
153 with open(filename,
'w')
as f:
154 f.write(
"<?xml version=\"1.0\"?>\n")
156 f.write(
" <camera>\n")
157 f.write(f
" <name>{camera_name}</name>\n")
158 f.write(f
" <image_width>{w}</image_width>\n")
159 f.write(f
" <image_height>{h}</image_height>\n")
160 f.write(
" <model>\n")
161 f.write(
" <type>perspectiveProjWithoutDistortion</type>\n")
162 f.write(f
" <px>{p_x}</px>\n")
163 f.write(f
" <py>{p_y}</py>\n")
164 f.write(f
" <u0>{u_0}</u0>\n")
165 f.write(f
" <v0>{v_0}</v0>\n")
166 f.write(
" </model>\n")
167 f.write(
" </camera>\n")
171if __name__ ==
'__main__':
172 """! Python script that save camera poses, color and depth images, but also depth to color transform.
174 camera_name_color =
"Camera_L"
175 camera_name_depth =
"Camera_R"
176 object_name =
"teabox"
177 prefix_data =
"/tmp/teabox/"
178 prefix_pose = prefix_data +
"ground-truth/"
179 prefix_color_images = prefix_data +
"color/"
180 prefix_depth_images = prefix_data +
"depth/"
181 images_suffix =
"JPEG"
183 if not os.path.exists(prefix_data):
184 print(f
"Create {prefix_data}")
185 os.makedirs(prefix_data)
187 if not os.path.exists(prefix_pose):
188 print(f
"Create {prefix_pose}")
189 os.makedirs(prefix_pose)
191 scene = bpy.context.scene
195 color_w, color_h, color_p_x, color_p_y, color_u_0, color_v_0 =
get_intrinsics(camera_name_color)
196 filename_color_intrinsics = prefix_data + camera_name_color +
".xml"
197 save_intrinsics(filename_color_intrinsics, camera_name_color, color_w, color_h, color_p_x, color_p_y, color_u_0, color_v_0)
199 depth_w, depth_h, depth_p_x, depth_p_y, depth_u_0, depth_v_0 =
get_intrinsics(camera_name_depth)
200 filename_depth_intrinsics = prefix_data + camera_name_depth +
".xml"
201 save_intrinsics(filename_depth_intrinsics, camera_name_depth, depth_w, depth_h, depth_p_x, depth_p_y, depth_u_0, depth_v_0)
203 for step
in range(scene.frame_start, scene.frame_end):
205 scene.frame_set(step)
208 if not os.path.exists(prefix_color_images):
209 os.makedirs(prefix_color_images)
210 scene.render.filepath = (prefix_color_images +
'%04d') % step
211 scene.render.image_settings.file_format = images_suffix
212 bpy.ops.render.render( write_still=
True )
219 filename_color_R = (prefix_color_images +
'%04d' +
"_R" + scene.render.file_extension) % step
220 if not os.path.exists(filename_color_R):
221 raise Exception(f
"Color image {filename_color_R} doesn't exists. Should not occur.")
223 print(f
"Remove file: {filename_color_R}")
224 os.remove(filename_color_R)
226 filename_depth_L = (prefix_depth_images +
'Image%04d' +
"_L" +
".exr") % step
227 if not os.path.exists(filename_depth_L):
228 raise Exception(f
"Depth image {filename_depth_L} doesn't exists. Check if you set the extension to OpenEXR in the compositor.")
230 print(f
"Remove file: {filename_depth_L}")
231 os.remove(filename_depth_L)
save_color_camera_pose(prefix, scene, camera_name, object_name)
Save homogeneous transformation from camera to object frames (cMo).
get_intrinsics(camera_name)
Save camera intrinsics in xml.
save_intrinsics(filename, camera_name, w, h, p_x, p_y, u_0, v_0)
Save camera intrinsics in xml.
save_depth_M_color_file(prefix_data, scene, camera_name_color, camera_name_depth)
Save depth_M_color.txt file.
get_camera_pose(camera_name, object_name)
Return the object pose in the camera frame as an homogenous matrices.
save_pose(filename, pose)
Save pose in a .txt file.
get_object_pose_in_world(object_name)
Return the object pose in the world frame w_M_o.