DepthAI v2 has been superseded by DepthAI v3. You are viewing legacy documentation.
DepthAI Tutorials
DepthAI API References

ON THIS PAGE

  • Demo
  • Setup
  • Source code
  • Pipeline

Edge Detector

This example performs edge detection on 3 different inputs: left, right and RGB camera. HW accelerated sobel filter 3x3 is used. Sobel filter parameters can be changed by keys 1 and 2.

Demo

software/depthai/examples/edge_detections.webp

Setup

Please run the install script to download all required dependencies. Please note that this script must be ran from git context, so you have to download the depthai-python repository first and then run the script
Command Line
1git clone https://github.com/luxonis/depthai-python.git
2cd depthai-python/examples
3python3 install_requirements.py
For additional information, please follow the installation guide.

Source code

Python

Python
GitHub
1#!/usr/bin/env python3
2
3import cv2
4import depthai as dai
5import numpy as np
6
7# Create pipeline
8pipeline = dai.Pipeline()
9
10# Define sources and outputs
11camRgb = pipeline.create(dai.node.ColorCamera)
12monoLeft = pipeline.create(dai.node.MonoCamera)
13monoRight = pipeline.create(dai.node.MonoCamera)
14
15edgeDetectorLeft = pipeline.create(dai.node.EdgeDetector)
16edgeDetectorRight = pipeline.create(dai.node.EdgeDetector)
17edgeDetectorRgb = pipeline.create(dai.node.EdgeDetector)
18
19xoutEdgeLeft = pipeline.create(dai.node.XLinkOut)
20xoutEdgeRight = pipeline.create(dai.node.XLinkOut)
21xoutEdgeRgb = pipeline.create(dai.node.XLinkOut)
22xinEdgeCfg = pipeline.create(dai.node.XLinkIn)
23
24edgeLeftStr = "edge left"
25edgeRightStr = "edge right"
26edgeRgbStr = "edge rgb"
27edgeCfgStr = "edge cfg"
28
29xoutEdgeLeft.setStreamName(edgeLeftStr)
30xoutEdgeRight.setStreamName(edgeRightStr)
31xoutEdgeRgb.setStreamName(edgeRgbStr)
32xinEdgeCfg.setStreamName(edgeCfgStr)
33
34# Properties
35camRgb.setBoardSocket(dai.CameraBoardSocket.CAM_A)
36camRgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P)
37
38monoLeft.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
39monoLeft.setCamera("left")
40monoRight.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
41monoRight.setCamera("right")
42
43edgeDetectorRgb.setMaxOutputFrameSize(camRgb.getVideoWidth() * camRgb.getVideoHeight())
44
45# Linking
46monoLeft.out.link(edgeDetectorLeft.inputImage)
47monoRight.out.link(edgeDetectorRight.inputImage)
48camRgb.video.link(edgeDetectorRgb.inputImage)
49
50edgeDetectorLeft.outputImage.link(xoutEdgeLeft.input)
51edgeDetectorRight.outputImage.link(xoutEdgeRight.input)
52edgeDetectorRgb.outputImage.link(xoutEdgeRgb.input)
53
54xinEdgeCfg.out.link(edgeDetectorLeft.inputConfig)
55xinEdgeCfg.out.link(edgeDetectorRight.inputConfig)
56xinEdgeCfg.out.link(edgeDetectorRgb.inputConfig)
57
58# Connect to device and start pipeline
59with dai.Device(pipeline) as device:
60
61    # Output/input queues
62    edgeLeftQueue = device.getOutputQueue(edgeLeftStr, 8, False)
63    edgeRightQueue = device.getOutputQueue(edgeRightStr, 8, False)
64    edgeRgbQueue = device.getOutputQueue(edgeRgbStr, 8, False)
65    edgeCfgQueue = device.getInputQueue(edgeCfgStr)
66
67    print("Switch between sobel filter kernels using keys '1' and '2'")
68
69    while(True):
70        edgeLeft = edgeLeftQueue.get()
71        edgeRight = edgeRightQueue.get()
72        edgeRgb = edgeRgbQueue.get()
73
74        edgeLeftFrame = edgeLeft.getFrame()
75        edgeRightFrame = edgeRight.getFrame()
76        edgeRgbFrame = edgeRgb.getFrame()
77
78        # Show the frame
79        cv2.imshow(edgeLeftStr, edgeLeftFrame)
80        cv2.imshow(edgeRightStr, edgeRightFrame)
81        cv2.imshow(edgeRgbStr, edgeRgbFrame)
82
83        key = cv2.waitKey(1)
84        if key == ord('q'):
85            break
86
87        if key == ord('1'):
88            print("Switching sobel filter kernel.")
89            cfg = dai.EdgeDetectorConfig()
90            sobelHorizontalKernel = [[1, 0, -1], [2, 0, -2], [1, 0, -1]]
91            sobelVerticalKernel = [[1, 2, 1], [0, 0, 0], [-1, -2, -1]]
92            cfg.setSobelFilterKernels(sobelHorizontalKernel, sobelVerticalKernel)
93            edgeCfgQueue.send(cfg)
94
95        if key == ord('2'):
96            print("Switching sobel filter kernel.")
97            cfg = dai.EdgeDetectorConfig()
98            sobelHorizontalKernel = [[3, 0, -3], [10, 0, -10], [3, 0, -3]]
99            sobelVerticalKernel = [[3, 10, 3], [0, 0, 0], [-3, -10, -3]]
100            cfg.setSobelFilterKernels(sobelHorizontalKernel, sobelVerticalKernel)
101            edgeCfgQueue.send(cfg)

C++

