DepthAI API详解

news2024/11/18 19:42:50

目录

  • 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),用于构建处理深度数据和图像的流水线

  1. depthai.node.ColorCamera:彩色摄像头节点,用于读取彩色图像数据。
  2. depthai.node.MonoCamera:单目摄像头节点,用于读取单目图像数据。
  3. depthai.node.SpatialDetectionNetwork:空间检测网络节点,用于进行实时目标检测。
  4. depthai.node.NeuralNetwork:神经网络节点,用于进行神经网络推理处理。
  5. depthai.node.PoseEstimationNetwork:姿态估计网络节点,用于进行实时姿态估计。
  6. depthai.node.XLinkIn:XLinkIn节点,用于接收来自外部设备的数据。
  7. depthai.node.XLinkOut:XLinkOut节点,用于将数据发送到外部设备。

ColorCamera节点

depthai.node.ColorCamera(彩色摄像头节点),功能:通过彩色摄像头获取彩色图像数据,主要方法有:

  1. setPreviewSize(width: int, height: int)
    • 功能:设置预览图像的大小。
    • 参数:
      • width(int):图像的宽度。
      • height(int):图像的高度。
  2. setVideoSize(width: int, height: int)
    • 功能:设置视频图像的大小。
    • 参数:
      • width(int):图像的宽度。
      • height(int):图像的高度。
    • 说明:这里设置的图像大小是相对于预览图像的大小,宽度和高度都是预览图像大小的4倍。
  3. 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)。
        • 其他可用的分辨率类型,具体取决于相机硬件。
  4. setInterleaved(interleaved: bool)
    • 功能:设置图像数据的存储格式。
    • 参数:
      • interleaved(bool):设置为True表示使用交错存储格式,设置为False表示使用非交错存储格式。
    • 说明:交错存储格式是将彩色图像的RGB三个通道数据存储在一起,而非交错存储格式是将RGB三个通道数据分开存储。
  5. setBoardSocket(board_socket: dai.CameraBoardSocket)
    • 功能:设置相机板上连接的数据线路。
    • 参数:
      • board_socket(dai.CameraBoardSocket):相机板上的数据线路类型,可选值包括:
        • RGB:用于连接彩色相机。
        • LEFT:用于连接左通道单目相机。
        • RIGHT:用于连接右通道单目相机。
        • RGB_STEREOLONG:用于连接长基线RGB相机。
        • RGB_STEREO:用于连接RGB立体相机。
  6. 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方法,您可以将文件路径作为输入数据传递给节点。

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的内如,就先介绍到这里。喜欢的小伙伴点赞关注加收藏哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/691969.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

泛微以低代码助力央企合规、案件管理数字化

近年来,国家出台一系列文件,不断强化央企国企合同、法务、合规、风控一体化管理,深化法治企业建设。 2022年,国资委印发《中央企业合规管理办法》,要求中央企业加强合规管理,切实防控风险,并指…

新手小白学JAVA_IDEA修改主题 设置背景图片

很多小白在刚刚使用IDEA的时候还不是很熟练 本文主要给大家提供一些使用的小技巧,希望能帮助到你 1.修改IDEA默认主题 IDEA的默认主题是黑色的,其实也可以选择其他的主题 我们一起来试一试吧~ 2.修改IDEA背景图片 IDEA的背景图片也是可以自定义的 我们…

arcgis波段提取--多波段合成

1、打开软件,导入彩色栅格影像,如下: 上图有RGB三个波段,在左侧图层下可以看到波段情况。 2、在菜单栏中选择"窗口"--"影像分析",如下: 点击影像分析功能,打开如下界面&am…

移除flyway,手动进行数据库的迁移

国产数据库如达梦、金仓数据库,开源数据迁移工具貌似支持的很少,手写工具类进行数据库脚本的迁移,主要有2个类如下: /*** 模拟flyway进行sql迁移*/ Component Slf4j public class SqlInitialize implements InitializingBean, Ord…

Java【String字符串不可变】

字符串不可变&练习 字符串不可变1. 字符串设置为不可变的原因2. 如何修改字符串内容3 StringBuilder类的具体使用4. 面试题 字符串不可变 1. 字符串设置为不可变的原因 方便实现字符串常量池,若String对象可变,常量池中的内容就会随时变化&#xf…

Linux SVN提交日志校验

#!/bin/bash export LANG"en_US.UTF-8" #确保中文日志显示正常,便于统计日志 REPOS"$1" TXN"$2" #限制日志长度 LENGTH20 #exit 0SVNLOOK"/usr/bin/svnlook" BLACKLIST".* *.o *.chw *.pck ~\$*"function error_…

五、菜单管理

