# ImageManip

ImageManip 节点可用于裁剪、旋转、翻转、调整大小、缩放、转换（类型）和变换
[ImgFrame](https://docs.luxonis.com/software-v3/depthai/depthai-components/messages/img_frame.md)。

它是 [ImageManip (v1)](https://docs.luxonis.com/software-v3/depthai/depthai-components/nodes/image_manip.md) 的更新版本，具有更清晰/更简洁的 API
和更多功能。

## 如何放置

#### Python

```python
with dai.Pipeline() as pipeline:
    manip = pipeline.create(dai.node.ImageManip)
```

#### C++

```cpp
dai::Pipeline pipeline;
auto manip = pipeline.create<dai::node::ImageManip>();
```

## 输入与输出

## 用法

#### Python

```python
pipeline = dai.Pipeline()
manip = pipeline.create(dai.node.ImageManip)

manip.initialConfig.setResize(300, 300, dai.ImageManipConfig.ResizeMode.STRETCH)
manip.initialConfig.setFrameType(dai.ImgFrame.Type.BGR888p)
```

#### C++

```cpp
dai::Pipeline pipeline;
auto manip = pipeline.create<dai::node::ImageManip>();

manip->initialConfig.setResize(300, 300, dai::ImageManipConfig::ResizeMode::STRETCH);
manip->initialConfig.setFrameType(dai::ImgFrame::Type::BGR888p);
```

## 支持的图像格式

ImageManip 节点支持以下图像格式（更多信息参见[此 PR](https://github.com/luxonis/depthai-core/pull/444)）：

 * 支持的输入格式：RGB/BGR、平面/交错、YUV/NV12、RAW8 和 GRAY8
 * 转换为上述任何其他格式
 * 支持 RAW16（uint16，depth 输出），但不具备颜色转换能力

请注意，平面格式处理速度更快，因此应避免使用交错图像（例如 NV12 输入）。

## 操作顺序

操作顺序很重要，因为操作是按设置顺序应用的。例如下面的示例（来自 [ImageManip
多操作](https://docs.luxonis.com/software-v3/depthai/examples/image_manip/image_manip_multi_ops.md)）会先裁剪图像，然后垂直翻转：

```python
manip = pipeline.create(dai.node.ImageManip)
manip.initialConfig.addCrop(50, 100, 500, 500)
manip.initialConfig.addFlipVertical()
```

## 调整大小与宽高比处理

当您的神经网络期望的宽高比与相机传感器不同时（例如 NN 期望 1:1，但传感器输出 4:3），您有三种主要选择：裁剪图像、拉伸图像或添加黑边（letterbox）。

要使用 ImageManip 调整图像大小以用于神经网络输入或其他处理，请使用：

```python
manip = pipeline.create(dai.node.ImageManip)
manip.initialConfig.setOutputSize(width, height, dai.ImageManipConfig.ResizeMode)
```

可用的调整大小模式

| 模式 | 保留宽高比 | 全视场角 | 优点 | 缺点 |
| --- | --- | --- | --- | --- |
| `CENTER_CROP` | 是 | 否 | 对 NN 准确性最佳；保留宽高比 | 裁剪图像；减少视场角 |
| `LETTERBOX` | 是 | 是 | 保留宽高比和全视场角 | 添加填充；NN 图像区域较小；可能降低 NN 准确性 |
| `STRETCH` | 否 | 是 | 保留全视场角 | 不保留宽高比；可能降低 NN 准确性 |

这些模式适用于处理 NN 输入形状与传感器原生宽高比不同的情况。更多信息请参阅[NN
分辨率技术](https://docs.luxonis.com/software-v3/depthai/tutorials/resolution-techniques.md)。

## 限制

除了上述提到的限制（不支持的帧格式）之外，还有其他限制：

 * 由于硬件 warp 约束，旋转/扭曲只能应用于宽度值为 16 的倍数的帧
 * 帧的最大输出宽度为 4056 像素

## 功能示例

 * [ImageManip 多操作](https://docs.luxonis.com/software-v3/depthai/examples/image_manip/image_manip_multi_ops.md) - 依次使用多个操作（顺序重要）
 * [ImageManip 所有操作](https://docs.luxonis.com/software-v3/depthai/examples/image_manip/image_manip_all_ops.md) - 展示所有可用操作
 * [ImageManip 调整大小](https://docs.luxonis.com/software-v3/depthai/examples/image_manip/image_manip_resize.md) - 将输入图像调整为 300x300 帧
 * [ImageManip 重映射](https://docs.luxonis.com/software-v3/depthai/examples/image_manip/image_manip_remap.md) - 使用 ImageManip
   修改帧并相应地重映射矩形。

## 参考

### dai::node::ImageManip

Kind: class

ImageManip node. Capability to crop, resize, warp, ... incoming image frames.

#### ImageManipProperties::Backend Backend

Kind: enum

#### ImageManipProperties::PerformanceMode PerformanceMode

Kind: enum

#### std::shared_ptr< ImageManipConfig > initialConfig

Kind: variable

Initial config to use when manipulating frames

#### Input inputConfig

Kind: variable

Input ImageManipConfig message with ability to modify parameters in runtime

#### Input inputImage

Kind: variable

Input image to be modified

#### Output out

Kind: variable

Outputs ImgFrame message that carries modified image.

#### ImageManip()

Kind: function

#### ImageManip(std::unique_ptr< Properties > props)

Kind: function

#### std::shared_ptr< ImageManip > build()

Kind: function

#### void setNumFramesPool(int numFramesPool)

Kind: function

Specify number of frames in pool. parameters: numFramesPool: How many frames should the pool have

#### void setMaxOutputFrameSize(int maxFrameSize)

Kind: function

Specify maximum size of output image. parameters: maxFrameSize: Maximum frame size in bytes

#### ImageManip & setRunOnHost(bool runOnHost)

Kind: function

Specify whether to run on host or device parameters: runOnHost: Run node on host

#### ImageManip & setBackend(Backend backend)

Kind: function

Set backend preference: CPU: Run ImageManip on the CPU.; HW: Prefer the dedicated hardware image manipulation backend.; GPU:
Prefer the GPU backend.; AUTO: Let the runtime select the backend automatically (GPU with CPU fallback). Hardware-accelerated
backends can cause some unexpected behavior when using multiple ImageManip nodes in series. Currently, the only operation affected
is downscaling. parameters: backend: Backend preference

#### ImageManip & setPerformanceMode(PerformanceMode performanceMode)

Kind: function

Set performance mode parameters: performanceMode: Performance mode

#### bool runOnHost()

Kind: function

Check if the node is set to run on host

#### void run()

Kind: function

#### DeviceNodeCRTP()

Kind: function

#### DeviceNodeCRTP(const std::shared_ptr< Device > & device)

Kind: function

#### DeviceNodeCRTP(std::unique_ptr< Properties > props)

Kind: function

#### DeviceNodeCRTP(std::unique_ptr< Properties > props, bool confMode)

Kind: function

#### DeviceNodeCRTP(const std::shared_ptr< Device > & device, std::unique_ptr< Properties > props, bool confMode)

Kind: function

### 需要帮助？

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