OpenCV||超详细的图像边缘检测

news2025/1/21 22:00:26

一、基本概念

1.图像边缘检测目的

  • 特征提取:边缘是图像中亮度变化最显著的部分,它们通常对应于物体的轮廓、不同区域的边界等。通过边缘检测,可以从图像中提取出这些重要的特征信息,为后续处理如图像分割、目标识别等提供基础。

  • 图像简化:边缘检测后的图像往往比原始图像更为简洁,只保留了重要的边缘信息,去除了大量冗余的像素点。这种简化有助于减少计算量,提高处理速度,并使得图像更易于分析和理解。

  • 结构分析:边缘检测可以帮助我们分析图像中的结构信息,如物体的形状、大小、方向等。这些信息对于图像理解、场景重建等任务至关重要。

2.图像边缘检测重要性

  • 提升图像质量:边缘检测可以突出图像中的轮廓信息,使得图像更加清晰、易于观察。这对于需要高精度图像处理的应用场景尤为重要,如医学影像分析、遥感图像处理等。

  • 促进后续处理:边缘检测是许多图像处理任务的预处理步骤,如图像分割、目标检测、目标跟踪等。通过边缘检测,可以更容易地识别出图像中的目标对象,并为后续处理提供准确的定位信息。

  • 增强系统性能:在机器视觉、自动驾驶等领域,边缘检测是实现高精度目标识别和场景理解的关键技术之一。通过准确的边缘检测,可以提高系统的识别准确率和鲁棒性,从而增强整个系统的性能。

  • 降低计算复杂度:由于边缘检测后的图像更为简洁,因此在后续处理中可以减少计算量,降低计算复杂度。这对于实时性要求较高的应用场景尤为重要,如视频监控、自动驾驶等。

3.何为图像边缘?

  • 亮度或灰度值的变化:边缘是图像中亮度或灰度值发生显著变化的地方。这种变化可以是突然的,也可以是渐变的,但边缘通常指的是那些变化最为明显的区域。

  • 方向性:边缘具有一定的方向性,即它们通常沿着某个特定的方向延伸。这个方向对应于亮度或灰度值变化最快的方向,也就是梯度的方向。

  • 局部性:边缘是图像中的局部特征,它们只影响图像中的一小部分区域。这意味着边缘检测算法通常只需要考虑每个像素点及其邻域内的像素点,而不需要考虑整个图像。

  • 不连续性:在理想情况下,边缘应该是图像中不连续的点或线段。然而,在实际应用中,由于噪声、光照变化等因素的影响,边缘可能会表现为模糊或不规则的形状。

4.图像边缘检测原理

  • 灰度变化:边缘检测的基本原理是基于图像中局部区域与周围区域之间的灰度变化。当图像中存在灰度变化时,这种变化通常被视为边缘。

  • 梯度计算:为了检测这些灰度变化,边缘检测算法会计算图像中每个像素点或其邻域的灰度梯度。梯度是一个向量,它反映了亮度变化的方向和速率。梯度的幅值(大小)表示亮度变化的强度,而梯度的方向则指出了亮度变化的方向。在实际应用中,梯度可以通过不同的算法来计算,如Sobel算子、Prewitt算子等。这些算法通过应用特定的卷积核(或模板)到图像上,来计算每个像素点的梯度。

  • 阈值处理:计算得到梯度后,通常需要进行阈值处理来进一步确定哪些像素点属于边缘。阈值处理通过比较梯度幅值与预设的阈值来判断该点是否为边缘点。如果梯度幅值大于阈值,则认为该点是边缘点;否则,认为该点是非边缘点。

  • 非极大值抑制(在某些算法中):为了进一步细化边缘,有些边缘检测算法(如Canny边缘检测算法)会采用非极大值抑制技术。非极大值抑制会沿着梯度的方向检查每个像素点,如果当前像素点的梯度幅值不是其邻域内的局部最大值,则将该点标记为非边缘点。

  • 边缘连接(在某些算法中):在某些情况下,边缘检测算法还会进行边缘连接,以将断开的边缘片段连接起来,形成完整的边缘轮廓。

5.边缘检测算法分类

