一步一步学OAK之五:通过OAK相机实现边缘检测

news2024/12/23 22:39:34

目录

  • 边缘检测简介
  • Setup 1: 创建文件
  • Setup 2: 安装依赖
  • Setup 3: 导入需要的包
  • Setup 4: 创建pipeline
  • Setup 5: 创建节点
    • 创建相机节点
    • 创建边缘检测节点
    • 创建XLinkOut数据交互的节点
  • Setup 6:设置相关属性
    • 设置彩色相机的相关属性
    • 设置左侧和右侧的单目相机的相关属性
    • 设置边缘检测器的最大输出帧大小
  • Setup 7: 建立链接关系
    • 建立相机和边缘检测器之间的链接
    • 建立边缘检测区与输出端口的链接
    • 建立xinEdgeCfg与边缘检测器配置输入的链接
  • Setup 8: 连接设备并启动管道
  • Setup 9: 创建与DepthAI设备通信的输入队列和输出队列
  • Setup 10: 主循环
    • 获取边缘检测器的输出
    • 从边缘检测器的输出中获取帧图像数据
    • 显示边缘检测器的输出图像
    • 对键盘输入响应程序
  • Setup 11:运行程序

边缘检测简介

边缘检测是计算机视觉和图像处理中的一种基本技术,用于识别图像中物体和图像中不同区域之间的边界或轮廓。边缘是图像中具有明显灰度或强度变化的区域,通常表示不同物体、纹理或形状之间的边界。

边缘检测算法通过分析图像中像素的灰度值或强度变化情况,以找到这些变化的区域。常见的边缘检测算法包括Sobel算子、Canny边缘检测和Laplacian算子等。

边缘检测的应用广泛,例如在目标识别、图像分割、物体测量、图像配准和图像压缩等领域都有重要作用。通过检测图像中的边缘,可以提取出物体的形状和结构信息,进而进行进一步的分析和处理。

这里我们实现对左边、右边和RGB摄像头三个不同的输入进行边缘检测。使用了硬件加速的Sobel滤波器3x3。可以通过按键1和2来改变Sobel滤波器的参数。

Setup 1: 创建文件

  • 创建新建5-edge-detector文件夹
  • 用vscode打开该文件夹
  • 新建一个main.py 文件

Setup 2: 安装依赖

安装依赖前需要先创建和激活虚拟环境,我这里已经创建了虚拟环境OAKenv,在终端中输入cd…退回到OAKenv的根目录,输入 OAKenv\Scripts\activate激活虚拟环境
安装pip依赖项:

pip install numpy opencv-python depthai blobconverter --user

Setup 3: 导入需要的包

在main.py中导入项目需要的包

import cv2
import depthai as dai
import numpy as np

这里导入了numpy库;

NumPy是一个Python库,用于进行科学计算和数据分析。它提供了高性能的多维数组对象(ndarray),以及一系列的函数用于操作这些数组。NumPy的主要功能包括:

  1. 多维数组:NumPy的核心是ndarray对象,它是一个具有固定大小的数组,可以容纳相同类型的元素。这使得NumPy数组比Python原生的列表更高效,更适合进行大规模数据处理和数值计算。

  2. 广播(Broadcasting):NumPy允许不同形状的数组执行相同的操作,而无需复制数据。通过广播,可以有效地对数组执行元素级别的数学运算。

  3. 数学和逻辑操作:NumPy提供了许多内置的数学函数(如sin,cos,exp等)和逻辑操作函数(如all,any,logical_and等),可以轻松地对数组进行操作。

  4. 线性代数运算:NumPy包含了一组用于执行线性代数运算的函数,如矩阵乘法、求解线性方程组等。

  5. 数组操作:NumPy提供了丰富的数组操作函数,如排序、切片、索引、重新形状等,以及用于数组合并和拆分的函数。

  6. 文件操作:NumPy可以读取和写入数组数据到磁盘中的文件,支持多种文件格式(如文本文件、CSV文件、二进制文件等)。

Setup 4: 创建pipeline

pipeline = dai.Pipeline()

Setup 5: 创建节点

创建相机节点

