# ImageManip

ImageManip node can be used to crop, rotate, flip, resize, scale, convert (type) and transform
[ImgFrames](https://docs.luxonis.com/software-v3/depthai/depthai-components/messages/img_frame.md).

It's an updated version of [ImageManip (v1)](https://docs.luxonis.com/software-v3/depthai/depthai-components/nodes/image_manip.md)
with a cleaner/clearer API and more features.

## How to place it

#### 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>();
```

## Inputs and Outputs

## Usage

#### 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);
```

## Image formats supported

ImageManip node supports the following image formats (more info [in PR here](https://github.com/luxonis/depthai-core/pull/444)):

 * Input formats supported: RGB/BGR, planar/interleaved, YUV/NV12, RAW8 and GRAY8
 * Convert format to any other format mentioned above
 * RAW16 (uint16, depth output) supported, but without color conversion capability

Note that planar formats are faster to process, so interleaved images should be avoided (eg. NV12 input).

## Operations order

Operations order is important, as operations are applied in the order they are set, eg. example below (from [ImageManip Multiple
operations](https://docs.luxonis.com/software-v3/depthai/examples/image_manip/image_manip_multi_ops.md)) will first crop the image
and then flip it vertically:

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

## Resizing and Aspect Ratio Handling

When your neural network expects a different aspect ratio than the camera sensor (e.g., NN expects 1:1 but the sensor outputs
4:3), you have three main options: crop the image, stretch it, or letterbox it.

To resize images for neural network input or other processing with ImageManip, use:

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

Available Resize Modes

| Mode | Preserves AR | Full FOV | Pros | Cons |
| --- | --- | --- | --- | --- |
| `CENTER_CROP` | Yes | No | Best for NN accuracy; preserves AR | Crops image; reduces field of view |
| `LETTERBOX` | Yes | Yes | Preserves AR and full FOV | Adds padding; smaller image area for NN; may reduce NN accuracy |
| `STRETCH` | No | Yes | Preserves full field of view | Aspect ratio not preserved; may reduce NN accuracy |

These modes are useful for handling cases where your NN input shape differs from your sensor's native aspect ratio. See more in
[Resolution Techniques for NNs](https://docs.luxonis.com/software-v3/depthai/tutorials/resolution-techniques.md).

## Limitations

Besides limitations mentioned above (unsupported frame formats), there are other limitations:

 * Due to HW warp constraint, rotating/warping can be done only on frames whose width values are multiples of 16
 * Maximum output width of a frame is 4056 pixels

## Examples of functionality

 * [ImageManip Multiple operations](https://docs.luxonis.com/software-v3/depthai/examples/image_manip/image_manip_multi_ops.md) -
   Uses multiple operations one after another (order matters)
 * [ImageManip All operations](https://docs.luxonis.com/software-v3/depthai/examples/image_manip/image_manip_all_ops.md) -
   Showcases all available operations
 * [ImageManip resize](https://docs.luxonis.com/software-v3/depthai/examples/image_manip/image_manip_resize.md) - Resizes the
   input image to 300x300 frame
 * [ImageManip remap](https://docs.luxonis.com/software-v3/depthai/examples/image_manip/image_manip_remap.md) - Use ImageManip to
   modify a frame and remap a rectangle accordingly.

## Reference

### 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 CPU as backend preference 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

### Need assistance?

Head over to [Discussion Forum](https://discuss.luxonis.com/) for technical support or any other questions you might have.