边缘检测算法大致可以分为两类:基于一阶导数的算法和基于二阶导数的算法。

  • 基于一阶导数的算法:如Sobel算子、Prewitt算子等,它们通过计算图像的一阶导数(即梯度)来检测边缘。这些算法对噪声有一定的抑制能力,且计算相对简单。
  • 基于二阶导数的算法:如Laplacian算子、Canny边缘检测算法等,它们通过计算图像的二阶导数来检测边缘。这些算法对噪声更加敏感,但能够检测到更细致的边缘。

 二、边缘检测步骤

1. 滤波

  • 目的:降低图像噪声。边缘检测算法主要基于图像强度的一阶和二阶导数,但这些导数对噪声非常敏感。因此,滤波是边缘检测前的必要步骤,以减少噪声对边缘检测结果的影响。
  • 方法:常用的滤波器是高斯滤波器。高斯滤波器通过离散化的高斯函数产生一组归一化的高斯核,然后基于这些高斯核对图像灰度矩阵的每一点进行加权求和,从而实现图像的平滑处理。

2. 增强

  • 目的:增强图像中的边缘信息。增强算法的目的是将图像中灰度有显著变化的点(即潜在的边缘点)凸显出来。
  • 方法:一般通过计算梯度幅值来完成。梯度是一个向量,表示图像中亮度变化的方向和速率。梯度的幅值反映了亮度变化的强度,因此可以通过计算每个像素点的梯度幅值来增强边缘信息。

3. 检测

  • 目的:从增强后的图像中提取边缘点。虽然经过增强处理后,图像中的边缘信息得到了凸显,但并非所有梯度幅值较大的点都是真正的边缘点。
  • 方法:常用的方法是通过阈值化来检测边缘点。即设定一个或多个阈值,将梯度幅值大于阈值的点视为边缘点。在实际应用中,可能会采用双阈值策略,先使用较低的阈值保留尽可能多的边缘信息,然后使用较高的阈值去除噪声和非边缘点,最后通过连接两个阈值结果中的边缘点来得到最终的边缘检测结果。

4. 定位

  • 目的:精确确定边缘的位置。在检测到边缘点后,需要进一步确定边缘的精确位置。
  • 方法:这通常涉及到对边缘点的进一步处理和分析,如亚像素边缘定位等。亚像素边缘定位技术可以在像素级别以下对边缘位置进行更精确的定位,从而提高边缘检测的精度。

5. 边缘连接(可选)

  • 目的:将检测到的边缘点连接成完整的边缘轮廓。在某些情况下,由于噪声、光照变化等因素的影响,检测到的边缘点可能会呈现为断开的片段。
  • 方法:通过一定的算法(如霍夫变换、轮廓跟踪等)将这些断开的边缘片段连接起来,形成完整的边缘轮廓。

三、边缘检测算法

以下算法(所有基于梯度的边缘检测器)根本区别有如下三点:

  • 算子应用的方向
  • 在这些方向上逼近图像一维导数的方式
  • 将这些近似值合成梯度幅值的方式

算法实现一般步骤:

1. Sobel边缘检测算法

基本原理

  • Sobel算法基于一阶导数的边缘检测算子,通过计算图像中每个像素点周围邻域内的灰度梯度来检测边缘。
  • 它结合了高斯模糊和一阶微分,并计算图像明暗程度的近似值,通过比较图像边缘的明暗程度把该区域内超过阈值的特定像素点记为边缘点。

特点

  • Sobel算子对噪声具有一定的抑制能力,且边缘定位精度较高。
  • 但由于引入了像素的灰度值平均化处理,可能会导致边缘轮廓的模糊。

OpenCV实现示例

import cv2  
import numpy as np  
import matplotlib.pyplot as plt  
  
# 读取图像  
def load_image(image_path):  
    # 使用cv2.imread()读取图像,参数0表示以灰度模式读取  
    img = cv2.imread(image_path, 0)  
    if img is None:  
        raise FileNotFoundError("图像文件未找到或路径错误")  
    return img  
  
