/argoverse/data_loading/simple_track_dataloader.py

https://github.com/argoai/argoverse-api
Python | 150 lines | 65 code | 15 blank | 70 comment | 4 complexity | f34345465b316c511e4f6c7a7833b184 MD5 | raw file
  1. # <Copyright 2019, Argo AI, LLC. Released under the MIT license.>
  2. import glob
  3. import sys
  4. from pathlib import Path
  5. from typing import Any, List, Mapping, Optional, Sequence
  6. import numpy as np
  7. from argoverse.data_loading.synchronization_database import SynchronizationDB
  8. from argoverse.utils.json_utils import read_json_file
  9. from argoverse.utils.se3 import SE3
  10. from argoverse.utils.transform import quat2rotmat
  11. class SimpleArgoverseTrackingDataLoader:
  12. """
  13. Simple abstraction for retrieving log data, given a path to the dataset.
  14. """
  15. def __init__(self, data_dir: str, labels_dir: str) -> None:
  16. """
  17. Args:
  18. data_dir: str, representing path to raw Argoverse data
  19. labels_dir: strrepresenting path to Argoverse data labels
  20. """
  21. self.data_dir = data_dir
  22. self.labels_dir = labels_dir
  23. self.sdb = SynchronizationDB(data_dir)
  24. def get_city_name(self, log_id: str) -> str:
  25. """
  26. Args:
  27. log_id: str
  28. Returns:
  29. city_name: str
  30. """
  31. city_info_fpath = f"{self.data_dir}/{log_id}/city_info.json"
  32. city_info = read_json_file(city_info_fpath)
  33. city_name = city_info["city_name"]
  34. assert isinstance(city_name, str)
  35. return city_name
  36. def get_log_calibration_data(self, log_id: str) -> Mapping[str, Any]:
  37. """
  38. Args:
  39. log_id: str
  40. Returns:
  41. log_calib_data: dictionary
  42. """
  43. calib_fpath = f"{self.data_dir}/{log_id}/vehicle_calibration_info.json"
  44. log_calib_data = read_json_file(calib_fpath)
  45. assert isinstance(log_calib_data, dict)
  46. return log_calib_data
  47. def get_city_to_egovehicle_se3(self, log_id: str, timestamp: int) -> Optional[SE3]:
  48. """
  49. Args:
  50. log_id: str, unique ID of vehicle log
  51. timestamp: int, timestamp of sensor observation, in nanoseconds
  52. Returns:
  53. city_to_egovehicle_se3: SE3 transformation to bring egovehicle frame point into city frame.
  54. """
  55. pose_fpath = f"{self.data_dir}/{log_id}/poses/city_SE3_egovehicle_{timestamp}.json"
  56. if not Path(pose_fpath).exists():
  57. return None
  58. pose_data = read_json_file(pose_fpath)
  59. rotation = np.array(pose_data["rotation"])
  60. translation = np.array(pose_data["translation"])
  61. city_to_egovehicle_se3 = SE3(rotation=quat2rotmat(rotation), translation=translation)
  62. return city_to_egovehicle_se3
  63. def get_closest_im_fpath(self, log_id: str, camera_name: str, lidar_timestamp: int) -> Optional[str]:
  64. """
  65. Args:
  66. log_id: str, unique ID of vehicle log
  67. camera_name: str
  68. lidar_timestamp: int, timestamp of LiDAR sweep capture, in nanoseconds
  69. Returns:
  70. im_fpath, string representing path to image, or else None.
  71. """
  72. cam_timestamp = self.sdb.get_closest_cam_channel_timestamp(lidar_timestamp, camera_name, log_id)
  73. if cam_timestamp is None:
  74. return None
  75. im_dir = f"{self.data_dir}/{log_id}/{camera_name}"
  76. im_fname = f"{camera_name}_{cam_timestamp}.jpg"
  77. im_fpath = f"{im_dir}/{im_fname}"
  78. return im_fpath
  79. def get_closest_lidar_fpath(self, log_id: str, cam_timestamp: int) -> Optional[str]:
  80. """
  81. Args:
  82. log_id: str, unique ID of vehicle log
  83. cam_timestamp: int, timestamp of image capture, in nanoseconds
  84. Returns:
  85. ply_fpath: str, string representing path to PLY file, or else None.
  86. """
  87. lidar_timestamp = self.sdb.get_closest_lidar_timestamp(cam_timestamp, log_id)
  88. if lidar_timestamp is None:
  89. return None
  90. lidar_dir = f"{self.data_dir}/{log_id}/lidar"
  91. ply_fname = f"PC_{lidar_timestamp}.ply"
  92. ply_fpath = f"{lidar_dir}/{ply_fname}"
  93. return ply_fpath
  94. def get_ordered_log_ply_fpaths(self, log_id: str) -> List[str]:
  95. """
  96. Args:
  97. log_id: str, unique ID of vehicle log
  98. Returns:
  99. ply_fpaths: List of strings, representing paths to ply files in this log
  100. """
  101. ply_fpaths = sorted(glob.glob(f"{self.data_dir}/{log_id}/lidar/PC_*.ply"))
  102. return ply_fpaths
  103. def get_ordered_log_cam_fpaths(self, log_id: str, camera_name: str) -> List[str]:
  104. """
  105. Args
  106. log_id: str, unique ID of vehicle log
  107. Returns
  108. cam_img_fpaths: List of strings, representing paths to JPEG files in this log,
  109. for a specific camera
  110. """
  111. cam_img_fpaths = sorted(glob.glob(f"{self.data_dir}/{log_id}/{camera_name}/{camera_name}_*.jpg"))
  112. return cam_img_fpaths
  113. def get_labels_at_lidar_timestamp(self, log_id: str, lidar_timestamp: int) -> Optional[List[Mapping[str, Any]]]:
  114. """
  115. Args:
  116. log_id: str, unique ID of vehicle log
  117. lidar_timestamp: int, timestamp of LiDAR sweep capture, in nanoseconds
  118. Returns:
  119. labels: dictionary
  120. """
  121. timestamp_track_label_fpath = (
  122. f"{self.labels_dir}/{log_id}/per_sweep_annotations_amodal/tracked_object_labels_{lidar_timestamp}.json"
  123. )
  124. if not Path(timestamp_track_label_fpath).exists():
  125. return None
  126. labels = read_json_file(timestamp_track_label_fpath)
  127. assert isinstance(labels, list), labels
  128. return labels