diff --git a/docs/imu_intrinsics.md b/docs/imu_intrinsics.md index 13ac23a..0ca6f49 100644 --- a/docs/imu_intrinsics.md +++ b/docs/imu_intrinsics.md @@ -1,15 +1,15 @@ # Example: Estimating IMU Intrinsics -For this example I am using a dataset recorded with the GoPro9. Please read the paper [11] on how to record the dataset and details on how the method works. +For this example I am using a dataset recorded with the GoPro9. Please read the paper [[11]](https://www.researchgate.net/publication/273383944_A_robust_and_easy_to_implement_method_for_IMU_calibration_without_external_equipments) on how to record the dataset and details on how the method works. Remember to let the camera stand still for >= 10-15 seconds in the beginning. The IMU bias will be estimated in this phase. This is also a parameter you need to supply to the calibration script. -You can get a sample dataset from: [link](https://drive.google.com/file/d/1XjtUX-4ZI0Ydkd2O3BWnaUzfmzm96He4/view?usp=share_link). +You can get a sample dataset from: [link](https://drive.google.com/file/d/1XjtUX-4ZI0Ydkd2O3BWnaUzfmzm96He4/view?usp=share_link). The folder **static_imu_calib** contains an example file. You can run the static imu calibration with. Remember to supply your build and source path of OpenICC to the script: ``` python -python python/static_multipose_imu_calibration.py --path_static_calib_dataset=/path/to/example_dataset/dataset3/static_multi_pose --initial_static_duration_s=10 --path_to_build=/your_path_to_openicc_build/applications --path_to_src=/your_path_to_openicc_src +python python/static_multipose_imu_calibration.py --path_static_calib_dataset=/path/to/example_dataset/dataset3/static_multi_pose --initial_static_duration_s=10 --path_to_build=/your_path_to_openicc_build/applications --path_to_src=/your_path_to_openicc_src ``` -If successfull this script will output a json file **static_calib_result.json** containing IMU intrinsics for your camera. +If successfull this script will output a json file **static_calib_result.json** containing IMU intrinsics for your camera. **You can supply this json file later to VI calibration using the --path_to_imu_intrinsics flag.** diff --git a/python/static_multipose_imu_calibration.py b/python/static_multipose_imu_calibration.py index e65c119..17cba41 100644 --- a/python/static_multipose_imu_calibration.py +++ b/python/static_multipose_imu_calibration.py @@ -1,90 +1,87 @@ import os -import json from argparse import ArgumentParser from subprocess import Popen from os.path import join as pjoin import glob import time -from utils import get_abbr_from_cam_model from telemetry_converter import TelemetryConverter +from py_gpmf_parser.gopro_telemetry_extractor import GoProTelemetryExtractor def main(): parser = ArgumentParser("OpenCameraCalibrator - GoPro Calibrator") - # Cast the input to string, int or float type - parser.add_argument('--path_static_calib_dataset', - default='/media/Data/work_projects/ImageStabelization/GoPro10Calibration/ImuIntrinsics/dataset1', + # Cast the input to string, int or float type + parser.add_argument('--path_static_calib_dataset', + default='/media/Data/work_projects/ImageStabelization/GoPro10Calibration/ImuIntrinsics/dataset1', help="Path to calibration dataset") - parser.add_argument('--path_to_build', + parser.add_argument('--path_to_build', help="Path to OpenCameraCalibrator build folder.", - default='/media/Data/builds/openicc_release/applications') - parser.add_argument("--gravity_const", help="gravity constant", + default='/media/Data/builds/openicc_release/applications') + parser.add_argument("--gravity_const", help="gravity constant", default=9.811104, type=float) - parser.add_argument("--initial_static_duration_s", - help="duration of the initial static phase for bias estimation", + parser.add_argument("--initial_static_duration_s", + help="duration of the initial static phase for bias estimation", default=15, type=float) - parser.add_argument("--verbose", help="If calibration steps should output more information.", + parser.add_argument("--verbose", help="If calibration steps should output more information.", default=0, type=int) args = parser.parse_args() - path_to_file = os.path.dirname(os.path.abspath(__file__)) - path_to_src = os.path.join(path_to_file,"../") - # # - # # 0. Check inputs + # # + # # 0. Check inputs # # bin_path = pjoin(args.path_to_build) cam_calib_path = args.path_static_calib_dataset - cam_calib_video = glob.glob(pjoin(cam_calib_path,"*.MP4")) + cam_calib_video = glob.glob(pjoin(cam_calib_path,"*.MP4"))[0] if len(cam_calib_video) == 0: print("Error! Could not find cam calibration video file with MP4 ending in path "+cam_calib_path) exit(-1) print(cam_calib_video) - # globals - cam_video_fn = os.path.basename(cam_calib_video[0])[:-4] - gopro_telemetry = glob.glob(pjoin(cam_calib_path,"G*.MP4"))[0][:-4]+".json" - gopro_telemetry_gen = glob.glob(pjoin(cam_calib_path,"G*.MP4"))[0][:-4]+"_gen.json" + # json telemetry globals + gopro_py_gmpf_telemetry = glob.glob(pjoin(cam_calib_video))[0][:-4]+"_pygpmf.json" + gopro_conv_telemetry = glob.glob(pjoin(cam_calib_video))[0][:-4]+".json" # # 1. Extracting GoPro telemetry - # - js_extract_file = pjoin(path_to_src,"javascript","extract_metadata.js") + # print("==================================================================") - print("Extracting GoPro telemetry.") + print("Extracting GoPro telemetry for imu bias and camera imu calibration.") print("==================================================================") start = time.time() - telemetry_extract = Popen(["node",js_extract_file, - cam_calib_path, - cam_video_fn+".MP4", - cam_calib_path]) - error = telemetry_extract.wait() + extractor = GoProTelemetryExtractor(os.path.join(cam_calib_video)) + extractor.open_source() + extractor.extract_data_to_json(os.path.join(cam_calib_path, gopro_py_gmpf_telemetry), + ["ACCL", "GYRO", "GPS5", "GPSP", "GPSU", "GPSF", "GRAV", "MAGN", "CORI", "IORI"]) + extractor.close_source() + print("==================================================================") print("Telemetry extraction took {:.2f}s.".format(time.time()-start)) print("==================================================================") - + + # # 2. Convert gopro json telemetry to common format # telemetry_conv = TelemetryConverter() - telemetry_conv.convert_gopro_telemetry_file(gopro_telemetry, gopro_telemetry_gen) + telemetry_conv.convert_pygpmf_telemetry(gopro_py_gmpf_telemetry, gopro_conv_telemetry) # # 3. Perform static multi pose calibration - # + # print("==================================================================") print("Performing static multi pose IMU calibration.") print("==================================================================") start = time.time() spline_init = Popen([pjoin(bin_path,"static_imu_calibration"), - "--telemetry_json="+gopro_telemetry_gen, + "--telemetry_json="+gopro_conv_telemetry, "--gravity_magnitude="+str(args.gravity_const), "--initial_static_interval_s="+str(args.initial_static_duration_s), - "--verbose="+str(args.verbose), + "--verbose="+str(args.verbose), "--output_calibration_path="+pjoin(args.path_static_calib_dataset,"static_calib_result.json"), "--logtostderr=1"]) - error_spline_init = spline_init.wait() + error_spline_init = spline_init.wait() print("==================================================================") print("Static multi pose IMU calibration took {:.2f}s.".format(time.time()-start)) print("==================================================================")