# 使用Sobel算子进行边缘检测  
def sobel_edge_detection(image):  
    # 将图像转换为float32类型,以避免在计算中出现数据类型溢出  
    image_float = np.float32(image)  
      
    # 分别计算X和Y方向的Sobel梯度  
    # 参数dx=1, dy=0, ksize=3表示计算X方向的Sobel梯度  
    sobelx = cv2.Sobel(image_float, cv2.CV_64F, 1, 0, ksize=3)  
    # 参数dx=0, dy=1, ksize=3表示计算Y方向的Sobel梯度  
    sobely = cv2.Sobel(image_float, cv2.CV_64F, 0, 1, ksize=3)  
      
    # 计算梯度幅度,这里使用欧几里得距离  
    sobel_magnitude = np.sqrt(sobelx**2 + sobely**2)  
      
    # 将梯度幅度转换为uint8类型,便于显示  
    sobel_magnitude_uint8 = np.uint8(np.absolute(sobel_magnitude))  
      
    return sobel_magnitude_uint8  
  
# 主函数  
def main():  
    # 图像路径  
    image_path = 'path_to_your_image.jpg'  
      
    # 加载图像  
    img = load_image(image_path)  
      
    # 使用Sobel算子进行边缘检测  
    edges = sobel_edge_detection(img)  
      
    # 显示原图和处理后的图像  
    plt.figure(figsize=(10, 5))  
    plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('Original Image')  
    plt.xticks([]), plt.yticks([])  
    plt.subplot(122), plt.imshow(edges, cmap='gray'), plt.title('Sobel Edge Detection')  
    plt.xticks([]), plt.yticks([])  
    plt.show()  
  
if __name__ == "__main__":  
    main()

 

2. Canny边缘检测算法

基本原理

  • Canny算法是一个综合了滤波、增强、检测等多阶段的边缘检测算子。
  • 它首先使用高斯滤波器对图像进行平滑处理,以减少噪声。
  • 然后计算图像中每个像素点的梯度幅值和方向。
  • 接着通过非极大值抑制技术来细化边缘。
  • 最后采用双阈值检测方法来确定最终的边缘点。

特点

  • Canny算法能够尽可能多地标示出图像中的实际边缘,且标示出的边缘与实际的边缘尽可能地相同。
  • 它对噪声的抑制能力较强,且边缘定位精度高。
  • 但计算量相对较大,且对参数设置较为敏感。
  • 低阈值用于边缘连接,高阈值用于检测强边缘。

OpenCV实现示例

import cv2  
import numpy as np  
  
# 读取图片  
# 请确保你的图片路径是正确的,或者将'path_to_your_image.jpg'替换为图片的文件名(如果图片和脚本在同一目录下)  
image_path = 'path_to_your_image.jpg'  
image = cv2.imread(image_path)  
  
# 检查图片是否成功读取  
if image is None:  
    print("Error: 图片没有成功读取。请检查文件路径。")  
else:  
    # 转换为灰度图,因为Canny边缘检测在灰度图上运行  
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  
  
    # 应用Canny边缘检测  
    # 第一个参数是灰度图  
    # 第二个和第三个参数分别是Canny算法中的低阈值和高阈值  
    # 这两个阈值的选择取决于你的具体图像,可能需要一些实验来找到最佳值  
    edges = cv2.Canny(gray_image, threshold1=100, threshold2=200)  
  
    # 显示原图和边缘检测结果  
    cv2.imshow('Original Image', image)  
    cv2.imshow('Canny Edges', edges)  
  
    # 等待按键操作,之后关闭所有窗口  
    cv2.waitKey(0)  
    cv2.destroyAllWindows()

 

3. Roberts边缘检测算法

基本原理

  • Roberts算法是一种基于对角线方向相邻两像素之差的边缘检测算子。
  • 它通过计算对角线方向上的差分来估计梯度,并根据梯度的大小来判断边缘。

特点

  • Roberts算子较为简单,且计算速度快。
  • 但它只能检测45°或135°方向的边缘,且对噪声较为敏感。

OpenCV实现示例

import cv2  
import numpy as np  
  
