---
title: 사전 어노테이션
slug: api-guide/ko/xCBPRU1c70XCzlKsIG6MH
docTags: 
createdAt: 2024-12-17T09:56:31.000Z
---

사전 어노테이션(Pre-annotation)은 그라운드 트루스 제작에서 다양하게 활용됩니다. 사전 어노테이션 기능을 사용하면 입력에 이미 존재하는 것으로 알려진 객체에 대한 정보를 지정할 수 있습니다. 사용 사례에 어떻게 활용할 수 있는지는 Advisory Services 팀에 문의해 주세요.

Kognic 플랫폼은 [kognic-openlabel 패키지](https://pypi.org/project/kognic-openlabel)를 사용하여 OpenLabel 형식의 사전 어노테이션 업로드를 지원합니다.

## kognic-io 클라이언트를 사용하여 사전 어노테이션 생성하기

Kognic 플랫폼에서 사전 어노테이션을 사용하려면 3단계가 필요합니다.

1. 필요한 모든 데이터를 업로드하여 씬 생성하기
2. 씬에 대해 하나 이상의 OpenLabel 어노테이션을 사전 어노테이션으로 업로드하기
3. 사전 어노테이션을 사용하여 씬으로부터 입력(input) 생성하기

이러한 단계는 `create_inputs` 함수를 사용하여 한 번의 호출로 여러 번 수행할 수 있습니다. 자세한 내용은 [씬 및 입력 다루기](docId\:QaZKWWF-MALaJ6kMci9m5)를 참고하세요.

또한 씬을 생성하면 즉시 씬 UUID를 받게 되며, 이를 사용하면 씬 처리가 시작되기를 기다리지 않고도 사전 어노테이션을 생성할 수 있습니다. 사전 어노테이션은 씬 처리가 완료되면 사용할 수 있게 됩니다.

### 1. 씬 생성하기

먼저 씬을 생성합니다.

```python
# 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
)
```

[씬 및 입력 다루기](docId\:QaZKWWF-MALaJ6kMci9m5) 수도 있지만, 이는 선택 사항이며 씬의 UUID는 즉시 사전 어노테이션과 입력을 생성하는 데 사용할 수 있습니다.

### 2. OpenLabel 어노테이션 업로드하기

씬이 초기화된 후(씬 UUID를 받은 후)에는 Kognic 플랫폼에 사전 어노테이션을 업로드할 수 있습니다.

`kognic-openlabel`의 문서에 따라 OpenLabel 어노테이션을 로드하고 다음과 같이 Kognic 플랫폼에 업로드합니다.

```python
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. 입력 생성하기&#x20;

:::hint{type="info"}
입력을 생성하기 전에 씬 및/또는 사전 어노테이션의 처리가 완료될 때까지 기다릴 필요는 없습니다. 씬 생성 시 반환되는 씬 UUID와 사전 어노테이션 생성 시 반환되는 사전 어노테이션 UUID를 다음 단계에 바로 사용할 수 있습니다. 다만 오류를 즉시/동기적으로 알고 싶다면 대기하는 것이 여전히 유용하며, 그렇지 않다면 나중에 쿼리하여 오류를 확인할 수 있습니다.
:::

씬과 사전 어노테이션이 성공적으로 생성되면 입력을 생성할 수 있습니다. Kognic IO 2.9.0부터는 이를 수행하는 두 가지 방법이 있습니다.
**3.1. 최신 사전 어노테이션을 사용하여 최신 프로젝트 배치에 입력 생성하기**

사용 가능한 최신 사전 어노테이션을 사용하여 씬으로부터 입력을 생성합니다. 프로젝트의 가장 최근의 열린(open) 배치에 입력을 추가하거나, 특정 배치가 주어진 경우 해당 배치에 추가하여 어노테이션 준비 상태로 만듭니다.

```python
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. 특정 사전 어노테이션을 사용하여 주어진 프로젝트/배치에 입력 생성하기.**

:::hint{type="info"}
**Kognic IO 2.9.0부터 사용 가능합니다.** 이를 통해 하나의 씬에서 서로 다른 사전 어노테이션을 사용하거나 사전 어노테이션 없이 여러 개의 입력을 생성하고, 이를 서로 다른 프로젝트/배치에 추가할 수 있습니다.
:::

특정 사전 어노테이션을 사용하거나 사전 어노테이션 없이 씬으로부터 입력을 생성합니다. 프로젝트의 가장 최근의 열린(open) 배치에 입력을 추가하거나, 특정 배치가 주어진 경우 해당 배치에 추가하여 어노테이션 준비 상태로 만듭니다.&#x20;

```python
# 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 기능이 사전 어노테이션에서 지원되는 것은 아닙니다.

## 지원되지 않는 사전 어노테이션 기능

다음 기능 또는 기능 조합은 현재 지원되지 않거나, 부분적으로만 지원됩니다.

- 정적 지오메트리: 지원되지 않음
  - 이는 OpenLabel의 `objects.*.objectData` 아래에 선언된 바운딩 박스, 큐보이드 등입니다.
- 지오메트리별 속성: 3D 지오메트리에서는 지원되지 않음
  - 이는 OpenLabel에서 단일 기하학적 형태에 선언된 속성, 즉 하나의 센서로 본 객체에만 적용되는 속성입니다. 일반적인 예로 각 카메라마다 별도로 기록되는 `occlusion`이 있습니다.
  - 소스별, 스트림별 또는 센서별 속성이라고도 부를 수 있습니다.
  - 3D 지오메트리는 포인트 클라우드를 어노테이션할 때 그릴 수 있는 모든 것, 예를 들어 큐보이드를 의미합니다.
  - 지오메트리별 속성은 바운딩 박스와 같은 2D 지오메트리에서는 허용됩니다.
  - [핵심 개념](docId\:ScnZ9HNtKPw7pvGOaKag1)에서 속성을 이러한 방식으로 사용하기 전에 반드시 소스별(source specific)로 지정해야 합니다.
  - `stream` 속성은 이 규칙의 예외인 특수한 경우입니다.

## 지원되는 사전 어노테이션 기능

### 지오메트리

객체는 같은 프레임에서 여러 개의 3D 지오메트리를 가질 수 없습니다.

| 이름                       | OpenLABEL 필드 | 설명                                                                                                                                                                                       | 속성                       |
| ------------------------ | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| Cuboid                   | `cuboid`     | 3D 큐보이드                                                                                                                                                                                  | -                        |
| Bounding box             | `bbox`       | 2D 바운딩 박스                                                                                                                                                                                | -                        |
| 3D line                  | `poly3d`     | 3D 라인. 닫힌 형태로 만들려면 첫 번째 포인트를 끝에 다시 추가하세요.                                                                                                                                                | -                        |
| Polygon                  | `poly2d`     | 2D [OpenLABEL 형식](docId\:ckqZ7DhGnfHAFkr7EMh3i)                                                                                                                                          | `is_hole`                |
| Multi-polygon            | `poly2d`     | 2D [OpenLABEL 형식](docId\:ckqZ7DhGnfHAFkr7EMh3i)                                                                                                                                          | `is_hole` & `polygon_id` |
| Curve                    | `poly2d`     | 2D [OpenLABEL 형식](docId\:ckqZ7DhGnfHAFkr7EMh3i) 또는 라인                                                                                                                                    | `interpolation_method`   |
| 2D point                 | `point2d`    | [OpenLABEL 형식](docId\:ckqZ7DhGnfHAFkr7EMh3i)                                                                                                                                             | -                        |
| Group of 2D points       | `point2d`    | [OpenLABEL 형식](docId\:ckqZ7DhGnfHAFkr7EMh3i)                                                                                                                                             | `point_class`            |
| 3D Semantic Segmentation | `binary`     |                                                                                                                                                                                          |                          |
| 3D Instance Segmentation | `binary`     |                                                                                                                                                                                          |                          |
| 3D point                 | `point3d`    |                                                                                                                                                                                          |                          |
| 3D lane                  | `poly3d`     | 차선의 각 가장자리마다 하나씩 총 2개의 `poly3d`를 제공하여 구성됩니다. `lane_edge` 속성을 사용해 어느 차선 가장자리인지 지정하며, 하나는 `right` 값을, 다른 하나는 `left` 값을 갖습니다. 따라서 이 지오메트리는 객체가 같은 프레임에서 여러 개의 3D 지오메트리를 가질 수 없다는 규칙의 예외입니다. | `lane_edge`              |

모든 지오메트리는 사전 어노테이션의 루트가 아니라 프레임 아래에 지정되어야 함에 유의하세요. 3D 지오메트리는 단일 라이다인 경우 라이다 좌표계로, 다중 라이다인 경우 기준 좌표계로 표현되어야 합니다. 큐보이드의 회전은 [OpenLABEL 형식](docId\:ckqZ7DhGnfHAFkr7EMh3i)에서와 동일해야 합니다. 2D 지오메트리는 픽셀 좌표로 표현되어야 합니다. 자세한 내용은 [좌표계](docId:2yUiGk3M8sJI14b4ZEkqq)를 참고하세요.

### 속성

- Text
- Num
- Boolean

2D 지오메트리의 경우, 속성은 지오메트리별(소스/센서별이라고도 함) 또는 객체별로 지정될 수 있습니다. 속성은 정적(`objects` 키에 지정)이거나 동적(프레임 내 객체의 `object_data`에 지정)일 수 있으며, [핵심 개념](docId\:ScnZ9HNtKPw7pvGOaKag1)가 있는 경우 작업 정의에서 허용된 속성이어야 합니다. 지오메트리별 속성(프레임 내 단일 형태에 나타나는 속성)도 작업 정의에서 그렇게 선언되어야 합니다. 임의의 속성을 소스별 방식으로 사용할 수는 없습니다.

### 컨텍스트

컨텍스트는 kognic 플랫폼에서 씬 속성을 정의하는 데 사용됩니다. 각 컨텍스트는 하나의 속성 값을 포함합니다.

컨텍스트에는 다음 네 가지 모드가 있습니다.

- Static global - 값이 씬의 모든 프레임과 센서에 대해 유효함
- Dynamic global - 값이 모든 센서에 유효하지만 프레임에 따라 변경될 수 있음
- Static source specific - 값이 모든 프레임에 대해 유효하지만 특정 하나의 스트림에만 유효함
- Dynamic source specific - 값이 특정 하나의 스트림에만 유효하며 프레임에 따라 변경될 수 있음

이 문서에서는 다음 두 종류의 컨텍스트 객체를 구분합니다.

- **컨텍스트 객체(또는 단순히 컨텍스트)** - 루트 키 `contexts` 아래에 정의됨
- **프레임 컨텍스트 객체(또는 단순히 프레임 컨텍스트)** - 프레임 내에 정의됨

openlabel에서 사용되는 모든 컨텍스트는 openlabel의 루트에 있는 context 키 아래에 정의되어야 합니다. kognic에서는 컨텍스트의 키가 다른 곳(예: 프레임 내)에서 참조할 때만 사용되며, 증가하는 숫자 형태의 문자열로 설정합니다.

컨텍스트 타입은 kognic 앱 내의 속성 이름에 대응하며, 속성 값은 컨텍스트의 attributes에 설정됩니다.

소스별 속성이 여러 센서에 존재해야 하는 경우, 예를 들어 각 카메라 센서마다 "sees car"라는 boolean 속성이 있다면, 동일한 컨텍스트 타입을 가진 컨텍스트 객체가 센서마다 하나씩 존재하게 됩니다.

컨텍스트의 경우 다음 속성 타입을 지원합니다.

- text
- num
- boolean
- vec - 문자열 vec만 지원

| 컨텍스트 모드                 | 컨텍스트에 stream 속성 있음 | 컨텍스트에 stream 외 속성 있음 | 프레임 컨텍스트에 속성 있음 | 컨텍스트에 stream 외 속성 2개 이상 | 프레임 컨텍스트에 속성 2개 이상 |
| ----------------------- | ------------------ | -------------------- | --------------- | ----------------------- | ------------------ |
| Static Global           | ❌                  | ✅                    | ❌               | ❌                       | ❌                  |
| Dynamic Global          | ❌                  | ❌                    | ✅               | ❌                       | ❌                  |
| Static Source Specific  | ✅                  | ✅                    | ❌               | ❌                       | ❌                  |
| Dynamic Source Specific | ✅                  | ❌                    | ✅               | ❌                       | ❌                  |

예제는 [여기](docId\:DLcU2TKVfZVkAn8XbGE1R)를 참고하세요.&#x20;

### 프레임

모든 사전 어노테이션은 고유한 타임스탬프를 가진 프레임을 포함해야 하며, 각 타임스탬프는 씬에 지정된 타임스탬프 중 하나여야 합니다. 이는 타임스탬프가 사전 어노테이션의 프레임을 씬 내 올바른 프레임에 매핑하는 데 사용되기 때문입니다. 정적인 경우에는 타임스탬프 0을 가진 프레임 하나를 사용해야 합니다.

### 관계(Relations)

[OpenLABEL 형식](docId\:ckqZ7DhGnfHAFkr7EMh3i) 문서에 설명된 대로 지원됩니다. 소스별 관계는 지원되지 않습니다.

[지오메트리 컬렉션](#)은 `geometry_collection` 타입을 사용하는 관계의 특수한 경우임에 유의하세요.

### 스트림

모든 지오메트리는 `stream` 속성을 지정해야 합니다. 이 속성은 지오메트리가 어느 스트림(또는 센서)에 나타나는지를 결정합니다. 스트림은 씬에 지정된 것 중 하나여야 하며 `camera`나 `lidar` 등 동일한 타입이어야 합니다.

## 희소성(Sparseness)

사전 어노테이션은 희소(sparse)할 수 있습니다. 즉, 객체나 지오메트리가 모든 프레임에 존재할 필요는 없습니다. 대신 일부 프레임에만 존재하고 그 사이 프레임에서는 보간될 수 있습니다. 이 기능을 활용하면 시퀀스의 어노테이션 프로세스 속도를 크게 높일 수 있습니다. 희소성은 객체 데이터 포인터를 사용하거나 boolean 속성 `interpolated`를 사용하는 두 가지 방식으로 구현할 수 있습니다. 대부분의 경우 더 컴팩트한 사전 어노테이션을 만들 수 있는 전자가 권장되는 방식입니다. 후자는 Kognic 플랫폼에서 내보낸 어노테이션으로부터 사전 어노테이션을 생성하는 경우에 유용합니다.

**보간(Interpolation)**&#xC740; 키 프레임 사이의 지오메트리 값을 선형 보간하는 방식으로 이루어집니다. 2D 지오메트리의 경우 픽셀 좌표에서 이루어집니다. 3D 지오메트리의 경우 프레임 로컬 좌표계 또는 월드 좌표계([좌표계](docId:2yUiGk3M8sJI14b4ZEkqq) 참고) 중 하나에서 보간이 이루어질 수 있습니다. 이는 어노테이션 지침에서 설정되므로, 확실하지 않다면 Kognic 팀에 문의하세요. 월드 좌표계에서의 보간이 권장되지만, 이를 위해서는 씬에 자차 포즈가 포함되어 있어야 함에 유의하세요.

### 객체 데이터 포인터(Object Data Pointers)

OpenLABEL에서 객체 데이터 포인터는 객체에 대한 명세를 만드는 데 사용됩니다. 예를 들어 특정 객체에 사용되는 속성과 지오메트리를 지정할 수 있습니다. 또한 이들이 존재하는 프레임도 지정할 수 있습니다. 객체 데이터 포인터에 지오메트리가 지정되면, 해당 객체 데이터 포인터가 가리키는 모든 프레임에 이 지오메트리가 존재하게 됩니다. 이러한 프레임 중 일부에 지오메트리가 제공되지 않으면 보간됩니다. 객체 데이터 포인터의 첫 프레임과 마지막 프레임에는 **반드시** 지오메트리가 제공되어야 함에 유의하세요. 그렇지 않으면 사전 어노테이션이 거부됩니다.

한 가지 제약사항은 객체 데이터 포인터를 사용할 때 지오메트리가 모든 프레임에서 동일한 스트림에 있어야 한다는 것입니다. 이는 보간이 스트림 좌표계에서 이루어지기 때문입니다. 서로 다른 스트림에서 같은 타입의 지오메트리를 사용해야 하는 경우, 각 스트림에서 지오메트리에 서로 다른 이름을 사용하면 됩니다.

[객체 데이터 포인터를 사용한 희소성](./#----)에서 객체 데이터 포인터 사용 예제를 확인할 수 있습니다.

### Interpolated 속성

boolean 속성 `interpolated`를 사용하여 지오메트리가 보간되어야 함을 지정할 수 있습니다. 보간된 프레임에서도 지오메트리는 여전히 존재해야 하지만 그 지오메트리 값은 무시됩니다. 보간된 지오메트리는 사전 어노테이션의 첫 프레임에 대응하는 지오메트리(보간 여부와 무관하게)를 가져야 함에 유의하세요. 그렇지 않으면 사전 어노테이션이 거부됩니다.

Kognic 플랫폼에서 내보낸 어노테이션으로부터 사전 어노테이션을 생성하는 경우 `interpolated` 속성을 사용하는 것이 권장되는 방식입니다.

[Interpolated 속성을 사용한 희소성](docId\:DLcU2TKVfZVkAn8XbGE1R)에서 `interpolated` 속성 사용 예제를 확인할 수 있습니다.

### 속성

속성은 지오메트리와 다르게 처리됩니다. 속성이 프레임에 존재하지 않으면, 객체(속성이 소스별인 경우 지오메트리)가 해당 프레임에 존재하는 한 마지막 값이 그대로 사용됩니다. 객체가 프레임에 존재하지 않으면 속성은 무시됩니다. 밀집된(dense) 속성은 사전 어노테이션이 Kognic 플랫폼에 업로드될 때 자동으로 희소화됩니다.

## Kognic 예약 객체 속성

Kognic 플랫폼에서 다양한 동작을 전환하기 위해 객체에 설정할 수 있는 특정 속성들이 있습니다.

### 잠긴 지오메트리(Locked Geometries)

사전 어노테이션 내 객체와 그 지오메트리가 이미 충분한 품질을 갖췄거나 사전 어노테이션 사용 중에 변경되지 않아야 하는 경우, 이를 잠금(locked)으로 표시할 수 있습니다. 잠금은 객체 수준에서 적용되며 해당 객체의 모든 지오메트리에 영향을 줍니다.

:::CodeblockTabs
```json
{
  "openlabel": {
    "objects": {
      "object_uuid": {
        "name": "object_uuid",
        "object_data": {
          "boolean": [
            {
              "name": "kognic_locked_geometries",
              "val": true
            }
          ]
        },
        "object_data_pointers": {},
        "type": "Vehicle"
      }
    }
  }
}
```

```python
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_locked_geometries", val=True),
        ]
    ),
)