1#include <iostream>
2
3// Includes common necessary includes for development using depthai library
4#include "depthai/depthai.hpp"
5
6int main() {
7    using namespace std;
8
9    // Create pipeline
10    dai::Pipeline pipeline;
11
12    // Define sources and outputs
13    auto camRgb = pipeline.create<dai::node::ColorCamera>();
14    auto monoLeft = pipeline.create<dai::node::MonoCamera>();
15    auto monoRight = pipeline.create<dai::node::MonoCamera>();
16
17    auto edgeDetectorLeft = pipeline.create<dai::node::EdgeDetector>();
18    auto edgeDetectorRight = pipeline.create<dai::node::EdgeDetector>();
19    auto edgeDetectorRgb = pipeline.create<dai::node::EdgeDetector>();
20
21    auto xoutEdgeLeft = pipeline.create<dai::node::XLinkOut>();
22    auto xoutEdgeRight = pipeline.create<dai::node::XLinkOut>();
23    auto xoutEdgeRgb = pipeline.create<dai::node::XLinkOut>();
24    auto xinEdgeCfg = pipeline.create<dai::node::XLinkIn>();
25
26    const auto edgeLeftStr = "edge left";
27    const auto edgeRightStr = "edge right";
28    const auto edgeRgbStr = "edge rgb";
29    const auto edgeCfgStr = "edge cfg";
30
31    xoutEdgeLeft->setStreamName(edgeLeftStr);
32    xoutEdgeRight->setStreamName(edgeRightStr);
33    xoutEdgeRgb->setStreamName(edgeRgbStr);
34    xinEdgeCfg->setStreamName(edgeCfgStr);
35
36    // Properties
37    camRgb->setBoardSocket(dai::CameraBoardSocket::CAM_A);
38    camRgb->setResolution(dai::ColorCameraProperties::SensorResolution::THE_1080_P);
39
40    monoLeft->setResolution(dai::MonoCameraProperties::SensorResolution::THE_400_P);
41    monoLeft->setCamera("left");
42    monoRight->setResolution(dai::MonoCameraProperties::SensorResolution::THE_400_P);
43    monoRight->setCamera("right");
44
45    edgeDetectorRgb->setMaxOutputFrameSize(camRgb->getVideoWidth() * camRgb->getVideoHeight());
46
47    // Linking
48    monoLeft->out.link(edgeDetectorLeft->inputImage);
49    monoRight->out.link(edgeDetectorRight->inputImage);
50    camRgb->video.link(edgeDetectorRgb->inputImage);
51
52    edgeDetectorLeft->outputImage.link(xoutEdgeLeft->input);
53    edgeDetectorRight->outputImage.link(xoutEdgeRight->input);
54    edgeDetectorRgb->outputImage.link(xoutEdgeRgb->input);
55
56    xinEdgeCfg->out.link(edgeDetectorLeft->inputConfig);
57    xinEdgeCfg->out.link(edgeDetectorRight->inputConfig);
58    xinEdgeCfg->out.link(edgeDetectorRgb->inputConfig);
59
60    // Connect to device and start pipeline
61    dai::Device device(pipeline);
62
63    // Output/input queues
64    auto edgeLeftQueue = device.getOutputQueue(edgeLeftStr, 8, false);
65    auto edgeRightQueue = device.getOutputQueue(edgeRightStr, 8, false);
66    auto edgeRgbQueue = device.getOutputQueue(edgeRgbStr, 8, false);
67    auto edgeCfgQueue = device.getInputQueue(edgeCfgStr);
68
69    std::cout << "Switch between sobel filter kernels using keys '1' and '2'" << std::endl;
70
71    while(true) {
72        auto edgeLeft = edgeLeftQueue->get<dai::ImgFrame>();
73        auto edgeRight = edgeRightQueue->get<dai::ImgFrame>();
74        auto edgeRgb = edgeRgbQueue->get<dai::ImgFrame>();
75
76        cv::Mat edgeLeftFrame = edgeLeft->getFrame();
77        cv::Mat edgeRightFrame = edgeRight->getFrame();
78        cv::Mat edgeRgbFrame = edgeRgb->getFrame();
79
80        // Show the frame
81        cv::imshow(edgeLeftStr, edgeLeftFrame);
82        cv::imshow(edgeRightStr, edgeRightFrame);
83        cv::imshow(edgeRgbStr, edgeRgbFrame);
84
85        int key = cv::waitKey(1);
86        switch(key) {
87            case 'q':
88                return 0;
89                break;
90
91            case '1': {
92                std::cout << "Switching sobel filter kernel." << std::endl;
93                dai::EdgeDetectorConfig cfg;
94                std::vector<std::vector<int>> sobelHorizontalKernel = {{1, 0, -1}, {2, 0, -2}, {1, 0, -1}};
95                std::vector<std::vector<int>> sobelVerticalKernel = {{1, 2, 1}, {0, 0, 0}, {-1, -2, -1}};
96                cfg.setSobelFilterKernels(sobelHorizontalKernel, sobelVerticalKernel);
97                edgeCfgQueue->send(cfg);
98            } break;
99
100            case '2': {
101                std::cout << "Switching sobel filter kernel." << std::endl;
102                dai::EdgeDetectorConfig cfg;
103                std::vector<std::vector<int>> sobelHorizontalKernel = {{3, 0, -3}, {10, 0, -10}, {3, 0, -3}};
104                std::vector<std::vector<int>> sobelVerticalKernel = {{3, 10, 3}, {0, 0, 0}, {-3, -10, -3}};
105                cfg.setSobelFilterKernels(sobelHorizontalKernel, sobelVerticalKernel);
106                edgeCfgQueue->send(cfg);
107            } break;
108
109            default:
110                break;
111        }
112    }
113    return 0;
114}

Pipeline

Need assistance?

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