def roberts_edge_detection(image_path):  
    # 读取图像  
    image = cv2.imread(image_path)  
    if image is None:  
        print("Error: Image not found or unable to read.")  
        return  
  
    # 转换为灰度图  
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  
  
    # 定义Roberts算子的两个卷积核  
    kernel_x45 = np.array([[-1, 0],  
                           [ 0, 1]], dtype=np.float32)  
    kernel_y135 = np.array([[0, -1],  
                            [1,  0]], dtype=np.float32)  
  
    # 应用Roberts算子得到两个方向的梯度图  
    grad_x45 = cv2.filter2D(gray_image, cv2.CV_16S, kernel_x45)  
    grad_y135 = cv2.filter2D(gray_image, cv2.CV_16S, kernel_y135)  
  
    # 将梯度图转换为绝对值,并转换为8位无符号整数  
    abs_grad_x45 = cv2.convertScaleAbs(grad_x45)  
    abs_grad_y135 = cv2.convertScaleAbs(grad_y135)  
  
    # 计算梯度的幅值(这里使用绝对值相加作为近似)  
    gradient_magnitude = cv2.addWeighted(abs_grad_x45, 0.5, abs_grad_y135, 0.5, 0)  
  
    # 对梯度幅值进行阈值化处理,得到二值边缘图像  
    _, edges = cv2.threshold(gradient_magnitude, 50, 255, cv2.THRESH_BINARY)  
  
    # 显示结果  
    cv2.imshow('Original Image', image)  
    cv2.imshow('Roberts Edges', edges)  
    cv2.waitKey(0)  
    cv2.destroyAllWindows()  
  
# 调用函数,传入图像路径  
roberts_edge_detection('path_to_your_image.jpg')

4. Prewitt边缘检测算法

基本原理

  • Prewitt算法也是一种基于一阶导数的边缘检测算子。
  • 它通过计算图像中每个像素点周围邻域内的灰度梯度来检测边缘。
  • Prewitt算子使用两个卷积核分别检测水平和垂直方向的边缘,然后取两个方向上的最大值作为该点的边缘强度。

特点

  • Prewitt算子对噪声具有一定的抑制能力,且边缘定位精度较高。
  • 但与Sobel算子相比,它可能更容易产生一些噪声。

 OpenCV实现示例

import cv2  
import numpy as np  
  
def prewitt_operator(image, axis='both'):  
    """  
    使用Prewitt算子进行边缘检测  
  
    参数:  
    - image: 输入图像,应为灰度图  
    - axis: 指定使用哪个方向的Prewitt算子,'x'为水平方向,'y'为垂直方向,'both'为两个方向都使用  
  
    返回:  
    - 如果axis为'x'或'y',则返回相应方向的边缘检测结果;  
    - 如果axis为'both',则返回两个方向边缘检测结果的叠加。  
    """  
    # 定义Prewitt算子  
    prewitt_x = np.array([[-1, 0, 1],  
                          [-1, 0, 1],  
                          [-1, 0, 1]], dtype=np.float32)  
    prewitt_y = np.array([[-1, -1, -1],  
                          [ 0,  0,  0],  
                          [ 1,  1,  1]], dtype=np.float32)  
  
    # 将图像转换为浮点数类型,以便进行精确计算  
    image_float = np.float32(image)  
  
    # 根据指定的axis计算边缘  
    if axis == 'x':  
        edges = cv2.filter2D(image_float, -1, prewitt_x)  
    elif axis == 'y':  
        edges = cv2.filter2D(image_float, -1, prewitt_y)  
    elif axis == 'both':  
        edges_x = cv2.filter2D(image_float, -1, prewitt_x)  
        edges_y = cv2.filter2D(image_float, -1, prewitt_y)  
        edges = cv2.addWeighted(edges_x, 0.5, edges_y, 0.5, 0)  
    else:  
        raise ValueError("Invalid axis value. Use 'x', 'y', or 'both'.")  
  
    # 将边缘检测结果转换为8位无符号整数  
    edges = np.uint8(np.absolute(edges))  
  
    return edges  
  
# 读取图像并转换为灰度图  
image = cv2.imread('your_image_path.jpg', cv2.IMREAD_GRAYSCALE)  
  
# 使用Prewitt算子进行边缘检测  
edges = prewitt_operator(image, 'both')  
  
# 显示原图和边缘检测结果  
cv2.imshow('Original Image', image)  
cv2.imshow('Prewitt Edges', edges)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

5. Laplacian边缘检测算法

基本原理

  • Laplacian算法是一种基于二阶导数的边缘检测算子。
  • 它通过计算图像中每个像素点的二阶导数(即拉普拉斯算子)来检测边缘。
  • 由于二阶导数对噪声非常敏感,因此Laplacian算子在检测边缘之前通常需要对图像进行平滑处理。

