Multi-Camera Calibration Tutorial

이 튜토리얼에서는 Zivid SDK를 사용하여 여러 대의 카메라를 서로 보정하는 방법을 설명합니다. 이 보정의 결과는 각 카메라에서 기본 카메라로 변환 행렬입니다. 기본 카메라는 기본적으로 연결된 첫 번째 카메라이지만, 일련 번호를 통해 쉽게 제어할 수 있습니다.

Prerequisites

Zivid SDK와 C++ 샘플이 설치되어 있어야 합니다. 자세한 내용은 zivid-cpp-samples 또는 zivid-python-samples 을 참조하세요. 이 튜토리얼에서는 초기화 및 캡처와 같은 SDK의 기본 사항에 대해서는 자세히 다루지 않습니다. 자세한 내용은 Capture Tutorial 을 참조하세요.

Connect to cameras

이 튜토리얼에서는 사용 가능한 모든 카메라에 연결합니다. 다음을 통해 연결할 수 있습니다.

소스로 이동

소스

auto cameras = zivid.cameras();
std::cout << "Number of cameras found: " << cameras.size() << std::endl;

auto connectedCameras = connectToAllAvailableCameras(cameras);
if(connectedCameras.size() < 2)
{
    throw std::runtime_error("At least two cameras need to be connected");
}
std::cout << "Number of connected cameras: " << connectedCameras.size() << std::endl;
소스로 이동

소스

cameras = app.cameras()
print(f"Number of cameras found: {len(cameras)}")

connected_cameras = connect_to_all_available_cameras(cameras)
if len(connected_cameras) < 2:
    raise RuntimeError("At least two cameras need to be connected")
print(f"Number of connected cameras: {len(connected_cameras)}")

Capture calibration object

이제 칼리브레이션 객체를 캡처할 준비가 되었습니다.

샘플에서의 캡처는 특수한 칼리브레이션 보드 캡처 기능을 통해 수행됩니다.

소스로 이동

소스

const auto frame = Zivid::Calibration::captureCalibrationBoard(camera);
소스로 이동

소스

frame = zivid.calibration.capture_calibration_board(camera)

파일에서 포인트 클라우드를 로드할 때 다음 코드 줄을 다음으로 바꾸기만 하면 됩니다.

소스로 이동

소스

const auto frame = Zivid::Frame(fileName);
소스로 이동

소스

frame = zivid.Frame(file_name)

Detect checkerboard feature points

이 튜토리얼에서 사용하는 캘리브레이션 객체는 체커보드입니다. 캘리브레이션을 실행하기 전에 모든 카메라의 체커보드에서 특징점을 검출해야 합니다.

소스로 이동

소스

const auto detectionResult = Zivid::Calibration::detectCalibrationBoard(frame);
소스로 이동

소스

detection_result = zivid.calibration.detect_calibration_board(frame)

이 시점에서 캡처 품질이 충분히 좋은지 확인할 수 있습니다. detectionResult 는 직접 테스트할 수 있는 유형입니다. 이 정보를 제공하기 위해 Bool 연산자를 오버로드합니다. 품질 테스트를 통과하면 감지 결과와 사용된 카메라의 일련 번호를 저장합니다.

소스로 이동

소스

if(detectionResult)
{
    Detection currentDetection(serial, detectionResult);
    detectionsList.push_back(currentDetection);
}
else
{
    throw std::runtime_error(
        "Could not detect checkerboard. Please ensure it is visible from all cameras.");
}
소스로 이동

소스

if detection_result:
    detections_list.append(Detection(serial, detection_result))
else:
    raise RuntimeError("Could not detect checkerboard. Please ensure it is visible from all cameras.")

Perform Multi-Camera Calibration

이제 모든 카메라의 모든 캡처에서 모든 특징점을 감지했으므로 다중 카메라 보정을 수행할 수 있습니다.

소스로 이동

소스

const auto results = Zivid::Calibration::calibrateMultiCamera(detectionResultsList);
소스로 이동

소스

results = zivid.calibration.calibrate_multi_camera(detection_results_list)

반환된 results 를 통해 보정이 성공했는지 직접 확인할 수 있습니다. 다시 말하지만, 이 유형은 bool 연산자를 오버로드합니다.

소스로 이동

소스

if(results)
{
    std::cout << "Multi-camera calibration OK." << std::endl;
}
else
{
    std::cout << "Multi-camera calibration FAILED." << std::endl;
}
소스로 이동

소스

if results:
    print("Multi-camera calibration OK.")
else:
    print("Multi-camera calibration FAILED.")

results 에는 두 개의 벡터가 포함되어 있습니다.

  1. transforms - 모든 변환 행렬을 포함합니다.

  2. residuals - 칼리브레이션 오류 표시가 포함되어 있습니다.

소스로 이동

소스

const auto &transforms = results.transforms();
const auto &residuals = results.residuals();
소스로 이동

소스

transforms = results.transforms()
residuals = results.residuals()

Save transformation matrices to YAML

나중에 결과를 사용할 예정이므로 변환 결과를 YAML 파일에 저장합니다. 이를 위해 API를 사용합니다. 어떤 변환 행렬이 어떤 카메라에 속하는지, 더 정확히는 캘리브레이션 중 카메라의 자세를 추적하는 것이 중요합니다. 따라서 카메라의 일련번호를 식별자로 사용하고 파일 이름에도 사용합니다.

소스로 이동

소스

transforms[i].save(transformationMatricesSavePath + "/" + detectionsList[i].serialNumber + ".yaml");
소스로 이동

소스

assert_affine_matrix_and_save(
    transform, transformation_matrices_save_path / f"{detections_list[i].serial_number}.yaml"
)

Conclusion

이 튜토리얼에서는 Zivid SDK를 사용해 여러 대의 카메라를 보정하는 방법을 보여드립니다. 이제 변환 행렬을 사용하여 여러 카메라의 포인트 클라우드를 스티칭할 수 있습니다. Stitch by Transform Tutorial 을 참조하세요.