プレアノテーション
プレアノテーションはグランドトゥルース作成において多くの用途があります。プレアノテーション機能を使用すると、インプット内にすでに存在することがわかっているオブジェクトに関する情報を指定できます。お客様のユースケースに最適な活用方法については、アドバイザリーサービスチームまでお問い合わせください。
KognicプラットフォームはOpenLabelフォーマットのプレアノテーションのアップロードをkognic-openlabelパッケージを使用してサポートしています。
kognic-ioクライアントを使用したプレアノテーションの作成
Kognicプラットフォームでプレアノテーションをするためのステップは3つあります
- 必要なデータをすべてアップロードしてシーンを作成する
- 1つ以上のOpenLabelアノテーションをシーンに対するプレアノテーションとしてアップロードする
- プレアノテーションを使用してシーンからインプットを作成する
これらのステップはcreate_inputs関数を使用して1回の呼び出しで複数回実行できることに注意してください。1回の呼び出しで複数のインプットを作成するを参照してください。
1. シーンの作成
まずシーンを作成します。
# Create Scene but not input since we don't provide project or batch
scene_response = client.lidars_and_cameras_sequence.create(
lidars_and_cameras_seq,
dryrun=dryrun
)次のステップに進む前にシーンの作成完了を待機する必要があることに注意してください。詳細についてはシーン作成の完了を待機するを参照してください。
2. OpenLabelアノテーションのアップロード
シーンが正常に作成されたら、プレアノテーションをKognicプラットフォームにアップロードできます。
kognic-openlabelのドキュメントに従ってOpenLabelアノテーションをロードし、以下のようにKognicプラットフォームにアップロードします。
pre_annotation_response = client.pre_annotation.create(
scene_uuid=scene_response.scene_uuid, # from step 1
external_id="20250811145051", # optional
pre_annotation=OpenLabelAnnotation(...),
dryrun=dryrun
)3. インプットの作成
シーンとプレアノテーションが正常に作成されたら、インプットを作成できます。Kognic IO 2.9.0以降、これを行う方法が2つあります。
3.1. 最新のプレアノテーションを使用して最新のプロジェクトバッチにインプットを作成する
最新の利用可能なプレアノテーションを使用してシーンからインプットを作成します。プロジェクトの最新のオープンバッチ、または指定されたバッチにインプットを追加し、アノテーション可能な状態にします。
client.lidars_and_cameras_sequence.create_from_scene(
scene_uuid=scene_response.scene_uuid, # from step 1
project=project, # Important: this is the external id and not the title
dryrun=dryrun
)3.2. 特定のプレアノテーションを使用して指定されたプロジェクト/バッチにインプットを作成する
Kognic IO 2.9.0以降で利用可能です
これにより、1つのシーンから異なるプレアノテーション(またはプレアノテーションなし)を使用して複数のインプットを作成し、異なるプロジェクト/バッチに配置することができます。
特定のプレアノテーションまたはプレアノテーションなしでシーンからインプットを作成します。プロジェクトの最新のオ ープンバッチ、または指定されたバッチにインプットを追加し、アノテーション可能な状態にします。
# scene is explicit, pre-annotation is optional
client.input.create_from_scene(scene_uuid, project) # no preannotation
client.input.create_from_scene(scene_uuid, project, batch) # no preannotation
client.input.create_from_scene(scene_uuid, pre_anno_uuid, project)
client.input.create_from_scene(scene_uuid, pre_anno_uuid, project, batch)
# pre-annotation is explicit, scene is implied
client.input.create_from_pre_annotation(pre_anno_uuid, project)
client.input.create_from_pre_annotation(pre_anno_uuid, project, batch)
# Examples
client.input.create_from_scene(
scene_uuid=scene_response.scene_uuid, # mandatory, from step 1
pre_annotation_uuid=pre_annotation_response.uuid # optional, from step 2
project=project, # Important: this is the external id and not the title
dryrun=dryrun
)
client.input.create_from_pre_annotation(
pre_annotation_uuid=pre_annotation_response.uuid # mandatory, from step 2
project=project, # Important: this is the external id and not the title
dryrun=dryrun
)OpenLabelサポート
プレアノテーションはOpenLabelフォーマット/スキーマを使用しますが、すべてのOpenLabel機能がプレアノテーションでサポートされているわけではありません。
サポートされていないプレアノテーション機能
以下の機能または機能の組み合わせは現在サポートされていないか、部分的なサポートのみです。
- 静的ジオメトリ:未サポート
- objects.*.objectData下のOpenLabelで宣言されたバウンディングボックス、キュービoidなどが該当します。
- ジオメトリ固有の属性:3Dジオメトリでは未サポート
- これらはOpenLabelの単一のジオメトリシェイプで宣言された属性です。つまり、1つのセンサーから見たオブジェクトにのみ適用される属性です。一般的な例として、各カメラで個別に記録れるocclusionがあります。
- ソース固有、ストリーム固有、またはセンサー固有の属性とも呼ばれます。
- 3Dジオメトリとは、点群をアノテーションする際に描画できるもの(例:キュービoid)を指します。
- ジオメトリ固有の属性は2Dジオメトリ(例:バウンディングボックス)では使用できます。
- タスク定義では、このように使用する前にプロパティをソース固有として指定する必要があることに注意してください。
- stream属性は特殊なケースであり、このルールから除外されます。
サポートされているプレアノテーション機能
ジオメトリ
オブジェクトは同一フレーム内に複数の3Dジオメトリを持つことはできません。
名称 | OpenLABELフィールド | 説明 | 属性 |
|---|---|---|---|
キュービオイド | cuboid | 3Dキュービオイド | - |
バウンディングボックス | bbox | 2Dバウンディングボックス | - |
3Dライン | poly3d | 3Dのライン。閉じたラインにする場合は最初の点を末尾に追加する。 | - |
ポリゴン | poly2d | 2Dのポリゴン | is_hole |
マルチポリゴン | poly2d | 2Dのマルチポリゴン | is_hole & polygon_id |
カーブ | poly2d | 2Dのカーブまたはライン | interpolation_method |
2D点 | point2d | OpenLABEL形式 | - |
2D点群 | point2d | 点群 | point_class |
3Dセマンティックセグメンテーション | binary | | |
3Dインスタンスセグメンテーション | binary | | |
3D点 | point3d | | |
3Dレーン | poly3d | 3Dレーンpoly3d各レーンエッジに1つずつ、計2つのpoly3dを提供することで構築されます。lane_edge属性を使用してレーンエッジを指定し、一方にright、もう一方にleftの値を設定します。このジオメトリは、オブジェクトが同一フレーム内に複数の3Dジオメトリを持てないというルールの例外です。 lane_edge | lane_edge |
すべてのジオメトリはプレアノテーションのルートではなく、フレーム下に指定する必要があることに注意してください。3Dジオメトリは、単一ライダーの場合はライダー座標系で、複数ライダーの場合は参照座標系で表現する必要があります。キュービオイドの回転は==!エクスポート!==と同じである必要があります。2Dジオメトリはピクセル座標で表現する必要があります。詳細については座標系を参照してください。
属性
- テキスト
- 数値
- ブール値
2Dジオメトリの場合、属性はジオメトリ固有(ソース/センサー固有とも呼ばれる)またはオブジェクト固有として指定できます。属性は静的(objectsキーで指定)または動的(フレーム内のオブジェクトのobject_dataで指定)にすることができ、タスク定義(存在する場合)によって許可されている必要があります。ジオメトリ固有 の属性(フレーム内の単一シェイプに現れるもの)もタスク定義でそのように宣言する必要があります。任意のプロパティをソース固有の方法で使用することはできません。
コンテキスト
コンテキストはKognicプラットフォームでシーンのプロパティを定義するために使用されます。各コンテキストには1つのプロパティ値が含まれます。
コンテキストには4つのモードがあります。
- 静的グローバル — シーンのすべてのフレームとセンサーに対して有効な値
- 動的グローバル — すべてのセンサーに対して有効だが、フレームをまたいで変化する可能性がある値
- 静的ソース固有 — すべてのフレームに対して有効だが、1つの特定のストリームにのみ適用される値
- 静的ソース固有 — すべてのフレームに対して有効だが、1つの特定のストリームにのみ適用される値
以下の2種類のコンテキストオブジェクトを参照します。
- コンテキストオブジェクト(または単にコンテキスト) — ルートキーcontexts下に定義される
- フレームコンテキストオブジェクト(または単にフレームコンテキスト) — フレーム内に定義される
OpenLabelで使用されるすべてのコンテキストは、OpenLabelのルートにあるcontextキー下に定義する必要があります。Kognicでは、コンテキストのキーはOpenLabelの他の場所(例:フレーム内)でコンテキストを参照する際にのみ使用され、インクリメントする数字の文字列に設定されます。コンテキストタイプはKognicアプリのプロパティ名に対応し、プロパティの値はコンテキストの属性に設定されます。ソース固有のプロパティが複数のセンサーに存在する必要がある場合(例:各カメラセンサーに「車が見える」というブール値のプロパティがある場合)、同じコンテキストタイプを持つセンサーごとに1つのコンテキストオブジェクトが作成されます。コンテキストでは以下の属性タイプをサポートしています。
- テキスト
- 数値
- ブール値
- ベクター — 文字列のみ
コンテキストモード | コンテキストにストリーム属性がある | コンテキストに非ストリーム属性がある | フレームコンテキストに属性がある | コンテキストに非ストリーム属性が2つ以上ある | フレームコンテキストに属性が2つ以上ある |
|---|---|---|---|---|---|
静的グローバル | ❌ | ✅ | ❌ | ❌ | ❌ |
動的グローバル | ❌ | ❌ | ✅ | ❌ | ❌ |
静的ソース固有 | ✅ | ✅ | ❌ | ❌ | ❌ |
動的ソース固有 | ✅ | ❌ | ✅ | ❌ | ❌ |
コンテキストを含むOpenLabelセクションの例を参照してください。
フレーム
すべてのプレアノテーションには、シーンで指定されたタイムスタンプの中から一意のタイムスタンプを持つフレームが含まれている必要があります。これは、タイムスタンプがプレアノテーション内のフレームをシーン内の正しいフレームにマッピングするために使用されるためです。静的な場合は、タイムスタンプ0の1つのフレームを使用する必要があります。
リレーション
OpenLabelフォーマットのドキュメントに従ってサポートされています。ソース固有のリレーションはサポートされていません。
ジオメトリコレクションはリレーションの特殊なケースであり、geometry_collectionタイプを使用することに注意してください。
ストリーム
すべてのジオメトリにはstreamプロパティが指定されている必要があります。このプロパティは、ジオメトリが表示されるストリーム(またはセンサー)を決定します。ストリームはシーンで指定されたものの中にあり、同じタイプ(例:cameraまたはlidar)である必要があります。
Sparseness
プレアノテーションはスパース(疎)にすることができます。つまり、オブジェクトやジオメトリはすべてのフレームに存在する必要はありません。代わりに、フレームの一部にのみ存在し、その間のフレームで補間することができます。この機能を活用することで、シーケンスのアノテーションプロセスを大幅に高速化できます。スパース性はオブジェクトデータポインターまたはブール値プロパティinterpolatedの2つの方法で実現できます。前者はより簡潔なプレアノテーションにつながるため、ほとんどの場合に推奨される方法です。後者はプレアノテーションがKognicプラットフォームからエクスポートされたアノテーションから作成される場合に便利です。
補間はキーフレーム間のジオメトリ値を線形補間することで行われます。2Dジオメトリの場合はピクセル座標で行われます。3Dジオメトリの場合、補間はフレームローカル座標系またはワールド座標系のいずれかで行うことができます(座標系を参照)。これはアノテーション指示で設定されるため、不明な場合はKognicチームにお問い合わせください。ワールド座標系での補間は推奨されますが、シーンにエゴポーズが含まれている必要があることに注意してください。
オブジェクトデータポインター
OpenLABELでは、オブジェクトデータポインターはオブジェクトの仕様を作成するために使用されます。例えば、特定のオブジェクトに使用される属性とジオメトリを指定できます。さらに、これらが存在するフレームを指定することもできます。ジオメトリがオブジェクトデータポインターで指定されている場合、そのジオメトリはオブジェクトデータポインターが指しているすべてのフレームに存在します。これらのフレームの一部でジオメトリが提供されていない場合は補間されます。ジオメトリはオブジェクトデータポインターの最初と最後のフレームに必ず提供する必要があることに注意してください。そうでない場合、プレアノテーションは拒否されます。オブジェクトデータポインターを使用する場合の制限として、ジオメトリはすべてのフレームで同じストリームに存在する必要があります。これは補間がストリーム座標系で行われるためです。異なるストリームで同じタイプのジオメトリを使用する必要がある場合は、異なるストリームのジオメトリに異なる名前を使用するだけで対応できます。オブジェクトデータポインターを使用したスパース性にオブジェクトデータポインターの使用例が示されています。
オブジェクトデータポインター
ブール値プロパティinterpolatedは、ジオメトリを補間することを指定するために使用できます。ジオメトリは補間フレームにも存在している必要がありますが、そのジオメトリ値は無視されます。補間されたジオメトリはプレアノテーションの最初のフレームに対応するジオメトリ(補間済みかどうかにかかわらず)が必要であることに注意してください。そうでない場合、プレアノテーションは拒否されます。interpolatedプロパティを使用することは、プレアノテーションがKognicプラットフォームからエクスポートされたアノテーションから作成される場合に推奨される方法です。補間プロパティを使用したスパース性にinterpolatedプロパティの使用例が示されています。
属性
属性はジオメトリとは異なる方法で処理されます。属性がフレームに存在しない場合、オブジェクト(またはプロパティがソース固有の場合はジオメトリ)がそのフレームに存在する限り、最後の値が使用されます。オブジェクトがフレームに存在しない場合、属性は無視されます。密な属性はプレアノテーションがKognicプラットフォームにアップロードされる際に自動的にスパース化されます。
Kognic予約済みオブジェクトプロパティ
Kognicプラットフォームでさまざまな動作を切り替えるために、オブジェクトに設定できる特定のプロパティがあります。
ロックされたジオメトリ
プレアノテーション内のオブジェクトとそのジオメトリがすでに十分な品質である場合、またはプレアノテーションの使用中に変更されないようにする必要がある場合は、ロック済みとしてマークできます。ロックはオブジェクトレベルに設定され、そのオブジェクトのすべてのジオメトリに影響します。
{
"openlabel": {
"objects": {
"object_uuid": {
"name": "object_uuid",
"object_data": {
"boolean": [
{
"name": "kognic_locked_geometries",
"val": true
}
]
},
"object_data_pointers": {},
"type": "Vehicle"
}
}
}
}静止オブジェクト
静止オブジェクトとは、移動できるが移動しないものを指します。良い例として駐車中の車が挙げられます。これは、ランドマークのような移動できない静的オブジェクトとは異なります。オブジェクトを静止としてマークすることで、特定のプラットフォーム機能を有効化できます。
import kognic.openlabel.models as OLM
uuid1 = str(uuid.uuid4())
object = OLM.Object(
name=uuid1,
type="car",
object_data=OLM.ObjectData(
boolean=[
OLM.Boolean(name="kognic_stationary_object", val=True),
]
),
)
openlabel = OLM.Openlabel(objects={uuid1: object}, metadata=OLM.Metadata(schema_version="1.0.0"))
openlabel_annotation = OLM.OpenLabelAnnotation(openlabel=openlabel)例
以下にサポートされているプレアノテーションの例を示します。
静的プロパティを持つ3Dキュービオイドと2Dバウンディングボックス
{
"openlabel": {
"frame_intervals": [],
"frames": {
"0": {
"frame_properties": {
"timestamp": 0,
"external_id": "0",
"streams": { "LIDAR1": {}, "ZFC": {} }
},
"objects": {
"1232b4f4-e3ca-446a-91cb-d8d403703df7": {
"object_data": {
"bbox": [
{
"attributes": {
"text": [{ "name": "stream", "val": "ZFC" }]
},
"name": "Bounding-box-1",
"val": [1.0, 1.0, 40.0, 30.0]
}
],
"cuboid": [
{
"attributes": {
"text": [{ "name": "stream", "val": "LIDAR1" }]
},
"name": "cuboid-89ac8a2b",
"val": [
2.079312801361084, -18.919870376586914, 0.3359137773513794,
-0.002808041640852679, 0.022641949116037438,
0.06772797660868829, 0.9974429197838155, 1.767102435869269,
4.099334155319101, 1.3691029802958168
]
}
]
}
}
}
}
},
"metadata": {
"schema_version": "1.0.0"
},
"objects": {
"1232b4f4-e3ca-446a-91cb-d8d403703df7": {
"name": "1232b4f4-e3ca-446a-91cb-d8d403703df7",
"object_data": {
"text": [{ "name": "color", "val": "red" }]
},
"type": "PassengerCar"
}
},
"streams": {
"LIDAR1": { "type": "lidar" },
"ZFC": { "type": "camera" }
}
}
}動的プロパティを持つ3Dライン
{
"openlabel": {
"frame_intervals": [{ "frame_end": 0, "frame_start": 0 }],
"frames": {
"0": {
"frame_properties": {
"streams": { "lidar": {} },
"timestamp": 0,
"external_id": "0"
},
"objects": {
"cc06aced-d7dc-4638-a6e9-dc7f5e215340": {
"object_data": {
"poly3d": [
{
"attributes": {
"text": [{ "name": "stream", "val": "lidar" }]
},
"closed": false,
"name": "line-3d-1",
"val": [
-5.0, 0.0, 0.0, -5.0, 10.0, 0.0, 5.0, 10.0, 0.0, 5.0, 0.0,
0.0, -5.0, 0.0, 0.0
]
}
],
"text": [{ "name": "occluded", "val": "No" }]
}
}
}
}
},
"metadata": { "schema_version": "1.0.0" },
"objects": {
"cc06aced-d7dc-4638-a6e9-dc7f5e215340": {
"name": "cc06aced",
"type": "Region"
}
},
"streams": {
"lidar": { "type": "lidar" },
"ZFC": { "type": "camera" }
}
}
}オブジェクトデータポインターを使用したスパース性
以下の例では、オブジェクト1232b4f4-e3ca-446a-91cb-d8d403703df7にはthe-bbox-nameというバウンディングボックスがあり、フレーム0と3に提供されています。フレーム1と2では、バウンディングボックスが補間されます
{
"openlabel": {
"objects": {
"1232b4f4-e3ca-446a-91cb-d8d403703df7": {
"name": "car-name",
"type": "car",
"object_data_pointers": {
"the-bbox-name": {
"type":"bbox",
"frame_intervals": [{"frame_start": 0, "frame_end": 3}]
}
}
}
},
"frames": {
"0": {
...,
"objects": {
"1232b4f4-e3ca-446a-91cb-d8d403703df7": {
"object_data": {
"bbox": [{"name": "the-bbox-name",...}]
}
}
}
},
"1": {},
"2": {},
"3": {
...,
"objects": {
"1232b4f4-e3ca-446a-91cb-d8d403703df7": {
"object_data": {
"bbox": [{"name": "the-bbox-name",...}]
}
}
}
}
}
}
}補間プロパティを使用したスパース性
以下の例では、スパース性はinterpolatedプロパティを使用して決定されます。オブジェクト1232b4f4-e3ca-446a-91cb-d8d403703df7にはバウンディングボックスがあり、フレーム1と2ではinterpolatedプロパティがtrueに設定されていますが、フレーム0と3では設定されていません。フレーム1と2のジオメトリ値は無視され、代わりにフレー ム0と3のジオメトリ値から補間されます。
{
"openlabel": {
...,
"frames": {
"0": {
...,
"objects": {
"1232b4f4-e3ca-446a-91cb-d8d403703df7": {
"object_data": {
"bbox": [
{
"attributes": {
"stream": [{ "name": "stream", "val": "CAM" }],
"boolean": [{ "name": "interpolated", "val": false }]
},
...
}
]
}
}
}
},
"1": {
...,
"objects": {
"1232b4f4-e3ca-446a-91cb-d8d403703df7": {
"object_data": {
"bbox": [
{
"attributes": {
"stream": [{ "name": "stream", "val": "CAM" }],
"boolean": [{ "name": "interpolated", "val": true }]
},
...
}
]
}
}
}
},
"2": {
...,
"objects": {
"1232b4f4-e3ca-446a-91cb-d8d403703df7": {
"object_data": {
"bbox": [
{
"attributes": {
"stream": [{ "name": "stream", "val": "CAM" }],
"boolean": [{ "name": "interpolated", "val": true }]
},
...
}
]
}
}
}
},
"3": {
...,
"objects": {
"1232b4f4-e3ca-446a-91cb-d8d403703df7": {
"object_data": {
"bbox": [
{
"attributes": {
"stream": [{ "name": "stream", "val": "CAM" }],
"boolean": [{ "name": "interpolated", "val": true }]
},
...
}
]
}
}
}
}
}
}
}コンテキストを含むOpenLabel
{
"openlabel": {
"context": {
"0": {
// A global static context
"name": "", // This has no meaning to us
"type": "isDayTime",
"attributes": {
"boolean": [{
"name": "", // This has no meaning to us
"val": true
}]
}
},
"1": {
// A global dynamic context
"name": "",
"type": "numberOfSignsPassed",
"attributes": {}
},
"2": {
// A stream specific static context
"name": "",
"type": "isCameraPointingForward",
"attributes": {
"text": [{ "name": "stream", "value": "CAM1"}],
"boolean": [{ "name": "", "value": true}
}
},
"3": {
// Same property as above but in a different sensor
"name": "",
"type": "isCameraPointingForward",
"attributes": {
"text": [{ "name": "stream", "value": "CAM2"}],
"boolean": [{ "name": "", "value": true}
}
},
"4": {
// A stream specific dynamic context
"name": "",
"type": "landscapeCharacteristics"
"attributes": {
"text": [{ "name": "stream", "value": "CAM1"}]
}
}
},
"frames": {
"0": {
...,
"contexts": {
"1": {
"attributes": {
"num": [{ "name": "", "value": 7 }]
}
}
}
},
"1": {},
"2": {},
"3": {
...,
"objects": {
"4": {
"attributes": {
"vec": [{ "name": "", "value": ["trees", "fields"] }]
}
}
}
}
}
}
}3Dセマンティックセグメンテーションとインスタンスセグメンテーション
3Dセグメンテーションタスクのプレアノテーションをアップロードする際、OpenLabelにはシーンに存在するクラス分類とインスタンスの両方が含まれます。クラス分類はオブジェクトタイプ3DPointcloudSegmentationを持つ特別なオブジェクトによって保持されます。このオブジェクトにはRLEを使用してエンコードされたクラス分類を含むバイナリオブジェクトデータエントリが必要です。インスタンスにはclassification_idの値を持つオブジェクトエントリが必要です。Kognicは以下のようなクラス分類の番号付けスキームを採用しています。
範囲 | 意味 |
|---|---|
0 | 未分類 |
1-255 | セマンティック分類(例:道路、建物) |
256 - 65535 | インスタンス分類(例:車1、車2、歩行者1、歩行者2) |
{
"openlabel": {
"frames": {
"0": {
"objects": {
"ecdb280e-0ff0-4f59-b9f2-9135e42f991c": {
"object_data": {}
},
"b088dcbf-c7fe-46a5-a71d-88ef49bdc107": {
"object_data": {
"binary": [
{
"attributes": {
"text": [
{
"val": "lidar",
"name": "stream"
}
]
},
"data_type": "",
"encoding": "rle",
"name": "labels",
"val": "<RLE string>"
}
]
}
}
}
}
},
"metadata": {
"schema_version": "1.0.0"
},
"objects": {
"ecdb280e-0ff0-4f59-b9f2-9135e42f991c": {
"name": "ecdb280e-0ff0-4f59-b9f2-9135e42f991c",
"type": "tree",
"object_data": {
"num": [
{
"val": 332.0,
"name": "classification_id"
}
]
}
},
"b088dcbf-c7fe-46a5-a71d-88ef49bdc107": {
"name": "b088dcbf-c7fe-46a5-a71d-88ef49bdc107",
"type": "3DPointCloudSegmentation"
}
}
}
}
リレーションとしてのジオメトリコレクション
以下は2つのカーブがジオメトリコレクションを形成する例です。ジオメトリコレクションは任意のタイプのジオメトリの任意のグループ化が可能であることに注意してください。
{
"openlabel": {
"frames": {
"0": {
"objects": {
"824e20e4-b3bd-4ba8-8d40-9d32a3985312": {
"object_data": {
"poly2d": [
{
"attributes": {},
"closed": false,
"mode": "MODE_POLY2D_ABSOLUTE",
"name": "curve-518f2936",
"val": []
}
]
}
},
"923eb0cf-ddf2-4eb3-881c-95846d8d1a3d": {
"object_data": {
"poly2d": [
{
"attributes": {},
"closed": false,
"mode": "MODE_POLY2D_ABSOLUTE",
"name": "curve-e63dc662",
"val": []
}
]
}
},
"f7b8704f-985c-4369-93a8-5b0c77757ee9": {
"object_data": {}
}
}
}
},
"metadata": {
"schema_version": "1.0.0"
},
"objects": {
"824e20e4-b3bd-4ba8-8d40-9d32a3985312": {
"name": "824e20e4-b3bd-4ba8-8d40-9d32a3985312",
"object_data": {},
"type": "dashed" // collection subtype 1
},
"923eb0cf-ddf2-4eb3-881c-95846d8d1a3d": {
"name": "923eb0cf-ddf2-4eb3-881c-95846d8d1a3d",
"object_data": {},
"type": "solid" // collection subtype 2
},
"f7b8704f-985c-4369-93a8-5b0c77757ee9": {
"name": "f7b8704f-985c-4369-93a8-5b0c77757ee9",
"object_data": {},
"type": "laneMarking" // the collection type
}
},
"relations": {
"0": {
"name": "0", // specifying the collection as a relation
"rdf_objects": [
{
"type": "object",
"uid": "824e20e4-b3bd-4ba8-8d40-9d32a3985312"
},
{
"type": "object",
"uid": "923eb0cf-ddf2-4eb3-881c-95846d8d1a3d"
}
],
"rdf_subjects": [
{
"type": "object",
"uid": "f7b8704f-985c-4369-93a8-5b0c77757ee9"
}
],
"type": "geometry_collection"
}
}
}
}