OpenCV形态学操作
1.1. 形态学操作介绍
初识:
形态学操作是一种基于图像形状的处理方法,主要用于分析和处理图像中的几何结构。其核心是通过结构元素(卷积核)对图像进行扫描和操作,从而改变图像的形状和特征。例如:
- 腐蚀(Erosion):将图像中的前景物体边界向内收缩,使物体变小。
- 膨胀(Dilation):将图像中的前景物体边界向外扩展,使物体变大。
- 开运算(Opening):先腐蚀后膨胀,用于去除小噪点。
- 闭运算(Closing):先膨胀后腐蚀,用于填补小孔。
功能:
形态学操作的主要功能包括:
- 去噪:通过腐蚀或开运算去除小的噪点。
- 边缘提取:通过形态学梯度(膨胀与腐蚀的差)突出边缘。
- 图像分割:通过闭运算或开运算分离或连接物体。
- 特征增强:通过顶帽或黑帽操作提取特定特征。
-
- 顶帽:原图与开运算的差
- 黑帽:闭运算与原图的差
应用场景:
操作类型 | 应用场景 |
腐蚀 | 去噪、细化边缘、分离相邻对象 |
膨胀 | 填补小孔、连接对象、加粗前景 |
开运算 | 去除小噪点、平滑前景边界 |
闭运算 | 填补暗孔、平滑前景边界 |
形态学梯度 | 边缘检测、轮廓提取 |
顶帽运算 | 提取亮点、去除低频背景信息 |
黑帽运算 | 提取暗纹、增强低频阴影 |
1.2. 原理介绍
1.2.1. 腐蚀(Erosion) :
- 腐蚀操作会将图像中的前景物体(通常是白色区域)的边界向内收缩。具体来说,当结构元素的中心移动到图像的某个像素时,只有当结构元素覆盖的所有像素都是前景物体的像素时,该中心像素才会被保留为前景物体的一部分。否则,该像素将被视为背景(黑色区域)。这种操作会使物体的边缘变细,可以去除小的突出物和噪点。
1.2.2. 膨胀(Dilation) :
- 膨胀操作与腐蚀相反,它会将前景物体的边界向外扩展。当结构元素的中心移动到图像的某个像素时,只要结构元素覆盖的像素中存在至少一个前景物体的像素,该中心像素就会被保留为前景物体的一部分。这种操作会使物体的边缘变粗,可以填补物体中的小孔和断开的部分。
1.2.3. 开运算(Opening) :
- 开运算是先腐蚀后膨胀的过程。它可以通过去除小的突出物和噪点来平滑前景物体的边界。开运算对于去除小的白色噪点特别有效。
-
- 腐蚀:可以有效的消除突出物体和噪点,但是原前景会变小,有的地方存在孔洞与断开
- 膨胀:修复孔洞,恢复大小。
1.2.4. 闭运算(Closing) :
- 闭运算是先膨胀后腐蚀的过程。它可以通过填补小的孔洞来平滑前景物体的边界。闭运算对于填补小的黑色孔洞特别有效。
-
- 膨胀:修复孔洞,但是前景图像会变大
- 腐蚀:将大小近似恢复到原图大小
1.2.5. 顶帽操作:
-
- 定义:顶帽操作是原始图像与开运算结果之间的差值。开运算是先进行腐蚀操作,再进行膨胀操作。
- 功能:
-
-
- 顶帽操作可以提取图像中比背景亮的细小区域。
- 提取比背景亮的细小区域。去除大范围的低频背景信息,
- 突出局部亮点。增强对比度。
-
-
- 原理:
-
-
- 开运算会去掉毛刺和突出部分
- 原图减去开运算结果,就可以获得开运算去除的细小区域
-
1.2.6. 黑帽操作:
-
- 定义: 黑帽操作是闭运算结果与原始图像之间的差值。闭运算是先进行膨胀操作,再进行腐蚀操作。黑帽操作可以提取图像中比背景暗的细小区域。
- 功能:
-
-
- 提取比背景暗的小区域。
- 突出细小的暗纹和阴影区域。
- 增强对比度,适合背景亮、局部暗区域的图像。
-
-
- 原理:
-
-
- 闭运算先膨胀在腐蚀,把孔洞和非连续区域不全了
- 闭运算减去原图像,就可以得到闭运算去除的部分——比背景暗的小区域
-
1.3. 在openCV中实现
1.3.1. kernel
以下函数都会用到kernel
,结构元素(卷积核),用于定义邻域的形状和大小。选择合适的形状与大小,可以提高形态学操作的效果。首先需要了解一下如何选择kernel
1.3.1.1. 确定结构元素形状
结构元素的形状应根据图像的特征和处理目标来选择。常见的结构元素形状包括:
- 矩形(Rectangular):
-
- 适用于处理规则形状的图像,如文本、表格等。
- 代码示例:
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
- 椭圆(Elliptical):
-
- 适用于处理圆形或椭圆形的图像,如细胞、颗粒等。
- 代码示例:
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
- 十字形(Cross-shaped):
-
- 适用于处理需要突出中心点的图像,如边缘检测等。
- 代码示例:
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
1.3.1.2. 确定结构元素大小
结构元素的大小应根据图像中物体的大小和细节来选择。以下是一些指导原则:
- 去除小噪点:
-
- 如果图像中有小的噪点,选择较小的结构元素(如 3x3 或 5x5)。
- 代码示例:
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
- 填补小孔:
-
- 如果图像中有小的孔洞,选择较大的结构元素(如 5x5 或 7x7)。
- 代码示例:
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
- 处理大物体:
-
- 如果图像中有较大的物体,选择更大的结构元素(如 7x7 或 9x9)。
- 代码示例:
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
1.3.1.3. 选择结构元素的步骤
- 分析图像特征:
-
- 观察图像中的物体大小、形状和细节。
- 确定需要处理的目标(如去除噪点、填补孔洞、提取边缘等)。
- 选择结构元素形状:
-
- 根据图像的特征选择合适的形状(矩形、椭圆、十字形等)。
- 选择结构元素大小:
-
- 根据图像中物体的大小和细节选择合适的大小。
- 可以通过实验逐步调整结构元素的大小,观察不同大小对结果的影响。
- 实验和调整:
-
- 使用不同的结构元素大小和形状进行实验,观察处理后的图像效果。
- 根据实验结果调整结构元素的大小和形状,直到达到满意的效果。
1.3.2. cv2.erode
函数:
def erode(src: cv2.typing.MatLike, kernel: cv2.typing.MatLike, dst: cv2.typing.MatLike | None = ..., anchor: cv2.typing.Point = ..., iterations: int = ..., borderType: int = ..., borderValue: cv2.typing.Scalar = ...) -> cv2.typing.MatLike: ...
参数解释:
src
:输入图像(通常是二值图像或灰度图像)。kernel
:结构元素(卷积核),用于定义邻域的形状和大小。dst
:输出图像。如果未指定,则默认与输入图像具有相同的类型和大小。anchor
:结构元素的锚点位置,默认为(-1, -1)
,表示锚点位于结构元素的中心。iterations
:迭代次数,默认为 1。增加迭代次数会增强腐蚀的效果。borderType
:边界填充方式,默认为cv2.BORDER_CONSTANT
。常见的边界填充方式有:
-
cv2.BORDER_CONSTANT
:用常数值填充边界。cv2.BORDER_REFLECT
:用镜像反射的方式填充边界。cv2.BORDER_REPLICATE
:用边界像素值重复填充边界。cv2.BORDER_WRAP
:用环绕方式填充边界。
borderValue
:边界填充的值,默认为 0。
参数确定方法:
- 结构元素(Kernel):如第一点所讲
- 迭代次数(Iterations):根据需要调整,次数越多,腐蚀效果越明显。通常设置为 1 或 2。
参数对结果的影响:
- 结构元素的形状和大小:影响腐蚀的范围和效果。较大的结构元素会使腐蚀效果更明显,但可能会导致图像失真。
- 迭代次数:增加迭代次数会使腐蚀效果更明显,但可能会导致图像过度腐蚀。
使用注意事项:
- 选择合适的结构元素大小和形状,避免过度腐蚀导致图像失真。
- 迭代次数不宜过多,以免影响图像的整体结构。
结合腐蚀和对不同结构元素的效果进行对比:
def TestMorphologicalErode(iterator:int):# 读取图像img = cv2.imread('Word.jfif', 0) # 以灰度模式读取图像# 定义不同形状和大小的结构元素kernel_rect = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) # 矩形结构元素kernel_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) # 椭圆结构元素kernel_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3)) # 十字形结构元素# 腐蚀操作erosion_rect = cv2.erode(img, kernel_rect, iterations=1)erosion_ellipse = cv2.erode(img, kernel_ellipse, iterations=1)erosion_cross = cv2.erode(img, kernel_cross, iterations=1)# 显示结果plt.figure(figsize=(12, 8))plt.subplot(2, 2, 1)plt.imshow(img, cmap='gray')plt.title('Original Image')plt.axis('off')plt.subplot(2, 2, 2)plt.imshow(erosion_rect, cmap='gray')plt.title('Erosion with Rectangular Kernel')plt.axis('off')plt.subplot(2, 2, 3)plt.imshow(erosion_ellipse, cmap='gray')plt.title('Erosion with Elliptical Kernel')plt.axis('off')plt.subplot(2, 2, 4)plt.imshow(erosion_cross, cmap='gray')plt.title('Erosion with Cross-shaped Kernel')plt.axis('off')plt.show()
结果发现:
- 腐蚀操作,字反而变粗了,其实这里可以理解前景为,黑色的字是背景,腐蚀会让白色的前景变小,即黑色的背景变大,所以黑色的字变大了
- 矩形的白色孔洞腐蚀的厉害,十字星与椭圆的与原图保留的较好(对比“惊”的口)
1.3.3. cv2.dilate
函数:
def dilate(src: cv2.typing.MatLike, kernel: cv2.typing.MatLike, dst: cv2.typing.MatLike | None = ..., anchor: cv2.typing.Point = ..., iterations: int = ..., borderType: int = ..., borderValue: cv2.typing.Scalar = ...) -> cv2.typing.MatLike: ...
参数解释:
src
:输入图像(通常是二值图像或灰度图像)。kernel
:结构元素(卷积核),用于定义邻域的形状和大小。dst
:输出图像。如果未指定,则默认与输入图像具有相同的类型和大小。anchor
:结构元素的锚点位置,默认为(-1, -1)
,表示锚点位于结构元素的中心。iterations
:迭代次数,默认为 1。增加迭代次数会增强膨胀的效果。borderType
:边界填充方式,默认为cv2.BORDER_CONSTANT
。borderValue
:边界填充的值,默认为 0。
参数确定方法:
- 结构元素(Kernel):如第一部分所示
- 迭代次数(Iterations):根据需要调整,次数越多,膨胀效果越明显。通常设置为 1 或 2。
参数对结果的影响:
- 结构元素的形状和大小:影响膨胀的范围和效果。较大的结构元素会使膨胀效果更明显,但可能会导致图像失真。
- 迭代次数:增加迭代次数会使膨胀效果更明显,但可能会导致图像过度膨胀。
使用注意事项:
- 选择合适的结构元素大小和形状,避免过度膨胀导致图像失真。
- 迭代次数不宜过多,以免影响图像的整体结构。
对比不同形状结构元素的膨胀操作:
def TestMorphologicalDilate(iterator:int):# 读取图像img = cv2.imread('Word.jfif', 0) # 以灰度模式读取图像# 定义不同形状和大小的结构元素kernel_rect = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) # 矩形结构元素kernel_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) # 椭圆结构元素kernel_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3)) # 十字形结构元素# 腐蚀操作erosion_rect = cv2.dilate(img, kernel_rect, iterations=1)erosion_ellipse = cv2.dilate(img, kernel_ellipse, iterations=1)erosion_cross = cv2.dilate(img, kernel_cross, iterations=1)# 显示结果plt.figure(figsize=(12, 8))plt.subplot(2, 2, 1)plt.imshow(img, cmap='gray')plt.title('Original Image')plt.axis('off')plt.subplot(2, 2, 2)plt.imshow(erosion_rect, cmap='gray')plt.title('Dilation with Rectangular Kernel')plt.axis('off')plt.subplot(2, 2, 3)plt.imshow(erosion_ellipse, cmap='gray')plt.title('Dilation with Elliptical Kernel')plt.axis('off')plt.subplot(2, 2, 4)plt.imshow(erosion_cross, cmap='gray')plt.title('Dilation with Cross-shaped Kernel')plt.axis('off')plt.show()
- 膨胀操作会让白色孔洞变大,黑色字体会变瘦
- 矩形效果不好,实际运行时可以在字体边缘看到一些处理过的痕迹,椭圆形与十字星更适合毛笔字的处理
1.3.4. cv2.morphologyEx
(开运算、闭运算、顶帽操作、黑帽操作、形态学梯度)
函数:
cv2.morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) -> dst
参数解释:
src
:输入图像(通常是二值图像或灰度图像)。op
:形态学操作类型:
-
cv2.MORPH_OPEN
:开运算。cv2.MORPH_CLOSE
:闭运算。cv2.MORPH_TOPHAT
:顶帽操作。cv2.MORPH_BLACKHAT
:黑帽操作。cv2.MORPH_GRADIENT
:形态学梯度。
kernel
:结构元素(卷积核),用于定义邻域的形状和大小。dst
:输出图像。如果未指定,则默认与输入图像具有相同的类型和大小。anchor
:结构元素的锚点位置,默认为(-1, -1)
,表示锚点位于结构元素的中心。iterations
:迭代次数,默认为 1。增加迭代次数会增强操作的效果。borderType
:边界填充方式,默认为cv2.BORDER_CONSTANT
。borderValue
:边界填充的值,默认为 0。
参数确定方法:
- 结构元素(Kernel):根据图像的特征和处理目标选择合适的形状和大小。例如,去除小噪点时,可以选择较小的结构元素,如
np.ones((3, 3), np.uint8)
;填补小孔时,可以选择较大的结构元素,如np.ones((5, 5), np.uint8)
。 - 迭代次数(Iterations):根据需要调整,次数越多,操作的效果越明显。通常设置为 1 或 2。
参数对结果的影响:
- 结构元素的形状和大小:影响操作的范围和效果。较大的结构元素会使操作效果更明显,但可能会导致图像失真。
- 迭代次数:增加迭代次数会使操作效果更明显,但可能会导致图像过度处理。
使用注意事项:
- 选择合适的结构元素大小和形状,避免过度处理导致图像失真。
- 迭代次数不宜过多,以免影响图像的整体结构。
- 不同的操作类型(如开运算、闭运算等)对图像的影响不同,需根据具体需求选择合适的操作类型。
根据运算结果,我们可以尝试对比一下结果图
def TestMorphologicalEx():image=cv2.imread("Word.jfif",0) #读取灰度图kernel=cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))#十字星 3*3 image_open=cv2.morphologyEx(image,cv2.MORPH_OPEN,kernel,iterations=1)image_close=cv2.morphologyEx(image,cv2.MORPH_CLOSE,kernel,iterations=1)image_TopHat=cv2.morphologyEx(image,cv2.MORPH_TOPHAT,kernel,iterations=1)image_BlackHat=cv2.morphologyEx(image,cv2.MORPH_BLACKHAT,kernel,iterations=1)# 显示结果plt.figure(figsize=(8, 12))plt.subplot(3, 2, 1)plt.imshow(image, cmap='gray')plt.title('Original Image')plt.axis('off')plt.subplot(3, 2, 2)plt.imshow(image, cmap='gray')plt.title('Original Image')plt.axis('off')plt.subplot(3, 2, 3)plt.imshow(image_open, cmap='gray')plt.title('image_open')plt.axis('off')plt.subplot(3, 2, 4)plt.imshow(image_close, cmap='gray')plt.title('image_close')plt.axis('off')plt.subplot(3, 2, 5)plt.imshow(image_TopHat, cmap='gray')plt.title('image_TopHat Original - open')plt.axis('off')plt.subplot(3, 2, 6)plt.imshow(image_BlackHat, cmap='gray')plt.title('image_BlackHat Close - Original')plt.axis('off')plt.show()
- 在这个图中前景是白色,黑色是背景
- 顶帽操作结果是开运算去除的噪点,可以看到白色前景的噪点确实去掉了,在这里体现在于背景(黑色部分)更连续了
- 黑帽操作是闭运算补全的孔洞,白色为前景,红框部分可以理解为前景中的孔洞,闭运算填补了孔洞
相关文章:

