4 Simple Script to Processes Bag files from RawSnapshot in Release 2.0 5 and writes the data to file for calibration 7 Please direct any question to multisense@carnegierobotics.com or 8 http://support.carnegierobotics.com 22 raise Exception(
"Error importing ROS. Source the ROS environment" \
23 +
" in the workspace where the multisense stack is located")
57 def process(self, directory='.', rename_file = True,
58 namespace =
'multisense'):
64 print "Could not find valid images in the bag file" 83 print "Average Pixel Error:", average_error,
"pixels" 85 if average_error < 2.:
86 print "Calibration is good" 88 print "Calibration appears to be poor. Place the unit 1 meter from"\
89 " a texture-rich corner an rerun the check." 108 with open(directory +
'/' +
'lidarData.csv',
'wb')
as laser_file:
109 topic_name =
'/%s/calibration/raw_lidar_data' % namespace
110 laser_writer = csv.writer(laser_file, delimiter=
',')
111 for topic, msg, t
in bag.read_messages(topics=[topic_name]):
113 scan_count = msg.scan_count
114 time_start = float(msg.time_start.secs +
115 msg.time_start.nsecs * 1e-9)
116 time_end = float(msg.time_end.secs + msg.time_end.nsecs * 1e-9)
117 angle_start = msg.angle_start
118 angle_end = msg.angle_end
120 reflect = msg.intensity
124 row = [scan_count, time_start, time_end,
125 angle_start, angle_end,
" "] + list(dist) + [
" "] \
126 + list(reflect) + [
" "] + [len(list(dist))]
128 laser_writer.writerow(row)
144 topic_name =
'/%s/calibration/raw_cam_data' % namespace
148 found_rectified_image =
False 149 found_disparity_image =
False 151 for topic, msg, t
in bag.read_messages(topics=[topic_name]):
156 if not found_rectified_image
and len(list(msg.gray_scale_image)) != 0:
157 self.
write_pgm(np.array(list(msg.gray_scale_image)),
158 directory +
'/' +
"stereo_left_0000.pgm",
160 found_rectified_image =
True 163 if not found_disparity_image
and len(list(msg.disparity_image)) != 0:
164 self.
disparityImage = np.array(list(msg.disparity_image), dtype=np.uint16)
165 self.
errorImage = np.zeros(len(list(msg.disparity_image)), dtype=np.float64) - 1
166 self.
laserDisparity = np.zeros(len(list(msg.disparity_image)), dtype=np.uint16)
170 directory +
'/' +
"disparity_0000.pgm",
172 found_disparity_image =
True 177 if found_disparity_image
and found_rectified_image:
187 image = open(name,
'wb')
190 pgm_header =
'P5' +
'\n' + str(width) +
' ' \
191 + str(height) +
'\n' + str(2**bits - 1) +
'\n' 195 data = data.byteswap()
198 image.write(pgm_header)
205 topic_name =
'/%s/calibration/raw_cam_config' % namespace
207 for topic, msg, t
in bag.read_messages(topics=[topic_name]):
216 p1 =
"[ %.17e, 0., %d, 0., 0., \n" % (fx, cx) \
217 +
" %.17e, %d, 0., 0., 0., 1., 0.]" % (fy, cy) \
219 p2 =
"[ %.17e, 0., %d, %.17e, 0., \n" % (fx, cx, tx*fx) \
220 +
" %.17e, %d, 0., 0., 0., 1., 0.]" % (fy, cy) \
226 self.
qMatrix = np.matrix([[fy * tx, 0 , 0, -fy * cx * tx],
227 [0, fx * tx, 0, -fx * cy * tx],
228 [0, 0, 0, fx * fy * tx],
241 yaml = open(name,
'wb')
243 yaml_header =
"%YAML:1.0\n" 244 yaml.write(yaml_header)
246 p1_header =
"P1: !!opencv-matrix\n" \
252 p2_header =
"P2: !!opencv-matrix\n" \
257 yaml.write(p1_header)
258 yaml.write(
" data: " + p1 +
'\n\n')
259 yaml.write(p2_header)
260 yaml.write(
" data: " + p2 +
'\n')
266 topic_name =
'/%s/calibration/raw_lidar_cal' % namespace
268 for topic, msg, t
in bag.read_messages(topics=[topic_name]):
271 lts = list(msg.laserToSpindle)
273 cts = list(msg.cameraToSpindleFixed)
276 laser_t_spind =
"[ %.17e, %.17e,\n" % (lts[0], lts[1]) \
277 +
" %.17e, %.17e,\n" % (lts[2], lts[3]) \
278 +
" %.17e, %.17e,\n" % (lts[4], lts[5]) \
279 +
" %.17e, %.17e,\n" % (lts[6], lts[7]) \
280 +
" %.17e, %.17e,\n" % (lts[8], lts[9]) \
281 +
" %.17e, 0., 0., 0., 0., 1. ]" % (lts[10])
284 camera_t_spind =
"[ %.17e, %.17e,\n" % (cts[0], cts[1]) \
285 +
" %.17e, %.17e,\n" % (cts[2], cts[3]) \
286 +
" %.17e, %.17e,\n" % (cts[4], cts[5]) \
287 +
" %.17e, %.17e,\n" % (cts[6], cts[7]) \
288 +
" %.17e, %.17e,\n" % (cts[8], cts[9]) \
289 +
" %.17e, %.17e, 0., 0., 0., 1. ]" % (cts[10], cts[11])
292 laser_t_spind, camera_t_spind)
294 self.
laserToSpindle = np.matrix([[lts[0], lts[1], lts[2], lts[3]],
295 [lts[4], lts[5], lts[6], lts[7]],
296 [lts[8], lts[9], lts[10], lts[11]],
297 [lts[12], lts[13], lts[14], lts[15]]])
300 [cts[4], cts[5], cts[6], cts[7]],
301 [cts[8], cts[9], cts[10], cts[11]],
302 [cts[12], cts[13], cts[14], cts[15]]])
311 yaml = open(name,
'wb')
312 yaml_header =
"%YAML:1.0\n" 313 yaml.write(yaml_header)
315 laser_t_spind_h =
"laser_T_spindle: !!opencv-matrix\n" \
320 cam_t_spind_h =
"camera_T_spindle_fixed: !!opencv-matrix\n" \
325 yaml.write(laser_t_spind_h)
326 yaml.write(
" data: " + laser_t_spind +
'\n')
327 yaml.write(cam_t_spind_h)
328 yaml.write(
" data: " + cam_t_spind +
'\n')
335 topic_name =
'/%s/calibration/device_info' % namespace
337 for topic, msg, t
in bag.read_messages(topics=[topic_name]):
341 sn = msg.serialNumber.strip()
342 exclude_characters = string.letters + string.punctuation +
" " 343 sn = sn.strip(exclude_characters)
348 sn =
"SN%04d" % int(sn)
352 info = open(os.path.join(directory,
"dev_info.txt"),
'wb')
358 bag = os.path.basename(self.
bag_file)
359 path = os.path.dirname(self.
bag_file)
361 fname = os.path.join(path, os.path.splitext(bag)[0]\
362 +
"_SL_%s_calCheck.bag" % sn)
384 average /= valid_elements
393 max_error = 3 * average_error
395 eight_bit_error = np.zeros(len(self.
errorImage), dtype=np.uint8)
402 eight_bit_error[i] = min((item - min_error) / (max_error - min_error) * 255, 255)
406 self.
write_pgm(eight_bit_error, os.path.join(directory,
"errorImage.pgm"),
424 if laser_scan ==
None:
431 for i
in range(disparity_scan.shape[1]):
435 u = round(disparity_scan[0,i]/disparity_scan[3,i])
436 v = round(disparity_scan[1,i]/disparity_scan[3,i])
437 d = disparity_scan[2,i]/disparity_scan[3,i]
458 if actual_disparity == 0:
466 self.
errorImage[index] = abs(d - actual_disparity)
483 start_mirror = -135.0 * np.pi /180.
484 end_mirror = 135.0 * np.pi/180.
489 for i, d
in enumerate(laser_msg.distance):
491 percentage = i / float(len(laser_msg.distance))
493 mirror_angle = start_mirror + percentage * (end_mirror - start_mirror)
499 point = np.matrix([[ distance * np.sin(mirror_angle)],
501 [ distance * np.cos(mirror_angle)],
507 spindle_angle = angle_start + percentage * angle_range
510 spindle_transform = np.matrix([[np.cos(spindle_angle), -np.sin(spindle_angle), 0., 0.],
511 [np.sin(spindle_angle), np.cos(spindle_angle), 0., 0.],
520 if transformed_point[2, 0] < 0.4:
525 if laserPoints ==
None:
526 laserPoints = transformed_point
528 laserPoints = np.append(laserPoints, transformed_point, axis=1)
539 positive_angle = ((angle % (2 * np.pi)) + (2 * np.pi)) % (2 * np.pi)
542 if positive_angle > (2 * np.pi):
543 return positive_angle - (2 * np.pi)
546 return positive_angle;
552 print "\nUsage: %s -b <bagfile> [Options]" % argv
553 print "Where [Options] are" 554 print " -o <output_directory>\t Specifies theoutput directory to save"\
555 +
" the output debug files. Default: ." 556 print " -n <namespace>\t\t The namespace the Multisense topics are in. "\
557 +
"Default: multisense" 558 print " -r\t\t\t\t Rename the input bag file to send to CRL" 559 print " -h\t\t\t\t Print the usage" 562 if __name__ ==
'__main__':
565 output_directory_name = time.strftime(
'%Y-%m-%d_%H-%M-%S_process_bags')
566 namespace =
'multisense' 570 opts, args = getopt.getopt(sys.argv[1:],
"b:o:n:rh")
571 except getopt.GetoptError
as err:
582 bag_file_name = str(a)
584 output_directory_name = str(a)
591 if None == bag_file_name:
592 print "Error no bag file specified" 598 if not os.path.exists(output_directory_name):
599 os.makedirs(output_directory_name)
602 if not os.path.isdir(output_directory_name):
603 raise IOError(
'%s is not a directory' % output_directory_name)
608 bagProcessor.process(output_directory_name, rename_file, namespace)
def write_pgm(self, data, name, width, height, bits)
def process_laser_yaml(self, directory=".", namespace='multisense')
def transform_laser_scan(self, laser_msg)
def write_laser_yaml(self, name, laser_t_spind, cam_t_spind)
def process_camera_yaml(self, directory='.', namespace='multisense')
def compute_average_error(self)
def __init__(self, bag_file)
def process_image(self, directory='.', namespace='multisense')
def rename_bag(self, directory=".", namespace='multisense')
def normalize_angle(self, angle)
def write_camera_yaml(self, name, p1, p2)
def process_laser(self, directory='.', namespace='multisense')
def compute_laser_error(self, laser_msg)
def compute_error_image(self, average_error, directory='.')
def process(self, directory='.', rename_file=True, namespace='multisense')