커스텀 카메라 캘리브레이션
참고
이 기능은 kognic-io 버전 1.8.0에서 새로 추가되었으며 일부 기능은 선택적 의존성이 필요합니다. 설치하려면 pip install kognic-io[wasm]을 실행하세요.
캘리브레이션이 지원되는 표준 카메라 캘리브레이션 목록에 없는 경우, 사용자 정의 캘리브레이션을 제공할 수 있습니다. 아래 표는 CustomCameraCalibration 객체의 속성을 보여줍니다. wasm_base64 속성은 캘리브레이션을 구현하는 WebAssembly 모듈을 base64로 인코딩한 문자열입니다. test_cases 속성은 생성 시 캘리브레이션을 검증하는 데 사용되는 TestCase 객체의 목록입니다. 캘리브레이션이 올바른지 확인할 수 있도록 몇 가지 테스트 케이스를 제공하는 것을 권장합니다.
Key | Value | Parameters |
|---|---|---|
rotation_quaternion | A RotationQuaternion object | w, x, y, z |
position | A Position object | x, y, z |
image_width | Integer | NA |
image_height | Integer | NA |
wasm_base64 | String | NA |
test_cases | A list of TestCase objects | point3d, point2d |
CustomCameraCalibration 객체는 바이너리나 wasm 파일로부터 편리하게 바로 인스턴스화할 수 있습니다.
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 제안을 통해 활성화할 수 있습니다.
만약 포인트가 시야(field of view) 내에 있지 않다면, 해당 함수는 x, y 좌표 모두에 대해 NaN을 반환해야 합니다.
검증
참고
이를 위해서는 kognic-io의 선택적 의존성인 wasmtime이 설치되어 있어야 합니다. 설치하려면 pip install kognic-io[wasm]을 실행하세요.
Python 함수와 kognicutil cli 모두를 통해 검증 코드를 제공합니다. 다음과 같은 항목들을 검증하지만 이에 국한되지는 않습니다.
- 모듈을 로드할 수 있는지
- 함수가 존재하고 시그니처가 올바른지
- 모듈을 사용하여 포인트를 투영할 수 있는지
- 테스트 케이스가 제공된 경우 포인트가 올바르게 투영되는지
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는 다음과 같이 사용할 수 있습니다.
kognicutil wasm validate calibration.wasm컴파일
주의
Rust 1.82.0에서는 여러 값을 함수에서 반환하는 multivalue 기능 타겟에 대한 지원이 제거되었습니다. 이 기능은 현재 사용자 정의 카메라 캘리브레이션이 동작하는 데 필요하므로, Rust 및/또는 Cargo 버전을 1.82.0 미만으로 고정해야 합니다.
참고
wasm 파일은 가능한 한 작게 유지하는 것이 좋습니다. 불필요한 의존성은 피하도록 하세요. 예를 들어 표준 라이브러리를 사용하는 대신 일부 수학 함수를 직접 구현하는 것이 나을 수 있습니다.
위에서 언급했듯이 WebAssembly 모듈은 엄격한 인터페이스를 따라야 하며 컴파일에는 multi-value 제안이 필요합니다. 몇 가지 언어에서 WebAssembly 모듈을 더 쉽게 컴파일할 수 있도록 유틸리티를 제공합니다. 아래 표를 참고하세요.
Language | Target | Compilation tool | Required version |
|---|---|---|---|
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에서는 다음과 같이 모듈을 컴파일할 수 있습니다.
from kognic.io.tools.calibration.compilation import compile_to_wasm
wasm_binary = compile_to_wasm("path/to/source")반환된 바이너리는 CustomCameraCalibration 객체를 생성하는 데 사용할 수 있습니다. output_wasm 파라미터가 전달되면, 바이너리는 지정된 경로에 저장됩니다. kognicutil cli는 다음과 같이 사용할 수 있습니다.
kognicutil wasm compile path/to/source path/to/output.wasm기본적으로 컴파일 후 검증이 실행됩니다. 이는 --skip-validation 플래그로 비활성화할 수 있습니다.
캘리브레이션 파라미터는 WebAssembly 모듈에서 사용할 수 있도록 바이너리에 내장되어야 합니다. 런타임에 투영 함수의 속도를 높이기 위해 가능한 한 많은 것을 사전에 계산해 두세요.
아래는 몇 가지 언어로 단순화한 pinhole 캘리브레이션의 예제입니다.
예제: Rust
참고
이를 위해서는 wasm32-wasi 타겟과 함께 Rust가 설치되어 있어야 합니다. 여기의 안내에 따라 Rust를 설치한 다음 rustup target add wasm32-wasi로 타겟을 추가하세요.
Rust 파일은 다음과 같이 컴파일할 수 있습니다.
kognicutil wasm compile path/to/source.rs path/to/output.wasmpanics는 지원되지 않으며 코드에 포함되어 있으면 컴파일이 실패한다는 점에 유의하세요.
Cargo를 사용한 Rust
참고
이를 위해서는 wasm32-wasi 타겟과 함께 Rust와 Cargo가 설치되어 있어야 합니다. 여기의 안내에 따라 Rust와 Cargo를 설치한 다음 rustup target add wasm32-wasi로 타겟을 추가하세요.
Cargo를 사용한 Rust 모듈은 다음과 같이 컴파일할 수 있습니다.
kognicutil wasm compile path/to/source/Cargo.toml path/to/output.wasm라이브러리가 cdylib임을 명시하는 것이 중요하며, WebAssembly 모듈의 크기를 줄이기 위해 strip = true를 설정하는 것도 권장됩니다. 이는 Cargo.toml 파일에 다음을 추가하여 수행합니다.
[lib]
crate-type = ["cdylib"]
[profile.release]
strip = true예제: C++
참고
이를 위해서는 Emscripten이 설치되어 있어야 하며, 여기의 안내에 따라 설치할 수 있습니다.
C++ 파일은 다음과 같이 컴파일할 수 있습니다.
kognicutil wasm compile path/to/source.cc path/to/output.wasm또는 다음과 같이도 가능합니다.
kognicutil wasm compile path/to/source.cpp path/to/output.wasm예제: C
참고
이를 위해서는 Emscripten이 설치되어 있어야 하며, 여기의 안내에 따라 설치할 수 있습니다.
C 파일은 다음과 같이 컴파일할 수 있습니다.
kognicutil wasm compile path/to/source.c path/to/output.wasm