DepthAI Core

repository·main·Indexed 43 days ago

https://github.com/luxonis/depthai-core

A C++ library with Python and JavaScript bindings designed to interface with Luxonis DepthAI hardware for advanced computer vision and depth sensing. Includes support for the DynamicCalibration node for live stereo rig calibration, as well as build instructions for depthai-js (WebAssembly) and the DepthAI Python library.

Tokens
15.2K
Snippets
53
Records
77
Agent score
57%

What's inside DepthAI

  1. What's new in the v3 API

    main

    The v3 API introduces several architectural improvements:

    • Automatic XLink: No more explicit XLink nodes required.
    • Host Nodes: Support for nodes running on the host machine, including:
      • ThreadedHostNode: Executes a user-specified run function in a separate thread (similar to ScriptNode).
      • HostNode: Exposes an inputs map with implicitly synced entries.
    • Record-and-replay nodes: New capability for data playback.
    • Live Device Querying: The Pipeline object can query a live device during the creation phase.
    • Model Zoo Support: Integration with the new Model Zoo.
    • Refreshed ImageManip: Improved API with sequential transformation tracking.
    • Unified Camera Node: ColorCamera and MonoCamera are deprecated in favor of the new Camera node.
  2. Understand DepthAI example platform support

    main

    Examples are categorized by the hardware platform they support:

    • Universal Examples: Located in the root examples/ directory, these work on both RVC2 and RVC4 platform devices.
    • Platform-Specific Examples: Located within the RVC2/ or RVC4/ directories, these are optimized for or restricted to a single platform type.
  3. High Frame Rate (HFR) resolutions for IMX586 on RVC4

    main

    When using the IMX586 sensor on the RVC4 platform, High Frame Rate (HFR) mode is available. Currently, HFR mode is restricted to two specific resolution and frame rate combinations. You cannot scale these resolutions arbitrarily or vary the FPS independently without using ImageManip to adjust the output.

    Supported HFR configurations:

    • 1920x1080 @ 240 FPS
    • 1280x720 @ 480 FPS
  4. Transform PointCloud coordinate systems

    main

    The PointCloud node can re-express output points in different coordinate frames using three primary methods:

    1. Camera Board Socket

    Uses extrinsic calibration between cameras. This is the preferred method for using calibrated translations between specific sockets.

    Available sockets: CAM_A through CAM_J.

    // Example: Transform to CAM_A coordinate system
    pc->setTargetCoordinateSystem(dai::CameraBoardSocket::CAM_A);

    Note: The legacy setTargetCoordinateSystem(socket, useSpecTranslation) overload is deprecated.

    2. Housing Coordinate System

    Uses housing calibration stored on the device. This is useful for aligning point clouds with the physical device housing or IMU.

    Available targets include:

    • CAM_A through CAM_J
    • FRONT_CAM_A through FRONT_CAM_J
    • VESA_A through VESA_J
    • IMU
    // Example: Transform to VESA_A coordinate system
    pc->setTargetCoordinateSystem(dai::HousingCoordinateSystem::VESA_A);

    3. Custom 4×4 Matrix

    Apply any homogeneous transform via initialConfig or the runtime inputConfig queue. If a custom matrix is used in conjunction with a Camera Board Socket or Housing Coordinate System, the custom matrix is applied after the calibration-derived transform.

    std::array<std::array<float, 4>, 4> mat = {{ 
        {{ 0.f, -1.f, 0.f, 0.f }}, 
        {{ 1.f,  0.f, 0.f, 0.f }}, 
        {{ 0.f,  0.f, 1.f, 0.f }}, 
        {{ 0.f,  0.f, 0.f, 1.f }}, 
    }};
    pc->initialConfig->setTransformationMatrix(mat);
    // Example of applying a custom 4x4 transformation matrix
    std::array<std::array<float, 4>, 4> mat = {{ 
        {{ 0.f, -1.f, 0.f, 0.f }}, 
        {{ 1.f,  0.f, 0.f, 0.f }}, 
        {{ 0.f,  0.f, 1.f, 0.f }}, 
        {{ 0.f,  0.f, 0.f, 1.f }}, 
    }};
    pc->initialConfig->setTransformationMatrix(mat);
  5. Understand PipelineEvent types and usage

    main

    A PipelineEvent is a data structure used to track various operations within a node. Events are generated via the PipelineEventDispatcher of a node.

    Event Types

    • CUSTOM: User-defined events for tracking specific operations (e.g., custom timings). Must be added manually.
    • LOOP: Tracks main processing loop timings. Can track one loop per node. Generated via mainLoop in simple nodes or tracked events in threaded nodes.
    • INPUT: Automatically tracks input queue operations and states.
    • OUTPUT: Automatically tracks output queue operations and states.
    • INPUT_BLOCK: Tracks a group of input operations. Only one block can be tracked per node; must be added manually.
    • OUTPUT_BLOCK: Tracks a group of output operations. Only one block can be tracked per node; must be added manually.

    Creating Events

    • Manual: Use startEvent and endEvent methods on the dispatcher.
    • Automatic (Block): Use the BlockPipelineEvent helper class (created via the blockEvent method) to automatically trigger a start event in the constructor and an end event in the destructor.
    // Conceptual C++ usage for manual event tracking
    // (Based on PipelineEvent class structure)
    // node.getDispatcher().startEvent(type, source);
    // ... code ...
    // node.getDispatcher().endEvent(type, source);
  6. Understand DynamicCalibration outputs and metrics

    main

    The DynamicCalibration node produces several key data structures for monitoring and evaluating calibration quality.

    CoverageData (coverageOutput)

    Used to monitor how much of the field of view has been adequately observed.

    • meanCoverage: float [0–1] (overall spatial coverage).
    • dataAcquired: float [0–1] (amount of calibration-relevant data gathered).
    • coveragePerCell: dict[CameraBoardSocket, list[list[float]]] (per-sensor coverage matrices).

    DynamicCalibrationResult (calibrationOutput)

    Returned after calibrate() or startCalibration().

    • calibrationData.newCalibration: dai.CalibrationHandler containing the updated parameters.
    • calibrationData.calibrationDifference: Quality deltas between current and new calibration:
      • pairwiseRotationDifference: dict[tuple[CameraBoardSocket, CameraBoardSocket], list[float]] (per-sensor-pair rotation deltas in degrees). This is the preferred field for rotation deltas.
      • sampsonErrorCurrent: float (reprojection error proxy in pixels for current calibration).
      • sampsonErrorNew: float (reprojection error proxy in pixels for the new calibration).
    • info: string (human-readable status, e.g., "success").

    Deprecated Fields

    • CalibrationQuality (qualityOutput): Legacy command; current runtimes return empty results and log warnings. Use DynamicCalibrationResult instead.
    • rotationChange: Legacy aggregate rotation delta. Use pairwiseRotationDifference instead.
    • depthErrorDifference[4]: Deprecated; do not rely on this in new code.
  7. Use experimental Beta features

    main

    The beta namespace contains experimental features that are well-developed but may undergo API or behavioral changes.

    On-device execution: Beta nodes are only supported on-device for RVC4 hardware. On RVC2 hardware, DepthAI automatically configures beta nodes to run on the host CPU.

    C++ Usage:

    auto node = pipeline.create<dai::beta::node::ImgDetectionsFilter>();

    Python Usage:

    node = pipeline.create(dai.beta.node.ImgDetectionsFilter)
  8. Understand device support for beta nodes

    main

    Beta nodes have specific hardware execution requirements:

    • RVC4: Supports full on-device execution of beta nodes.
    • RVC2: Does not support on-device execution for beta nodes. If you attempt to run beta nodes on an RVC2 device, DepthAI will automatically configure them to run on the host instead.
  9. Use the DynamicCalibration node for live stereo calibration

    main

    The dai::node::DynamicCalibration node consumes raw, unrectified mono frames (typically NV12 full-res) to perform live stereo rig calibration. It provides coverage feedback and produces either a new CalibrationHandler to apply to the device or a quality report comparing current vs. achieved calibration.

    Core Workflow

    1. Setup: Link unrectified mono cameras to DynamicCalibration.left/right and StereoDepth.left/right.
    2. Initiate: Send DynamicCalibrationControl::Commands::StartCalibration{} to begin the collection/solve process.
    3. Monitor: Poll coverageOutput for spatial coverage progress and calibrationOutput for results.
    4. Apply: When a result arrives, apply the new parameters using DynamicCalibrationControl::Commands::ApplyCalibration{result.calibrationData->newCalibration}.
    // Example flow snippet
    dai::node::DynamicCalibrationControl::Commands::StartCalibration{} 
    // ... in loop ...
    if (result.calibrationData) {
        controlQueue.send(DynamicCalibrationControl::Commands::ApplyCalibration{result.calibrationData->newCalibration});
    }
  10. Use experimental features in the beta namespace

    main

    The beta namespace provides a staging area for experimental DepthAI features. These features are well-developed but may undergo minor API or behavioral changes between releases without notice.

    Use these features when you need access to cutting-edge functionality that has not yet been promoted to the main depthai namespace.

  11. How Pipeline Event Aggregation and State Merging work

    main

    The debugging system uses a distributed architecture to collect and merge telemetry from the device to the host:

    1. Event Emission: Each node has a pipelineEventOutput that emits PipelineEvent objects via its PipelineEventDispatcher.
    2. PipelineEventAggregation (Device): This node collects events from nodes on the same device. It processes events in batches at fixed intervals to improve performance. It matches START and END interval events using sequence numbers. It can be configured to send state on request or at regular intervals (using the repeat flag).
    3. StateMerge (Host): This node collects PipelineState objects from multiple PipelineEventAggregation nodes (one per device) and merges them into a single unified PipelineState. It uses unique node IDs to combine the maps and matches requests using a configuration sequence number.