云尚办公系统:菜单管理 B站直达【为尚硅谷点赞】: https://www.bilibili.com/video/BV1Ya411S7aT 本博文以课程相关为主发布,并且融入了自己的一些看法以及对学习过程中遇见的问题给出相关的解决方法。一起学习一起进步!!&#x…

【Linux系统编程】Linux基本指令详解(二)

文章目录 前言1. cp 指令(重要)2. mv 指令(重要)3. cat 指令echo 命令输出重定向追加重定向wc 命令输入重定向 4. more 指令5. less指令(重要)6. head指令7. tail指令8. 命令行管道(了解&#x…

《AVL树》

文章目录 一、AVL树的基本概念二、AVL树的结点定义三、AVL树的插入四、AVL树的旋转1. 右单旋2. 左单旋3. 右左双旋4. 左右双旋 五、AVL树的验证六、AVL树的性能七、源代码 一、AVL树的基本概念 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将…

Mysql+ETLCloud CDC+Doris实时数仓同步实战

业务需求及其痛点 很多大型企业需要对各种销售及营销数据进行实时同步分析,例如销售订单信息,库存信息,会员信息,设备状态信息等等,这些统计分析信息可以实时同步到Doris中进行分析和统计,Doris作为分析型…

《深入浅出SSD:固态存储核心技术、原理与实战》----学习记录(一)

前言 传统数据存储介质有磁带、光盘等,但更多的是硬盘(HDD)。随着数据呈爆炸式增长,对数据存储介质在速度上、容量上有更高的要求。时势造英雄,固态硬盘(Solid State Disk,SSD)横空出世。SSD使用电子芯片存储数据,没有…

数学建模算法(基于matlab和python)之 改进的欧拉方法与四阶L-K方法(4/10)

实验目的及要求: 1、熟悉各种初值问题的算法,编出算法程序; 2、明确各种算法的精度寓所选步长有密切关系; 3、熟悉在Matlab平台上直接求解常微分方程初值问题。 实验内容: 1、编写改进的欧拉公式通用子程序&#xff0…

禽流感病毒防治VR模拟实训教学效率高-深圳华锐视点

对于临床兽医学实训而言,学生在实验教学中依托传统的教学方式已经无法满足学生的学习效率,理论知识和实验教学无法完美结合。 随着互联网数字化的飞速发展,数字化虚拟仿真教学兴起,有效的提升了传统教学的质量,学生在实…

Blender骨骼绑定

演示视频参考连接:Blender骨骼绑定教程3:清除绑定 & Deform & 权重修改_哔哩哔哩_bilibili 对给定人体Mesh建立骨骼的操作步骤: 在Blender中打开人体Mesh模型,并确保该模型处于object模式。或者使用快捷键“Shift A”并选择“骨骼…

【FFmpeg实战】视频容器

原文地址:https://alphahinex.github.io/2020/03/12/video-container/ 视频容器 我们常见的视频格式有 avi 或 mp4 等,这些所谓的视频格式,实际上指的只是视频容器的格式。就像 zip 格式的压缩包里面可以放置任意类型的文件一样,…

【初识 Docker | 中级篇】 Docker 中部署 Spring Boot 微服务详解

文章目录 前言一、生成 Docker 镜像1.编写Dockerfile2.构建镜像 二、启动容器1.运行服务2.测试 三、jar包映射部署1.更新Dockerfile文件2.构建镜像3.创建&启动容器 总结 前言 本文将为您详细介绍如何在Docker容器中部署Spring Boot服务。 首先,您需要为您的Sp…

Argo CD 实践教程 07

在本章中,我们将探讨如何设置用户访问Argo CD的权限,以及从终端或CI/CD管道连接CLI的选项,以及如何执行基于角色的访问控制。我们将查看单点登录(SSO)选项,通常这是一个需要付费的功能,但由于Ar…

Bean与@Bean注解

文章目录 一、背景与IoC二、注解Bean1、Bean注解用法2、Bean注解源码3、Bean注解演示 一、背景与IoC 之前的代码书写现状—耦合度偏高。如下图,业务层需要数据层实现类对象BookDaoImpl,于是自己new了一个,此时,当数据层类名改为B…

隐藏菜单之菜单和搜索

先看效果&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>菜单</title><style>/* css代码开始*/* {margin: 0;padding: 0;box-sizing: border-box;}b…

人工智能(pytorch)搭建模型15-手把手搭建MnasNet模型,并实现模型的训练与预测

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型15-手把手搭建MnasNet模型&#xff0c;并实现模型的训练与预测&#xff0c;本文将介绍MnasNet模型的原理&#xff0c;并使用PyTorch框架构建一个MnasNet模型用于图像分类任务&#xff0c;…