# 校准读取器

本示例展示如何读取通过 XLink 存储在设备上的校准数据。该示例将打印相机的外参和内参参数，以及写入设备（EEPROM）的其他校准值。

### 相似示例

 * [校准闪存 v5](https://docs.luxonis.com/software/depthai/examples/calibration_flash_v5.md)
 * [校准闪存](https://docs.luxonis.com/software/depthai/examples/calibration_flash.md)
 * [校准加载](https://docs.luxonis.com/software/depthai/examples/calibration_load.md)

## 相机内参

校准数据还包含相机的内参和外参参数。

```bash
import depthai as dai

with dai.Device() as device:
  calibData = device.readCalibration()
  intrinsics = calibData.getCameraIntrinsics(dai.CameraBoardSocket.RIGHT)
  print('右侧单目相机焦距（像素）：', intrinsics[0][0])
```

以下是焦距（像素）的理论计算公式：

```python
f_x = width * (1 / (2 * math.tan((HFOV / 2) * (math.pi / 180))))
```

要获取 HFOV，你可以使用[这个脚本](https://gist.github.com/Erol444/4aff71f4576637624d56dce4a60ad62e)，它也适用于广角相机，并且允许你指定 alpha 参数。

在 400P（640x400）相机分辨率下，HFOV=71.9 度：

```code
f_x_640 = 640 * (1 / (2 * math.tan((71.9 / 2) * (math.pi / 180))))  # = 441.25
```

在 800P（1280x800）相机分辨率下，HFOV=71.9 度：

```code
f_x_1280 = 1280 * (1 / (2 * math.tan((71.9 / 2) * (math.pi / 180))))  # = 882.5
```

## 设置

请运行[安装脚本](https://github.com/luxonis/depthai-python/blob/main/examples/install_requirements.py)以下载所有必需的依赖项。请注意，此脚本必须在 git
上下文中运行，因此您需要先下载 [depthai-python](https://github.com/luxonis/depthai-python) 仓库，然后运行该脚本。

```bash
git clone https://github.com/luxonis/depthai-python.git
cd depthai-python/examples
python3 install_requirements.py
```

更多信息，请参考[安装指南](https://docs.luxonis.com/software/depthai/manual-install.md)。

## 源代码

#### Python

```python
#!/usr/bin/env python3

import depthai as dai
import numpy as np
import sys
from pathlib import Path

# Connect Device
with dai.Device() as device:
    calibFile = str((Path(__file__).parent / Path(f"calib_{device.getMxId()}.json")).resolve().absolute())
    if len(sys.argv) > 1:
        calibFile = sys.argv[1]

    calibData = device.readCalibration()
    calibData.eepromToJsonFile(calibFile)

    M_rgb, width, height = calibData.getDefaultIntrinsics(dai.CameraBoardSocket.CAM_A)
    print("RGB Camera Default intrinsics...")
    print(M_rgb)
    print(width)
    print(height)

    if "OAK-1" in calibData.getEepromData().boardName or "BW1093OAK" in calibData.getEepromData().boardName:
        M_rgb = np.array(calibData.getCameraIntrinsics(dai.CameraBoardSocket.CAM_A, 1280, 720))
        print("RGB Camera resized intrinsics...")
        print(M_rgb)

        D_rgb = np.array(calibData.getDistortionCoefficients(dai.CameraBoardSocket.CAM_A))
        print("RGB Distortion Coefficients...")
        [print(name + ": " + value) for (name, value) in
         zip(["k1", "k2", "p1", "p2", "k3", "k4", "k5", "k6", "s1", "s2", "s3", "s4", "τx", "τy"],
             [str(data) for data in D_rgb])]

        print(f'RGB FOV {calibData.getFov(dai.CameraBoardSocket.CAM_A)}')

    else:
        M_rgb, width, height = calibData.getDefaultIntrinsics(dai.CameraBoardSocket.CAM_A)
        print("RGB Camera Default intrinsics...")
        print(M_rgb)
        print(width)
        print(height)

        M_rgb = np.array(calibData.getCameraIntrinsics(dai.CameraBoardSocket.CAM_A, 3840, 2160))
        print("RGB Camera resized intrinsics... 3840 x 2160 ")
        print(M_rgb)

        M_rgb = np.array(calibData.getCameraIntrinsics(dai.CameraBoardSocket.CAM_A, 4056, 3040 ))
        print("RGB Camera resized intrinsics... 4056 x 3040 ")
        print(M_rgb)

        M_left, width, height = calibData.getDefaultIntrinsics(dai.CameraBoardSocket.CAM_B)
        print("LEFT Camera Default intrinsics...")
        print(M_left)
        print(width)
        print(height)

        M_left = np.array(calibData.getCameraIntrinsics(dai.CameraBoardSocket.CAM_B, 1280, 720))
        print("LEFT Camera resized intrinsics...  1280 x 720")
        print(M_left)

        M_right = np.array(calibData.getCameraIntrinsics(dai.CameraBoardSocket.CAM_C, 1280, 720))
        print("RIGHT Camera resized intrinsics... 1280 x 720")
        print(M_right)

        D_left = np.array(calibData.getDistortionCoefficients(dai.CameraBoardSocket.CAM_B))
        print("LEFT Distortion Coefficients...")
        [print(name+": "+value) for (name, value) in zip(["k1","k2","p1","p2","k3","k4","k5","k6","s1","s2","s3","s4","τx","τy"],[str(data) for data in D_left])]

        D_right = np.array(calibData.getDistortionCoefficients(dai.CameraBoardSocket.CAM_C))
        print("RIGHT Distortion Coefficients...")
        [print(name+": "+value) for (name, value) in zip(["k1","k2","p1","p2","k3","k4","k5","k6","s1","s2","s3","s4","τx","τy"],[str(data) for data in D_right])]

        print(f"RGB FOV {calibData.getFov(dai.CameraBoardSocket.CAM_A)}, Mono FOV {calibData.getFov(dai.CameraBoardSocket.CAM_B)}")

        R1 = np.array(calibData.getStereoLeftRectificationRotation())
        R2 = np.array(calibData.getStereoRightRectificationRotation())
        M_right = np.array(calibData.getCameraIntrinsics(calibData.getStereoRightCameraId(), 1280, 720))

        H_left = np.matmul(np.matmul(M_right, R1), np.linalg.inv(M_left))
        print("LEFT Camera stereo rectification matrix...")
        print(H_left)

        H_right = np.matmul(np.matmul(M_right, R1), np.linalg.inv(M_right))
        print("RIGHT Camera stereo rectification matrix...")
        print(H_right)

        lr_extrinsics = np.array(calibData.getCameraExtrinsics(dai.CameraBoardSocket.CAM_B, dai.CameraBoardSocket.CAM_C))
        print("Transformation matrix of where left Camera is W.R.T right Camera's optical center")
        print(lr_extrinsics)

        l_rgb_extrinsics = np.array(calibData.getCameraExtrinsics(dai.CameraBoardSocket.CAM_B, dai.CameraBoardSocket.CAM_A))
        print("Transformation matrix of where left Camera is W.R.T RGB Camera's optical center")
        print(l_rgb_extrinsics)
```

#### C++

```cpp
#include <cstdio>
#include <iostream>
#include <string>

// Includes common necessary includes for development using depthai library
#include "depthai-shared/common/CameraBoardSocket.hpp"
#include "depthai-shared/common/EepromData.hpp"
#include "depthai/depthai.hpp"

void printMatrix(std::vector<std::vector<float>> matrix) {
    using namespace std;
    std::string out = "[";
    for(auto row : matrix) {
        out += "[";
        for(auto val : row) out += to_string(val) + ", ";
        out = out.substr(0, out.size() - 2) + "]\n";
    }
    out = out.substr(0, out.size() - 1) + "]\n\n";
    cout << out;
}

int main(int argc, char** argv) {
    using namespace std;

    // Connect Device
    dai::Device device;

    dai::CalibrationHandler calibData = device.readCalibration();
    // calibData.eepromToJsonFile(filename);
    std::vector<std::vector<float>> intrinsics;
    int width, height;

    cout << "Intrinsics from defaultIntrinsics function:" << endl;
    std::tie(intrinsics, width, height) = calibData.getDefaultIntrinsics(dai::CameraBoardSocket::CAM_C);
    printMatrix(intrinsics);

    cout << "Width: " << width << endl;
    cout << "Height: " << height << endl;

    cout << "Stereo baseline distance: " << calibData.getBaselineDistance() << " cm" << endl;

    cout << "Mono FOV from camera specs: " << calibData.getFov(dai::CameraBoardSocket::CAM_B)
         << ", calculated FOV: " << calibData.getFov(dai::CameraBoardSocket::CAM_B, false) << endl;

    cout << "Intrinsics from getCameraIntrinsics function full resolution:" << endl;
    intrinsics = calibData.getCameraIntrinsics(dai::CameraBoardSocket::CAM_C);
    printMatrix(intrinsics);

    cout << "Intrinsics from getCameraIntrinsics function 1280 x 720:" << endl;
    intrinsics = calibData.getCameraIntrinsics(dai::CameraBoardSocket::CAM_C, 1280, 720);
    printMatrix(intrinsics);

    cout << "Intrinsics from getCameraIntrinsics function 720 x 450:" << endl;
    intrinsics = calibData.getCameraIntrinsics(dai::CameraBoardSocket::CAM_C, 720);
    printMatrix(intrinsics);

    cout << "Intrinsics from getCameraIntrinsics function 600 x 1280:" << endl;
    intrinsics = calibData.getCameraIntrinsics(dai::CameraBoardSocket::CAM_C, 600, 1280);
    printMatrix(intrinsics);

    std::vector<std::vector<float>> extrinsics;

    cout << "Extrinsics from left->right test:" << endl;
    extrinsics = calibData.getCameraExtrinsics(dai::CameraBoardSocket::CAM_B, dai::CameraBoardSocket::CAM_C);
    printMatrix(extrinsics);

    cout << "Extrinsics from right->left test:" << endl;
    extrinsics = calibData.getCameraExtrinsics(dai::CameraBoardSocket::CAM_C, dai::CameraBoardSocket::CAM_B);
    printMatrix(extrinsics);

    cout << "Extrinsics from right->rgb test:" << endl;
    extrinsics = calibData.getCameraExtrinsics(dai::CameraBoardSocket::CAM_C, dai::CameraBoardSocket::CAM_A);
    printMatrix(extrinsics);

    cout << "Extrinsics from rgb->right test:" << endl;
    extrinsics = calibData.getCameraExtrinsics(dai::CameraBoardSocket::CAM_A, dai::CameraBoardSocket::CAM_C);
    printMatrix(extrinsics);

    cout << "Extrinsics from left->rgb test:" << endl;
    extrinsics = calibData.getCameraExtrinsics(dai::CameraBoardSocket::CAM_B, dai::CameraBoardSocket::CAM_A);
    printMatrix(extrinsics);

    return 0;
}
```

### 需要帮助？

请前往 [OAKChina 官网](https://www.oakchina.cn/) 获取技术支持或解答您的任何疑问。
