此页面由 AI 自动翻译。查看英文原版
DepthAI
软件栈

本页目录

  • 演示
  • 管道
  • 源代码

ImageManip 所有操作

Supported on:RVC2RVC4
展示了所有可用的 ImageManip 操作:
  • 缩放 (conf.setOutputSize())
  • 裁剪 (conf.addCrop())
  • 垂直翻转 (conf.addFlipVertical())
  • 水平翻转 (conf.addFlipHorizontal())
  • 缩放比例 (conf.addScale())
  • 旋转 (conf.addRotateDeg())
  • 变换 (conf.addTransformAffine()conf.addTransformPerspective())
每个操作都在一个单独的 ImageManip 节点上完成,因此您可以分别查看每个操作的效果。

演示

此示例需要 DepthAI v3 API,请参阅 安装说明

管道

源代码

Python

Python
GitHub
1import depthai as dai
2import cv2
3
4pipeline = dai.Pipeline()
5
6manip_input = pipeline.create(dai.node.ImageManip)
7manip_input.initialConfig.setFrameType(dai.ImgFrame.Type.BGR888p)
8inputQueue = manip_input.inputImage.createInputQueue()
9
10manip_ops = [
11    # Resize operations. If aspect ratio isn't the same, the image will be stretched/cropped/letterboxed (depending on resize mode)
12    # Docs here: https://docs.luxonis.com/software/depthai/resolution-techniques/
13    ('resize_stretch', lambda conf: conf.setOutputSize(256, 200, dai.ImageManipConfig.ResizeMode.STRETCH)),
14    ('resize_letterbox', lambda conf: conf.setOutputSize(256, 200, dai.ImageManipConfig.ResizeMode.LETTERBOX)),
15    ('resize_center_crop', lambda conf: conf.setOutputSize(256, 200, dai.ImageManipConfig.ResizeMode.CENTER_CROP)),
16    # Crop the image topLeft (10,40) to bottomRight (310,110)
17    ('crop', lambda conf: conf.addCrop(x=50, y=50, w=150, h=200)),
18    # Flip the frame vertically/horizontally
19    ('flip_vertical', lambda conf: conf.addFlipVertical()),
20    ('flip_horizontal', lambda conf: conf.addFlipHorizontal()),
21    # Scale the image by 0.7x in x and 0.5x in y
22    ('scale', lambda conf: conf.addScale(0.7, 0.5)),
23    # Rotate. If center isn't specified, it will rotate around center (0.5, 0.5)
24    ('rotate_90_deg', lambda conf: conf.addRotateDeg(90)),
25    ('rotate_90_deg_center', lambda conf: conf.addRotateDeg(90, center=dai.Point2f(0.2, 0.3)).setOutputCenter(False)),
26    ('transform_affine', lambda conf: conf.addTransformAffine( # Shearing
27        [1, 0.5,
28         0.2, 1])),
29    ('transform_perspective', lambda conf: conf.addTransformPerspective(
30        [1.0, 0.2, 0.0,  # First row
31        0.1, 1.0, 0.0,  # Second row
32        0.001, 0.002, 1.0])),  # Third row
33    ('frame_type', lambda conf: conf.setFrameType(dai.ImgFrame.Type.RAW8)), # to Grayscale
34]
35
36# Dynamically create ImageManip nodes, apply configurations, and set up queues
37queues = {}
38for name, config in manip_ops:
39    print(name, config)
40    manip = pipeline.create(dai.node.ImageManip)
41    config(manip.initialConfig)
42    manip_input.out.link(manip.inputImage)
43    queues[name] = manip.out.createOutputQueue(maxSize=4, blocking=False)
44
45
46imgFrame = dai.ImgFrame()
47
48input_frame = cv2.imread('../models/lenna.png') # 512x512
49# Send 256x256 image to the device
50imgFrame.setCvFrame(cv2.pyrDown(input_frame), dai.ImgFrame.Type.BGR888i)
51inputQueue.send(imgFrame)
52
53cv2.imshow('input_image', input_frame)
54
55
56pipeline.start()
57
58for name, queue in queues.items():
59    inFrame = queue.get()
60    cv2.imshow(name, inFrame.getCvFrame())
61
62key = cv2.waitKey(0)

C++