openlabel = OLM.Openlabel(objects={uuid1: object}, metadata=OLM.Metadata(schema_version="1.0.0"))

openlabel_annotation = OLM.OpenLabelAnnotation(openlabel=openlabel)
```
:::

### 정지 객체(Stationary Objects)

정지 객체는 움직일 수 *있지만* 움직이지 않는 객체입니다. 좋은 예로 주차된 차가 있습니다.
이는 움직일 수 *없는* 정적 객체(예: 랜드마크)와는 다릅니다.

특정 플랫폼 기능을 활성화하기 위해 객체를 정지 객체로 표시할 수 있습니다.

:::CodeblockTabs
```json
{
  "openlabel": {
    "objects": {
      "object_uuid": {
        "name": "object_uuid",
        "object_data": {
          "boolean": [
            {
              "name": "kognic_stationary_object",
              "val": true
            }
          ]
        },
        "object_data_pointers": {},
        "type": "Vehicle"
      }
    }
  }
}
```

```python
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)
```
:::

### 지오메트리 신뢰도(Geometry Confidence)

사전 어노테이션이 예측된 각 지오메트리에 대해 신뢰도 점수를 산출하는 모델에서 나온 경우, `kognic_geometry_confidence` 속성으로 해당 점수를 첨부하세요. 어노테이터는 도구 내에서 신뢰도 임계값으로 사전 어노테이션을 필터링할 수 있습니다. 값은 `[0, 1]` 범위의 숫자이며 프레임별, 형태별로 설정됩니다.

3D 차선의 경우, `left` 차선 가장자리 `poly3d`에만 신뢰도를 설정하세요. 오른쪽 가장자리에는 설정하면 안 됩니다.

:::CodeblockTabs
```json
{
  "openlabel": {
    "frames": {
      "0": {
        "objects": {
          "object_uuid": {
            "object_data": {
              "cuboid": [
                {
                  "name": "cuboid_uuid",
                  "val": [x, y, z, qx, qy, qz, qw, sx, sy, sz],
                  "attributes": {
                    "num": [
                      {
                        "name": "kognic_geometry_confidence",
                        "val": 0.87
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}
```

```python
import kognic.openlabel.models as OLM

uuid1 = str(uuid.uuid4())

object = OLM.Object(
    name=uuid1,
    type="car",
)

cuboid = OLM.Cuboid(
    name="cuboid_uuid",
    val=[x, y, z, qx, qy, qz, qw, sx, sy, sz],
    attributes=OLM.Attributes(
        num=[
            OLM.Num(name="kognic_geometry_confidence", val=0.87),
        ],
    ),
)

frame = OLM.Frame(
    objects={uuid1: OLM.Objects(object_data=OLM.ObjectData(cuboid=[cuboid]))},
)

openlabel = OLM.Openlabel(
    objects={uuid1: object},
    frames={"0": frame},
    metadata=OLM.Metadata(schema_version="1.0.0"),
)
openlabel_annotation = OLM.OpenLabelAnnotation(openlabel=openlabel)
```
:::

## 예제

아래는 지원되는 사전 어노테이션의 예제들입니다.

### 정적 속성을 가진 3D 큐보이드와 2D 바운딩 박스

```json
{
  "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 라인

```json
{
  "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`는 프레임 0과 3에 제공되는 `the-bbox-name`이라는 바운딩 박스를 가지고 있습니다. 프레임 1과 2에서는 바운딩 박스가 보간됩니다.

```json
{
  "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 속성을 사용한 희소성

아래 예제에서는 `interpolated` 속성을 사용해 희소성을 결정합니다. 객체 `1232b4f4-e3ca-446a-91cb-d8d403703df7`는 바운딩 박스를 가지고 있으며, 프레임 1과 2에서는 `interpolated` 속성이 `true`로 설정되어 있지만 프레임 0과 3에서는 그렇지 않습니다. 프레임 1과 2의 지오메트리 값은 무시되며 대신 프레임 0과 3의 지오메트리 값으로부터 보간됩니다.

```json
{
  "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

```json
{
  "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로 인코딩된 분류 정보를 담은 binary object data 항목을 포함해야 합니다. 인스턴스가 있는 경우 `classification_id` 값을 가진 객체 항목이 있어야 합니다.

Kognic은 다음과 같은 분류 번호 체계를 적용합니다.

| 범위          | 의미                                               |
| ----------- | ------------------------------------------------ |
| 0           | 미분류                                              |
| 1-255       | 시맨틱 분류, 예: 도로, 건물                                |
| 256 - 65535 | 인스턴스 분류, 예: Car1, Car2, Pedestrian1, Pedestrian2 |

```json
{
  "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개의 곡선 예제입니다. 지오메트리 컬렉션은 임의 타입의 지오메트리를 임의로 그룹화한 것일 수 있음에 유의하세요.

```json
{
  "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"
      }
    }
  }
}


```