camRgb = pipeline.create(dai.node.ColorCamera)
monoLeft = pipeline.createMonoCamera()
monoRight = pipeline.createMonoCamera()
  1. camRgb = pipeline.create(dai.node.ColorCamera):创建一个彩色相机节点(ColorCamera),用于捕获RGB图像。
  2. monoLeft = pipeline.createMonoCamera():创建一个单通道相机节点(MonoCamera),用于捕获左侧单色图像。
  3. monoRight = pipeline.createMonoCamera():创建一个单通道相机节点(MonoCamera),用于捕获右侧单色图像。

这三个节点将在管道中以并行方式工作,可以同时捕获彩色和单色图像。

创建边缘检测节点

edgeDetectorLeft = pipeline.createEdgeDetector()
edgeDetectorRight = pipeline.createEdgeDetector()
edgeDetectorRgb = pipeline.createEdgeDetector()

这段代码在pipeline中创建三个边缘检测节点。

  1. edgeDetectorLeft = pipeline.createEdgeDetector():创建了一个边缘检测节点用于处理左侧单色图像。
  2. edgeDetectorRight = pipeline.createEdgeDetector():创建了一个边缘检测节点用于处理右侧单色图像。
  3. edgeDetectorRgb = pipeline.createEdgeDetector():创建了一个边缘检测节点用于处理彩色图像。

这些边缘检测节点可以应用于左侧单色图像、右侧单色图像和彩色图像,以便检测图像中的边缘特征。

创建XLinkOut数据交互的节点

xoutEdgeLeft = pipeline.createXLinkOut()
xoutEdgeRight = pipeline.createXLinkOut()
xoutEdgeRgb = pipeline.createXLinkOut()
xinEdgeCfg = pipeline.createXLinkIn()

xoutEdgeLeft.setStreamName("edge left")
xoutEdgeRight.setStreamName("edge right")
xoutEdgeRgb.setStreamName("edge rgb")
xinEdgeCfg.setStreamName("edge cfg")

这段代码创建了四个与外部设备进行数据交互的节点。

  1. 使用pipeline.createXLinkOut()方法创建了三个用于与外部设备进行数据输出的节点。
  2. 使用pipeline.createXLinkIn()方法创建了一个用于与外部设备进行数据输入的节点。

为每个输出节点和输入节点设置了一个数据流名称

  • xoutEdgeLeft.setStreamName("edge left"):设置了输出节点xoutEdgeLeft的数据流名称为"edge left"。
  • xoutEdgeRight.setStreamName("edge right"):设置了输出节点xoutEdgeRight的数据流名称为"edge right"。
  • xoutEdgeRgb.setStreamName("edge rgb"):设置了输出节点xoutEdgeRgb的数据流名称为"edge rgb"。
  • xinEdgeCfg.setStreamName("edge cfg"):设置了输入节点xinEdgeCfg的数据流名称为"edge cfg"。

通过这些节点和数据流名称,我们可以将外部设备与图像处理管道连接起来,以实现图像数据的输入和输出。

Setup 6:设置相关属性

设置彩色相机的相关属性

camRgb.setBoardSocket(dai.CameraBoardSocket.RGB)
camRgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P)
  1. camRgb.setBoardSocket(dai.CameraBoardSocket.RGB):设置了彩色相机的板载插槽为RGB。这表明彩色相机将通过RGB接口与系统板连接。

  2. camRgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_1080_P):设置了彩色相机的分辨率为1080P。这意味着彩色相机将以1080P的分辨率进行图像捕获。

monoLeft.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
monoLeft.setBoardSocket(dai.CameraBoardSocket.LEFT)
monoRight.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
monoRight.setBoardSocket(dai.CameraBoardSocket.RIGHT)

设置左侧和右侧的单目相机的相关属性

对于左侧的单目相机:

  1. monoLeft.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P):设置了左侧单目相机的分辨率为400P。这意味着左侧单目相机将以400P的分辨率进行图像捕获。
  2. monoLeft.setBoardSocket(dai.CameraBoardSocket.LEFT):设置了左侧单目相机的板载插槽为LEFT。这表明左侧单目相机将通过与系统板的左侧接口连接。

对于右侧的单目相机:

  1. monoRight.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P):设置了右侧单目相机的分辨率为400P。这意味着右侧单目相机将以400P的分辨率进行图像捕获。
  2. monoRight.setBoardSocket(dai.CameraBoardSocket.RIGHT):设置了右侧单目相机的板载插槽为RIGHT。这表明右侧单目相机将通过与系统板的右侧接口连接。

设置边缘检测器的最大输出帧大小