1#include <atomic>
2#include <csignal>
3#include <functional>
4#include <iostream>
5#include <map>
6#include <memory>
7#include <opencv2/opencv.hpp>
8
9#include "depthai/depthai.hpp"
10
11std::atomic<bool> quitEvent(false);
12
13void signalHandler(int) {
14    quitEvent = true;
15}
16
17int main() {
18    signal(SIGTERM, signalHandler);
19    signal(SIGINT, signalHandler);
20
21    try {
22        // Create pipeline
23        dai::Pipeline pipeline;
24
25        // Create input manipulator
26        auto manipInput = pipeline.create<dai::node::ImageManip>();
27        manipInput->initialConfig->setFrameType(dai::ImgFrame::Type::BGR888p);
28        auto inputQueue = manipInput->inputImage.createInputQueue();
29
30        // Define manipulation operations
31        std::vector<std::pair<std::string, std::function<void(dai::ImageManipConfig&)>>> manipOps = {
32            // Resize operations
33            {"resize_stretch", [](dai::ImageManipConfig& conf) { conf.setOutputSize(256, 200, dai::ImageManipConfig::ResizeMode::STRETCH); }},
34            {"resize_letterbox", [](dai::ImageManipConfig& conf) { conf.setOutputSize(256, 200, dai::ImageManipConfig::ResizeMode::LETTERBOX); }},
35            {"resize_center_crop", [](dai::ImageManipConfig& conf) { conf.setOutputSize(256, 200, dai::ImageManipConfig::ResizeMode::CENTER_CROP); }},
36            // Crop operation
37            {"crop", [](dai::ImageManipConfig& conf) { conf.addCrop(50, 50, 150, 200); }},
38            // Flip operations
39            {"flip_vertical", [](dai::ImageManipConfig& conf) { conf.addFlipVertical(); }},
40            {"flip_horizontal", [](dai::ImageManipConfig& conf) { conf.addFlipHorizontal(); }},
41            // Scale operation
42            {"scale", [](dai::ImageManipConfig& conf) { conf.addScale(0.7f, 0.5f); }},
43            // Rotate operations
44            {"rotate_90_deg", [](dai::ImageManipConfig& conf) { conf.addRotateDeg(90); }},
45            {"rotate_90_deg_center",
46             [](dai::ImageManipConfig& conf) {
47                 conf.addRotateDeg(90, dai::Point2f(0.2f, 0.3f));
48                 conf.setOutputCenter(false);
49             }},
50            // Transform operations
51            {"transform_affine",
52             [](dai::ImageManipConfig& conf) {
53                 std::array<float, 4> matrix = {1.0f, 0.5f, 0.2f, 1.0f};
54                 conf.addTransformAffine(matrix);
55             }},
56            {"transform_perspective",
57             [](dai::ImageManipConfig& conf) {
58                 std::array<float, 9> matrix = {
59                     1.0f,
60                     0.2f,
61                     0.0f,  // First row
62                     0.1f,
63                     1.0f,
64                     0.0f,  // Second row
65                     0.001f,
66                     0.002f,
67                     1.0f  // Third row
68                 };
69                 conf.addTransformPerspective(matrix);
70             }},
71            // Frame type conversion
72            {"frame_type", [](dai::ImageManipConfig& conf) { conf.setFrameType(dai::ImgFrame::Type::RAW8); }}};
73
74        // Create manipulator nodes and queues
75        std::map<std::string, std::shared_ptr<dai::MessageQueue>> queues;
76        for(const auto& [name, config] : manipOps) {
77            std::cout << "Creating manipulator: " << name << std::endl;
78            auto manip = pipeline.create<dai::node::ImageManip>();
79            config(*manip->initialConfig);
80            manipInput->out.link(manip->inputImage);
81            queues[name] = manip->out.createOutputQueue(4, false);
82        }
83
84        // Load and prepare input image
85        cv::Mat inputFrame = cv::imread(LENNA_PATH);  // 512x512
86        if(inputFrame.empty()) {
87            throw std::runtime_error("Could not read input image");
88        }
89
90        // Create and send input frame
91        auto imgFrame = std::make_shared<dai::ImgFrame>();
92        cv::Mat downscaled;
93        cv::pyrDown(inputFrame, downscaled);
94        imgFrame->setCvFrame(downscaled, dai::ImgFrame::Type::BGR888i);
95        inputQueue->send(imgFrame);
96
97        // Display input image
98        cv::imshow("input_image", inputFrame);
99
100        // Start pipeline
101        pipeline.start();
102
103        // Process and display results
104        for(const auto& [name, queue] : queues) {
105            auto inFrame = queue->get<dai::ImgFrame>();
106            cv::imshow(name, inFrame->getCvFrame());
107        }
108
109        // Wait for key press or signal
110        while(!quitEvent) {
111            if(cv::waitKey(50) >= 0) break;
112        }
113
114        // Cleanup
115        pipeline.stop();
116        pipeline.wait();
117
118    } catch(const std::exception& e) {
119        std::cerr << "Error: " << e.what() << std::endl;
120        return 1;
121    }
122
123    return 0;
124}

需要帮助?

请前往 Discussion Forum 获取技术支持或提出您可能有的任何其他问题。