---
title: 커스텀 카메라 캘리브레이션
slug: api-guide/ko/niLzCMzZNuL2UdkoVG1FP
docTags: 
createdAt: 2024-12-17T10:20:02.000Z
---

:::hint{type="info"}
### 참고

이 기능은 kognic-io 버전 1.8.0에서 새로 추가되었으며 일부 기능은 선택적 의존성이 필요합니다. 설치하려면 `pip install kognic-io[wasm]`을 실행하세요.
:::

캘리브레이션이 지원되는 표준 카메라 캘리브레이션 목록에 없는 경우, 커스텀 캘리브레이션을 제공할 수 있습니다. 아래 표는 `CustomCameraCalibration` 객체의 속성을 보여줍니다. `wasm_base64` 속성은 캘리브레이션을 구현하는 WebAssembly 모듈을 base64로 인코딩한 문자열입니다. `test_cases` 속성은 생성 시 캘리브레이션을 검증하는 데 사용되는 `TestCase` 객체의 목록입니다. 캘리브레이션이 올바른지 확인할 수 있도록
몇 가지 테스트 케이스를 제공하는 것을 권장합니다.

| 키                     | 값                       | 파라미터               |
| --------------------- | ----------------------- | ------------------ |
| `rotation_quaternion` | `RotationQuaternion` 객체 | `w`, `x`, `y`, `z` |
| `position`            | `Position` 객체           | `x`, `y`, `z`      |
| `image_width`         | 정수                      | NA                 |
| `image_height`        | 정수                      | NA                 |
| `wasm_base64`         | 문자열                     | NA                 |
| `test_cases`          | `TestCase` 객체 목록        | point3d, point2d   |

`CustomCameraCalibration` 객체는 바이너리나 wasm 파일로부터 편리하게 바로 인스턴스화할 수 있습니다.

```python
calibration_file = CustomCameraCalibration.from_file("/path/to/calibration.wasm", ...)
calibration_binary = CustomCameraCalibration.from_bytes(b"...", ...)
```

WebAssembly 모듈을 더 쉽게 다룰 수 있도록 여러 유틸리티를 제공합니다. 구체적으로는 검증 코드와, 몇 가지 언어에서 WebAssembly로 변환하는 컴파일 코드를 제공합니다. 이 코드는 Python 함수와 `kognicutil` cli 모두를 통해 사용할 수 있습니다.

## WebAssembly 모듈

