DepthAI
Software Stack

ON THIS PAGE

  • Demo
  • Pipeline
  • Source code

Undistort camera stream

Supported on:RVC2RVC4
This example shows how to undistort a wide FOV camera stream using the Camera node. Undistortion is not automatic; it is enabled per output with requestOutput(..., enableUndistortion=True) (or requestFullResolutionOutput). Any requested output can be undistorted this way.Notes:
  • Undistortion does not change the stored camera intrinsics, and there is no exposed "alpha" or equivalent to tune the undistortion crop.
  • Undistortion does change the effective FOV; depending on your requested output size and resize mode, you may see less FOV after undistortion.

Demo

This example requires the DepthAI v3 API, see installation instructions.

Pipeline

Source code

Python

Python
GitHub
1#!/usr/bin/env python3
2
3import cv2
4import depthai as dai
5
6# Create pipeline
7with dai.Pipeline() as pipeline:
8    # Define source and output
9    cam = pipeline.create(dai.node.Camera).build(dai.CameraBoardSocket.CAM_B)
10    croppedQueue = cam.requestOutput((300,300), resizeMode=dai.ImgResizeMode.CROP, enableUndistortion=True).createOutputQueue()
11    stretchedQueue = cam.requestOutput((300,300), resizeMode=dai.ImgResizeMode.STRETCH, enableUndistortion=True).createOutputQueue()
12    letterBoxedQueue = cam.requestOutput((300,300), resizeMode=dai.ImgResizeMode.LETTERBOX, enableUndistortion=True).createOutputQueue()
13
14    # Connect to device and start pipeline
15    pipeline.start()
16    while pipeline.isRunning():
17        croppedIn = croppedQueue.get()
18        assert isinstance(croppedIn, dai.ImgFrame)
19        cv2.imshow("cropped undistorted", croppedIn.getCvFrame())
20
21        stretchedIn = stretchedQueue.get()
22        assert isinstance(stretchedIn, dai.ImgFrame)
23        cv2.imshow("stretched undistorted", stretchedIn.getCvFrame())
24
25        letterBoxedIn = letterBoxedQueue.get()
26        assert isinstance(letterBoxedIn, dai.ImgFrame)
27        cv2.imshow("letterboxed undistorted", letterBoxedIn.getCvFrame())
28
29        if cv2.waitKey(1) == ord("q"):
30            break

C++

1#include <atomic>
2#include <csignal>
3#include <iostream>
4#include <memory>
5#include <opencv2/opencv.hpp>
6#include <optional>
7
8#include "depthai/depthai.hpp"
9
10// Global flag for graceful shutdown
11std::atomic<bool> quitEvent(false);
12
13// Signal handler
14void signalHandler(int signum) {
15    quitEvent = true;
16}
17
18int main() {
19    // Set up signal handlers
20    signal(SIGTERM, signalHandler);
21    signal(SIGINT, signalHandler);
22
23    try {
24        // Create pipeline
25        dai::Pipeline pipeline;
26
27        // Define source and outputs
28        auto cam = pipeline.create<dai::node::Camera>();
29        cam->build(dai::CameraBoardSocket::CAM_B, std::nullopt, 30);
30
31        // Create output queues with different resize modes
32        auto croppedQueue = cam->requestOutput(std::make_pair(300, 300), dai::ImgFrame::Type::NV12, dai::ImgResizeMode::CROP, 20, 20)->createOutputQueue();
33
34        auto stretchedQueue = cam->requestOutput(std::make_pair(300, 300), dai::ImgFrame::Type::NV12, dai::ImgResizeMode::STRETCH, 20, 20)->createOutputQueue();
35
36        auto letterBoxedQueue =
37            cam->requestOutput(std::make_pair(300, 300), dai::ImgFrame::Type::NV12, dai::ImgResizeMode::LETTERBOX, 20, 20)->createOutputQueue();
38
39        // Start pipeline
40        pipeline.start();
41
42        // Main loop
43        while(pipeline.isRunning() && !quitEvent) {
44            // Get and show cropped undistorted frame
45            auto croppedIn = croppedQueue->get<dai::ImgFrame>();
46            cv::imshow("cropped undistorted", croppedIn->getCvFrame());
47
48            // Get and show stretched undistorted frame
49            auto stretchedIn = stretchedQueue->get<dai::ImgFrame>();
50            cv::imshow("stretched undistorted", stretchedIn->getCvFrame());
51
52            // Get and show letterboxed undistorted frame
53            auto letterBoxedIn = letterBoxedQueue->get<dai::ImgFrame>();
54            cv::imshow("letterboxed undistorted", letterBoxedIn->getCvFrame());
55
56            // Check for quit key
57            if(cv::waitKey(1) == 'q') {
58                break;
59            }
60        }
61
62        // Cleanup
63        pipeline.stop();
64        pipeline.wait();
65
66    } catch(const std::exception& e) {
67        std::cerr << "Error: " << e.what() << std::endl;
68        return 1;
69    }
70
71    return 0;
72}

Need assistance?

Head over to Discussion Forum for technical support or any other questions you might have.