edgeDetectorRgb.setMaxOutputFrameSize(camRgb.getVideoWidth() * camRgb.getVideoHeight())

这行代码设置了边缘检测器的最大输出帧大小,以与彩色相机的视频帧大小相匹配。

camRgb.getVideoWidth()camRgb.getVideoHeight()分别返回彩色相机的视频帧的宽度和高度。通过将这两个值相乘,可以得到彩色相机视频帧的总像素数。

edgeDetectorRgb.setMaxOutputFrameSize()用于设置边缘检测器的最大输出帧大小。通过将其设置为彩色相机视频帧的总像素数,确保边缘检测器的输出帧尺寸与彩色相机视频帧的尺寸相匹配。

这样做可以确保边缘检测器能够处理完整的彩色相机视频帧,并生成与原始视频帧相同尺寸的边缘检测结果。

Setup 7: 建立链接关系

建立相机和边缘检测器之间的链接

monoLeft.out.link(edgeDetectorLeft.inputImage)
monoRight.out.link(edgeDetectorRight.inputImage)
camRgb.video.link(edgeDetectorRgb.inputImage)

这段代码建立了相机和边缘检测器之间的链接,将相机的图像作为输入传递给相应的边缘检测器。

  • monoLeft.out.link(edgeDetectorLeft.inputImage): 将左侧单目相机的输出连接到左侧边缘检测器的输入。这意味着左侧边缘检测器将接收来自左侧单目相机的图像作为输入进行边缘检测。

  • monoRight.out.link(edgeDetectorRight.inputImage): 将右侧单目相机的输出连接到右侧边缘检测器的输入。这意味着右侧边缘检测器将接收来自右侧单目相机的图像作为输入进行边缘检测。

  • camRgb.video.link(edgeDetectorRgb.inputImage): 将彩色相机的视频输出连接到彩色边缘检测器的输入。这意味着彩色边缘检测器将接收来自彩色相机的视频帧作为输入进行边缘检测。

建立边缘检测区与输出端口的链接

edgeDetectorLeft.outputImage.link(xoutEdgeLeft.input)
edgeDetectorRight.outputImage.link(xoutEdgeRight.input)
edgeDetectorRgb.outputImage.link(xoutEdgeRgb.input)

这段代码将左侧、右侧和彩色边缘检测器的输出图像连接到相应的输出端口,以便将边缘检测结果输出。

  • edgeDetectorLeft.outputImage.link(xoutEdgeLeft.input): 将左侧边缘检测器的输出图像连接到xoutEdgeLeft的输入端口,以便将左侧边缘检测结果输出。

  • edgeDetectorRight.outputImage.link(xoutEdgeRight.input): 将右侧边缘检测器的输出图像连接到xoutEdgeRight的输入端口,以便将右侧边缘检测结果输出。

  • edgeDetectorRgb.outputImage.link(xoutEdgeRgb.input): 将彩色边缘检测器的输出图像连接到xoutEdgeRgb的输入端口,以便将彩色边缘检测结果输出。

建立xinEdgeCfg与边缘检测器配置输入的链接

xinEdgeCfg.out.link(edgeDetectorLeft.inputConfig)
xinEdgeCfg.out.link(edgeDetectorRight.inputConfig)
xinEdgeCfg.out.link(edgeDetectorRgb.inputConfig)

这段代码将xinEdgeCfg的输出链接到左侧、右侧和彩色边缘检测器的配置输入,以便将配置信息传递给边缘检测器。

  • xinEdgeCfg.out.link(edgeDetectorLeft.inputConfig): 将xinEdgeCfg的输出链接到左侧边缘检测器的配置输入。这意味着边缘检测器将接收来自xinEdgeCfg的配置信息,以进行相应的设置和调整。

  • xinEdgeCfg.out.link(edgeDetectorRight.inputConfig):将xinEdgeCfg的输出链接到右侧边缘检测器的配置输入。这意味着边缘检测器将接收来自xinEdgeCfg的配置信息,以进行相应的设置和调整。

  • xinEdgeCfg.out.link(edgeDetectorRgb.inputConfig): 将xinEdgeCfg的输出链接到彩色边缘检测器的配置输入。这意味着边缘检测器将接收来自xinEdgeCfg的配置信息,以进行相应的设置和调整。

Setup 8: 连接设备并启动管道

with dai.Device(pipeline) as device:

