# ImageManip multiple operations

This example showcases multiple [ImageManip](https://docs.luxonis.com/software-v3/depthai/depthai-components/nodes/image_manip.md)
operations in a row (one after another):

 * Resizing ([resize mode: letterbox](https://docs.luxonis.com/software-v3/depthai/tutorials/resolution-techniques.md))
 * Cropping
 * Vertical flipping
 * Changing of frame type (NV12)

All of this is done within the single ImageManip node in the pipeline. Note that operations order is important, as operations are
applied in the order they are set.

## Demo

This example requires the DepthAI v3 API, see [installation instructions](https://docs.luxonis.com/software-v3/depthai.md).

## Pipeline

## Source code

#### Python

```python
import depthai as dai
import cv2

pipeline = dai.Pipeline()

camRgb = pipeline.create(dai.node.Camera).build(dai.CameraBoardSocket.CAM_A)
manip = pipeline.create(dai.node.ImageManip)

manip.initialConfig.setOutputSize(1270, 710, dai.ImageManipConfig.ResizeMode.LETTERBOX)
manip.initialConfig.addCrop(50, 100, 500, 500)
manip.initialConfig.addFlipVertical()
manip.initialConfig.setFrameType(dai.ImgFrame.Type.NV12)
manip.setMaxOutputFrameSize(2709360)

camRgb.requestOutput((1920, 1080)).link(manip.inputImage)

out = manip.out.createOutputQueue()

pipeline.start()

print(manip.initialConfig)

while True:
    inFrame = out.get()
    if inFrame is not None:
        cv2.imshow("Show frame", inFrame.getCvFrame())
        key = cv2.waitKey(1)
        if key == ord('q'):
            break
```

#### C++

```cpp
#include <atomic>
#include <csignal>
#include <memory>

#include "depthai/depthai.hpp"
#include "depthai/pipeline/datatype/ImgFrame.hpp"
#include "depthai/pipeline/node/host/Display.hpp"

std::atomic<bool> quitEvent(false);

void signalHandler(int) {
    quitEvent = true;
}

int main(int argc, char** argv) {
    signal(SIGTERM, signalHandler);
    signal(SIGINT, signalHandler);

    std::shared_ptr<dai::Device> device = nullptr;
    if(argc <= 1) {
        device = std::make_shared<dai::Device>();
    } else {
        device = std::make_shared<dai::Device>(argv[1]);
    }
    dai::Pipeline pipeline(device);

    auto camRgb = pipeline.create<dai::node::Camera>()->build(dai::CameraBoardSocket::CAM_A);
    auto manip = pipeline.create<dai::node::ImageManip>();

    manip->setMaxOutputFrameSize(4000000);
    manip->initialConfig->setOutputSize(1280, 720, dai::ImageManipConfig::ResizeMode::LETTERBOX);
    manip->initialConfig->setBackgroundColor(100, 100, 100);
    manip->initialConfig->addRotateDeg(45);
    manip->initialConfig->addCrop(100, 100, 800, 600);
    manip->initialConfig->addFlipVertical();
    manip->initialConfig->setFrameType(dai::ImgFrame::Type::RGB888p);

    auto* rgbOut = camRgb->requestOutput({1920, 1080});
    rgbOut->link(manip->inputImage);
    auto outputQueue = manip->out.createOutputQueue();
    pipeline.start();
    while(pipeline.isRunning() && !quitEvent) {
        auto imgFrame = outputQueue->get<dai::ImgFrame>();
        cv::imshow("Manipulated Frame", imgFrame->getCvFrame());
        int key = cv::waitKey(1);
        if(key == 'q') {
            break;
        }
    }

    pipeline.stop();
    pipeline.wait();

    return 0;
}
```

### Need assistance?

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