---
title: OpenLABEL形式
slug: api-guide/ja/openlabel
docTags: 
createdAt: 2024-12-17T12:57:39.872Z
---

OpenLABELは、[ASAM](https://www.asam.net/)が開発した標準化されたアノテーション形式です。この形式には、詳細な[ドキュメント](https://www.asam.net/index.php?eID=dumpFile\&t=f\&f=4566\&token=9d976f840af04adee33b9f85aa3c22f2de4968dd)および[JSONスキーマ](https://openlabel.asam.net/V1-0-0/schema/openlabel_json_schema.json)が付属しており、形式の妥当性を確認するために使用できます。

OpenLABELは厳格な形式ですが、解釈の余地が一部残っています。このセクションでは、そのような部分をいくつか明確にし、標準内で行った選択について説明します。

## キューボイドの回転

回転はY軸が前方を向くように設定されており、回転順序は`XYZ`です。これは、ヘディング（ヨー）が0のキューボイドが、軸の正方向においてY軸と整列していることを意味します。これは、前方方向がX軸に沿う[ISO 8855](https://www.sis.se/api/document/preview/914200/#:~\:text=This%20International%20Standard%20defines%20the,to%20multi%2Dunit%20vehicle%20combinations.)標準とは多少異なります。ISO 8855への変換は、Z軸周りの回転を適用し、以下の方法で`sx`と`sy`を入れ替えることで行えます。

```python
import math 
from typing import List

from scipy.spatial.transform import Rotation

def convert_to_iso8855(val: List[float]) -> List[float]:
    """ Converts cuboid values to ISO 8855 """
    [x, y, z, qx, qy, qz, qw, sx, sy, sz] = val
    rotation_1 = Rotation.from_quat([qx, qy, qz, qw])
    rotation_2 = Rotation.from_rotvec([0, 0, math.pi / 2])
    rot_object = rotation_1 * rotation_2
    [qx, qy, qz, qw] = rot_object.as_quat()
    return [x, y, z, qx, qy, qz, qw, sy, sx, sz]
```

## 非シーケンスは1フレームのシーケンス

シンプルさを考慮して、非シーケンスをシーケンスと同じ方法で扱う選択をしました。これは、非シーケンスが1フレームのみのシーケンスとして表現されることを意味します。`name`や`type`などのデータのみがトップレベル要素のキーで定義されます。その他の情報はすべてframesの下に格納されます。以下の例を参照してください。

```json
{
    "objects": {
        "0": {
            "name": "car-0",
            "type": "Car"
        }
    },
    "frames": {
        "0": {
            "objects": {
                "0": {"object_data": {...}}
            }
        }
    }
}
```

## ストリームは単なるテキストプロパティの1つ

`stream`プロパティは、ジオメトリとプロパティがどのストリーム/センサー/ソースでアノテーションされたかを示すために使用されます。例えば、以下は`Camera`という名前のストリームでアノテーションされたポイントを持つオブジェクトです。ジオメトリに対応するすべての属性も同じストリームでアノテーションされていることに注意してください。

```json
{
    "object_data": {
        "point2d": [
            {
                "name": "point-4d2d325f",
                "val": [300.5300, 286.4396],
                "attributes": {
                    "text": [
                        {"name": "stream", "val": "Camera"},
                        {"name": "Color", "val": "Black"}
                    ]
                }
            }
        ]
    }
}
```

## リレーション

2種類のリレーションを考慮しています。2つのオブジェクト間の単方向リレーションとグループリレーションです。これらに加えて、偽リレーション、すなわち実際には他のオブジェクトへのポインタではなく、`Inconclusive`、`Nothing`、`Unclear`などの値を取るリレーションプロパティを表現する必要があります。

### リレーションは単方向

リレーションは単方向です。つまり、あるオブジェクト`object1`が別のオブジェクト`object2`へのリレーションを持っていても、`object2`が`object1`へのリレーションを持つことにはなりません。以下は、`car-0`が`car-1`に追従しており、`car-2`が別の車に追従しているかどうか不明な例です。

```json
{
    "objects": {
        "0": {"name": "car-0", "type": "Car"},
        "1": {"name": "car-1", "type": "Car"},
        "2": {"name": "car-2", "type": "Car"}
    },
    "relations": {
        "0": {
            "name": "0",
            "type": "isFollowing",
            "rdf_subjects": [{"type": "object", "uid": "0"}],
            "rdf_objects": [{"type": "object", "uid": "1"}]
        }
    }
}
```

### アクションによる偽リレーションの表現

Kognicプラットフォームでは、実際には他のオブジェクトへの参照ではない値をリレーションに割り当てることがサポートされています。例としては`Inconclusive`や`Nothing`があります。アクションはこれらを以下の方法で表現するために使用され、アクションの名前が値を決定し、typeがプロパティ名を決定します。

```json
{
    "objects": {
        "0": {"name": "lane-0", "type": "Lane"}
    },
    "relations": {
        "0": {
            "name": "0",
            "type": "isSubjectOfAction",
            "rdf_subjects": [{"type": "object", "uid": "0"}],
            "rdf_objects": [{"type": "action", "uid": "0"}]
        }
    },
    "actions": {
        "0": {"name": "Nothing", "type": "is_pulling_or_pushing"}
    }
}
```

### ストリーム固有のリレーション

リレーションがストリーム固有の場合、`stream_relations`プロパティが存在し、リレーションのリストがどのストリームに属するかを示します。

```json
{ // frames.0
    // ...
    "frame_properties": {
        "streams": {
            "CAMERA_FRONT": {
                "description": null,
                "stream_properties": {
                    "stream_relations": {
                        "1": {}
                    }
                }
            }
        }
    },
    "relations": {
        "0": {}
    }
}
```

## ポリゴンの表現

ポリゴンはOpenLABELにおいて`Poly2d`オブジェクトのリストで記述されます。そのうちの1つが外形を表し、残りは潜在的な穴を表します。これはブール型プロパティ`is_hole`によって決定されます。以下は1つの穴を持つポリゴンの例です。

```json
{
    "object_data": {
        "poly2d": [
            {
                "name": "poly1",
                "mode": "MODE_POLY2D_ABSOLUTE",
                "val": [...],
                "attributes": { "boolean": [{"name": "is_hole", "val": false}] }
            },
            {
                "name": "poly2",
                "mode": "MODE_POLY2D_ABSOLUTE",
                "val": [...],
                "attributes": { "boolean": [{"name": "is_hole", "val": true}] }
            }
        ]
    }
}
```

`mode`に対してサポートされている値は`MODE_POLY2D_ABSOLUTE`のみです。絶対モードとは、`val`の値がピクセル座標として解釈されることを意味します（最初の座標ペアからの相対値ではありません）。

## マルチポリゴンの表現

マルチポリゴンは単純にポリゴンのリストであるため、`is_hole`プロパティを持つ`Poly2d`オブジェクトのリストを使用して同様の方法で記述します。ただし、マルチポリゴン内で`Poly2d`オブジェクトがどのポリゴンに属するかを決定する`polygon_id`プロパティを追加します。以下は、それぞれ1つの穴を持つ2つのポリゴンからなるマルチポリゴンの例です。

```json
{
    "object_data": {
        "poly2d": [
            {
                "name": "poly1",
                "mode": "MODE_POLY2D_ABSOLUTE",
                "val": [...],
                "attributes": {
                    "text": [{"name": "polygon_id", "val": "1"}],
                    "boolean": [{"name": "is_hole", "val": false}]
                }
            },
            {
                "name": "poly2",
                "mode": "MODE_POLY2D_ABSOLUTE",
                "val": [...],
                "attributes": {
                    "text": [{"name": "polygon_id", "val": "1"}],
                    "boolean": [{"name": "is_hole", "val": true}]
                }
            },
            {
                "name": "poly3",
                "mode": "MODE_POLY2D_ABSOLUTE",
                "val": [...],
                "attributes": {
                    "text": [{"name": "polygon_id", "val": "2"}],
                    "boolean": [{"name": "is_hole", "val": false}]
                }
            },
            {
                "name": "poly4",
                "mode": "MODE_POLY2D_ABSOLUTE",
                "val": [...],
                "attributes": {
                    "text": [{"name": "polygon_id", "val": "2"}],
                    "boolean": [{"name": "is_hole", "val": true}]
                }
            }
        ]
    }
}
```

`mode`に対してサポートされている値は`MODE_POLY2D_ABSOLUTE`のみです。絶対モードとは、`val`の値がピクセル座標として解釈されることを意味します（最初の座標ペアからの相対値ではありません）。

## 曲線の表現

:::hint{type="warning"}
### 注意

補間メソッドの名前が`interpolation-method`から`interpolation_method`に変更されました。ただし、古いアノテーションには依然として古い名前が含まれている場合があります。
:::

曲線は`poly2d`ジオメトリを使用して表現され、補間メソッドは以下の方法でテキストプロパティとして指定されます。

```json
{
  "poly2d": [
    {
      "closed": false,
      "mode": "MODE_POLY2D_ABSOLUTE",
      "name": "curve-d633ca89",
      "val": [...],
      "attributes": {
        "text": [
          {
            "name": "interpolation_method",
            "val": "natural-cubic-spline"
          }
        ]
      }
    }
  ]
}
```

`mode`に対してサポートされている値は`MODE_POLY2D_ABSOLUTE`のみです。絶対モードとは、`val`の値がピクセル座標として解釈されることを意味します（最初の座標ペアからの相対値ではありません）。プロパティ`interpolation_method`は必須であり、ノード同士をどのように結ぶかを決定します。以下の値がサポートされています：

- `natural-cubic-spline`
- `catmull-rom-0.5`
- `polyline`

## 3Dレーンの表現

3Dレーンは3D空間における2本の線（`poly3d`）として表現され、1本は右側、もう1本は左側です。テキストプロパティ`lane_edge`が線が右側か左側かを決定します。線の`closed`は常に`false`に設定されます。

```json
{
  "object_data": {
    "poly3d": [
      {
        "attributes": {
          "text": [
            { "name": "lane_edge", "val": "left" },
            { "name": "stream", "val": "lidar" }
          ]
        },
        "closed": false,
        "name": "",
        "val": [
          1.2647494200238287, -51.51747573498745, -2.315540290283199,
          1.0807419132566136, -48.91298533071834, -2.313640304199211,
          -0.0892715141237751, -34.705936676401016, -2.235569814758307,
          -0.4442893388935316, -29.60917111552865, -2.1894531147766174,
          -1.0952988968721313, -17.193981050037397, -2.1397902661132875
        ]
      },
      {
        "attributes": {
          "text": [
            { "name": "lane_edge", "val": "right" },
            { "name": "stream", "val": "lidar" }
          ]
        },
        "closed": false,
        "name": "",
        "val": [
          1.5845765823868767, -51.49487958011918, -2.315540290283199,
          1.4004322100638888, -48.888528958803036, -2.313640304199211,
          0.23043085215069048, -34.68163859008775, -2.235569814758307,
          -0.12426061849402326, -29.589636067040036, -2.1894531147766174
        ]
      }
    ]
  }
}
```

## 2Dポイントの表現

2Dポイントは単一の`point2d`として表現されます。各`point2d`にはオプションの`point_class`属性があります。単一ポイントの場合は省略できますが、設定する場合はオブジェクトの`type`と等しくなければなりません。この属性は、将来ほかのポイントベースのジオメトリで使用するために予約されています。

```json
{
  "openlabel": {
    ...,
    "frames": {
      "0": {
        "objects": {
          "a940239d-ff27-4480-8294-c482977a1b32": {
            "object_data": {
              "point2d": [
                {
                  "attributes": {
                    "text": [
                      { "name": "point_class", "val": "APoint" },
                      { "name": "stream", "val": "stream1" }
                    ]
                  },
                  ...
                }
              ]
            }
          },
          "e027e626-eb7a-4a8e-a9ae-083464e137d1": {
            "object_data": {
              "point2d": [
                {
                  "attributes": {
                    "text": [
                      { "name": "stream", "val": "stream1" }
                    ]
                  },
                  ....
                }
              ]
            }
          }
        }
      }
    },
    "metadata": {...},
    "objects": {
      "a940239d-ff27-4480-8294-c482977a1b32": {
        ...
        "type": "APoint"
      },
      "e027e626-eb7a-4a8e-a9ae-083464e137d1": {
        ...
        "type": "AnotherPoint"
      }
    },
    ...
  }
}

```

## 2D点グループの表現

点グループは、複数のポイントが同じオブジェクトを参照する場合に使用されます。点グループ内の各ポイントには`point_class`属性が必須であり、`point_class`はオブジェクトの`type`と異なる必要があります。`point_class`の値`"line_reference_point"`は将来のユースケースのために予約されています。

## ジオメトリコレクションの表現

:::hint{type="info"}
### 注記

`kognic_format_version` 2.2で導入されました。
:::

タスクビューに関する関連ドキュメント：[ジオメトリコレクション](#)

上記リンクで説明されているジオメトリのコレクションは、`geometry_collection`をtypeとする予約済みリレーションを持つものとして表現されます。

```json
{
  "openlabel": {
    "frames": {
      "0": {
        "objects": {
          "516b6045-87e8-40e4-a104-5eaa600e8e3a": {
            "object_data": {
              "bbox": [
                {
                  "name": "bbox-abc123",
                  "val": [
                    ...
                  ]
                }
              ]
            }
          },
          "fe07e9cf-f42c-4b48-b4d8-bab75b7e9827": {
            "object_data": {
              "poly2d": [
                {
                  "name": "curve-abc123",
                  "val": [
                    ...
                  ]
                }
              ]
            }
          },
          "329508b7-729c-4298-8141-f329dbc32ad0": {
            "object_data": {
              "poly2d": [
                {
                  "name": "curve-abc123",
                  "val": [
                    ...
                  ]
                }
              ]
            }
          },
          "4c321584-0e88-4578-b0f0-b5e8c974244b": {
            "object_data": {
              "text": [
                {
                  "name": "lane",
                  "val": "right"
                }
              ]
            }
          }
        }
      }
    },
    "metadata": {
      "schema_version": "1.0.0",
      "kognic_format_version": "2.2",
      "uuid": "63698712-b18e-426b-9ad5-1b178cc29838"
    },
    "objects": {
      "516b6045-87e8-40e4-a104-5eaa600e8e3a": {
        "name": "516b6045-87e8-40e4-a104-5eaa600e8e3a",
        "object_data": {
            ...
        },
        "type": "some_bbox"
      },
      "fe07e9cf-f42c-4b48-b4d8-bab75b7e9827": {
        "name": "fe07e9cf-f42c-4b48-b4d8-bab75b7e9827",
        "object_data": {
            ...
        },
        "type": "some_line"
      },
      "329508b7-729c-4298-8141-f329dbc32ad0": {
        "name": "329508b7-729c-4298-8141-f329dbc32ad0",
        "object_data": {
            ...
        },
        "type": "some_line"
      },
      "4c321584-0e88-4578-b0f0-b5e8c974244b": {
        "name": "4c321584-0e88-4578-b0f0-b5e8c974244b",
        "object_data": {
            ...
        },
        "type": "some_collection"
      }
    },
    "relations": {
      "0": {
        "name": "0",
        "rdf_objects": [
          {
            "uid": "516b6045-87e8-40e4-a104-5eaa600e8e3a",
            "type": "object"
          },
          {
            "uid": "fe07e9cf-f42c-4b48-b4d8-bab75b7e9827",
            "type": "object"
          },
          {
            "uid": "329508b7-729c-4298-8141-f329dbc32ad0",
            "type": "object"
          }
        ],
        "rdf_subjects": [
          {
            "uid": "4c321584-0e88-4578-b0f0-b5e8c974244b",
            "type": "object"
          }
        ],
        "type": "geometry_collection"
      }
    }
  }
}
```

## 3Dセグメンテーションの表現

分類はランレングス符号化（RLE）によって値を表現します。例として、11122222222000000000000は#3V1#8V2#13V0に変換され、文字#の後の数字が繰り返し値の数を定義し、文字Vの後に値が定義されます。

```json
"b088dcbf-c7fe-46a5-a71d-88ef49bdc107": {
  "object_data": {
    "binary": [
      {
        "attributes": {
          "text": [
            {
              "val": "lidar",
              "name": "stream"
            }
          ]
        },
        "data_type": "",
        "encoding": "rle",
        "name": "labels",
        "val": "<RLE string>"
      }
    ]
  }
}
```