特点

  • Laplacian算子能够检测到图像中的孤立点和噪声点,因此它更适合于对图像中的细节进行检测。
  • 但由于它对噪声敏感,且边缘定位精度不如一阶导数算子,因此在实际应用中可能需要与其他算法结合使用。

6.LoG边缘检测算法

 OpenCV实现示例

import cv2  
import numpy as np  
  
def log_edge_detection(image_path, sigma=1.4, ksize=5):  
    """  
    使用LoG(Laplacian of Gaussian)算子进行边缘检测  
  
    参数:  
    image_path : str  
        图像文件的路径  
    sigma : float  
        高斯模糊的标准差。较大的sigma值会产生更平滑的图像,适用于检测更广泛的边缘。  
    ksize : int  
        高斯核的大小,必须是正数和奇数。它会影响高斯模糊的效果。  
  
    返回:  
    edges : ndarray  
        边缘检测后的图像  
    """  
    # 读取图像  
    image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)  
    if image is None:  
        raise FileNotFoundError("无法找到或读取图像文件")  
  
    # 应用高斯模糊  
    blurred = cv2.GaussianBlur(image, (ksize, ksize), sigma)  
  
    # 计算拉普拉斯算子  
    # 注意:OpenCV中的Laplacian函数默认使用ddepth=cv2.CV_64F,然后转换为8位以显示  
    laplacian = cv2.Laplacian(blurred, cv2.CV_64F)  
    laplacian = np.uint8(np.absolute(laplacian))  
  
    # 由于拉普拉斯算子可能会产生负值,使用绝对值函数将其转换为正值  
    # 然后将数据类型转换为uint8以用于显示  
  
    # 返回边缘检测后的图像  
    return laplacian  
  
# 使用示例  
if __name__ == "__main__":  
    image_path = 'path_to_your_image.jpg'  # 替换为你的图像文件路径  
    edges = log_edge_detection(image_path)  
  
    # 显示原图和处理后的图像  
    cv2.imshow('Original Image', cv2.imread(image_path, cv2.IMREAD_GRAYSCALE))  
    cv2.imshow('LoG Edge Detection', edges)  
    cv2.waitKey(0)  
    cv2.destroyAllWindows()

 详细参考以下几篇文章:@搬运程序的小垃圾

http://t.csdnimg.cn/s71P6icon-default.png?t=N7T8http://t.csdnimg.cn/s71P6深度学习系列-几种边缘检测算法 - 知乎 (zhihu.com)icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/324540079数字图像处理——边缘检测算法 - 知乎 (zhihu.com)icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/357515658

四、边缘检测最新技术与方法

一、基于深度学习的边缘检测

  1. 扩散模型(如DiffusionEdge)
    • 简介:国防科技大学提出的DiffusionEdge是首个用于二维边缘检测任务的扩散概率模型方法。该方法通过学习迭代的去噪过程获得边缘结果图,能够在保留最终性能的同时减少计算资源的消耗。
    • 优势:无需任何后处理即可预测出更细更准确的边缘图,且在多个公共基准数据集上表现出卓越的性能。
    • 技术细节:在隐空间中训练网络,引入不确定性蒸馏模块以优化模型,采用解耦架构加速去噪过程,并提出自适应傅立叶滤波器调整特征。
  2. 其他深度学习模型
    • 深度学习模型如卷积神经网络(CNN)和生成对抗网络(GAN)也被广泛应用于边缘检测。这些模型通过自动学习图像特征,能够更准确地识别边缘。

二、基于小波与分形理论的边缘检测

  • 小波变换:小波分析在图像工程中应用广泛,通过多尺度分解图像,能够有效提取不同尺度下的边缘特征。小波包变换更是对图像的高频部分也进行分解,提高了边缘检测的准确性。
  • 分形理论:基于分形特征的边缘检测方法通过分析图像的几何结构来检测边缘,适用于复杂图像的边缘检测。

三、基于数学形态学的边缘检测

  • 数学形态学是一种分析几何形状和结构的数学方法,通过膨胀、腐蚀等基本变换以及它们的组合来进行图像形态和结构分析处理,包括边缘检测。
  • 形态学边缘检测方法具有算法简便、速度快、效果好等特点,对图像细节和边缘定位也有不错的效果。