Setup 9: 创建与DepthAI设备通信的输入队列和输出队列

    edgeLeftQueue = device.getOutputQueue(name="edge left", maxSize=8, blocking=False)
    edgeRightQueue = device.getOutputQueue(name="edge right", maxSize=8, blocking=False)  
    edgeRgbQueue = device.getOutputQueue(name="edge rgb", maxSize=8, blocking=False)
    edgeCfgQueue = device.getInputQueue(name="edge cfg")

    print("Switch between sobel filter kernels using keys '1' and '2'")

这段代码创建了三个输出队列和一个输入队列,用于接收边缘检测器的输出和配置信息。

  • 使用device.getOutputQueue(name="edge left", maxSize=8, blocking=False): 创建了三个输出队列edgeLeftQueueedgeRightQueueedgeRgbQueue,用于接收三个边缘检测器的输出。同时指定了name,maxSize=8表示队列的最大大小为8个元素。blocking=False表示队列是非阻塞模式的,即如果队列已满,新的元素将被丢弃。

  • 使用device.getInputQueue(edgeCfgStr): 创建了一个输入队列edgeCfgQueue,用于接收边缘检测器的配置信息。指定name=“edge cfg”。

Setup 10: 主循环

    while True:

获取边缘检测器的输出

        edgeLeft = edgeLeftQueue.get()
        edgeRight = edgeRightQueue.get()
        edgeRgb = edgeRgbQueue.get()

从每个输出队列中获取边缘检测器的输出。

  • edgeLeft = edgeLeftQueue.get(): 从左侧边缘检测器的输出队列edgeLeftQueue中获取最新的输出。将这个输出赋值给变量edgeLeft

  • edgeRight = edgeRightQueue.get(): 从右侧边缘检测器的输出队列edgeRightQueue中获取最新的输出。将这个输出赋值给变量edgeRight

  • edgeRgb = edgeRgbQueue.get(): 从彩色边缘检测器的输出队列edgeRgbQueue中获取最新的输出。将这个输出赋值给变量edgeRgb

从边缘检测器的输出中获取帧图像数据

        edgeLeftFrame = edgeLeft.getFrame()
        edgeRightFrame = edgeRight.getFrame()
        edgeRgbFrame = edgeRgb.getFrame()

这段代码从边缘检测器的输出中获取帧图像数据。

  • edgeLeftFrame = edgeLeft.getFrame(): 从左侧边缘检测器的输出edgeLeft中获取帧图像数据,并将其赋值给edgeLeftFrame变量。
  • edgeRightFrame = edgeRight.getFrame(): 从右侧边缘检测器的输出edgeRight中获取帧图像数据,并将其赋值给edgeRightFrame变量。
  • edgeRgbFrame = edgeRgb.getFrame(): 从彩色边缘检测器的输出edgeRgb中获取帧图像数据,并将其赋值给edgeRgbFrame变量。

显示边缘检测器的输出图像

        cv2.imshow("edge left", edgeLeftFrame)
        cv2.imshow("edge right", edgeRightFrame)
        cv2.imshow("edge rgb", edgeRgbFrame)

这段代码使用OpenCV库的imshow函数来显示边缘检测器的输出图像。

  • cv2.imshow("edge left", edgeLeftFrame): 使用imshow函数显示左侧边缘检测器的输出图像。edgeLeftStr是窗口标题,edgeLeftFrame是要显示的图像数据。

  • cv2.imshow("edge right", edgeRightFrame): 使用imshow函数显示右侧边缘检测器的输出图像。edgeRightStr是窗口标题,edgeRightFrame是要显示的图像数据。

  • cv2.imshow("edge rgb", edgeRgbFrame): 使用imshow函数显示彩色边缘检测器的输出图像。edgeRgbStr是窗口标题,edgeRgbFrame是要显示的图像数据。

通过这些代码,我们可以将边缘检测器的输出图像显示在窗口中,以便查看和分析结果。

