LiDARとカメラシーケンス
kognic-io 2.5.0以降、シーンタイプ(LidarsAndCamerasSequence)を公開せず、単一のモデルからあらゆるシーンを簡単に作成できる新しいシーンモデルを推奨しています。
LidarsAndCamerasSequenceは、カメラ画像とLiDAR点群のシーケンスで構成され、各フレームには1〜20枚のカメラ画像と1〜20個の点群が含まれます。LidarsAndCamerasSequenceオブジェクトの各フィールドの詳細については、シーンの概要概要の関連セクションをご覧ください。
from __future__ import absolute_import
from datetime import datetime
from typing import Optional
from uuid import uuid4
import kognic.io.model.scene.lidars_and_cameras_sequence as LCSM
from examples.calibration.calibration import create_sensor_calibration
from kognic.io.client import KognicIOClient
from kognic.io.logger import setup_logging
from kognic.io.model import CreateSceneResponse, Image, PointCloud
def run(client: KognicIOClient, dryrun: bool = True, **kwargs) -> Optional[CreateSceneResponse]:
print("Creating Lidar and Camera Sequence Scene...")
lidar_sensor1 = "lidar"
cam_sensor1 = "RFC01"
cam_sensor2 = "RFC02"
metadata = {"location-lat": 27.986065, "location-long": 86.922623, "vehicle_id": "abg"}
# Create calibration
# (Please refer to the API documentation about calibration for more details)
calibration_spec = create_sensor_calibration(
f"Collection {datetime.now()}",
[lidar_sensor1],
[cam_sensor1, cam_sensor2],
)
created_calibration = client.calibration.create_calibration(calibration_spec)
scene = LCSM.LidarsAndCamerasSequence(
external_id=f"LCS-example-{uuid4()}",
frames=[
LCSM.Frame(
frame_id="1",
relative_timestamp=0,
point_clouds=[
PointCloud(
filename="./examples/resources/point_cloud_RFL01.las",
sensor_name=lidar_sensor1,
),
],
images=[
Image(
filename="./examples/resources/img_RFC01.jpg",
sensor_name=cam_sensor1,
),
Image(
filename="./examples/resources/img_RFC02.jpg",
sensor_name=cam_sensor2,
),
],
metadata={"dut_status": "active"},
),
LCSM.Frame(
frame_id="2",
relative_timestamp=100,
point_clouds=[
PointCloud(
filename="./examples/resources/point_cloud_RFL02.las",
sensor_name=lidar_sensor1,
),
],
images=[
Image(
filename="./examples/resources/img_RFC11.jpg",
sensor_name=cam_sensor1,
),
Image(
filename="./examples/resources/img_RFC12.jpg",
sensor_name=cam_sensor2,
),
],
metadata={"dut_status": "active"},
),
],
calibration_id=created_calibration.id,
metadata=metadata,
)
# Create scene
return client.lidars_and_cameras_sequence.create(scene, dryrun=dryrun, **kwargs)
if __name__ == "__main__":
setup_logging(level="INFO")
client = KognicIOClient()
# Project - Available via `client.project.get_projects()`
project = "<project-identifier>"
run(client, project)dryrunを使用してシーンを検証する
メソッド呼び出しでdryrunパラメータをtrueに設定すると、APIを使用してシーンが検証されますが、実際には作成されません。
キャリブレーションの再利用
可能であれば、同じキャリブレーションを複数のシーンで再利用でき、また再利用すべきです。
自車両モーション情報を提供する
自車両モーション(すなわち、自車両の位置と回転)は、LidarsAndCamerasSeqを作成する際に提供できるオプション情報です。この情報により、静的オブジェクトのアノテーションにかかる時間を大幅に短縮できます。自車両モーション情報は、シーン内の各FrameにEgoVehicleMotionオブジェクトを渡すことで提供します。
from __future__ import absolute_import
from datetime import datetime
from typing import Optional
from uuid import uuid4
import kognic.io.model.scene.lidars_and_cameras_sequence as LCSM
from examples.calibration.calibration import create_sensor_calibration
from kognic.io.client import KognicIOClient
from kognic.io.logger import setup_logging
from kognic.io.model import CreateSceneResponse, EgoVehiclePose, Image, PointCloud, Position, RotationQuaternion
def run(client: KognicIOClient, dryrun: bool = True, **kwargs) -> Optional[CreateSceneResponse]:
print("Creating Lidar and Camera Sequence Scene...")
lidar_sensor1 = "lidar"
cam_sensor1 = "RFC01"
cam_sensor2 = "RFC02"
cam_sensor3 = "RFC03"
metadata = {"location-lat": 27.986065, "location-long": 86.922623, "vehicle_id": "abg"}
# Create calibration
calibration_spec = create_sensor_calibration(f"Collection {datetime.now()}", [lidar_sensor1], [cam_sensor1, cam_sensor2, cam_sensor3])
created_calibration = client.calibration.create_calibration(calibration_spec)
scene = LCSM.LidarsAndCamerasSequence(
external_id=f"LCS-full-example-{uuid4()}",
frames=[
LCSM.Frame(
frame_id="1",
relative_timestamp=0,
point_clouds=[
PointCloud(filename="./examples/resources/point_cloud_RFL01.las", sensor_name=lidar_sensor1),
],
images=[
Image(filename="./examples/resources/img_RFC01.jpg", sensor_name=cam_sensor1),
Image(filename="./examples/resources/img_RFC02.jpg", sensor_name=cam_sensor2),
],
metadata={"dut_status": "active"},
ego_vehicle_pose=EgoVehiclePose(
position=Position(x=1.0, y=1.0, z=1.0), rotation=RotationQuaternion(w=0.01, x=1.01, y=1.01, z=1.01)
),
),
LCSM.Frame(
frame_id="2",
relative_timestamp=500,
point_clouds=[
PointCloud(filename="./examples/resources/point_cloud_RFL02.las", sensor_name=lidar_sensor1),
],
images=[
Image(filename="./examples/resources/img_RFC11.jpg", sensor_name=cam_sensor1),
Image(filename="./examples/resources/img_RFC12.jpg", sensor_name=cam_sensor2),
],
ego_vehicle_pose=EgoVehiclePose(
position=Position(x=2.0, y=2.0, z=2.0), rotation=RotationQuaternion(w=0.01, x=2.01, y=2.01, z=2.01)
),
),
],
calibration_id=created_calibration.id,
metadata=metadata,
)
# Create scene
return client.lidars_and_cameras_sequence.create(scene, dryrun=dryrun, **kwargs)
if __name__ == "__main__":
setup_logging(level="INFO")
client = KognicIOClient()
# Project - Available via `client.project.get_projects()`
project = "<project-identifier>"
run(client, project=project)座標系
自車両ポーズのpositionとrotationは、いずれもローカル座標系を基準とすることにご注意ください。
シャッタータイミング
シャッタータイミングは、Frame内のImageに指定できます。
シャッタータイミングは、ナノ秒単位のUnixタイムスタンプ値のペア(シャッター開始時刻と終了時刻)で、両方を指定する必要があります。各フレームの各画像に対して指定します。
from __future__ import absolute_import
import os.path
from datetime import datetime
from typing import Optional
from uuid import uuid4
import kognic.io.model.scene.lidars_and_cameras_sequence as LCSM
from examples.calibration.calibration import create_sensor_calibration
from examples.imu_data.create_imu_data import create_dummy_imu_data
from kognic.io.client import KognicIOClient
from kognic.io.logger import setup_logging
from kognic.io.model import CreateSceneResponse, Image, ImageMetadata, PointCloud
def run(client: KognicIOClient, dryrun: bool = True, **kwargs) -> Optional[CreateSceneResponse]:
print("Creating Lidar and Camera Sequence Scene...")
lidar_sensor1 = "RFL01"
lidar_sensor2 = "RFL02"
cam_sensor1 = "RFC01"
cam_sensor2 = "RFC02"
metadata = {"location-lat": 27.986065, "location-long": 86.922623, "vehicleId": "abg"}
examples_path = os.path.dirname(__file__)
# Create calibration
calibration_spec = create_sensor_calibration(f"Collection {datetime.now()}", [lidar_sensor1, lidar_sensor2], [cam_sensor1, cam_sensor2])
created_calibration = client.calibration.create_calibration(calibration_spec)
# Generate IMU data
ONE_MILLISECOND = 1000000 # one millisecond, expressed in nanos
start_ts = 1648200140000000000
end_ts = start_ts + 10 * ONE_MILLISECOND
imu_data = create_dummy_imu_data(start_timestamp=start_ts, end_timestamp=end_ts, samples_per_sec=1000)
scene = LCSM.LidarsAndCamerasSequence(
external_id=f"LCS-full-with-imu-and-shutter-example-{uuid4()}",
frames=[
LCSM.Frame(
frame_id="1",
unix_timestamp=start_ts + ONE_MILLISECOND,
relative_timestamp=0,
point_clouds=[
PointCloud(filename=examples_path + "/resources/point_cloud_RFL01.csv", sensor_name=lidar_sensor1),
PointCloud(filename=examples_path + "/resources/point_cloud_RFL02.csv", sensor_name=lidar_sensor2),
],
images=[
Image(
filename=examples_path + "/resources/img_RFC01.jpg",
sensor_name=cam_sensor1,
metadata=ImageMetadata(
shutter_time_start_ns=start_ts + 0.5 * ONE_MILLISECOND, shutter_time_end_ns=start_ts + 1.5 * ONE_MILLISECOND
),
),
Image(
filename=examples_path + "/resources/img_RFC02.jpg",
sensor_name=cam_sensor2,
metadata=ImageMetadata(
shutter_time_start_ns=start_ts + 0.5 * ONE_MILLISECOND, shutter_time_end_ns=start_ts + 1.5 * ONE_MILLISECOND
),
),
],
),
LCSM.Frame(
frame_id="2",
unix_timestamp=start_ts + 5 * ONE_MILLISECOND,
relative_timestamp=4,
point_clouds=[
PointCloud(filename=examples_path + "/resources/point_cloud_RFL11.csv", sensor_name=lidar_sensor1),
PointCloud(filename=examples_path + "/resources/point_cloud_RFL12.csv", sensor_name=lidar_sensor2),
],
images=[
Image(
filename=examples_path + "/resources/img_RFC11.jpg",
sensor_name=cam_sensor1,
metadata=ImageMetadata(
shutter_time_start_ns=start_ts + 4.5 * ONE_MILLISECOND, shutter_time_end_ns=start_ts + 5.5 * ONE_MILLISECOND
),
),
Image(
filename=examples_path + "/resources/img_RFC12.jpg",
sensor_name=cam_sensor2,
metadata=ImageMetadata(
shutter_time_start_ns=start_ts + 4.5 * ONE_MILLISECOND, shutter_time_end_ns=start_ts + 5.5 * ONE_MILLISECOND
),
),
],
),
],
calibration_id=created_calibration.id,
metadata=metadata,
imu_data=imu_data,
)
# Create scene
return client.lidars_and_cameras_sequence.create(scene, dryrun=dryrun, **kwargs)
if __name__ == "__main__":
setup_logging(level="INFO")
client = KognicIOClient()
# Project - Available via `client.project.get_projects()`
project = "<project-id>"
run(client, project=project)リバースローリングシャッター
Kognic IO 2.17.0以降で利用できます。
シャッタータイミングが設定されている場合、カメラのローリングシャッターが下から上に走査されるケースでは、Imagesのreversed_shutterフラグをTrueに設定できます。例えば、カメラが上下逆に取り付けられている場合、回転後の画像の最上行のピクセルは最下行のピクセルよりも後に撮像されます。アノテーションツールで最高品質の投影を得るには、アノテーションツールがこの違いを把握していることが重要です。
ImageMetadata(
shutter_time_start_ns=1775128684200000000,
shutter_time_end_ns=1775128685000000000,
reversed_shutter=True
)