四、基于模糊理论的边缘检测

  • 模糊综合评判理论在边缘检测中的应用主要体现在模糊增强技术上,通过增加不同区域的对比度来提取模糊边缘。
  • 该方法在处理含噪图像时具有较好的噪声抑制效果,但计算复杂度较高。

五、基于神经网络的边缘检测

  • 人工神经网络广泛应用于模式识别领域,包括图像边缘检测。通过训练神经网络来识别图像中的边缘特征,可以实现高精度的边缘检测。
  • 神经网络方法具有较强的抗噪性能,能够处理复杂背景下的边缘检测问题。

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

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

相关文章

请你学习:前端布局3 - 浮动 float

1 标准流(也称为普通流、文档流) 标准流(也称为普通流、文档流)是CSS中元素布局的基础方式,它决定了元素在页面上的默认排列方式。这种布局方式遵循HTML文档的结构,不需要额外的CSS样式来指定元素的位置。…

python open cv(图像处理的基本操作)

概要图 1读取图像 cv2.imread() 函数是OpenCV库中用于读取图像文件的函数。它有两个参数: 文件名:这是第一个也是必需的参数,它指定了要读取的图像文件的路径和文件名。这个路径可以是相对路径,也可以是绝对路径。 标志&#xf…

小技巧大功效,「仅阅读两次提示」让循环语言模型超越Transformer++

在当前 AI 领域,大语言模型采用的主流架构是 Transformer。不过,随着 RWKV、Mamba 等架构的陆续问世,出现了一个很明显的趋势:在语言建模困惑度方面与 Transformer 较量的循环大语言模型正在快速进入人们的视线。 令人兴奋的是&am…

c++ string解析及其实现

因为字符串是固定长度&#xff0c;不好进行操作&#xff0c;因此c就用类将字符串进行了封装让其变得方便实用。 要深刻了解string&#xff0c;我们必须要熟练掌握类的使用&#xff0c;如果还有疑问可以看这一篇博客:c 类 (要学习类这一篇就够了 ) string #include<string…

Android 11(R)启动流程 初版

启动流程 bootloader会去启动android第一个进程Idle&#xff0c;pid为0&#xff0c;会对进程 内存管理等进行初始化。Idle还被称作swapper。Idle会去创建两个进程&#xff0c;一个是init&#xff0c;另外一个是kthread。 kthread会去启动内核&#xff0c;用户是由init进行启动。…

算法通关:017_1:二叉树及三种顺序的递归遍历

