Camera multiple outputs
Example showcases DepthAIv3's functionality to request an output stream directly from the Camera node, instead of having to create and configure multiple ImageManip nodes.Python
1output1 = camera_node.requestOutput(
2 size=(640, 480),
3 type=dai.ImgFrame.Type.BGR888p,
4 resize_mode=dai.ImgResizeMode.CROP,
5 fps=15
6)
7output2 = cam.requestOutput(
8 size=(1000, 500),
9 type=dai.ImgFrame.Type.NV12,
10 resize_mode=dai.ImgResizeMode.STRETCH,
11 fps=20
12)
CROP
, STRETCH
, or LETTERBOX
, which come into play if there's a missmatch between sensor aspect ratio (AR) and requested aspect ratio. For more information (pros/cons of each) check Input frame AR missmatch documentation.Setup
This example requires the DepthAI v3 API, see installation instructions.Pipeline
Source code
Python
C++
Python
PythonGitHub
1#!/usr/bin/env python3
2
3import sys
4
5import cv2
6import depthai as dai
7import time
8
9# Create pipeline
10
11
12def exit_usage() -> None:
13 print(
14 "WRONG USAGE! correct usage example:\n"
15 "python camera_multiple_outputs.py 640 480 0 30 CAM_A 300 300 0 30 CAM_A 300 300 1 30 CAM_A \n"
16 "where 0 is resize mode: 0 == CROP, 1 == STRETCH, 2 == LETTERBOX\n"
17 "and 30 is FPS"
18 )
19 exit(1)
20
21class FPSCounter:
22 def __init__(self):
23 self.frameTimes = []
24
25 def tick(self):
26 now = time.time()
27 self.frameTimes.append(now)
28 self.frameTimes = self.frameTimes[-100:]
29
30 def getFps(self):
31 if len(self.frameTimes) <= 1:
32 return 0
33 # Calculate the FPS
34 return (len(self.frameTimes) - 1) / (self.frameTimes[-1] - self.frameTimes[0])
35
36
37args = sys.argv[1:]
38if len(args) < 5 or len(args) % 5 != 0:
39 exit_usage()
40
41with dai.Pipeline() as pipeline:
42 cams: dict = {}
43 queues = []
44 for i in range(0, len(args), 5):
45 cap = dai.ImgFrameCapability()
46 cap.size.fixed((int(args[i]), int(args[i + 1])))
47 cropArg = int(args[i + 2])
48 if cropArg == 0:
49 cap.resizeMode = dai.ImgResizeMode.CROP
50 elif cropArg == 1:
51 cap.resizeMode = dai.ImgResizeMode.STRETCH
52 elif cropArg == 2:
53 cap.resizeMode = dai.ImgResizeMode.LETTERBOX
54 else:
55 exit_usage()
56 cap.fps.fixed(float(args[i + 3]))
57 camArg = args[i + 4]
58 socket: dai.CameraBoardSocket
59 if camArg == "CAM_A":
60 socket = dai.CameraBoardSocket.CAM_A
61 elif camArg == "CAM_B":
62 socket = dai.CameraBoardSocket.CAM_B
63 elif camArg == "CAM_C":
64 socket = dai.CameraBoardSocket.CAM_C
65 elif camArg == "CAM_D":
66 socket = dai.CameraBoardSocket.CAM_D
67 else:
68 exit_usage()
69 if socket not in cams:
70 cams[socket] = pipeline.create(dai.node.Camera).build(socket)
71 queues.append(cams[socket].requestOutput(cap, True).createOutputQueue())
72
73 # Connect to device and start pipeline
74 pipeline.start()
75 FPSCounters = [FPSCounter() for _ in queues]
76 while pipeline.isRunning():
77 for index, queue in enumerate(queues):
78 videoIn = queue.tryGet()
79 if videoIn is not None:
80 FPSCounters[index].tick()
81 assert isinstance(videoIn, dai.ImgFrame)
82 print(
83 f"frame {videoIn.getWidth()}x{videoIn.getHeight()} | {videoIn.getSequenceNum()}: exposure={videoIn.getExposureTime()}us, timestamp: {videoIn.getTimestampDevice()}"
84 )
85 # Get BGR frame from NV12 encoded video frame to show with opencv
86 # Visualizing the frame on slower hosts might have overhead
87 cvFrame = videoIn.getCvFrame()
88 # Draw FPS
89 cv2.putText(cvFrame, f"{FPSCounters[index].getFps():.2f} FPS", (2, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0))
90 cv2.imshow("video " + str(index), cvFrame)
91
92 if cv2.waitKey(1) == ord("q"):
93 break
Need assistance?
Head over to Discussion Forum for technical support or any other questions you might have.