OpenCV-Python (官方)中文教程(部分一)_Day15
18.图像梯度
梯度简单来说就是求导。
OpenCV 提供了三种不同的梯度滤波器,或者说高通滤波器:Sobel, Scharr和Laplacian。Sobel,Scharr 其实就是求一阶或二阶导数。Scharr 是对 Sobel(使用小的卷积核求解求解梯度角度时)的优化。Laplacian 是求二阶导数。
-
Sobel算子和Scharr算子
1. Sobel 算子
原理
Sobel 算子结合了高斯平滑和微分操作,能有效抑制噪声。
它计算图像的一阶梯度(导数),分为水平方向(x方向)和垂直方向(y方向):
x方向:检测垂直边缘(对水平变化敏感)。
y方向:检测水平边缘(对垂直变化敏感)。
卷积核
3×3 Sobel 核(x方向):
3×3 Sobel 核(y方向):
特点
抗噪声能力强(因高斯平滑)。
可通过 ksize 参数调整核大小(如 3×3、5×5)。
2. Scharr 算子
原理
Scharr 是 Sobel 的改进版,对边缘的响应更强,尤其在3×3核时效果更优。
当 ksize=-1 时,OpenCV 会自动使用 Scharr 核替代 Sobel。
卷积核
3×3 Scharr 核(x方向):
3×3 Scharr 核(y方向):
特点
比 Sobel 的梯度计算更精确,适合对边缘敏感的场景。
计算速度与 Sobel 相同,推荐在 3×3 核时优先使用。
Sobel 算子是高斯平滑与微分操作的结合体,所以它的抗噪声能力很好。你可以设定求导的方向(xorder 或 yorder)。还可以设定使用的卷积核的大小(ksize)。如果 ksize=-1,使用 3x3 的 Scharr 滤波器要 比 3x3 的 Sobel 滤波器的效果好(而且速度相同,所以在使用 3x3 滤波器时应该尽量使用 Scharr 滤波器)。3x3 的 Scharr 滤波器卷积核如下:
3.Laplacian算子
原理
Laplacian 算子是二阶导数算子,直接计算图像的曲率(即梯度的梯度),能同时突出边缘和角点。
它对噪声敏感,通常需先高斯滤波(如结合 GaussianBlur)。
卷积核
3×3 Laplacian 核:
扩展核(增强对角线响应):
特点
直接检测灰度突变区域(如边缘、孤立点)。
OpenCV 内部通过调用 Sobel 算子实现二阶导数计算。
拉普拉斯(Laplacian)算子可以使用二阶导数的形式定义,可假设其离散实现类似于二阶 Sobel 导数,事实上,OpenCV 在计算拉普拉斯算子时直接调用 Sobel 算 子。计算公式如下:
拉普拉斯滤波器使用的卷积核:
三者的对比
关键点总结
Sobel/Scharr:一阶导数,检测边缘方向;Scharr 在 3×3 核时更优。
Laplacian:二阶导数,对噪声敏感,需配合平滑使用。
卷积核:不同核决定了算子的敏感性和计算特性。
import cv2
import numpy as np
# 读取图像(灰度化)
img = cv2.imread('2.png', cv2.IMREAD_GRAYSCALE)
# Sobel 算子
#cv2.CV_64F:输出图像的深度(64位浮点型,避免梯度计算时的截断)。1, 0:对 x 方向求一阶导数(检测垂直边缘)。
#0, 1:对 y 方向求一阶导数(检测水平边缘)。ksize=3:使用 3×3 的 Sobel 核
sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) #检测垂直边缘x方向
#Sobel/Laplacian 的输出是浮点数,直接显示可能导致全白/全黑
sobel_x = cv2.convertScaleAbs(sobel_x) # 转为8位无符号整型
sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3) #检测水平边缘y方向
# Scharr 算子(当 ksize=-1 时自动启用)更精确的边缘检测
scharr_x = cv2.Scharr(img, cv2.CV_64F, 1, 0)
#Sobel/Laplacian 的输出是浮点数,直接显示可能导致全白/全黑
scharr_x = cv2.convertScaleAbs(scharr_x)
scharr_y = cv2.Scharr(img, cv2.CV_64F, 0, 1)
# Laplacian 算子 计算图像的二阶导数,同时突出边缘和角点(如纹理细节)。对噪声敏感,通常需先高斯滤波(但代码中未预处理)。
laplacian = cv2.Laplacian(img, cv2.CV_64F)
#二阶导数可能产生负值,需取绝对值
laplacian = np.absolute(laplacian) # 取绝对值
laplacian = np.uint8(255 * laplacian / np.max(laplacian)) # 归一化
# 水平拼接三个结果
combined = np.hstack((sobel_x, scharr_x, laplacian))
# 显示合并后的图像
cv2.imshow('Sobel X | Scharr X | Laplacian', combined)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
总结
Sobel:检测方向性边缘(分x/y方向)。
Scharr:更精确的3×3边缘检测。
Laplacian:检测边缘+角点(二阶导数)。
应用场景:
车牌识别(Sobel找边缘)
医学图像分析(Scharr增强细节)
纹理分析(Laplacian突出特征)
代码
下面的代码分别使用以上三种滤波器对同一幅图进行操作。使用的卷积核都是5x5。
import cv2
from matplotlib import pyplot as plt
img=cv2.imread('dave.jpg',0)
#cv2.CV_64F 输出图像的深度(数据类型),可以使用-1, 与原图像保持一致 np.uint8
laplacian=cv2.Laplacian(img,cv2.CV_64F)
# 参数 1,0 为只在 x 方向求一阶导数,最大可以求 2 阶导数。
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5) # 参数 0,1 为只在 y 方向求一阶导数,最大可以求 2 阶导数。
sobely=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray')
plt.title('Laplacian'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray')
plt.title('Sobel X'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray')
plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])
plt.show()
结果:
注意!
在查看上面这个例子的注释时不知道你有没有注意到:当我们可以通过参 数 -1 来设定输出图像的深度(数据类型)与原图像保持一致,但是我们在代码中使用的却是 cv2.CV_64F。这是为什么呢?想象一下一个从黑到白的边界的导数是整数,而一个从白到黑的边界点导数却是负数。如果原图像的深度是 np.int8 时,所有的负值都会被截断变成 0,换句话说就是把边界丢失掉。
所以如果这两种边界你都想检测到,最好的的办法就是将输出的数据类型设置的更高,比如 cv2.CV_16S,cv2.CV_64F 等。取绝对值然后再把它转回到cv2.CV_8U。
1. 为什么不能直接用 cv2.CV_8U(8位无符号整数)?
问题场景:
假设图像中有一个从白→黑的边缘(如下图),其导数(梯度值)为负值。
白像素(255) → 黑像素(0) → 导数 = 0 - 255 = -255
数据类型的影响:
如果输出深度是 cv2.CV_8U(0~255的无符号整数),所有负值会被截断为0。
结果:白→黑的边缘完全丢失,只能检测黑→白的边缘!
2. 为什么用 cv2.CV_64F(64位浮点数)?
关键原因:
保留负值:导数计算结果可能是正(黑→白)、负(白→黑)或零(平坦区域)。
浮点类型(如 CV_64F)可以存储这些负数,避免截断。
后续处理:
通过 np.absolute() 或 cv2.convertScaleAbs() 取绝对值,再转回 cv2.CV_8U 显示。
3. 不同数据类型的对比示例
(1) 错误做法:直接输出 cv2.CV_8U
laplacian_bad = cv2.Laplacian(img, cv2.CV_8U) # 负值被截断为0
cv2.imshow('Bad (CV_8U)', laplacian_bad) # 丢失白→黑边缘
效果:边缘不完整,部分方向消失。
(2) 正确做法:使用 cv2.CV_64F + 取绝对值
laplacian_good = cv2.Laplacian(img, cv2.CV_64F) # 保留负值
laplacian_good = np.absolute(laplacian_good) # 取绝对值
laplacian_good = np.uint8(laplacian_good) # 转回8位显示
cv2.imshow('Good (CV_64F)', laplacian_good) # 完整边缘
效果:所有方向的边缘均被检测到。
4. 数据类型选择建议
5. 完整流程的代码注释
import cv2
import numpy as np
# 读取图像(灰度化)
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# Step 1: 使用 cv2.CV_64F 保留负值导数
laplacian = cv2.Laplacian(img, cv2.CV_64F) # 输出包含正/负/零
# Step 2: 取绝对值(白→黑和黑→白边缘均保留)
laplacian_abs = np.absolute(laplacian)
# Step 3: 归一化到 0~255 并转为 8位无符号整型
laplacian_8u = np.uint8(255 * laplacian_abs / np.max(laplacian_abs))
# 显示结果
cv2.imshow('Laplacian Edges', laplacian_8u)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
import cv2
import numpy as np
def enhanced_laplacian_edge_detection(image_path, blur_ksize=(5,5), display=True):
"""优化的Laplacian边缘检测函数
Args:
image_path: 输入图像路径
blur_ksize: 高斯模糊核大小,默认(5,5)
display: 是否显示结果,默认True
Returns:
处理后的边缘图像
"""
# 1. 图像读取与预处理
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if img is None:
raise FileNotFoundError(f"无法加载图像: {image_path}")
# 2. 高斯模糊降噪(优化:自动计算sigma)
blurred = cv2.GaussianBlur(img, blur_ksize, sigmaX=0)
# 3. Laplacian边缘检测(优化:使用CV_16S节省内存)
laplacian = cv2.Laplacian(blurred, cv2.CV_16S, ksize=3)
# 4. 后处理(优化:自适应对比度增强)
laplacian_abs = cv2.convertScaleAbs(laplacian) # 比np.absolute更快
# 自适应归一化(排除前5%的极值)
v_min, v_max = np.percentile(laplacian_abs, [5, 95])
laplacian_norm = np.clip((laplacian_abs - v_min) * 255. / (v_max - v_min), 0, 255)
laplacian_8u = laplacian_norm.astype(np.uint8)
# 5. 可选显示
if display:
# 对比显示原图与结果
comparison = np.hstack([img, laplacian_8u])
cv2.imshow(f'Original vs Enhanced Laplacian (ksize={blur_ksize})', comparison)
cv2.waitKey(0)
cv2.destroyAllWindows()
return laplacian_8u
# 使用示例
enhanced_edges = enhanced_laplacian_edge_detection('2.png', blur_ksize=(7,7))
使用建议:
对于高噪声图像,建议增大blur_ksize(如(9,9))
需要更强边缘时,可在归一化前乘以增强系数:
laplacian_abs = laplacian_abs * 1.5 # 边缘增强
对于需要进一步处理的情况,建议保留CV_16S格式的原始结果
相关文章:
OpenCV-Python (官方)中文教程(部分一)_Day15
18.图像梯度 梯度简单来说就是求导。 OpenCV 提供了三种不同的梯度滤波器,或者说高通滤波器:Sobel, Scharr和Laplacian。Sobel,Scharr 其实就是求一阶或二阶导数。Scharr 是对 Sobel(使用小的卷积核求解求解梯度角度时)的优化。Laplacian 是…...
大厂面试:MySQL篇
前言 本章内容来自B站黑马程序员java大厂面试题和小林coding 博主学习笔记,如果有不对的地方,海涵。 如果这篇文章对你有帮助,可以点点关注,点点赞,谢谢你! 1.MySQL优化 1.1 定位慢查询 定位 一个SQL…...
软件工程的13条“定律”:从Hyrum定律到康威定律,再到Zawinski定律
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
Linux删除大文件df空间avail空间不增加
背景 根磁盘被同事写满,使用> 删除一些安装包后,df中的avail空间还是0 排除有进程正在占用文件,已使用lsof命令检测过我所删的文件是没有进程在使用 原因 是文件系统预留空间在作祟 解决 # 文件系统预留块 tune2fs -l /dev/vda2 | gr…...
【C语言-选择排序算法】实现对十个数进行排序
目录 前言 一、选择排序算法原理 二、选择排序算法实现对十个数进行排序 三、代码运行示例 四、选择排序算法的时间复杂度和空间复杂度分析 五、选择排序算法的优缺点 六、总结 前言 在计算机科学领域,排序算法是基石般的存在,它们就像是整理杂乱…...
驱动开发硬核特训 · Day 18:深入理解字符设备驱动与子系统的协作机制(以 i.MX8MP 为例)
日期:2025年04月23日 回顾:2025年04月22日(Day 17:Linux 中的子系统概念与注册机制) 本日主题:字符设备驱动 子系统协作机制剖析 学习目标:理解字符设备的注册原理,掌握其与子系统间…...
SQL Server 2022 常见问题解答:从安装到优化的全场景指南
SQL Server 2022 作为微软最新的数据库管理系统,在性能、安全性和云集成方面带来了多项革新。然而,用户在实际使用中仍可能遇到各类问题。本文将围绕安装配置、性能优化、备份恢复、安全设置、高可用性方案、兼容性问题及错误代码解析等核心场景…...
软件开发版本库命名规范说明
背景:近期一直再更新自己所开发的一个前端大文件上传npm库(enlarge-file-upload),为了让库的发版更加规范,于是参考了各种文档写下了这篇关于软件开发库的版本命名规范,且不仅局限于前端的版本命名规范,适用于整个软件…...
Kafka 详解
1.基本概念:Kafka 是分布式发布 - 订阅消息系统,具有高吞吐量、可扩展性等优势,支持点对点和发布订阅两种消息模式,涉及 Broker、Topic、Partition 等多种角色。 2.安装步骤:需先安装 JDK 和 Zookeeper,下…...
【Qwen2.5-VL 踩坑记录】本地 + 海外账号和国内账号的 API 调用区别(阿里云百炼平台)
API 调用 阿里云百炼平台的海内外 API 的区别: 海外版:需要进行 API 基础 URL 设置国内版:无需设置。 本人的服务器在香港,采用海外版的 API 时,需要进行如下API端点配置 / API基础URL设置 / API客户端配置…...
硬核解析:整车行驶阻力系数插值计算与滑行阻力分解方法论
引言:阻力优化的核心价值 在汽车工程领域,行驶阻力是影响动力性、经济性及排放的核心因素。根据统计,车辆行驶中约60%的燃油消耗用于克服阻力(风阻、滚阻、传动内阻等)。尤其在电动化趋势下,阻力降低1%可提…...
【网络原理】TCP提升效率机制(一):滑动窗口
目录 一. 前言 二. 滑动窗口 三. 丢包现象 1)ACK报文丢失 2)数据丢失 四. 总结 一. 前言 TCP最核心的机制就是可靠传输 ,确认应答,超时重传,连接管理这些都保证了可靠传输,得到了可靠传输,…...
移动端使用keep-alive将页面缓存和滚动缓存具体实现方法 - 详解
1. 配置组件名称 确保列表页组件设置了name选项,(组合式API额外配置): <!-- vue2写法 --> export default {name: UserList // 必须与 <keep-alive> 的 include 匹配 }<!-- vue3写法 --> defineOptions({na…...
工作记录9
1.点击按钮发送AJAX请求 <!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title&…...
Java 异常 SSLException: fatal alert: protocol_version 全解析与解决方案
在 Java 网络通信中,SSLException: fatal alert: protocol_version 是典型的 TLS/SSL 协议版本不兼容异常。本文结合 Java 官方规范、TLS 协议标准及实战经验,提供体系化解决方案,帮助开发者快速定位并解决协议版本冲突问题。 一、异常本质&…...
连锁美业管理系统「数据分析」的重要左右分析︳博弈美业系统疗愈系统分享
美业管理系统中的数据分析功能在提升运营效率、优化客户体验、增强决策科学性等方面具有重要作用。 数据分析功能将美业从“经验驱动”升级为“数据驱动”,帮助商家在客户管理、成本控制、服务创新等环节实现精细化运营,最终提升盈利能力与品牌竞争力…...
Openharmony 和 HarmonyOS 区别?
文章目录 OpenHarmony 与 HarmonyOS 的区别:开源生态与商业发行版的定位差异一、定义与定位二、技术架构对比1. OpenHarmony2. HarmonyOS 三、应用场景差异四、开发主体与生态支持五、关键区别总结六、如何选择?未来展望 OpenHarmony 与 HarmonyOS 的区别…...
26.OpenCV形态学操作
OpenCV形态学操作 形态学操作(Morphological Operations)源自二值图像处理,主要用于分析和处理图像中的结构元素,对图像进行去噪、提取边缘、分割等预处理步骤。OpenCV库中提供了丰富的形态学函数,常见的包括…...
uniapp小程序使用echarts
1、引入插件 在Dcloud插件市场下载echarts插件:插件地址 2、页面使用简单示例: <template><view class"pie-view flex-center"><view style"width: 100%; height: 600rpx"><l-echart ref"chartRef&quo…...
Vue 中 使用 Mixins 解决 多页面共用相同组件的相关问题
1. 需要解决的问题 最近在vue项目中,有多个页面需要用到同一个组件,至于是什么组件,这里不重要,重要的这个组件需要被多个文件引用,而且有组件有一些控制逻辑。 1.1代码展示 <template><div class"ap…...
Rust 学习笔记:Rust 简介
Rust 学习笔记:Rust 简介 Rust 学习笔记:Rust 简介历史与发展历程核心特性优点缺点应用领域 Rust 学习笔记:Rust 简介 Rust 是一种系统级编程语言,由 Mozilla 研究院的 Graydon Hoare 于 2006 年设计,旨在提供内存安全…...
第六节:进阶特性高频题-自定义指令实现场景
示例:v-lazy(图片懒加载)、v-permission(权限控制) 钩子函数:mounted、updated、unmounted等 一、自定义指令核心机制 指令生命周期钩子 const myDirective {// 元素插入父节点时调用(初始化…...
未曾设想的道路1
写在前面: 与其转去读博,倾向自学就业。 中国科学技术大学数学科学学院拥有一支优秀的师资团队,以下是部分教授的简介: 陈发来教授: 荣誉:2024年6月13日,在德国莱布尼茨信息科学中心召开的国际…...
Axure按钮设计分享:打造高效交互体验的六大按钮类型
在产品设计过程中,按钮作为用户与界面交互的核心元素,其设计质量直接影响用户体验与操作效率。Axure作为一款强大的原型设计工具,为设计师提供了丰富的按钮设计选项。本文将围绕基础按钮、禁用按钮、圆角按钮、动态按钮、渐变按钮和图标按钮六…...
MySQL 8.4企业版 安装和配置审计插件
在最新的MySQL 8.4.4企业版上启用审计日志功能 操作系统:Ubuntu 24.04 数据库:8.4.4-commercial for Linux on x86_64 (MySQL Enterprise Server - Commercial) 1.查看安装脚本 下面2个脚本位于mysql安装目录 share 下,一个是window一个是linux可以用…...
AI大模型学习十一:尝鲜ubuntu 25.04 桌面版私有化sealos cloud + devbox+minio,实战运行成功
一、说明 用了ubuntu 25.04,内核为GNU/Linux 6.14.0-15-generic x86_64,升级了部分image,过程曲折啊 sealos 能干啥 对集群生命周期进行管理,一键安装高可用 Kubernetes 集群,增删节点清理集群自恢复等 通过 sealos…...
idea无法下载源代码
通过idea找到用户设置文件路径 查看 setting.xml 文件,找到了以下相关的配置,注释掉这个maven-default-http-blocker的镜像,这个东西阻碍了去阿里的镜像库查找依赖,注释掉。 然后重启idea就能下载了...
【敏矽微ME32G030系列】介绍、环境搭建、工程测试
【敏矽微ME32G030系列】介绍、环境搭建、工程测试 本文介绍了敏矽微ME32G030系列单片机及开发板、包括参数特点、原理图、应用场景,以及开发环境搭建、工程测试等流程。 简介 本节介绍了开发板主控、特点、开发板原理图、板载资源等信息。 主控 开发板采用 ME3…...
Hooks的使用限制及原因
Hooks的使用限制及原因 Hooks的核心限制 只能在函数组件顶层调用 ⭐不能在条件语句、循环、嵌套函数中调用 ⭐只能在React函数组件或自定义Hooks中调用 ⭐ 为什么有这些限制? 根本原因:React依赖Hooks的调用顺序 React内部使用数组来存储每个组件的…...
【JavaScript】二十六、正则表达式
文章目录 1、正则表达式1.1 定义1.2 校验 2、元字符2.1 边界符2.2 量词2.3 字符类2.3.1 方括号[ ]2.3.2 小点.2.3.3 预定义 2.4 案例:用户名验证 3、修饰符3.1 语法3.2 案例:过滤敏感词 1、正则表达式 Regular Expression,正则表达式&#x…...
Geek强大的电脑卸载软件工具,免费下载
一款强大的卸载电脑软件工具,无需安装 免费下载...
tomcat Server 连接服务器 进展
由于机房的环境变更,所接触的问题也不一样!!!! 但后来出现以下提示: 已连接到服务器 配置错误: 部署源 springmvc:war 无效[2025-04-23 11:19:50,192] 工件 springmvc:war: 部署工件时出错。请参阅服务器日…...
Elasticsearch 集群节点下线方案
Elasticsearch 集群节点下线方案 在 Elasticsearch(ES)集群中,节点(Node)下线可能会影响数据的可用性和集群的健康状态。因此,正确的下线步骤需要确保数据不会丢失,并且不会影响查询或写入。 &…...
【模板匹配】图像处理(OpenCV)-part10
19.1模板匹配 模板匹配就是用模板图(通常是一个小图)在目标图像(通常是一个比模板图大的图片)中不断的滑动比较,通过某种比较方法来判断是否匹配成功,找到模板图所在的位置。 不会有边缘填充。 类似于卷积,…...
VMware中CentOS 7虚拟机设置固定IP(NAT模式)完整教程
前言 在VMware中为CentOS 7虚拟机配置固定IP是搭建稳定服务环境的关键步骤。本文基于用户提供的最新配置文件,详细演示如何从DHCP自动获取IP调整为固定IP(192.168.89.129),并提供修改前后的配置对比及操作验证。 一、当前配置状态…...
Ragflow、Dify、FastGPT、COZE核心差异对比与Ragflow的深度文档理解能力和全流程优化设计
一、Ragflow、Dify、FastGPT、COZE核心差异对比 以下从核心功能、目标用户、技术特性等维度对比四款工具的核心差异: 核心功能定位 • Ragflow:专注于深度文档理解的RAG引擎,擅长处理复杂格式(PDF、扫描件、表格等)的…...
飞帆控件:在编辑模式下额外加载的库
飞帆是一个自由的控件设计平台。在飞帆中,我们可以很方便地创建基于 Vue 2 组件的控件,并使用控件来搭建网页。 他山之石,可以攻玉。在创建控件中,使用 js 、css 依赖库能让我们的控件更强大。 有些时候,在编辑模式下…...
Agentic AI——当AI学会主动思考与决策,世界将如何被重塑?
一、引言:2025,Agentic AI的元年 “如果ChatGPT是AI的‘聊天时代’,那么2025年将开启AI的‘行动时代’。”——Global X Insights[1] 随着Agentic AI(自主决策型人工智能)的崛起,AI系统正从被动应答的“工具…...
68元撬动未来:明远智睿2351开发板重塑嵌入式开发生态
在嵌入式开发领域,价格与性能的矛盾始终存在:高端开发板功能强大但成本高昂,低价产品则往往受限于性能与扩展性。明远智睿2351开发板以68元(含税)的定价打破这一僵局,通过四核1.4G处理器、全功能Linux系统与…...
C# 全局 Mutex 是否需使用 `Global\` 前缀
回顾一下Mutex在Windows中的作用。Mutex是用于同步多个进程或线程的机制,确保同一时间只有一个实例访问资源。当创建Mutex时,如果命名时没有指定Global\前缀,默认可能是在会话内创建的,也就是只在当前用户会话中可见。这样的话&am…...
C# 中的 `lock` 关键字本质
C# 中的 lock 关键字本质上是基于 Monitor 类实现的线程同步机制,其核心是通过 互斥锁(Mutex) 确保代码块的原子性执行。以下是其实现本质的分步解析: 1. 语法糖的转换 当使用 lock 关键字时: lock (obj) {// 临界区…...
Java 集合:泛型、Set 集合及其实现类详解
参考资料:java入门到飞起 Java;泛型;Set 集合;TreeSet;HashSet;数据结构 一、引言 在 Java 编程中,集合框架是一个重要的组成部分,它提供了丰富的数据结构和算法来存储和操作数据。泛型与 Set…...
前端基础之《Vue(8)—内置组件》
一、Vue2.0中的内置组件 1、<slot> 插槽 2、<keep-alive> 动态组件 被keep-alive所包裹的组件: (1)不会被销毁。 (2)还会多两个生命周期钩子:activated()、deactivated()。 (3&a…...
Zookeeper是什么?基于zookeeper实现分布式锁
zookeeper听的很多,但实际在应用开发中用的不错,主要是作为中间件配合使用的,例如:Kafka。 了解zk首先需要知道它的数据结构,可以想象为树、文件夹目录。每个节点有基本的信息,例如:创建时间、…...
计算机网络 第二章:应用层(四)
2.6 视频流和内容分发网 对如何在因特网中实现流行的视频流服务进行概述。它们的实现方式是使用应用层协议和以像高速缓存那样方式运行的服务器。 2.6.1 因特网视频 在流式存储视频应用中,基础的媒体是预先录制的视频,例如电影、电视节目、录制好的体育…...
什么是数据库的DDL和DML,有什么区别?
数据库中的 DDL 和 DML 是两类不同的 SQL 语言,用于不同的数据库操作目的。以下是它们的定义、区别和具体说明: 1. DDL(Data Definition Language,数据定义语言) 作用:定义或修改数据库的结构(…...
HCIP实验二(OSPF网络配置与优化)
一.拓扑图与题目 1.R5为ISP,其上只能配置IP地址; R5与其他所有直连设备间均使用公有IP;环回地址为100.1.1.1/3 2.R4设备为企业出口路由器 3.整个0SPF环境IP基于172.16.0.0/16划分 4.所有设备均可访问R5的环回; 5.减少LSA的更新里,加快收敛࿰…...
第十六讲、isaaclab中使用任务空间(task-space)控制
0 前言 官方教程:https://isaac-sim.github.io/IsaacLab/main/source/tutorials/05_controllers/run_diff_ik.html IsaacsimIsaaclab安装:https://blog.csdn.net/m0_47719040/article/details/146389391?spm1001.2014.3001.5502 在之前的教程中我们利…...
无人船 | 图解基于PID控制的路径跟踪算法(以欠驱动无人艇Otter为例)
目录 1 PID控制的三大组成1.1 比例控制作用1.2 积分控制作用1.3 微分控制作用 2 基于欠驱动运动学的PID控制3 跟踪效果分析 1 PID控制的三大组成 PID控制律的定量表达请参考无人船 | 图解基于PID控制的路径跟踪算法(以全驱动无人艇WAMV为例),本文进一步介绍PID每个…...
【C++】13.list的模拟实现
首先,我们需要把链表管理起来,也就是把一个个节点管理起来,但是每个节点的信息我们也需要管理,例如节点的前驱指针和后驱指针,以及节点的值,所以我们这里先封装两个类来管理节点和链表。 namespace Ro {te…...