文章目录 题目思路代码运行结果 题目 二叉树及三种顺序的递归遍历 思路 代码 /*** Author: ggdpzhk* CreateTime: 2024-08-04** 二叉树及三种顺序的递归遍历* LeetCode 144. 二叉树的前序遍历* LeetCode 94. 二叉树的中序遍历* LeetCode 145. 二叉树的后序遍历* LeetCode 10…

sqli-labs靶场——第二关

1、判断注入类型 ?id1和?id2-1的页面一样所以是数字型 2、判断闭合类型 数字型没有闭合符号 3、order by查看有几列 当输入order by 4 时候页面变化&#xff0c;3的时候正常&#xff0c;所以是3列 4、union select联合查询查看回显 /sqli-labs/Less-2/?id-1 union sel…

ESP32使用MQTT协议通讯(EMQX)

一、背景介绍 前面完成了ESP32MicroPython环境的搭建01_ESP32 MicroPython开发环境搭建_eps32开发板-CSDN博客 现在想实现以下功能&#xff1a; 1.通过手机或电脑&#xff0c;远程给ESP32发送相关指令。 2.ESP32接到指令后&#xff0c;做出相应的高低电平输出。 这样就相当…

视频编辑SDK,底层架构合理,前端自定义程度高

如何高效、专业地制作出符合品牌形象、吸引目标受众的视频内容&#xff0c;成为了众多企业面临的共同挑战。美摄科技&#xff0c;作为视频编辑技术的先行者&#xff0c;以其卓越的视频编辑SDK&#xff08;Software Development Kit&#xff09;&#xff0c;为企业用户量身打造了…

进程状态都有哪些?

目录 前言&#xff1a; 进程的各个状态&#xff1a; 1、R状态&#xff08;进程运行状态&#xff09;和S状态&#xff08;休眠状态&#xff09; 2、T状态和t状态&#xff08;暂停进程&#xff09; 3、D状态&#xff08;磁盘休眠状态&#xff09; 4、Z状态&#xff08;僵尸状…

学习笔记 韩顺平 零基础30天学会Java(2024.8.2)

P447 五大运行时异常 P448 异常课堂练习 P449 异常处理机制 try-catch-finally throws(处理机制二选一)&#xff0c;如果没有显式处理异常&#xff0c;默认throws JVM处理异常直接输出异常信息&#xff0c;退出程序 P450 tryCatch 对于第一个细节&#xff0c;发生异常之后时try…

C语言快速入门及精通学习指南——手把手教零基础/新手入门(完整C语言学习笔记整理)

前言 作为一名拥有多年开发经验的码农&#xff0c;我的职业生涯涵盖了多种编程语言&#xff0c;包括 C 语言、C、C# 和 JavaScript。在这一过程中&#xff0c;我深刻地意识到扎实的基础对于编程学习的重要性&#xff0c;尤其是对于 C 语言这样一门核心语言来说。 出于对…

sgg快餐项目-3 项目

一、数仓架构 本项目的数据是事务数据&#xff0c;都存储在mysql数据库&#xff0c;如果是其他的项目&#xff0c;那数据可能会在文本、爬虫等。要使用相关的组件将数据导入到HDFS上。&#xff08;因为要把数据导入到hive做数据管理、存储和分析&#xff0c;而hive就是在hfds上…

2024年文件防泄密系统TOP3|遥遥领先的文件防泄密系统

古语有云&#xff1a;“密者&#xff0c;国之重器&#xff0c;不可不慎。” 在今日之数字化时代&#xff0c;信息的保密与安全&#xff0c;已然成为企业乃至国家生存与发展的基石。 随着数据泄露事件频发&#xff0c;文件防泄密系统的重要性愈发凸显。 2024年&#xff0c;随着…

数据存储与访问

一、文件存储读写 1.Android文件的操作模式 2.文件的相关操作方法 3.文件读写的实现 Android中的文件读写和Java中的文件I/O相同&#xff0c;流程也很简单&#xff0c;下面我们来写个简单的示例&#xff1a; PS:这里用的是模拟器&#xff0c;因为笔者的N5并没有root&#xf…

Go语言加Vue3零基础入门全栈班11 Go语言+gorm用户管理系统实战 2024年08月03日 课程笔记

概述 如果您没有Golang的基础&#xff0c;应该学习如下前置课程。 Golang零基础入门Golang面向对象编程Go Web 基础Go语言开发REST API接口_20240728Go语言操作MySQL开发用户管理系统API教程_20240729Redis零基础快速入门_20231227GoRedis开发用户管理系统API实战_20240730Mo…

工业人工智能真的能落地吗?

文章目录 前言Part1 聊聊技术1 人工智能、机器学习和深度学习的关系2 优化思想的一个案例 part2 聊聊业务3 工业人工智能与消费互联网人工智能的区别3.1 消费互联网中人工智能的应用3.2 为什么如此成熟的消费互联网人工智能扩展到工业场景那么难 4 工业互联网人工智能的发展方向…

wxPython中wx.adv.DatePickerCtrl用法

wx.adv.DatePickerCtrl是一个日期选择组件&#xff0c;支持键盘手工录入日期和弹出日历窗口选择日期两种方式。 一、组件样式 wx.adv.DP_SPIN &#xff1a; 只允许键盘手工录入和组件右侧上下箭头调整日期。 wx.adv.DP_DROPDOWN &#xff1a; 只允许健盘手工录入和组件右侧打开…

CentOS7 编译ffmpeg wasm库

1. 安装 emscripten 1)克隆 emsdk git clone https://github.com/emscripten-core/emsdk.git 2)cd 到emsdk 3)安装,按照官网的步骤(Download and install — Emscripten 3.1.65-git (dev) documentation) 4)验证 注意:如果emcc -v 报错: 提示是python脚本错误,是因为…

Qt Modbus 寄存器读写实例

一.线圈状态寄存器读写 项目效果如下 1. 写单个寄存器 MODBUS_API int modbus_write_bit(modbus_t *ctx, int coil_addr, int status); int addrui->spinBoxwirte_addr->value();int dataui->spinBoxwirte_data->value();int ret modbus_write_bit(mb,addr,d…