对键盘输入响应程序

        key = cv2.waitKey(1)
        if key == ord('q'):
            break

        if key == ord('1'):
            print("Switching sobel filter kernel.")
            cfg = dai.EdgeDetectorConfig()
            sobelHorizontalKernel = [[1, 0, -1], [2, 0, -2], [1, 0, -1]]
            sobelVerticalKernel = [[1, 2, 1], [0, 0, 0], [-1, -2, -1]]
            cfg.setSobelFilterKernels(sobelHorizontalKernel, sobelVerticalKernel)
            edgeCfgQueue.send(cfg)

        if key == ord('2'):
            print("Switching sobel filter kernel.")
            cfg = dai.EdgeDetectorConfig()
            sobelHorizontalKernel = [[3, 0, -3], [10, 0, -10], [3, 0, -3]]
            sobelVerticalKernel = [[3, 10, 3], [0, 0, 0], [-3, -10, -3]]
            cfg.setSobelFilterKernels(sobelHorizontalKernel, sobelVerticalKernel)
            edgeCfgQueue.send(cfg)

这段代码实现了对键盘输入的响应,以实现一些功能的切换和配置更改。

  • key = cv2.waitKey(1): 等待并获取键盘输入的ASCII码。

  • if key == ord('q'): break: 如果按下的键是字母 ‘q’ 的ASCII码,即表示想要退出程序,那么会跳出循环,结束程序的运行。

  • if key == ord('1'):: 如果按下的键是字母 ‘1’ 的ASCII码,即表示想要切换到第一种卷积核,那么会执行以下操作:

    • 创建一个名为cfgdai.EdgeDetectorConfig对象,用于配置边缘检测器。
    • 定义sobelHorizontalKernelsobelVerticalKernel分别为第一种卷积核的水平和垂直滤波器矩阵。
    • 使用cfg.setSobelFilterKernels方法将这些滤波器矩阵设置到配置对象中。
    • 将配置对象发送到名为edgeCfgQueue的消息队列中。
  • if key == ord('2'):: 如果按下的键是字母 ‘2’ 的ASCII码,即表示想要切换到第二种卷积核,那么会执行以下操作:

    • 创建一个名为cfgdai.EdgeDetectorConfig对象,用于配置边缘检测器。
    • 定义sobelHorizontalKernelsobelVerticalKernel分别为第二种卷积核的水平和垂直滤波器矩阵。
    • 使用cfg.setSobelFilterKernels方法将这些滤波器矩阵设置到配置对象中。
    • 将配置对象发送到名为edgeCfgQueue的消息队列中。

通过这些代码,我们可以根据按键的不同切换卷积核或退出程序。

Setup 11:运行程序

在终端中输入如下指令运行程序

python main.py

程序运行以后,可以看到如下效果
在这里插入图片描述

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

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

相关文章

【计算机网络 - 第三章】运输层

目录 一、多路复用和多路分解 1、运输层端口号 2、概述 3、原理 1、无连接的多路复用与多路分解 - UDP 2、面向连接的多路复用与多路分解 - TCP 二、无连接运输——UDP用户数据报协议 1、UDP概述 2、UDP的优点 三、可靠数据传输原理 1、概述 2、rdt1.0——可靠信道上…

【AUTOSAR】BMS开发实际项目讲解(十一)----电池管理系统相关项功能安全要求

相关项功能安全要求 SG-BMS-1 : BMS系统应防止电池单体过充导致热失控(ASIL C) 功能框图(SG-BMS-1) 功能组件说明 功能组件ID 功能组件名称 描述 ASIL等级 FSC-FC-01 Detection Cell Volt&Temp 采集表征单体电压和温度的…

Qt中QCompleter自动补全功能

在Qt中有QCompleter这个类可以和QLineEdit组合实现自动补全功能,类似搜索框形式的, 1.QCompleter类可以在输入框输入字符时,进行提示可以匹配上的字符 例:为QLineEdit设置自动补全QLineEdit* pLineEdit new QLineEdit(this);QStr…

【算法】最长递增子序列:动态规划贪心+二分查找

文章目录 最长递增子序列解法一:动态规划解法二:LIS 和 LCS 的关系解法三:贪心 二分查找 相关题目673. 最长递增子序列的个数 https://leetcode.cn/problems/number-of-longest-increasing-subsequence/1964. 找出到每个位置为止最长的有效障…

29.组件库 Element UI

Element UI是PC端常用的组件库,支持vue2与vue3,vue2项目使用的叫 Element UI,vue3使用的叫 Elements Plus,官网地址 一个 Vue 3 UI 框架 | Element Plus 我们下面的代码都是以vue3为例 目录 1 安装 2 引入 3 使用 1 安装 2 引入 完…

快消EDI:联合利华Unilever EDI需求分析

