主机节点
HostNode 和 ThreadedHostNode 类实现,这些类提供了一个框架,用于在管道内创建自定义主机端逻辑。DepthAI 附带了几个预定义的主机节点,例如 BasaltVIO、RTABMapSLAM 以及 Record/Replay。这些节点提供了强大的开箱即用功能。然而,主机节点最令人兴奋的方面之一是开发人员能够创建自己的自定义节点。这些自定义节点可以设计用于捕获帧、操作数据、解码神经网络输出等。此外,开发人员可以将自定义主机节点打包成 Python 包,并通过 pip 进行分发。这使得在不同项目和社区之间共享和重用自定义节点更加容易。例如,像 geaxgx 的手部跟踪器 这样的自定义节点可以打包并发布到 PyPI,允许其他人通过简单的 pip install 轻松地将其安装并集成到他们的 DepthAI 管道中。在主机上运行
- 在 RVC2 设备上(OAK-D、OAK-1) - 主机是通过 USB 连接到 DepthAI 设备的设备。这意味着主机节点将在连接到 DepthAI 设备的机器上运行(通常是 PC)。
- 在 RVC4 设备上(OAK4-S、OAK4-D) - 主机端取决于设备运行的模式。在 外设模式 下,主机是通过 USB 连接到 DepthAI 设备的设备——与 RVC2 设备相同。在 独立模式 下,OAK4 设备本身就是主机(运行 Linux),主机节点在设备 CPU 上运行(见下图)。

线程主机节点
ThreadedHostNode 是需要多线程的主机节点基类。此类允许节点在其自己的专用线程中异步运行其逻辑,使其适用于不应阻塞管道主执行流程的操作。样板代码
ThreadedHostNode 派生一个新类并实现以下方法:__init__:用于初始化节点的构造函数。您可以在此处创建输入和输出队列。run()方法是节点的主要执行循环,其中实现了自定义逻辑。onStart()和onStop()方法分别在节点启动和停止时调用。这些方法是可选的,可用于执行任何初始化或清理任务。
代码示例
来自 主机摄像头 示例的简单线程主机节点示例。定义节点后,可以使用
Python
1class HostCamera(dai.node.ThreadedHostNode):
2 def __init__(self):
3 super().__init__() # 调用基类构造函数
4 self.output = self.createOutput() # 创建一个输出队列 - 这将发送 ImgFrame 消息
5
6 def run(self): # 节点的主要执行循环
7 cap = cv2.VideoCapture(0) # 为主机摄像头创建 VideoCapture 对象
8 if not cap.isOpened():
9 p.stop()
10 raise RuntimeError("Error: Couldn't open host camera")
11 while self.isRunning(): # 循环直到节点停止
12 ret, frame = cap.read() # 从摄像头读取帧
13 if not ret:
14 break
15 # 创建一个 ImgFrame 消息并设置其数据、宽度、高度和类型
16 imgFrame = dai.ImgFrame()
17 imgFrame.setData(frame)
18 imgFrame.setWidth(frame.shape[1])
19 imgFrame.setHeight(frame.shape[0])
20 imgFrame.setType(dai.ImgFrame.Type.BGR888i)
21 # 将消息发送到输出队列
22 self.output.send(imgFrame)
23 # 等待下一帧
24 time.sleep(0.1)pipeline.create() 将其添加到管道中。Python
1with dai.Pipeline() as p:
2 hostCamera = p.create(HostCamera) # 在管道内创建自定义主机摄像头节点的实例
3 camQueue = hostCamera.output.createOutputQueue() # 创建一个输出队列以接收帧
4
5 p.start() # 启动管道,这将同时启动主机摄像头,隐式运行 `onStart()` 以及 `run()` 方法
6 while p.isRunning():
7 image : dai.ImgFrame = camQueue.get() # 从输出队列获取帧
8 cv2.imshow("HostCamera", image.getCvFrame())
9 key = cv2.waitKey(1)
10 if key == ord('q'):
11 p.stop() # 停止管 道和主机摄像头,隐式运行 `onStop()` 方法
12 break