目录
- DepthAI的整体架构
- Device 对象
- 通过标识连接到指定设备
- 定义输入/输出队列
- Device对象的常用方法
- addLogCallback()方法
- close()方法
- getInputQueue()方法
- getOutputQueue()方法
- Pipeline
- Pipeline常用的方法
- create()方法
- `createColorCamera()`方法
- `createMonoCamera()`方法
- createNeuralNetwork()方法
- createXLinkIn()方法
- createXLinkOut()方法
- link()方法
- setOpenVINOVersion()方法
- Nodes
- ColorCamera节点
- MonoCamera节点
- EdgeDetector节点
- 常用方法
- 常用属性:
- FeatureTracker节点
- NeuralNetwork节点
- XLinkIn节点
- XLinkOut节点
- Messages
- 补充名词解释
- Sobel滤波器
DepthAI的整体架构
官方给的DepthAI的整体架构如下图所示:
其中:
- Host 主机端是连接 OAK 设备的计算机,如 PC 或 RPi。
- Device 设备端是 OAK 设备本身。如果设备端发生了某些事情,则意味着它正在机器人视觉核心(RVC)上运行。
- Pipeline 管道是设备端的完整工作流,由节点和它们之间的连接组成。
- Node 节点 Node 是DepthAI的单一功能。节点具有输入或输出,并具有可配置的属性(如相机节点上的分辨率)。
- Connection 连接 是一个节点的输出和另一个节点的输入之间的链接。为了定义管道数据流,连接定义在何处发送消息以实现预期结果
- XLink 是一个中间件,能够在设备和主机之间交换数据。XLinkIn节点允许将数据从主机发送到设备,而XLinkOut则相反。
- Message 消息在节点之间传输,由连接定义
Device 对象
Device
对象表示 OAK 设备。启动设备时,我们必须向其上传一个管道,该管道将在 VPU 上执行。 在代码中创建Device时,固件将与管道和其他资产(例如 NN blob)一起上传。
创建Device即OAK设备的代码如下:
#使用depthai库创建了一个空的Pipeline对象
pipeline = depthai.Pipeline()
# 通过depthai.Device(pipeline)创建与OAK相机的连接
with depthai.Device(pipeline) as device:
# 打印 MxID(设备标识)、USB速度和已连接的相机数量。
print('MxId:',device.getDeviceInfo().getMxId())
print('USB speed:',device.getUsbSpeed())
print('Connected cameras:',device.getConnectedCameras())
# 使用device.getInputQueue("input_name", maxSize=4, blocking=False)创建了一个输入队列(input_q),用于在主机和设备之间传递消息。该输入队列可以在设备端使用XLinkIn来接收消息。
input_q = device.getInputQueue("input_name", maxSize=4, blocking=False)
# 使用device.getOutputQueue("output_name", maxSize=4, blocking=False)创建了一个输出队列(output_q),用于从设备端向主机传递消息。该输出队列可以在设备端使用XLinkOut来发送消息。
output_q = device.getOutputQueue("output_name", maxSize=4, blocking=False)
# 主循环
while True:
# 通过output_q.get()来从output_q队列中获取一个来自设备的消息。这里使用了阻塞模式,即如果队列为空,则会等待一个消息。也可以使用output_q.tryGet()来进行非阻塞的消息获取,如果队列为空,则返回None。
output_q.get() # Or output_q.tryGet() for non-blocking
# 创建了一个depthai.ImageManipConfig对象cfg,并使用input_q.send(cfg)将该消息发送给设备。这里的cfg可以是在主机上进行图像处理的配置,通过发送该配置给设备,可以控制设备上的图像处理操作。
cfg = depthai.ImageManipConfig()
input_q.send(cfg)
上面这段代码使用depthai库创建了一个Pipeline对象,并在与OAK相机连接的设备上进行了一些基本的配置和消息传递操作。
通过标识连接到指定设备
如果有多台设备,并且只想连接到特定的设备,或者 OAK PoE 摄像头在外部 子网中,可以通过指定 MxID、IP 或 USB 端口名称来连接要连接到的设备。
# 通过depthai.DeviceInfo()创建了一个DeviceInfo对象,用于存储设备信息,并指定MXID参数。
device_info = depthai.DeviceInfo("14442C108144F1D000") # MXID
#device_info = depthai.DeviceInfo("192.168.1.44") # IP Address
#device_info = depthai.DeviceInfo("3.3.3") # USB port name
# 使用depthai.Device()创建设备连接时,将pipeline和device_info作为参数传递给Device对象。这将使用指定的设备信息来建立与相机的连接。
with depthai.Device(pipeline, device_info) as device:
定义输入/输出队列
在初始化设备之后,还必须初始化输入/输出队列。这些队列将位于主机上(在RAM中)。
# 定义输出队列
outputQueue = device.getOutputQueue("output_name")
# 定义输入队列
inputQueue = device.getInputQueue("input_name")
定义输出队列时,设备可以在任何时间点向其推送新消息,主机可以在任何时候从中读取。通常,当主机从队列中快速读取时,队列(无论其大小)大部分时间都将保持为空。但是,当我们在主机端添加东西(额外的处理、分析等)时,可能会发生设备向队列写入的速度比主机从中读取的速度快的情况。然后,队列中的消息将开始添加-在这种情况下,maxSize和blocking标志都决定了队列的行为。我们可以通过以下方式设置这些标志:
# 初始化队列时指定
queue = device.getOutputQueue(name="myQueue", maxSize=5, blocking=False)
# 或者 通过调用方法指定
queue.setMaxSize(10)
queue.setBlocking(True)
这段代码初始化和配置了输出队列(OutputQueue)对象。
通过device.getOutputQueue(name=“myQueue”, maxSize=5, blocking=False)方法创建了一个输出队列(OutputQueue)对象。这里的name参数用于给输出队列命名,maxSize参数指定了队列的最大大小,即最多可以存储的消息数量,blocking参数指定了队列的阻塞模式。
在这段代码中,输出队列的名称被设置为"myQueue",最大大小为5,阻塞模式为非阻塞式。这意味着,当没有消息可用时,调用输出队列的get()方法将立即返回,而不会等待消息的到达。
然后,在初始化之后,通过调用queue.setMaxSize(10)和queue.setBlocking(True)来分别更改输出队列的最大大小和阻塞模式。这里的setMaxSize()方法将输出队列的最大大小更改为10,setBlocking()方法将输出队列的阻塞模式更改为阻塞式(即当队列为空时,调用get()方法将会阻塞并等待消息的到达)。
通过修改输出队列的大小和阻塞模式,可以根据具体的需求来调整和控制消息的处理和传输方式。
Device对象的常用方法
addLogCallback()方法
addLogCallback()方法允许我们添加一个回调函数来处理设备的日志消息。
方法如下:
addLogCallback(self: depthai.DeviceBase, callback: Callable[[depthai.LogMessage], None]) → int
参数:
- callback:一个可调用的函数,用于处理设备的日志消息。该函数的参数是一个LogMessage对象,该对象包含了日志消息的信息,如级别、模块、文件名等。
返回值:
- int:回调函数的ID。你可以使用此ID来删除回调函数。
使用addLogCallback()方法,win可以注册一个回调函数来监听设备产生的日志消息。当设备产生新的日志消息时,所注册的回调函数将被调用,并传递相应的LogMessage对象作为参数。
close()方法
close()是方法用于关闭与设备的连接并释放相关资源。
方法如下:
close(self: depthai.DeviceBase) → None
参数:无
返回值:None
使用close()方法,我们可以在程序结束或不再需要与设备通信时,关闭与设备的连接并释放相关资源。该方法会终止与设备的通信,停止图像处理管道,并释放设备所占用的系统资源。
getInputQueue()方法
getInputQueue()方法用于获取一个输入队列。输入队列用于向设备发送待处理的数据,例如图像、视频帧等。
方法如下:
getInputQueue(self: depthai.DeviceBase, name: str = ‘’, maxSize: int = 8) → depthai.InputQueue
参数:
- name(可选):输入流的名称。如果指定了名称,则只返回与该名称匹配的输入流队列。如果未指定名称,则返回所有可用的输入流队列。
- maxSize(可选):输入队列的最大大小。默认为8,即队列中最多存储8条数据。如果队列已满,则新的数据将替换最早的数据。
返回值:
- depthai.InputQueue对象:输入队列对象,用于向设备发送待处理的数据。你可以使用InputQueue的send()方法向队列中发送数据。
使用getInputQueue()方法,我们可以为特定的输入流或所有可用的输入流创建一个输入队列。我们可以将待处理的数据逐个发送到输入队列中,然后设备会按照接收到的顺序进行处理。
getOutputQueue()方法
getOutputQueue()方法用于获取一个输出队列。输出队列用于从设备获取处理后的数据,例如图像、深度图、推理结果等。
方法如下:
getOutputQueue(self: depthai.DeviceBase, name: str = ‘’, maxSize: int = 8, blocking: bool = True) → depthai.OutputQueue
参数:
- name(可选):输出流的名称。如果指定了名称,则只返回与该名称匹配的输出流队列。如果未指定名称,则返回所有可用的输出流队列。
- maxSize(可选):输出队列的最大大小。默认为8,即队列中最多存储8条数据。如果队列已满,则新的数据将替换最早的数据。
- blocking(可选):指定是否在队列为空时阻塞等待新的数据。默认为True,即如果队列为空,则get()方法会一直阻塞直到有新的数据到达。
返回值:
- depthai.OutputQueue对象:输出队列对象,用于获取设备的处理结果。你可以使用OutputQueue的get()方法从队列中获取数据。
使用getOutputQueue()方法,我们可以为特定的输出流或所有可用的输出流创建一个输出队列。输出队列可以在我们方便的时候逐个获取数据,并且可以控制队列的大小和阻塞行为。
Pipeline
Pipeline是DepthAI API中的一个重要概念,它表示一个处理流程或流水线,用于设置和连接设备的不同模块,以实现数据的输入、处理和输出。
Pipeline可以被视为一个处理图,由多个节点组成,这些节点按照一定的顺序连接在一起,形成了数据的流动路径。Pipeline中的节点可以包括输入节点、处理节点和输出节点,用于读取输入数据、进行算法处理,以及输出处理结果。
Pipeline是节点及其之间的链接的集合。此流程为用户的OAK设备提供了广泛的灵活性。当pipeline对象被传递到Device对象时,pipeline被序列化为JSON,并通过XLink发送到OAK设备。
使用Pipeline的示例代码如下:
import depthai
# 创建一个Pipeline对象
pipeline = depthai.Pipeline()
# 添加模块到Pipeline中
cam = pipeline.createColorCamera()
neural_network = pipeline.createNeuralNetwork()
# 连接模块
cam.preview.link(neural_network.input)
# 连接设备并启动Pipeline
with dai.Device(pipeline) as device:
# 在这里执行我们的逻辑,例如获取输出结果
在上面这段代码中,我们首先创建了一个Pipeline对象。然后,使用Pipeline的createXXX()方法创建各个节点(例如这里的ColorCamera和NeuralNetwork)。接下来,通过调用模块的link()方法,对模块进行连接。在这段代码中,我们将摄像头模块的预览输出连接到神经网络模块的输入。
最后,使用Device对象启动Pipeline并运行设备的处理流程。在程序的逻辑中,我们可以通过获取模块的输出来获取处理结果。
Pipeline常用的方法
create()方法
create(self: depthai.Pipeline, arg0: object) -> depthai.Node
是Pipeline对象中的一个方法,用于创建自定义的节点。
参数:
arg0
:表示要创建的节点对象。
返回值:
- 返回一个depthai.Node对象,表示创建的节点。
这个方法允许我们通过自定义节点来扩展DepthAI的功能。我们可以创建自己的节点类,并将其作为参数传递给create()
方法,以在Pipeline中添加自定义功能。
createColorCamera()
方法
createColorCamera()
:创建ColorCamera节点。
- 参数:无。
- 返回值:depthai.node.ColorCamera对象。
- 功能:创建一个彩色摄像头节点,用于读取彩色图像数据。
createMonoCamera()
方法
createMonoCamera()
:创建MonoCamera节点。
- 参数:无。
- 返回值:depthai.node.MonoCamera对象。
- 功能:创建一个单目摄像头节点,用于读取单目图像数据。
createNeuralNetwork()方法
createNeuralNetwork()
:创建NeuralNetwork节点。
- 参数:无。
- 返回值:depthai.node.NeuralNetwork对象。
- 功能:创建一个神经网络节点,用于进行神经网络推理处理。
createXLinkIn()方法
createXLinkIn()
:创建XLinkIn节点。
- 参数:name(节点名称)。
- 返回值:depthai.node.XLinkIn对象。
- 功能:创建一个XLinkIn节点,用于接收来自外部设备的数据。
createXLinkOut()方法
createXLinkOut()
:创建XLinkOut节点。
- 参数:name(节点名称)。
- 返回值:depthai.node.XLinkOut对象。
- 功能:创建一个XLinkOut节点,用于将数据发送到外部设备。
link()方法
link()
:连接节点。
- 参数:output(输出节点),input(输入节点)。
- 返回值:无。
- 功能:将输出节点与输入节点连接在一起,形成数据的流动路径。
setOpenVINOVersion()方法
setOpenVINOVersion()
:设置OpenVINO版本。
- 参数:version(OpenVINO版本)。
- 返回值:无。
- 功能:设置使用的OpenVINO版本,可以是"2020.4"、“2021.2"或"latest”。
Nodes
Nodes是填充Pipeline时的构建块。每个节点在DepthAI上提供一个特定的功能,一组可配置的属性和输入/输出。在管道上创建节点后,还可以根据需要对其进行配置,并将其链接到其他节点。
在depthai库中,提供了一些常用的节点(Nodes),用于构建处理深度数据和图像的流水线
depthai.node.ColorCamera
:彩色摄像头节点,用于读取彩色图像数据。depthai.node.MonoCamera
:单目摄像头节点,用于读取单目图像数据。depthai.node.SpatialDetectionNetwork
:空间检测网络节点,用于进行实时目标检测。depthai.node.NeuralNetwork
:神经网络节点,用于进行神经网络推理处理。depthai.node.PoseEstimationNetwork
:姿态估计网络节点,用于进行实时姿态估计。depthai.node.XLinkIn
:XLinkIn节点,用于接收来自外部设备的数据。depthai.node.XLinkOut
:XLinkOut节点,用于将数据发送到外部设备。
ColorCamera节点
depthai.node.ColorCamera
(彩色摄像头节点),功能:通过彩色摄像头获取彩色图像数据,主要方法有:
setPreviewSize(width: int, height: int)
:- 功能:设置预览图像的大小。
- 参数:
width
(int):图像的宽度。height
(int):图像的高度。
setVideoSize(width: int, height: int)
:- 功能:设置视频图像的大小。
- 参数:
width
(int):图像的宽度。height
(int):图像的高度。
- 说明:这里设置的图像大小是相对于预览图像的大小,宽度和高度都是预览图像大小的4倍。
setResolution(sensor_resolution: dai.ColorCameraProperties.SensorResolution)
:- 功能:设置图像传感器的分辨率。
- 参数:
sensor_resolution
(dai.ColorCameraProperties.SensorResolution):图像传感器的分辨率类型,可选值包括:THE_720_P
:720p分辨率(1280x720)。THE_1080_P
:1080p分辨率(1920x1080)。THE_12_MP
:12MP分辨率(4056x3040)。- 其他可用的分辨率类型,具体取决于相机硬件。
setInterleaved(interleaved: bool)
:- 功能:设置图像数据的存储格式。
- 参数:
interleaved
(bool):设置为True表示使用交错存储格式,设置为False表示使用非交错存储格式。
- 说明:交错存储格式是将彩色图像的RGB三个通道数据存储在一起,而非交错存储格式是将RGB三个通道数据分开存储。
setBoardSocket(board_socket: dai.CameraBoardSocket)
:- 功能:设置相机板上连接的数据线路。
- 参数:
board_socket
(dai.CameraBoardSocket):相机板上的数据线路类型,可选值包括:RGB
:用于连接彩色相机。LEFT
:用于连接左通道单目相机。RIGHT
:用于连接右通道单目相机。RGB_STEREOLONG
:用于连接长基线RGB相机。RGB_STEREO
:用于连接RGB立体相机。
setCamId(self, cam_id: int)
:设置使用的摄像头ID。
MonoCamera节点
depthai.node.MonoCamera
(单目摄像头节点):
- 功能:通过单目摄像头获取单目图像数据。
- 主要方法和属性:
setCamId(self, cam_id: int)
:设置使用的摄像头ID。setResolution(self: depthai.node.MonoCamera, resolution: depthai.MonoCameraProperties.SensorResolution)
设置图像传感器的分辨率getFps()
:获取摄像头应该产生帧的速率。返回值为每秒帧数(FPS)。getFrameEventFilter()
:获取摄像头事件过滤器。getImageOrientation()
:获取摄像头图像方向。getInputRefs()
:获取输入引用。setResolution()
:设置摄像头分辨率。setCenterOfFocus()
:设置摄像头对焦中心。setExposure()
:设置摄像头曝光度。setGain()
:设置摄像头增益。
EdgeDetector节点
depthai.node.EdgeDetector
(边缘检测器节点)
EdgeDetector节点主要用于在图像或视频流中提取边缘信息。它采用Sobel滤波器来创建一幅突出边缘的图像。要使用EdgeDetector节点,需要创建一个EdgeDetector对象,并将其添加到管道中。
边缘检测器节点。使用 3x3 Sobel 滤波器执行边缘检测
创建边缘检测器节点
pipeline = dai.Pipeline()
edgeDetector = pipeline.create(dai.node.EdgeDetector)
常用方法
-
getAssetManager()方法
getAssetManager方法是EdgeDetector节点类的一个函数,用于获取当前节点的AssetManager实例。从而可以访问和管理节点所使用的资源文件。你可以使用AssetManager加载、转换和保存模型文件、配置文件和标签文件,以便在边缘检测过程中使用。在DepthAI中,AssetManager用于管理资源文件,包括模型文件、配置文件、标签文件等。
# 创建EdgeDetector节点 edge_detector = pipeline.create(dai.node.EdgeDetector) # 获取EdgeDetector节点的AssetManager实例 asset_manager = edge_detector.getAssetManager() # 使用AssetManager加载模型文件 asset_manager.loadBlobFile('/path/to/model.blob') # 使用AssetManager加载配置文件 asset_manager.loadJsonFile('/path/to/config.json') # 使用AssetManager加载标签文件 asset_manager.loadLabelsFile('/path/to/labels.txt')
-
getInputRefs()方法
getInputRefs()方法用于获取与某个节点关联的输入流(input stream)的引用。每个节点可以有多个输入流,通过使用getInputRefs方法,可以获取节点输入流的引用,以便在程序中进行流操作。 -
getWaitForConfigInput()方法
getWaitForConfigInput方法用于获取节点是否等待配置输入的状态。每个节点在开始运行之前,需要先接收到配置信息才能正常工作。这个方法可以用来查询节点是否已经配置好,并准备好接收输入。 -
setMaxOutputFrameSize()方法
setMaxOutputFrameSize方法用于设置节点输出帧的最大大小。每个节点在运行时可以生成输出帧,该方法可以用来限制输出帧的大小,以便有效管理内存和处理性能。 -
setNumFramesPool()方法
setNumFramesPool方法用于设置节点的帧缓冲池的大小。帧缓冲池是为节点保留的用于存储帧数据的缓冲区,用于在节点运行期间保存输入和输出帧的内容。 -
setWaitForConfigInput()方法
setWaitForConfigInput方法用于设置节点是否等待配置输入帧。 在DepthAI中,节点可以接收配置输入帧,这些帧包含用于调整节点行为的参数。通过设置setWaitForConfigInput方法,可以控制节点是否等待配置输入帧。如果设置为True,节点将等待配置输入帧进行设置,然后再开始处理其他输入帧。如果设置为False,节点将立即开始处理输入帧,而不等待配置输入帧。
常用属性:
- id:节点的Id
- initialConfig:边缘检测的初始配置。
- inputConfig:输入 EdgeDetectorConfig 消息,能够在运行时修改参数。 默认队列为非阻塞,大小为 4。
- inputImage:执行边缘检测的输入图像。默认队列是非阻塞的 尺寸为 4。
- outputImage:输出具有检测到的边缘的图像帧
FeatureTracker节点
depthai.node.FeatureTracker
(特征点跟踪器节点):
FeatureTracker用于在输入的图像帧中跟踪特征点。它可以用于实现对目标物体或场景中的稳定特征点的跟踪和定位。
NeuralNetwork节点
depthai.node.NeuralNetwork
(神经网络节点):
- 功能:用于进行神经网络的推理处理。
- 常用方法:
- setBlob()方法:
setBlob
是一种用于设置节点输入的方法,它允许将自定义的二进制数据(blob)作为节点的输入。使用setBlob
方法时,需要将二进制数据和相关参数传递给节点。这些参数包括blob的名称、blob的格式(如depthai.AreaConfig
)和blob的实际数据。然后,节点将使用提供的blob数据进行处理。 - setBlobPath()方法:
setBlobPath
是一种设置节点输入的方法,它允许您通过指定文件路径来设置节点的输入。使用setBlobPath
方法,您可以将文件路径作为输入数据传递给节点。
- setBlob()方法:
XLinkIn节点
depthai.node.XLinkIn
(XLinkIn节点):
- 功能:用于接收来自外部设备的数据。
- 常用方法:
setStreamName(self, streamName: str)
:设置数据流的名称。getStreamName(self: depthai.node.XLinkIn)
:获取数据流的名称。
XLinkOut节点
depthai.node.XLinkOut
(XLinkOut节点):
- 功能:用于将数据发送到外部设备。
- 常用方法:
setStreamName(self, streamName: str)
:设置数据流的名称。getStreamName(self: depthai.node.XLinkIn)
:获取数据流的名称。
Depthai提供的节点有很多,这里不一一介绍了,想深入了解的小伙伴可以去官网查看。
Messages
在DepthAI库中,Message
类是用来在节点之间传递数据和消息的主要机制。消息是不同节点之间进行通信和数据交换的基本单元。
Message
类是一个用于构建消息的高级接口,它提供了各种方法来设置和读取消息的各个属性。具体查看官方文档,这里不再做详细介绍
补充名词解释
Sobel滤波器
Sobel滤波器是一种常用的图像处理滤波器,用于边缘检测和图像梯度计算。它基于离散的一阶差分运算,通过在图像上应用两个卷积核来计算图像的水平和垂直方向梯度。
Sobel滤波器的卷积核是一个3x3的矩阵,其中心像素对应待处理像素,其余像素具有正负权重。对于水平方向的Sobel滤波器,卷积核如下所示:
-1 0 1
-2 0 2
-1 0 1
对于垂直方向的Sobel滤波器,卷积核如下所示:
-1 -2 -1
0 0 0
1 2 1
Sobel滤波器通过将这两个卷积核应用于图像的每个像素,计算像素的水平和垂直方向梯度值。水平方向梯度值表示像素值在水平方向上的变化强度,垂直方向梯度值表示像素值在垂直方向上的变化强度。这些梯度值用于检测图像中的边缘。
Sobel滤波器在边缘检测中广泛应用,它对噪声具有一定的抑制能力,并可以准确地检测到边缘的位置和方向。通过计算水平和垂直方向梯度的幅值和方向,可以进一步进行图像增强、特征提取、形状分析等操作。
好了,关于DepthAI API的内如,就先介绍到这里。喜欢的小伙伴点赞关注加收藏哦!