# RGB-D

RGBD 指的是同时包含颜色 (RGB) 和深度 (D) 信息的图像数据类型。

### RGB-D 的应用

### 彩色点云

在设备上生成点云

[彩色点云](https://docs.luxonis.com/software/depthai/examples/pointcloud_visualization.md)

### 空间 AI

将深度与神经网络结合

[空间 AI](https://docs.luxonis.com/software/perception/spatial-ai.md)

## 对齐 RGB 和深度图像

RGB-D 流水线的核心要素是对齐。其思路是将深度图像中的每个像素与彩色图像中对应的像素对齐。这是必要的，因为由于相机位置不同，深度图像的视角与彩色图像的视角存在差异。

对齐可以通过重投影实现。默认情况下，在立体匹配过程中，深度会与 rectified_left 图像对齐。我们可以将该图像投影到 3D 空间（利用获取的深度信息），然后使用彩色相机内参将其重新投影回彩色图像平面。

## 使用 DepthAI 进行对齐

DepthAI 提供了几种实现 RGB 和深度图像对齐的方法，它们功能相同，但各有优劣。

### StereoDepth - 用于立体相机

[StereoDepth](https://docs.luxonis.com/software/depthai-components/nodes/stereo_depth.md) 节点开箱即用地提供了对齐功能。该节点接收一对立体图像（left 和
right），并输出深度图。默认情况下，深度图像与 rectified_left 图像对齐，但可以使用 setDepthAlign() 方法更改。

```python
stereo.setDepthAlign(dai.CameraBoardSocket.RGB) # 假设 RGB 相机连接到 RGB/CAM_A 端口
```

### 示例

 * [RGB 深度对齐](https://docs.luxonis.com/software/depthai/examples/rgb_depth_aligned.md)

### ImageAlign - 通用对齐

[ImageAlign](https://docs.luxonis.com/software/depthai-components/nodes/image_align.md) 节点是一个更通用的节点，可用于对齐任意两个图像。该节点接收两个图像（input 和
inputAlignTo），并输出对齐后的图像。对于 RGB-D，该节点允许我们将[飞行时间 (ToF)
深度](https://docs.luxonis.com/hardware/platform/features/depth.md#Depth%20Perception-Time-of-Flight%20Depth)对齐到 RGB。

### 示例

 * [RGB-ToF 对齐](https://docs.luxonis.com/software/depthai/examples/tof_align.md)
 * [RGB-立体对齐](https://github.com/luxonis/depthai-python/blob/main/examples/ImageAlign/depth_align.py)

> **效率**
> 对于立体相机，请使用
> [StereoDepth](https://docs.luxonis.com/software/depthai-components/nodes/stereo_depth.md)
> 节点，因为其在重投影步骤中进行了优化，比使用
> [ImageAlign](https://docs.luxonis.com/software/depthai-components/nodes/image_align.md)
> 更高效。

### 广角相机上的 RGB-D

使用广角相机时，由于镜头引起的大畸变，对齐可能会很棘手。默认情况下，深度图像在校正-去畸变过程中会被去畸变，但彩色图像不会。这可能导致两幅图像之间的错位。为了解决这个问题，彩色图像也需要进行去畸变。

### 使用 Camera 节点

使用 [Camera](https://docs.luxonis.com/software/depthai-components/nodes/camera.md) 节点。该节点可以使用相机的内参对彩色图像进行去畸变。

#### Python

```python
cam = pipeline.create(dai.node.Camera)
cam.setBoardSocket(dai.CameraBoardSocket.RGB)
cam.setMeshSource(dai.CameraProperties.WarpMeshSource.CALIBRATION)
```

#### C++

```cpp
auto cam = pipeline.create<dai::node::Camera>();
cam->setBoardSocket(dai::CameraBoardSocket::RGB);
cam->setMeshSource(dai::CameraProperties::WarpMeshSource::CALIBRATION);
```

### 手动去畸变

可以使用相机的内参和 OpenCV 手动进行去畸变。

```python
alpha = 0
stereo.setAlphaScaling(alpha)

rgb_w = camRgb.getResolutionWidth()
rgb_h = camRgb.getResolutionHeight()
rgbIntrinsics = np.array(calibData.getCameraIntrinsics(rgbCamSocket, rgb_w, rgb_h))
rgb_d = np.array(calibData.getDistortionCoefficients(rgbCamSocket))
rgb_new_cam_matrix, _ = cv2.getOptimalNewCameraMatrix(rgbIntrinsics, rgb_d, (rgb_w, rgb_h), alpha)
map_x, map_y = cv2.initUndistortRectifyMap(rgbIntrinsics, rgb_d, None, rgb_new_cam_matrix, (rgb_w, rgb_h), cv2.CV_32FC1)

frameRgb = cv2.remap(frameRgb, map_x, map_y, cv2.INTER_LINEAR)
```

### 完整代码

使用 OpenCV 去畸变的示例

[完整代码](https://gist.githubusercontent.com/Erol444/bf0fa3debde7e4479477b03e1a98867e/raw/7541837302af9c7b304a50102eb64ce8c938c8fa/rgb-depth-align-alpha1.py)

### Alpha 与最大化 FOV

对广角相机拍摄的图像进行去畸变时，畸变校正会导致图像的部分区域被裁剪。这会导致视野 (FOV) 的损失，而 FOV 正是使用广角相机的主要优势。为了最大化 FOV，可以使用 alpha 参数 [0-1] 来缩放去畸变后的图像
[[指南](https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html)]。

### 设置 alpha 参数

 * alpha = 0 - 无缩放，去畸变后的图像与原始图像尺寸相同。

 * alpha = 1 - 最大缩放，去畸变后的图像是能容纳在原始图像中的最大可能图像。

#### StereoDepth 去畸变

```python
stereo.setAlphaScaling(alpha)
```

#### Camera 去畸变

```python
camRgb.setCalibrationAlpha(alpha)
```

#### OpenCV 去畸变

```python
rgb_new_cam_matrix, _ = cv2.getOptimalNewCameraMatrix(rgbIntrinsics, rgb_d, (rgb_w, rgb_h), alpha)
```

### 需要帮助？

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