WebAssembly는 모듈이 `project_point_to_image`라는 함수를 export하는 엄격한 인터페이스를 따라야 합니다. 이 함수는 `float64` 타입의 인자 3개를 받아 `float64` 타입의 값 2개를 반환해야 합니다. 따라서 이 인터페이스의 WebAssembly 텍스트 표현은 `func (param f64 f64 f64) (result f64 f64)`입니다. 세 인자는 3D 포인트의 x, y, z 좌표입니다. 두 반환값은 이미지 평면에 투영된 포인트의 x, y 좌표입니다. WebAssembly는 기본적으로 다중 반환값을 지원하지 않지만, [multi-value](https://github.com/WebAssembly/multi-value) 제안을 통해 활성화할 수 있습니다.

만약 포인트가 시야(field of view) 내에 있지 않다면, 해당 함수는 x, y 좌표 모두에 대해 [NaN](https://en.wikipedia.org/wiki/NaN)을 반환해야 합니다.

## 검증

:::hint{type="info"}
### 참고

이를 위해서는 kognic-io의 선택적 의존성인 `wasmtime`이 설치되어 있어야 합니다. 설치하려면 `pip install kognic-io[wasm]`을 실행하세요.
:::

Python 함수와 `kognicutil` cli 모두를 통해 검증 코드를 제공합니다. 다음과 같은 항목들을 검증하지만 이에 국한되지는 않습니다.

1. 모듈을 로드할 수 있는지
2. 함수가 존재하고 시그니처가 올바른지
3. 모듈을 사용하여 포인트를 투영할 수 있는지
4. 테스트 케이스가 제공된 경우 포인트가 올바르게 투영되는지

Python에는 캘리브레이션을 검증하는 세 가지 방법이 있습니다.

```python
import kognic.io.tools.calibration.validation as wasm_validation
from kognic.io.model.calibration.camera.custom_camera_calibration import CustomCameraCalibration, Point2d, Point3d, TestCase

test_cases = [
    TestCase(
        point3d=Point3d(x=1.0, y=2.0, z=3.0),
        point2d=Point2d(x=2.0, y=5.6)
    ),
    TestCase(
        point3d=Point3d(x=1.0, y=1.0, z=-1.0),
        point2d=Point2d(x=float("nan"), y=float("nan")) # point is outside field of view
    )
]

wasm_file = "/path/to/calibration.wasm"
calibration = CustomCameraCalibration.from_bytes(wasm_file, test_cases=test_cases, ...)
wasm_bytes = calibration.to_bytes()

# Validate the calibration object
wasm_validation.validate_custom_camera_calibration(calibration, test_cases=test_cases)

# Validate the wasm file
wasm_validation.validate_wasm_file(wasm_file, test_cases=test_cases)

# Validate the wasm binary
wasm_validation.validate_wasm_bytes(wasm_bytes, test_cases=test_cases)
```

`kognicutil` cli는 다음과 같이 사용할 수 있습니다.

```bash
kognicutil wasm validate calibration.wasm
```

## 컴파일

:::hint{type="warning"}
### 주의
:::

Rust 1.82.0에서는 여러 값을 함수에서 반환하는 multivalue 기능 타겟에 대한 지원이 제거되었습니다. 이 기능은 현재 커스텀 카메라 캘리브레이션이 동작하는 데 필요하므로, Rust 및/또는 Cargo 버전을 1.82.0 미만으로 고정해야 합니다.

:::hint{type="info"}
### 참고

wasm 파일은 가능한 한 작게 유지하는 것이 좋습니다. 불필요한 의존성은 피하도록 하세요. 예를 들어 표준 라이브러리를 사용하는 대신 일부 수학 함수를 직접 구현하는 것이 나을 수 있습니다.
:::

위에서 언급했듯이 WebAssembly 모듈은 엄격한 인터페이스를 따라야 하며 컴파일에는 multi-value 제안이 필요합니다. 몇 가지 언어에서 WebAssembly 모듈을 더 쉽게 컴파일할 수 있도록 유틸리티를 제공합니다. 아래 표를 참고하세요.

| **언어**       | **타겟**        | **컴파일 도구** | **요구 버전** |
| ------------ | ------------- | ---------- | --------- |
| Rust         | \*.rs         | rustc      | \< 1.82.0 |
| Rust (Cargo) | Cargo.toml    | cargo      | \< 1.82.0 |
| C++          | \*.cc, \*.cpp | emscripten | N/A       |
| C            | \*.c          | emscripten | N/A       |

이 유틸리티는 Python 함수와 `kognicutil` cli 모두를 통해 사용할 수 있습니다. Python에서는 다음과 같이 모듈을 컴파일할 수 있습니다.

```python
from kognic.io.tools.calibration.compilation import compile_to_wasm
wasm_binary = compile_to_wasm("path/to/source")
```

반환된 바이너리는 `CustomCameraCalibration` 객체를 생성하는 데 사용할 수 있습니다. `output_wasm` 파라미터가 전달되면, 바이너리는 지정된 경로에 저장됩니다. `kognicutil` cli는 다음과 같이 사용할 수 있습니다.

```bash
kognicutil wasm compile path/to/source path/to/output.wasm
```

기본적으로 컴파일 후 검증이 실행됩니다. 이는 `--skip-validation` 플래그로 비활성화할 수 있습니다.

캘리브레이션 파라미터는 WebAssembly 모듈에서 사용할 수 있도록 바이너리에 내장되어야 합니다. 런타임에 투영 함수의 속도를 높이기 위해 가능한 한 많은 것을 사전에 계산해 두세요.

아래는 몇 가지 언어로 단순화한 pinhole 캘리브레이션의 예제입니다.

### 예제: Rust

:::hint{type="info"}
### 참고

이를 위해서는 `wasm32-wasi` 타겟과 함께 Rust가 설치되어 있어야 합니다. [여기](https://www.rust-lang.org/tools/install)의 안내에 따라 Rust를 설치한 다음 `rustup target add wasm32-wasi`로 타겟을 추가하세요.
:::

[Rust 파일](https://github.com/annotell/kognic-io-examples-python/tree/master/examples/calibration/custom/pinhole.rs)은 다음과 같이 컴파일할 수 있습니다.

```bash
kognicutil wasm compile path/to/source.rs path/to/output.wasm
```

`panics`는 지원되지 않으며 코드에 포함되어 있으면 컴파일이 실패한다는 점에 유의하세요.

### Cargo를 사용한 Rust

:::hint{type="info"}
### 참고

이를 위해서는 `wasm32-wasi` 타겟과 함께 Rust와 Cargo가 설치되어 있어야 합니다. [여기](https://doc.rust-lang.org/cargo/getting-started/installation.html)의 안내에 따라 Rust와 Cargo를 설치한 다음 `rustup target add wasm32-wasi`로 타겟을 추가하세요.
:::

[Cargo를 사용한 Rust 모듈](https://github.com/annotell/kognic-io-examples-python/tree/master/examples/calibration/custom/pinhole-rust-cargo)은 다음과 같이 컴파일할 수 있습니다.

```bash
kognicutil wasm compile path/to/source/Cargo.toml path/to/output.wasm
```

라이브러리가 `cdylib`임을 명시하는 것이 중요하며, WebAssembly 모듈의 크기를 줄이기 위해 `strip = true`를 설정하는 것도 권장됩니다. 이는 `Cargo.toml` 파일에 다음을 추가하여 수행합니다.

```toml
[lib]
crate-type = ["cdylib"]

[profile.release]
strip = true
```

### 예제: C++

:::hint{type="info"}
### 참고

이를 위해서는 Emscripten이 설치되어 있어야 하며, [여기](https://emscripten.org/docs/getting_started/downloads.html)의 안내에 따라 설치할 수 있습니다.
:::

[C++ 파일](https://github.com/annotell/kognic-io-examples-python/tree/master/examples/calibration/custom/pinhole.cc)은 다음과 같이 컴파일할 수 있습니다.

```bash
kognicutil wasm compile path/to/source.cc path/to/output.wasm
```

또는 다음과 같이도 가능합니다.

```bash
kognicutil wasm compile path/to/source.cpp path/to/output.wasm
```

### 예제: C

:::hint{type="info"}
### 참고

이를 위해서는 Emscripten이 설치되어 있어야 하며, [여기](https://emscripten.org/docs/getting_started/downloads.html)의 안내에 따라 설치할 수 있습니다.
:::

[C 파일](https://github.com/annotell/kognic-io-examples-python/tree/master/examples/calibration/custom/pinhole.c)은 다음과 같이 컴파일할 수 있습니다.

```bash
kognicutil wasm compile path/to/source.c path/to/output.wasm
```