联合利华(Unilever)是一家跨国消费品公司,总部位于英国和荷兰,在全球范围内经营着众多知名品牌,涵盖了食品、饮料、清洁剂、个人护理产品等多个领域。作为一家跨国公司,联合利华在全球各地都有业务和生产基…

el-table表单一键展开折叠,展开部分后一键全部展开或折叠

实现功能: 1.表单一键展开或者一键折叠 2.表单点击展开一部分后,再次点击展开或折叠按钮可以全部展开或全部折叠 3.完整代码在最后 1.建立el-table的树形结构 1.ref"table",用节点绑定的方式实现 2.data:树形结构…

Redis系列--数据过期清除策略缓存淘汰策略

一、过期策略 一、前言 Redis 所有的数据结构都可以设置过期时间,时间一到,就会自动删除。可以想象里面有一个专门删除过期数据的线程,数据已过期就立马删除。这个时候可以思考一下,会不会因为同一时间太多的 key 过期&#xff0…

windows电脑设置每天自动关机

有时候我们需要我们的笔记本或者电脑在每天固定的时间自动关机,但是windows本身是没有带这个设置的,下面记录下如何设置电脑每天自动关机,无需安装任何第三方软件; 文章目录 一、设置自动关机程序二、取消自动关机三、Windows任务…

chatgpt赋能python:Python连接表

Python连接表 Python作为一种高级编程语言,可以用于各种各样的任务。其中之一就是连接表格数据。连接表是在数据管理中非常重要的概念,因为它可以将不同表格中的数据合并在一起,从而使我们能够更好地分析和理解数据。在这篇文章中&#xff0…

蓝桥杯专题-试题版含答案-【猜算式】【排列序数】【还款计算】【滑动解锁】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

探索Gradio的CheckboxGroup模块:交互式多选框组件

❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️ 👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…

详解金融机构敏捷营销落地:体系架构、关键技术和实施方法

本文根据 2023 年金融营销科技价值发现论坛中,神策数据金融首席架构师王仕的主题演讲整理所得,聚焦营销 5.0 理念下的敏捷营销,详细讲解金融机构落地时涉及到的体系架构、关键技术及实施方法。 根据国家发改委官网披露的数据,2022…

macOS编译AirMap开源全景图源码image-processing

1.克隆源码 git clone --recursive https://github.com/airmap/image-processing.git 2. 使用CLion打开CMakeLists.txt并做为工程打开 2.默认配置名为Default,可修改,下面的所有配置项都可改 3.点击OK后会自动生成

青翼自研--4通道DAC播放子卡产品数据手册

FMC131是一款4通道3GSPS采样率或者2通道6GSPS采样率16位DA播放FMC子卡模块,该板卡为FMC标准,符合VITA57.4规范,可以作为一个理想的IO模块耦合至FPGA前端,16通道的JESD204B接口通过FMC连接器连接至FPGA的高速串行端口GTH。插值模式…

突破性5G NTN技术,美格智能携手高通发布卫星物联网连接方案

通信技术的快速发展,使得万物互联成为现实,物联网深刻影响我们的生活方式。目前,全球物联网连接主要由WiFi、蓝牙和蜂窝网络等几类技术支撑。数据显示,蜂窝基站的陆地覆盖率约为20%,而海洋覆盖率则不到5%。 这意味着陆…

十大编程算法

算法一:快速排序算法 快速排序是由东尼霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快&a…

uni-app/vue 文字转语音朗读(附小程序语音识别和朗读)

语音播报的实现的方法有很多种,我这里介绍集中不引用百度、阿里或者迅飞的API的实现方式。 一、采用new SpeechSynthesisUtterance的方式 废话不多说直接上代码 data() {return {utterThis:null,} },//方法使用this.utterThis new SpeechSynthesisUtterance(); …

地下水管三维可视化综合管控平台提升政府服务质量

随着当前互联网技术数据的快速发展和增长,总数越来越大,结构越来越复杂。如果你想更清楚、更快地理解和理解数据,传统的二维平面图数据图性能不能满足需求。 什么是三维可视化? 三维可视化是一种利用计算机技术,再现三维世界中的…

命令模式(Command)

别名 动作(Action)事务(Transaction) 定义 命令是一种行为设计模式,它可将请求转换为一个包含与请求相关的所有信息的独立对象。该转换让你能根据不同的请求将方法参数化、延迟请求执行或将其放入队列中&#xff0c…