OpenCV图像形态学详解
文章目录
- 一、什么是图像形态学?
- 二、基本概念:结构元素
- 三、基本形态学操作
- 1. 腐蚀(Erosion)
- 2. 膨胀(Dilation)
- 3. 开运算(Opening)
- 4. 闭运算(Closing)
- 四、高级形态学操作
- 1. 形态学梯度
- 2. 顶帽(Top Hat)与黑帽(Black Hat)
- 五、总结
一、什么是图像形态学?
图像形态学(Image Morphology)是数字图像处理领域的一个重要分支,主要研究基于形状的图像处理技术。它最初源于对生物体形态的研究,后来被引入到图像分析中,成为提取图像中有用形状特征的有效工具。
在OpenCV中,形态学操作主要基于二值图像(黑白图像)进行处理,通过结构元素(kernel)与图像进行特定操作来实现各种效果,广泛应用于边缘检测、噪声去除、形状分析等领域。
二、基本概念:结构元素
结构元素(Structuring Element)是形态学操作的核心,它决定了操作的邻域形状和大小。可以把它想象成一个小的矩阵或模板,在图像上滑动并进行比较。
import cv2
import numpy as np# 创建矩形结构元素
kernel_rect = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
# 创建椭圆形结构元素
kernel_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
# 创建十字形结构元素
kernel_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (5,5))print("矩形结构元素:\n", kernel_rect)
print("椭圆形结构元素:\n", kernel_ellipse)
print("十字形结构元素:\n", kernel_cross)
三、基本形态学操作
1. 腐蚀(Erosion)
腐蚀操作可以看作是将图像"收缩"或"细化"的过程。它会侵蚀掉物体的边界,使物体变小。
原理:结构元素在图像上滑动,只有当结构元素完全覆盖前景像素时,中心像素才保留为前景,否则变为背景
- 图像腐蚀, 函数为:
cv2.erode(src, kernel, dst,anchor,iterations,borderType,borderValue)
src: 输入的图像
kernel: 用于腐蚀的结构元件如果element = Mat(),则使用3 × 3的矩形结构单元。
dst: 它是与src相同大小和类型的输出图像。
iterations:腐蚀操作的迭代次数,默认为1。次数越多, 腐蚀操作执行的次数越多,腐蚀效果越明显
下面我们以一张太阳的图片来进行腐蚀:
import cv2
import numpy as np
sun = cv2.imread('sun.png')
cv2.imshow('src',sun)
cv2.waitKey(0)
kernel = np.ones((3,3),np.uint8) #设置kernel大小
erosion_1 = cv2.erode(sun,kernel,iterations=2)
cv2.imshow('erosion_1',erosion_1)
cv2.waitKey(0)
左图是原图,右边为腐蚀后的图片:
应用场景:
- 去除小的白噪声
- 分离相连的物体
- 消除细小的突出物
2. 膨胀(Dilation)
膨胀是腐蚀的对偶操作,可以看作是将图像"扩张"或"变粗"的过程。
原理:结构元素在图像上滑动,只要结构元素与前景像素有重叠,中心像素就设置为前景。
- 图像腐蚀, 函数为:
cv2.dilate(img, kernel, iteration)
参数含义:
img – 目标图片
kernel – 进行操作的内核,默认为3×3的矩阵
iterations – 膨胀次数,默认为1
# 膨胀操作
dilated = cv2.dilate(binary, kernel_rect, iterations=1)cv2.imshow('Original', binary)
cv2.imshow('Dilated', dilated)
cv2.waitKey(0)
cv2.destroyAllWindows()
左图是原图,右边为膨胀后的图片:
应用场景:
- 填补物体中的空洞
- 连接相邻的物体
- 增加物体尺寸
3. 开运算(Opening)
开运算是先腐蚀后膨胀的过程。
作用:平滑物体的轮廓、断开较窄的狭颈并消除细的突出物。
下面以一张指纹图片,进行开运算操作
import cv2
import numpy as np
zhiwen = cv2.imread('zhiwen.png')
cv2.imshow('src2',zhiwen)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)
zhiwen_new = cv2.morphologyEx(zhiwen,cv2.MORPH_OPEN,kernel)
cv2.imshow('zhiwen_new',zhiwen_new)
cv2.waitKey(0)
- 运行结果如下:
特点:
- 消除小的前景区域(噪声)
- 平滑物体轮廓但不明显改变面积
- 断开狭窄的连接
4. 闭运算(Closing)
闭运算是先膨胀后腐蚀的过程。
作用:弥合较窄的间断和细长的沟壑,清除小的孔洞,填补轮廓线中的断裂
zhiwen = cv2.imread('zhiwen_duan.png')
cv2.imshow('src3',zhiwen)
cv2.waitKey(0)
kernel = np.ones((5,5),np.uint8)
zhiwen_new = cv2.morphologyEx(zhiwen,cv2.MORPH_CLOSE,kernel)
cv2.imshow('zhiwen_new1',zhiwen_new)
cv2.waitKey(0)
- 运行结果如下:
特点: - 填补前景区域中的小孔
- 连接邻近物体
- 平滑轮廓但不明显改变面积
四、高级形态学操作
1. 形态学梯度
形态学梯度是膨胀图与腐蚀图之差,可以得到物体的轮廓。
作用:突出显示图像中强度变化剧烈的地方
import cv2
import numpy as np
wenzi = cv2.imread('wenzi.png')
cv2.imshow('wenzi_new',wenzi)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)
#膨胀-腐蚀
bianyuan = cv2.morphologyEx(wenzi,cv2.MORPH_GRADIENT,kernel)
cv2.imshow('bianyuan',bianyuan)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 运行结果如下:
应用:边缘检测、轮廓提取
2. 顶帽(Top Hat)与黑帽(Black Hat)
顶帽是原图像与开运算结果之差,黑帽是闭运算结果与原图像之差。
import cv2
import numpy as np
# # 顶帽 = 原始图像 - 开运算结果(先腐蚀后膨胀)
# # 黑帽 = 闭运算(先膨胀后腐蚀) - 原始图像
sun = cv2.imread('sun.png')
cv2.imshow('sun_yuantu',sun)
cv2.waitKey(0)
kernel = np.ones((2,2),np.uint8)#顶帽
tophat = cv2.morphologyEx(sun,cv2.MORPH_TOPHAT,kernel)
cv2.imshow('TOPHAT',tophat)
cv2.waitKey(0)#黑帽
blackhat = cv2.morphologyEx(sun,cv2.MORPH_BLACKHAT,kernel)
cv2.imshow('BLACKHAT',blackhat)
cv2.waitKey(0)
- 运行结果如下
应用:
- 顶帽:突出比邻近区域亮的微小物体
- 黑帽:突出比邻近区域暗的微小物体
五、总结
OpenCV中的形态学操作是图像处理中极为强大的工具,通过合理组合基本操作可以解决许多实际问题。关键点包括:
- 理解结构元素对结果的影响
- 掌握腐蚀、膨胀、开运算、闭运算等基本操作
- 学会根据实际问题选择适当的操作组合
- 通过调整迭代次数和结构元素大小优化效果
形态学操作虽然简单,但在实际应用中往往能发挥意想不到的效果,大家一定要多去练习并且在这些运行结果种发现各个操作的区别。
代码的学习就是多练,多看,多思考,相信大家坚持下去一定会成功的,希望这篇文章能帮助到您!
相关文章:
OpenCV图像形态学详解
文章目录 一、什么是图像形态学?二、基本概念:结构元素三、基本形态学操作1. 腐蚀(Erosion)2. 膨胀(Dilation)3. 开运算(Opening)4. 闭运算(Closing) 四、高级…...
Java-servlet(完结篇)过滤器乱码解决与监听器
Java-servlet(完结篇)过滤器乱码解决与监听器 前言一、过滤器乱码解决二、监听器1. HttpSessionListener2. ServletContextListener3. ServletRequestListener 三、监听器的使用场景Java-servlet 结语 前言 在之前的 Java Servlet 学习中,我…...
【发布】dtns协议的js-sdk(实现a2a协议:agent2agent)
【发布】dtns协议的js-sdk(实现a2a协议:agent2agent) dtns协议简介 dtns协议是用于dtns.network分布式智体网络的通讯协议。主要目标是将各个独立的智体节点,通过dtns协议(dtns.network)连接在一起&#…...
深度学习总结(8)
模型工作流程 模型由许多层链接在一起组成,并将输入数据映射为预测值。随后,损失函数将这些预测值与目标值进行比较,得到一个损失值,用于衡量模型预测值与预期结果之间的匹配程度。优化器将利用这个损失值来更新模型权重。 下面是…...
[特殊字符] Hyperlane:为现代Web服务打造的高性能Rust文件上传解决方案
🚀 Hyperlane:为现代Web服务打造的高性能Rust文件上传解决方案 ▎开发者必备:为什么选择Hyperlane处理大文件上传? 在实时数据爆炸式增长的时代,开发者面临两大核心挑战: 如何实现TB级大文件的可靠传输如…...
英伟达开源253B语言模型:Llama-3.1-Nemotron-Ultra-253B-v1 模型情况
Llama-3.1-Nemotron-Ultra-253B-v1 模型情况 1. 模型概述 Llama-3.1-Nemotron-Ultra-253B-v1 是一个基于 Meta Llama-3.1-405B-Instruct 的大型语言模型 (LLM),专为推理、人类对话偏好和任务(如 RAG 和工具调用)而优化。该模型支持 128K 令…...
2025年智能合约玩法创新白皮书:九大核心模块与收益模型重构Web3经济范式
——从国库管理到动态激励的加密生态全栈解决方案 一、核心智能合约架构解析 1. 国库合约:生态财政中枢 作为协议的金库守卫者,国库合约通过多签冷钱包与跨链资产池实现资金沉淀。其创新点包括: 储备资产动态再平衡:采用预言机实…...
[250411] Meta 发布 Llama 4 系列 AI 模型 | Rust 1.86 引入重大语言特性
目录 Llama 4 家族登场:开启原生多模态 AI 创新新纪元Rust 1.86.0 版本发布亮点主要新特性与改进其他重要信息 Llama 4 家族登场:开启原生多模态 AI 创新新纪元 Meta AI 近日发布了其最新、最先进的 Llama 4 系列人工智能模型,标志着 AI 技术…...
缓存不只是加速器:深入理解 Redis 的底层机制
一、Redis 是什么?为什么我们需要它? Redis(Remote Dictionary Server)是一种高性能的内存型键值对数据库。 通俗地讲,它就像一个超快的、放在内存中的超级字典,你可以用它来存数据、查数据,而…...
windows虚拟内存
windows的虚拟内存只是 虚拟内存技术的一个拓展, 叫他分页文件更好, 真正的虚拟内存是 CPU 内存管理单元 用于调度物理内存和磁盘衍生出来的技术. 在此基础上, 虚拟内存会根据页表 去物理内存中找数据, 找不到就去磁盘找, 找到之后再登记到页表. 这里的磁盘就是window系统中所…...
Ajax------免刷新地前后端交互
本文略带PHP代码需要在PHP环境下使用 介绍 AJAX (Asynchronous JavaScript and XML) 是一种创建快速动态网页应用的开发技术,它允许网页在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容。例如,在我们做爬虫的时候发现有些…...
python办公自动化---pdf文件的读取、添加水印
需要安装包:pdfminer、pypdf2 一、读取pdf中的内容 from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfdocument import PDFDocument from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterprete…...
下一代数据架构全景:云原生实践、行业解法与 AI 底座 | Databend Meetup 成都站回顾
3 月底,Databend 2025 开年首场 Meetup 在成都多点公司成功举办!活动特别邀请到四位重量级嘉宾:多点科技数据库架构师王春涛、多点DMALL数据平台负责人李铭、Databend联合创始人吴炳锡,以及鹏城实验室王璞博士。在春日的蓉城&…...
Kubernetes容器编排与云原生实践
第一部分:Kubernetes基础架构与核心原理 第1章 容器技术的演进与Kubernetes的诞生 1.1 虚拟化技术的三次革命 物理机时代:资源浪费严重,利用率不足15% 虚拟机突破:VMware与Hyper-V实现硬件虚拟化,利用率提升至50% …...
vue项目使用html2canvas和jspdf将页面导出成PDF文件
一、需求: 页面上某一部分内容需要生成pdf并下载 二、技术方案: 使用html2canvas和jsPDF插件 三、js代码 // 页面导出为pdf格式 import html2Canvas from "html2canvas"; import jsPDF from "jspdf"; import { uploadImg } f…...
JAVA实现在H5页面中点击链接直接进入微信小程序
在普通的Html5页面中如何实现点击URL链接直接进入微信小程序,不需要扫描小程序二维码? 网上介绍的很多方法是在小程序后台设置Schema,不过我进入我的小程序后台在开发设置里面 没有找到设置小程序Schema的地方,我是通过调用API接口…...
深入剖析 Kafka 的零拷贝原理:从操作系统到 Java 实践
Kafka 作为一款高性能的分布式消息系统,其卓越的吞吐量和低延迟特性得益于多种优化技术,其中“零拷贝”(Zero-Copy)是核心之一。零拷贝通过减少用户态与内核态之间的数据拷贝,提升了 Kafka 在消息传输中的效率。本文将…...
深度学习:AI 大模型时代的智能引擎
当 Deepspeek 以逼真到难辨真假的语音合成和视频生成技术横空出世,瞬间引发了全球对 AI 伦理与技术边界的激烈讨论。从伪造名人演讲、制造虚假新闻,到影视行业的特效革新,这项技术以惊人的速度渗透进大众视野。但在 Deepspeek 强大功能的背后…...
【Flask开发】嘿马文学web完整flask项目第4篇:4.分类,4.分类【附代码文档】
教程总体简介:2. 目标 1.1产品与开发 1.2环境配置 1.3 运行方式 1.4目录说明 1.5数据库设计 2.用户认证 Json Web Token(JWT) 3.书架 4.1分类列表 5.搜索 5.3搜索-精准&高匹配&推荐 6.小说 6.4推荐-同类热门推荐 7.浏览记录 8.1配置-阅读偏好 8.配置 9.1项目…...
【MySQL】002.MySQL数据库基础
文章目录 数据库基础1.1 什么是数据库1.2 基本使用创建数据库创建数据表表中插入数据查询表中的数据 1.3 主流数据库1.4 服务器,数据库,表关系1.5 MySQL架构1.6 SQL分类1.7 存储引擎1.7.1 存储引擎1.7.2 查看存储引擎1.7.3 存储引擎对比 前言:…...
Python爬取视频的架构方案,Python视频爬取入门教程
文章目录 前言方案概述架构设计详细实现步骤1.环境准备2. 网页请求模块3. 网页解析模块4. 视频下载模块5. 异常处理与日志模块 代码示例:性能优化注意事项 前言 以下是一个全面的使用 Python 爬取视频的架构方案,包含方案概述、架构设计、详细实现步骤、…...
ERC-20 代币标准
文章目录 一、什么是 ERC-20?核心价值:互操作性简化开发生态基石 二、ERC-20 的六大核心功能基础功能授权与代理转账事件通知 三、ERC-20 代币的典型应用场景四、ERC-20 的技术优势与局限性优势:局限性: 五、ERC-20 代币的创建步骤…...
SpringBoot实战1
SpringBoot实战1 一、开发环境,环境搭建-----创建项目 通过传统的Maven工程进行创建SpringBoot项目 (1)导入SpringBoot项目开发所需要的依赖 一个父依赖:(工件ID为:spring-boot-starter-parent…...
GSO-YOLO:基于全局稳定性优化的建筑工地目标检测算法解析
论文地址:https://arxiv.org/pdf/2407.00906 1. 论文概述 《GSO-YOLO: Global Stability Optimization YOLO for Construction Site Detection》提出了一种针对建筑工地复杂场景优化的目标检测模型。通过融合全局优化模块(GOM)、稳定捕捉模块(SCM)和创新的AIoU损失函…...
解读json.loads函数参数
json.loads()函数是解码JSON字符串为Python对象的核心工具。本文将深入探讨json.loads()函数的各个参数。 一、基本功能与输入类型 1. 功能概述 json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=N…...
2025.04.10-拼多多春招笔试第一题
📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 01. 神奇公园的福娃占卜 问题描述 LYA在一个神奇的公园里发现了一条特殊的小径,小径上排列着一群可爱的福娃玩偶。这条小径有 n n...
【学习笔记】CPU 的“超线程”是什么?
1. 什么是超线程? 超线程(Hyper-Threading)是Intel的技术,让一个物理CPU核心模拟出两个逻辑核心。 效果:4核CPU在系统中显示为8线程。 本质:通过复用空闲的硬件单元(如ALU、FPU)&a…...
Docker Harbor
下载Harbor安装包 wget https://github.com/goharbor/harbor/releases/download/v2.5.0/harbor-offline-installer-v2.5.0.tgz 解压安装包 tar xvf harbor-offline-installer-v2.5.0.tgz cd harbor 配置harbor vi harbor.yml hostname: registry.example.com # Harbor …...
天梯集训笔记整理
1.着色问题 直接标注哪些行和列是被标注过的,安全格子的数量就是未标注的行*列 #include <bits/stdc.h> using namespace std;const int N 1e510; int hang[N],lie[N];int main(){int n,m;cin>>n>>m;int q;cin>>q;while(q--){int x,y;ci…...
C语言复习笔记--指针(4)
在经过前几篇的复习后我们已经了解了大部分指针的类型,今天让我们继续复习指针的其他内容吧. 函数指针变量 函数指针变量的创建 什么是函数指针变量呢?函数指针变量应该是⽤来存放函数地址的,未来通过地址能够调⽤函数的。 那么函数是否有地址呢&#x…...
008二分答案+贪心判断——算法备赛
二分答案贪心判断 有些问题,从已知信息推出答案,细节太多,过程繁杂,不易解答。 从猜答案出发,贪心地判断该答案是否合法是个不错的思路,这要求所有可能的答案是单调的(例:x满足条件…...
Netty之内存池的原理和实战
深入理解Netty的内存池机制及其应用实践 在高性能网络编程中,内存管理对于系统的稳定性和性能至关重要。Netty作为一个高效的网络通信框架,通过引入内存池机制有效地解决了内存分配和回收频繁带来的性能瓶颈和内存碎片问题。本文将深入探讨Netty内存池的…...
Elasticsearch 向量数据库,原生支持 Google Cloud Vertex AI 平台
作者:来自 Elastic Valerio Arvizzigno Elasticsearch 将作为第一个第三方原生语义对齐引擎,支持 Google Cloud 的 Vertex AI 平台和 Google 的 Gemini 模型。这使得联合用户能够基于企业数据构建完全可定制的生成式 AI 体验,并借助 Elastics…...
《算法笔记》3.1小节——入门模拟->简单模拟
1001 害死人不偿命的(3n1)猜想 #include <iostream> using namespace std;int main() {int n,count0;cin>>n;while(n!1){if(n%20) n/2;else n(3*n1)/2;count1;}std::cout <<count;return 0; }1032 挖掘机技术哪家强 #include <iostream> using namespa…...
每日一题(小白)暴力娱乐篇24
由题已知这是一个匹配题目,题目已经说了三阶幻方是给定的,经过镜像和旋转,镜像*2旋转*4; 总共八种方案,然后接收每次的数据去匹配(跳过0),如果匹配就输出匹配的数组,如果…...
C++:函数模板类模板
程序员Amin 🙈作者简介:练习时长两年半,全栈up主 🙉个人主页:程序员Amin 🙊 P S : 点赞是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全…...
第18章:基于Global Context Vision Transformers(GCTx_unet)网络实现的oct图像中的黄斑水肿和裂孔分割
1. 网络概述 GCTx-UNET是基于传统UNet架构的改进版本,主要引入了以下几个关键创新: GCT模块:全局上下文变换器(Global Context Transformer)模块 多尺度特征融合:增强的特征提取能力 改进的跳跃连接:优化编码器与解…...
深入理解 Spring 的 MethodParameter 类
MethodParameter 是 Spring 框架中一个非常重要的类,它封装了方法参数(或返回类型)的元数据信息。这个类在 Spring MVC、AOP、数据绑定等多个模块中都有广泛应用。 核心功能 MethodParameter 主要提供以下功能: 获取参数类型信息…...
Docker部署HivisionIDPhotos1分钟生成标准尺寸证件照实操指南
文章目录 前言1. 安装Docker2. 本地部署HivisionIDPhotos3. 简单使用介绍4. 公网远程访问制作照片4.1 内网穿透工具安装4.2 创建远程连接公网地址 5. 配置固定公网地址 前言 相信大部分人办驾照、护照或者工作证时都得跑去照相馆,不仅费时还担心个人信息泄露。好消…...
python多线程+异步编程让你的程序运行更快
多线程简介 多线程是Python中实现并发编程的重要方式之一,它允许程序在同一时间内执行多个任务。在某些环境中使用多线程可以加快我们代码的执行速度,例如我们通过爬虫获得了一个图片的url数组,但是如果我们一个一个存储很明显会非常缓慢&…...
HDCP(五)
HDCP 2.2 测试用例设计详解 基于HDCP 2.2 CTS v1.1规范及协议核心机制,以下从正常流程与异常场景两大方向拆解测试用例设计要点,覆盖认证、密钥管理、拓扑验证等关键环节: 1. 正常流程测试 1.1 单设备认证 • 测试目标:验证源设…...
datagrip如何连接数据库
datagrip连接数据库的步骤 2025版本 想要链接数据库是需要一个jar包的,所以将上面进行删除之后,需要下载一个jar包 那么这个时候需要链接上传一个mysql链接的jar包 选择核心驱动类 上述操作完成之后,然后点击apply再点击ok即可 如下图说明my…...
Spring Boot 自动配置与启动原理全解析
下面分两部分系统讲解: 第一部分:Spring Boot 自动配置原理(核心是自动装配) 一、Spring Boot 的自动配置是干嘛的? 传统 Spring 开发时,你要写一堆 XML 或配置类,非常麻烦。Spring Boot 引入…...
python 基础:句子缩写
n int(input()) for _ in range(n):words input().split()result ""for word in words:result word[0].upper()print(result)知识点讲解 input()函数 用于从标准输入(通常是键盘)读取用户输入的内容。它返回的是字符串类型。例如在代码中…...
QML 中 Z 轴顺序(z 属性)
在 QML 中,z 属性用于控制元素的堆叠顺序(Z 轴顺序),决定元素在视觉上的前后层次关系。 基本概念 默认行为: 所有元素的默认 z 值为 0 同层级元素后声明的会覆盖先声明的 父元素的 z 值会影响所有子元素 核心规则…...
Redis快的原因
1、基于内存实现 Redis将所有数据存储在内存中,因此它可以非常快速地读取和写入数据,而无需像传统数据库那样将数据从磁盘读取和写入磁盘,这样也就不受I/O限制。 2、I/O多路复用 多路指的是多个socket连接;复用指的是复用一个线…...
蓝桥杯c ++笔记(含算法 贪心+动态规划+dp+进制转化+便利等)
蓝桥杯 #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std; //常使用的头文件动态规划 小蓝在黑板上连续写下从 11 到 20232023 之间所有的整数,得到了一个数字序列: S12345…...
每日算法-250410
今天分享两道 LeetCode 题目,它们都可以巧妙地利用二分查找来解决。 275. H 指数 II 问题描述 思路:二分查找 H 指数的定义是:一个科学家有 h 篇论文分别被引用了至少 h 次。 题目给定的 citations 数组是升序排列的。这为我们使用二分查找…...
swagger + Document
swagger 虽然有了api接口,对于复杂接口返回值说明,文档还是不能少。如果是一个人做的还简单一点,现在都搞前后端分离,谁知道你要取那个值呢...
线程同步与互斥(下)
线程同步与互斥(中)https://blog.csdn.net/Small_entreprene/article/details/147003513?fromshareblogdetail&sharetypeblogdetail&sharerId147003513&sharereferPC&sharesourceSmall_entreprene&sharefromfrom_link我们学习了互斥…...