# Neural Depth

This example demonstrates the [NeuralDepth](https://docs.luxonis.com/software-v3/depthai/depthai-components/nodes/neural_depth.md)
node with runtime configuration of confidence threshold, edge threshold, and temporal filtering.

## Demo

## Pipeline

### examples/neural_depth.pipeline.json

```json
{"pipeline": {"connections": [{"node1Id": 4, "node1Output": "out", "node1OutputGroup": "", "node2Id": 5, "node2Input": "input", "node2InputGroup": ""}, {"node1Id": 7, "node1Output": "out", "node1OutputGroup": "", "node2Id": 3, "node2Input": "nnDataInput", "node2InputGroup": ""}, {"node1Id": 5, "node1Output": "right", "node1OutputGroup": "outputs", "node2Id": 6, "node2Input": "input2", "node2InputGroup": ""}, {"node1Id": 5, "node1Output": "left", "node1OutputGroup": "outputs", "node2Id": 6, "node2Input": "input1", "node2InputGroup": ""}, {"node1Id": 6, "node1Output": "output2", "node1OutputGroup": "", "node2Id": 7, "node2Input": "right", "node2InputGroup": "inputs"}, {"node1Id": 6, "node1Output": "output1", "node1OutputGroup": "", "node2Id": 7, "node2Input": "left", "node2InputGroup": "inputs"}, {"node1Id": 6, "node1Output": "output2", "node1OutputGroup": "", "node2Id": 3, "node2Input": "rightFrameInternal", "node2InputGroup": ""}, {"node1Id": 6, "node1Output": "output1", "node1OutputGroup": "", "node2Id": 3, "node2Input": "leftFrameInternal", "node2InputGroup": ""}, {"node1Id": 1, "node1Output": "0", "node1OutputGroup": "dynamicOutputs", "node2Id": 4, "node2Input": "right", "node2InputGroup": "inputs"}, {"node1Id": 0, "node1Output": "0", "node1OutputGroup": "dynamicOutputs", "node2Id": 4, "node2Input": "left", "node2InputGroup": "inputs"}], "globalProperties": {"calibData": null, "cameraTuningBlobSize": null, "cameraTuningBlobUri": "", "eepromId": 0, "leonCssFrequencyHz": 700000000.0, "leonMssFrequencyHz": 700000000.0, "pipelineName": null, "pipelineVersion": null, "sippBufferSize": 18432, "sippDmaBufferSize": 16384, "xlinkChunkSize": -1}, "nodes": [[7, {"alias": "neuralNetwork", "id": 7, "ioInfo": [[["", "passthrough"], {"blocking": false, "group": "", "id": 36, "name": "passthrough", "queueSize": 8, "type": 0, "waitForMessage": false}], [["inputs", "left"], {"blocking": false, "group": "inputs", "id": 34, "name": "left", "queueSize": 1, "type": 3, "waitForMessage": true}], [["", "out"], {"blocking": false, "group": "", "id": 35, "name": "out", "queueSize": 8, "type": 0, "waitForMessage": false}], [["inputs", "right"], {"blocking": false, "group": "inputs", "id": 33, "name": "right", "queueSize": 1, "type": 3, "waitForMessage": true}], [["", "in"], {"blocking": true, "group": "", "id": 32, "name": "in", "queueSize": 3, "type": 3, "waitForMessage": true}]], "logLevel": 3, "name": "NeuralNetwork", "parentId": 3, "properties": {"backend": "", "backendProperties": {}, "blobSize": null, "blobUri": "", "deviceModel": 0, "modelSource": 0, "modelUri": "", "numFrames": 8, "numNCEPerThread": 0, "numShavesPerThread": 0, "numThreads": 0}}], [6, {"alias": "rectification", "id": 6, "ioInfo": [[["", "output2"], {"blocking": false, "group": "", "id": 31, "name": "output2", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "passthrough2"], {"blocking": false, "group": "", "id": 29, "name": "passthrough2", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "output1"], {"blocking": false, "group": "", "id": 30, "name": "output1", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "input2"], {"blocking": false, "group": "", "id": 27, "name": "input2", "queueSize": 4, "type": 3, "waitForMessage": false}], [["", "passthrough1"], {"blocking": false, "group": "", "id": 28, "name": "passthrough1", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "input1"], {"blocking": false, "group": "", "id": 26, "name": "input1", "queueSize": 4, "type": 3, "waitForMessage": false}]], "logLevel": 3, "name": "Rectification", "parentId": 3, "properties": {"enableRectification": true, "outputHeight": 480, "outputWidth": 768}}], [5, {"alias": "messageDemux", "id": 5, "ioInfo": [[["outputs", "right"], {"blocking": false, "group": "outputs", "id": 24, "name": "right", "queueSize": 8, "type": 0, "waitForMessage": false}], [["outputs", "left"], {"blocking": false, "group": "outputs", "id": 25, "name": "left", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "input"], {"blocking": true, "group": "", "id": 23, "name": "input", "queueSize": 3, "type": 3, "waitForMessage": false}]], "logLevel": 3, "name": "MessageDemux", "parentId": 3, "properties": {"dummy": 0}}], [4, {"alias": "sync", "id": 4, "ioInfo": [[["", "out"], {"blocking": false, "group": "", "id": 22, "name": "out", "queueSize": 8, "type": 0, "waitForMessage": false}], [["inputs", "left"], {"blocking": false, "group": "inputs", "id": 21, "name": "left", "queueSize": 10, "type": 3, "waitForMessage": false}], [["inputs", "right"], {"blocking": false, "group": "inputs", "id": 20, "name": "right", "queueSize": 10, "type": 3, "waitForMessage": false}]], "logLevel": 3, "name": "Sync", "parentId": 3, "properties": {"syncAttempts": -1, "syncThresholdNs": 10000000}}], [3, {"alias": "", "id": 3, "ioInfo": [[["", "confidence"], {"blocking": false, "group": "", "id": 19, "name": "confidence", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "edge"], {"blocking": false, "group": "", "id": 18, "name": "edge", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "depth"], {"blocking": false, "group": "", "id": 17, "name": "depth", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "disparity"], {"blocking": false, "group": "", "id": 16, "name": "disparity", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "rightFrameInternal"], {"blocking": false, "group": "", "id": 15, "name": "rightFrameInternal", "queueSize": 1, "type": 3, "waitForMessage": false}], [["", "leftFrameInternal"], {"blocking": false, "group": "", "id": 14, "name": "leftFrameInternal", "queueSize": 1, "type": 3, "waitForMessage": false}], [["", "nnDataInput"], {"blocking": true, "group": "", "id": 13, "name": "nnDataInput", "queueSize": 5, "type": 3, "waitForMessage": false}], [["", "inputConfig"], {"blocking": true, "group": "", "id": 12, "name": "inputConfig", "queueSize": 5, "type": 3, "waitForMessage": false}]], "logLevel": 3, "name": "NeuralDepth", "parentId": -1, "properties": {"initialConfig": {"algorithmControl": {"customDepthUnitMultiplier": 1000.0, "depthUnit": 2}, "postProcessing": {"confidenceThreshold": 125, "edgeThreshold": 10, "temporalFilter": {"alpha": 0.4000000059604645, "delta": 3, "enable": false, "persistencyMode": 3}}}}}], [2, {"alias": "", "id": 2, "ioInfo": [[["dynamicOutputs", "0"], {"blocking": false, "group": "dynamicOutputs", "id": 11, "name": "0", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "raw"], {"blocking": false, "group": "", "id": 10, "name": "raw", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "mockIsp"], {"blocking": true, "group": "", "id": 9, "name": "mockIsp", "queueSize": 8, "type": 3, "waitForMessage": false}], [["", "inputControl"], {"blocking": true, "group": "", "id": 8, "name": "inputControl", "queueSize": 3, "type": 3, "waitForMessage": false}]], "logLevel": 3, "name": "Camera", "parentId": -1, "properties": {"boardSocket": 0, "cameraName": "", "fps": 10.0, "imageOrientation": -1, "initialControl": {"aeLockMode": false, "aeMaxExposureTimeUs": 256, "aeRegion": {"height": 0, "priority": 0, "width": 24336, "x": 47448, "y": 4828}, "afRegion": {"height": 0, "priority": 0, "width": 0, "x": 0, "y": 0}, "antiBandingMode": 130, "autoFocusMode": 3, "awbLockMode": false, "awbMode": 232, "brightness": 0, "captureIntent": 227, "chromaDenoise": 0, "cmdMask": 0, "contrast": 96, "controlMode": 21, "effectMode": 95, "enableHdr": false, "expCompensation": 0, "expManual": {"exposureTimeUs": 0, "frameDurationUs": 0, "sensitivityIso": 64}, "frameSyncMode": 0, "lensPosAutoInfinity": 64, "lensPosAutoMacro": 0, "lensPosition": 0, "lensPositionRaw": 0.0, "lowPowerNumFramesBurst": 152, "lowPowerNumFramesDiscard": 71, "lumaDenoise": 0, "miscControls": [], "saturation": 0, "sceneMode": 128, "sharpness": 0, "strobeConfig": {"activeLevel": 232, "enable": 0, "gpioNumber": -128}, "strobeTimings": {"durationUs": 0, "exposureBeginOffsetUs": 24341, "exposureEndOffsetUs": 0}, "wbColorTemp": 0}, "isp3aFps": 0, "maxSizePoolIsp": 10485760, "maxSizePoolOutputs": null, "maxSizePoolRaw": 10485760, "mockIspHeight": -1, "mockIspWidth": -1, "numFramesPoolIsp": 3, "numFramesPoolOutputs": null, "numFramesPoolPreview": 4, "numFramesPoolRaw": 3, "numFramesPoolStill": 4, "numFramesPoolVideo": 4, "outputRequests": [{"enableUndistortion": null, "fps": {"value": null}, "resizeMode": 0, "size": {"value": {"index": 0, "value": [768, 480]}}, "type": null}], "resolutionHeight": -1, "resolutionWidth": -1, "sensorType": -1}}], [1, {"alias": "", "id": 1, "ioInfo": [[["dynamicOutputs", "0"], {"blocking": false, "group": "dynamicOutputs", "id": 7, "name": "0", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "raw"], {"blocking": false, "group": "", "id": 6, "name": "raw", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "mockIsp"], {"blocking": true, "group": "", "id": 5, "name": "mockIsp", "queueSize": 8, "type": 3, "waitForMessage": false}], [["", "inputControl"], {"blocking": true, "group": "", "id": 4, "name": "inputControl", "queueSize": 3, "type": 3, "waitForMessage": false}]], "logLevel": 3, "name": "Camera", "parentId": -1, "properties": {"boardSocket": 2, "cameraName": "", "fps": 10.0, "imageOrientation": -1, "initialControl": {"aeLockMode": false, "aeMaxExposureTimeUs": 3816975664, "aeRegion": {"height": 0, "priority": 96, "width": 0, "x": 352, "y": 0}, "afRegion": {"height": 4828, "priority": 24336, "width": 21270, "x": 0, "y": 0}, "antiBandingMode": 130, "autoFocusMode": 3, "awbLockMode": false, "awbMode": 160, "brightness": 0, "captureIntent": 227, "chromaDenoise": 0, "cmdMask": 0, "contrast": 1, "controlMode": 21, "effectMode": 95, "enableHdr": false, "expCompensation": 0, "expManual": {"exposureTimeUs": 3258047490, "frameDurationUs": 0, "sensitivityIso": 0}, "frameSyncMode": 0, "lensPosAutoInfinity": 0, "lensPosAutoMacro": 52, "lensPosition": 0, "lensPositionRaw": 0.0, "lowPowerNumFramesBurst": 121, "lowPowerNumFramesDiscard": 0, "lumaDenoise": 0, "miscControls": [], "saturation": 0, "sceneMode": 108, "sharpness": 0, "strobeConfig": {"activeLevel": 0, "enable": 0, "gpioNumber": 0}, "strobeTimings": {"durationUs": 0, "exposureBeginOffsetUs": 0, "exposureEndOffsetUs": 0}, "wbColorTemp": 0}, "isp3aFps": 0, "maxSizePoolIsp": 10485760, "maxSizePoolOutputs": null, "maxSizePoolRaw": 10485760, "mockIspHeight": -1, "mockIspWidth": -1, "numFramesPoolIsp": 3, "numFramesPoolOutputs": null, "numFramesPoolPreview": 4, "numFramesPoolRaw": 3, "numFramesPoolStill": 4, "numFramesPoolVideo": 4, "outputRequests": [{"enableUndistortion": null, "fps": {"value": null}, "resizeMode": 0, "size": {"value": {"index": 0, "value": [1280, 800]}}, "type": null}], "resolutionHeight": -1, "resolutionWidth": -1, "sensorType": -1}}], [0, {"alias": "", "id": 0, "ioInfo": [[["dynamicOutputs", "0"], {"blocking": false, "group": "dynamicOutputs", "id": 3, "name": "0", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "raw"], {"blocking": false, "group": "", "id": 2, "name": "raw", "queueSize": 8, "type": 0, "waitForMessage": false}], [["", "mockIsp"], {"blocking": true, "group": "", "id": 1, "name": "mockIsp", "queueSize": 8, "type": 3, "waitForMessage": false}], [["", "inputControl"], {"blocking": true, "group": "", "id": 0, "name": "inputControl", "queueSize": 3, "type": 3, "waitForMessage": false}]], "logLevel": 3, "name": "Camera", "parentId": -1, "properties": {"boardSocket": 1, "cameraName": "", "fps": 10.0, "imageOrientation": -1, "initialControl": {"aeLockMode": false, "aeMaxExposureTimeUs": 3395871759, "aeRegion": {"height": 23539, "priority": 1680057611, "width": 27103, "x": 57443, "y": 14509}, "afRegion": {"height": 8229, "priority": 143477788, "width": 58441, "x": 63661, "y": 34201}, "antiBandingMode": 159, "autoFocusMode": 3, "awbLockMode": false, "awbMode": 16, "brightness": -56, "captureIntent": 16, "chromaDenoise": 0, "cmdMask": 0, "contrast": -118, "controlMode": 46, "effectMode": 31, "enableHdr": false, "expCompensation": -85, "expManual": {"exposureTimeUs": 4008679, "frameDurationUs": 2196813195, "sensitivityIso": 238377071}, "frameSyncMode": 243, "lensPosAutoInfinity": 238, "lensPosAutoMacro": 27, "lensPosition": 0, "lensPositionRaw": 0.0, "lowPowerNumFramesBurst": 66, "lowPowerNumFramesDiscard": 21, "lumaDenoise": 0, "miscControls": [], "saturation": 68, "sceneMode": 246, "sharpness": 141, "strobeConfig": {"activeLevel": 31, "enable": 70, "gpioNumber": -56}, "strobeTimings": {"durationUs": 1359893532, "exposureBeginOffsetUs": -1803871563, "exposureEndOffsetUs": 115413366}, "wbColorTemp": 44429}, "isp3aFps": 0, "maxSizePoolIsp": 10485760, "maxSizePoolOutputs": null, "maxSizePoolRaw": 10485760, "mockIspHeight": -1, "mockIspWidth": -1, "numFramesPoolIsp": 3, "numFramesPoolOutputs": null, "numFramesPoolPreview": 4, "numFramesPoolRaw": 3, "numFramesPoolStill": 4, "numFramesPoolVideo": 4, "outputRequests": [{"enableUndistortion": null, "fps": {"value": null}, "resizeMode": 0, "size": {"value": {"index": 0, "value": [1280, 800]}}, "type": null}], "resolutionHeight": -1, "resolutionWidth": -1, "sensorType": -1}}]]}}
```

## Source code

#### Python

```python
#!/usr/bin/env python3

import cv2
import depthai as dai
import numpy as np

FPS = 25
# Create pipeline
with dai.Pipeline() as pipeline:
    cameraLeft = pipeline.create(dai.node.Camera).build(dai.CameraBoardSocket.CAM_B, sensorFps=FPS)
    cameraRight = pipeline.create(dai.node.Camera).build(dai.CameraBoardSocket.CAM_C, sensorFps=FPS)
    leftOutput = cameraLeft.requestFullResolutionOutput()
    rightOutput = cameraRight.requestFullResolutionOutput()

    neuralDepth = pipeline.create(dai.node.NeuralDepth).build(leftOutput, rightOutput, dai.DeviceModelZoo.NEURAL_DEPTH_LARGE)

    confidenceQueue = neuralDepth.confidence.createOutputQueue()
    edgeQueue = neuralDepth.edge.createOutputQueue()
    disparityQueue = neuralDepth.disparity.createOutputQueue()

    inputConfigQueue = neuralDepth.inputConfig.createInputQueue()
    # Connect to device and start pipeline
    pipeline.start()
    maxDisparity = 1
    colorMap = cv2.applyColorMap(np.arange(256, dtype=np.uint8), cv2.COLORMAP_JET)
    colorMap[0] = [0, 0, 0]  # to make zero-disparity pixels black
    currentConfig = neuralDepth.initialConfig
    print("For adjusting thresholds, use keys:")
    print(" - 'w': Increase confidence threshold")
    print(" - 's': Decrease confidence threshold")
    print(" - 'd': Increase edge threshold")
    print(" - 'a': Decrease edge threshold")
    print(" - 't': Toggle temporal filtering")
    while pipeline.isRunning():
        confidenceData = confidenceQueue.get()
        assert isinstance(confidenceData, dai.ImgFrame)
        npConfidence = confidenceData.getFrame()
        colorizedConfidence = cv2.applyColorMap(((npConfidence)).astype(np.uint8), colorMap)
        cv2.imshow("confidence", colorizedConfidence)

        edgeData = edgeQueue.get()
        assert isinstance(edgeData, dai.ImgFrame)
        npEdge = edgeData.getFrame()
        colorizedEdge = cv2.applyColorMap(((npEdge)).astype(np.uint8), colorMap)
        cv2.imshow("edge", colorizedEdge)

        disparityData = disparityQueue.get()
        assert isinstance(disparityData, dai.ImgFrame)
        npDisparity = disparityData.getFrame()
        maxDisparity = max(maxDisparity, np.max(npDisparity))
        colorizedDisparity = cv2.applyColorMap(((npDisparity / maxDisparity) * 255).astype(np.uint8), colorMap)
        cv2.imshow("disparity", colorizedDisparity)

        key = cv2.waitKey(1)
        if key == ord('q'):
            pipeline.stop()
            break
        if key == ord('w'):
            currentThreshold = currentConfig.getConfidenceThreshold()
            currentConfig.setConfidenceThreshold((currentThreshold + 5) % 255)
            print("Setting confidence threshold to:", currentConfig.getConfidenceThreshold())
            inputConfigQueue.send(currentConfig)
        if key == ord('s'):
            currentThreshold = currentConfig.getConfidenceThreshold()
            currentConfig.setConfidenceThreshold((currentThreshold - 5) % 255)
            print("Setting confidence threshold to:", currentConfig.getConfidenceThreshold())
            inputConfigQueue.send(currentConfig)
        if key == ord('d'):
            currentThreshold = currentConfig.getEdgeThreshold()
            currentConfig.setEdgeThreshold((currentThreshold + 1) % 255)
            print("Setting edge threshold to:", currentConfig.getEdgeThreshold())
            inputConfigQueue.send(currentConfig)
        if key == ord('a'):
            currentThreshold = currentConfig.getEdgeThreshold()
            currentConfig.setEdgeThreshold((currentThreshold - 1) % 255)
            print("Setting edge threshold to:", currentConfig.getEdgeThreshold())
            inputConfigQueue.send(currentConfig)
        if key == ord('t'):
            currentConfig.postProcessing.temporalFilter.enable = not currentConfig.postProcessing.temporalFilter.enable
            print("Temporal filtering:", "on" if currentConfig.postProcessing.temporalFilter.enable else "off")
            inputConfigQueue.send(currentConfig)

        if cv2.waitKey(1) == ord('q'):
            break
```

#### C++

```cpp
#include <atomic>
#include <csignal>
#include <iostream>
#include <opencv2/opencv.hpp>

#include "depthai/depthai.hpp"

// Global flag for graceful shutdown
std::atomic<bool> quitEvent(false);

void signalHandler(int signum) {
    quitEvent = true;
}

int main() {
    // Set up signal handlers for clean exit
    signal(SIGTERM, signalHandler);
    signal(SIGINT, signalHandler);

    constexpr float FPS = 25.0f;

    // Create pipeline
    dai::Pipeline pipeline;

    // Define sources
    auto cameraLeft = pipeline.create<dai::node::Camera>();
    cameraLeft->build(dai::CameraBoardSocket::CAM_B, std::nullopt, FPS);

    auto cameraRight = pipeline.create<dai::node::Camera>();
    cameraRight->build(dai::CameraBoardSocket::CAM_C, std::nullopt, FPS);

    // Get full resolution outputs
    auto leftOutput = cameraLeft->requestFullResolutionOutput();
    auto rightOutput = cameraRight->requestFullResolutionOutput();

    // Create and build NeuralDepth node
    auto neuralDepth = pipeline.create<dai::node::NeuralDepth>();
    neuralDepth->build(*leftOutput, *rightOutput, dai::DeviceModelZoo::NEURAL_DEPTH_LARGE);

    // Create output queues
    auto confidenceQueue = neuralDepth->confidence.createOutputQueue();
    auto edgeQueue = neuralDepth->edge.createOutputQueue();
    auto disparityQueue = neuralDepth->disparity.createOutputQueue();

    // Create input queue for runtime configuration
    auto inputConfigQueue = neuralDepth->inputConfig.createInputQueue();

    // Start the pipeline
    pipeline.start();

    // Variables for visualization
    double maxDisparity = 1.0;
    cv::Mat colorMap;
    cv::Mat gray(256, 1, CV_8UC1);
    for(int i = 0; i < 256; i++) {
        gray.at<uchar>(i) = i;
    }
    cv::applyColorMap(gray, colorMap, cv::COLORMAP_JET);
    colorMap.at<cv::Vec3b>(0) = cv::Vec3b(0, 0, 0);  // Set zero-disparity pixels to black

    // Get the initial configuration
    auto currentConfig = neuralDepth->initialConfig;

    std::cout << "For adjusting thresholds, use keys:" << std::endl;
    std::cout << " - 'w': Increase confidence threshold" << std::endl;
    std::cout << " - 's': Decrease confidence threshold" << std::endl;
    std::cout << " - 'd': Increase edge threshold" << std::endl;
    std::cout << " - 'a': Decrease edge threshold" << std::endl;
    std::cout << " - 't': Toggle temporal filtering" << std::endl;

    while(!quitEvent && pipeline.isRunning()) {
        // Get confidence data and display it
        auto confidenceData = confidenceQueue->get<dai::ImgFrame>();
        cv::Mat npConfidence = confidenceData->getFrame();
        cv::Mat colorizedConfidence;
        cv::applyColorMap(npConfidence, colorizedConfidence, colorMap);
        cv::imshow("confidence", colorizedConfidence);

        // Get edge data and display it
        auto edgeData = edgeQueue->get<dai::ImgFrame>();
        cv::Mat npEdge = edgeData->getFrame();
        cv::Mat colorizedEdge;
        cv::applyColorMap(npEdge, colorizedEdge, colorMap);
        cv::imshow("edge", colorizedEdge);

        // Get disparity data, normalize, and display it
        auto disparityData = disparityQueue->get<dai::ImgFrame>();
        cv::Mat npDisparity = disparityData->getFrame();

        double minVal, curMax;
        cv::minMaxLoc(npDisparity, &minVal, &curMax);
        maxDisparity = std::max(maxDisparity, curMax);

        cv::Mat normalized;
        npDisparity.convertTo(normalized, CV_8UC1, 255.0 / maxDisparity);

        cv::Mat colorizedDisparity;
        cv::applyColorMap(normalized, colorizedDisparity, colorMap);
        cv::imshow("disparity", colorizedDisparity);

        // Check for keyboard input
        int key = cv::waitKey(1);
        bool configChanged = false;
        if(key == 'q') {
            break;
        } else if(key == 'w') {  // Increase confidence threshold
            uint8_t currentThreshold = currentConfig->getConfidenceThreshold();
            currentConfig->setConfidenceThreshold((currentThreshold + 5) % 255);
            std::cout << "Setting confidence threshold to: " << (int)currentConfig->getConfidenceThreshold() << std::endl;
            configChanged = true;
        } else if(key == 's') {  // Decrease confidence threshold
            uint8_t currentThreshold = currentConfig->getConfidenceThreshold();
            currentConfig->setConfidenceThreshold(currentThreshold - 5);  // uint8_t will wrap around on underflow
            std::cout << "Setting confidence threshold to: " << (int)currentConfig->getConfidenceThreshold() << std::endl;
            configChanged = true;
        } else if(key == 'd') {  // Increase edge threshold
            uint8_t currentThreshold = currentConfig->getEdgeThreshold();
            currentConfig->setEdgeThreshold((currentThreshold + 1) % 255);
            std::cout << "Setting edge threshold to: " << (int)currentConfig->getEdgeThreshold() << std::endl;
            configChanged = true;
        } else if(key == 'a') {  // Decrease edge threshold
            uint8_t currentThreshold = currentConfig->getEdgeThreshold();
            currentConfig->setEdgeThreshold(currentThreshold - 1);  // uint8_t will wrap around on underflow
            std::cout << "Setting edge threshold to: " << (int)currentConfig->getEdgeThreshold() << std::endl;
            configChanged = true;
        } else if(key == 't') {
            bool enable = !currentConfig->postProcessing.temporalFilter.enable;
            currentConfig->postProcessing.temporalFilter.enable = enable;
            std::cout << "Temporal filtering: " << (enable ? "on" : "off") << std::endl;
            configChanged = true;
        }

        // Send the updated configuration to the device
        if(configChanged) {
            inputConfigQueue->send(currentConfig);
        }
    }

    // Pipeline is stopped automatically when the 'pipeline' object goes out of scope.
    return 0;
}
```

### Need assistance?

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