OpenCV形态学操作
1.1. 形态学操作介绍 初识: 形态学操作是一种基于图像形状的处理方法,主要用于分析和处理图像中的几何结构。其核心是通过结构元素(卷积核)对图像进行扫描和操作,从而改变图像的形状和特征。例如: 腐蚀&…...
深入理解WebSocket接口:如何使用C++实现行情接口
在现代网络应用中,实时数据传输变得越来越重要。通过WebSocket,我们可以建立一个持久连接,让服务器和客户端之间进行双向通信。这种技术不仅可以提供更快的响应速度,还可以减少不必要的网络流量。本文将详细介绍如何使用C来实现We…...

汇能感知的光谱相机/模块产品有哪些?
CM020A 分辨率:1600H1200V 光谱范围:350~950nm 光谱分辨率:1nm 接口:USB2.0 帧率:16001200 (6帧) 输出格式:Raw 8bit FOV:D73.5H58.8V44.1 相机尺寸:505055mm VM02S10 分辨率…...
抓包工具是什么?
抓包工具是一种用于捕获和分析网络数据包的软件或硬件设备。它可以帮助用户监控网络通信过程,查看网络中传输的数据内容、协议类型、源地址、目的地址等信息。以下是关于抓包工具的一些详细解释: 1. 主要功能 捕获数据包:抓包工具能够实时捕…...
Kubernetes的Ingress 资源是什么?
在Kubernetes中,Ingress资源是一种用于管理集群外部对内部服务访问的API对象,主要用于将不同的外部请求路由到集群内的不同服务,以下是关于它的详细介绍: 定义与作用 Ingress资源定义了从集群外部到内部服务的HTTP和HTTPS路由规…...
【操作幂等和数据一致性】保障业务在MySQL和COS对象存储的一致
业务场景 发布信息,更新到数据库MySQLCOS操作,更新JSON文件 不过可能存在幂等性和数据一致性的问题。 // 批量存MySQL entityPublishService.saveOrUpdateBatch(entityPublishList); // 遍历批量存COS对象存储searchEntitys.forEach(req -> {//删除…...
DevOps自动化部署详解:从理念到实践
在软件开发日益快速迭代的今天,如何以高效、稳定且可重复的方式将代码变更从开发环境自动部署到生产环境成为企业竞争的重要因素。DevOps 正是在这一背景下应运而生,它打破开发、测试、运维之间的壁垒,通过自动化工具和流程,实现持…...
LeetCodehot 力扣热题100
class Solution { public:int max_sum INT_MIN; // 初始化为最小值,确保能够处理所有可能的路径和int maxPathSum(TreeNode* root) {dfs(root);return max_sum;}int dfs(TreeNode* root) {if (root nullptr) return 0; // 如果是空节点,返回0// 递归…...

解锁 AIoT 无限可能,乐鑫邀您共赴 Embedded World 2025
2025 年 3 月 11-13 日,全球规模最大的嵌入式展览会——Embedded World 2025 将在德国纽伦堡盛大开幕。作为物联网和嵌入式技术领域的领先企业,乐鑫信息科技 (688018.SH) 将展示在 AI LLM、HMI、双频 Wi-Fi 6、低功耗 MCU 和 Matter 等领域的最新技术及解…...

C# 背景 透明 抗锯齿 (效果完美)
主要是通过 P/Invoke 技术调用 Windows API 函数 gdi32.dll/user32.dll,同时定义了一些结构体来配合这些 API 函数的使用,常用于处理图形绘制、窗口显示等操作。 运行查看效果 局部放大,抗锯齿效果很不错,尾巴毛毛清晰可见。 using System; u…...
Debezium:实时数据捕获与同步的利器
一、什么是 Debezium Debezium 是一个开源的分布式平台,专门用于捕获数据库中的数据变更。它通过读取数据库的事务日志,能够以非侵入性的方式捕获数据库中发生的所有变化,并将这些变化转化为事件流,实时推送到像 Kafka 这样的消息…...

Word中接入大模型教程
前言 为什么要在word中接入大模型呢? 个人觉得最大的意义就是不用来回切换与复制粘贴了吧。 今天分享一下昨天实践的在word中接入大模型的教程。 在word中接入大模型最简单的方式就是使用vba。 vba代码要做的事,拆分一下就是: 获取用户…...

Centos修改ip
1 查看ip [rootlocalhost ~]# ip addr2 root账号修改ip [rootlocalhost ~]# su [rootlocalhost ~]# cd /etc/sysconfig/network-scripts/ [rootlocalhost network-scripts]# llvi编辑ifcfg-ens33 3 重启网卡 [rootlocalhost network-scripts]# systemctl restart network...

uni-app小程序开发 基础知识2
目标: 构建一个文章发表平台。 我们先来写一个静态框架。 以下是 首页初代码文章列表页代码: <template><view class"content"><!-- 轮播图 --><swiper class"swiper-container" autoplay"true"…...

第4章 4.1 Entity Framework Core概述
4.1.1 什么是ORM ORM (object tralstional mapping ,对象关系映射)中的“对象”指的就是C#中的对象,而“关系”是关系型数据库,“映射”指搭建数据库与C#对象之间的“桥梁”。 比如使用ORM ,可以通过创建C#对象的方式把数据插入数据库而不需…...
在 Spring Boot 中使用 `@Autowired` 和 `@Bean` 注解
文章目录 在 Spring Boot 中使用 Autowired 和 Bean 注解示例背景 1. 定义 Student 类2. 配置类:初始化 Bean3. 测试类:使用 Autowired 注解自动注入 Bean4. Spring Boot 的自动装配5. 总结 在 Spring Boot 中使用 Autowired 和 Bean 注解 在 Spring Bo…...
Langchain vs. LlamaIndex:哪个在集成MongoDB并分析资产负债表时效果更好?
Langchain vs. LlamaIndex:哪个在集成MongoDB并分析资产负债表时效果更好? 随着大语言模型(LLM)在实际应用中的普及,许多开发者开始寻求能够帮助他们更高效地开发基于语言模型的应用框架。在众多框架中,La…...
Java 中的内存泄漏问题及解决方案
在 Java 中,内存泄漏(Memory Leak)是指在程序运行过程中,某些对象已经不再使用,但由于引用仍然存在,这些对象无法被垃圾回收器回收,从而导致内存无法释放,最终可能导致系统性能下降甚…...

VS Code 如何搭建C/C++开发环境
目录 1.VS Code是什么 2. VS Code的下载和安装 2.1 下载和安装 2.2.1 下载 2.2.2 安装 2.2 环境的介绍 2.3 安装中文插件 3. VS Code配置C/C开发环境 3.1 下载和配置MinGW-w64编译器套件 3.1.1 下载 3.1.2 配置 3.2 安装C/C插件 3.3 重启VSCode 4. 在VSCode上编写…...
【Linux C/C++开发】Linux系统轻量级的队列缓存mqueue
前言 开发设计时,通常会对业务流程进行模块化,有些流程之间,不要求同步,但又需要传递信息时,如果存储到数据库,效率降低很多,如果是存放在内存是最好的。此时可以选择系统的IPC(进程…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...

MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

高端性能封装正在突破性能壁垒,其芯片集成技术助力人工智能革命。
2024 年,高端封装市场规模为 80 亿美元,预计到 2030 年将超过 280 亿美元,2024-2030 年复合年增长率为 23%。 细分到各个终端市场,最大的高端性能封装市场是“电信和基础设施”,2024 年该市场创造了超过 67% 的收入。…...

【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录
#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...

使用python进行图像处理—图像变换(6)
图像变换是指改变图像的几何形状或空间位置的操作。常见的几何变换包括平移、旋转、缩放、剪切(shear)以及更复杂的仿射变换和透视变换。这些变换在图像配准、图像校正、创建特效等场景中非常有用。 6.1仿射变换(Affine Transformation) 仿射变换是一种…...

Gitlab + Jenkins 实现 CICD
CICD 是持续集成(Continuous Integration, CI)和持续交付/部署(Continuous Delivery/Deployment, CD)的缩写,是现代软件开发中的一种自动化流程实践。下面介绍 Web 项目如何在代码提交到 Gitlab 后,自动发布…...

Qt 按钮类控件(Push Button 与 Radio Button)(1)
文章目录 Push Button前提概要API接口给按钮添加图标给按钮添加快捷键 Radio ButtonAPI接口性别选择 Push Button(鼠标点击不放连续移动快捷键) Radio Button Push Button 前提概要 1. 之前文章中所提到的各种跟QWidget有关的各种属性/函数/方法&#…...