OpenCV-Python(21):轮廓特征及周长、面积凸包检测和形状近似
2. 轮廓特征
轮廓特征是指由轮廓形状和结构衍生出来的一些特征参数。这些特征参数可以用于图像识别、目标检测和形状分析等应用中。常见的轮廓特征包括:
- 面积:轮廓所包围的区域的面积。
- 周长:轮廓的周长,即轮廓线的长度。
- 弧长:轮廓线的弧长,即轮廓的长度。
- 轮廓矩:轮廓的几何矩,用于描述轮廓的形状。
- 轮廓重心:轮廓所包围区域的重心坐标。
- 外接矩形:能够完全包围轮廓的矩形。
- 最小外接矩形:能够紧密包围轮廓的矩形,且角度与轮廓的方向一致。
- 外接圆:能够完全包围轮廓的圆。
- 最小外接圆:能够紧密包围轮廓的圆。
- 椭圆拟合:能够最好地拟合轮廓的椭圆。
- 凸包:能够包围轮廓的最小凸多边形。
- 轮廓层级:描述轮廓的嵌套关系。
这些轮廓特征可以通过OpenCV库的cv2.contourArea()
、cv2.arcLength()
、cv2.moments()
、cv2.boundingRect()
、cv2.minAreaRect()
、cv2.minEnclosingCircle()
、cv2.fitEllipse()
、cv2.convexHull()
等函数来计算和获取,下面主要介绍一些常用的特征。
2.1 目标
-
查找轮廓的不同特征,例如面积、周长、重心、边界框等。
-
学习和掌握轮廓相关函数
2.2 矩特征
图像矩是一种描述图像几何特征的数学工具,用于描述图像的形状、位置和分布等信息,以帮助我们计算图像的质心、面积等。图像矩可以用于图像识别、目标检测、形状分析等应用中。图像矩的计算是基于图像像素的灰度值进行的,常见的图像矩包括原点矩、中心矩和归一化矩。使用OpenCV库的cv2.moments()
函数可以计算图像的矩。该函数接受一个二值化的图像作为输入,并返回一个包含各种矩的字典。可以通过字典的键来获取不同的矩。以下是一个示例代码,演示如何计算图像的矩:
import cv2# 读取图像
image = cv2.imread("image.jpg")# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 计算矩
moments = cv2.moments(thresh)# 获取原点矩
m00 = moments["m00"]
m10 = moments["m10"]
m01 = moments["m01"]# 获取中心矩
cx = int(m10 / m00)
cy = int(m01 / m00)# 获取归一化矩
nu20 = moments["nu20"]
nu02 = moments["nu02"]
nu11 = moments["nu11"]# 打印矩的值
print("m00:", m00)
print("m10:", m10)
print("m01:", m01)
print("cx:", cx)
print("cy:", cy)
print("nu20:", nu20)
print("nu02:", nu02)
print("nu11:", nu11)
上述代码中,首先读取了一张图像,并对其进行了灰度化和二值化处理。然后使用cv2.moments()
函数计算了图像的矩。通过字典的键可以获取不同的矩的值。在示例代码中,获取了原点矩的值(m00、m10和m01)、中心矩的值(cx和cy)以及归一化矩的值(nu20、nu02和nu11)。最后打印了这些矩的值。需要注意的是,图像矩对图像的形状和位置非常敏感,因此在计算图像矩之前需要对图像进行预处理,如灰度化、二值化等。
注意:根据这些矩的值,我们可以计算出对象的重心,
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
2.3 轮廓面积
轮廓面积是指闭合轮廓所包围的区域的面积,可以用来描述对象的大小。在OpenCV中,可以使用cv2.contourArea()
函数计算轮廓的面积,也可以使用0阶矩(M['m00'])计算得到。
area = cv2.contourArea(cnt)
cv2.contourArea()
函数接受一个轮廓作为输入,并返回轮廓的面积。该函数的语法如下:
area = cv2.contourArea(contour)
其中,contour
是一个包含轮廓点的数组。可以通过cv2.findContours()
函数找到图像中的轮廓,并提取其中的某个轮廓来计算面积。以下是一个示例代码,演示如何计算轮廓的面积:
import cv2# 读取图像
image = cv2.imread("image.jpg")# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 遍历轮廓
for contour in contours:# 计算轮廓面积area = cv2.contourArea(contour)# 打印轮廓面积print("Contour area:", area)
在上述代码中,首先读取了一张图像,并对其进行了灰度化和二值化处理。然后使用cv2.findContours()
函数找到图像中的轮廓。返回的contours
是一个包含所有轮廓的列表。接下来,遍历轮廓列表,并使用cv2.contourArea()
函数计算每个轮廓的面积。最后打印了每个轮廓的面积。需要注意的是,cv2.contourArea()
函数计算的是轮廓的面积,而不是对象的实际面积。因此,在使用该函数之前,需要对图像进行预处理,如灰度化、二值化等,以确保轮廓能够正确识别。
2.4 轮廓周长
轮廓周长是指闭合轮廓的长度,可以用来描述对象的形状。在OpenCV中,可以使用cv2.arcLength()
函数计算轮廓的周长。cv2.arcLength()
函数接受一个轮廓作为输入,并返回轮廓的周长。该函数的语法如下:
perimeter = cv2.arcLength(contour, closed)
其中,contour
是一个包含轮廓点的数组,closed
是一个布尔值,指示轮廓是否是闭合的。如果轮廓是闭合的,则closed
为True
;如果轮廓是开放的,则closed
为False
。以下是一个示例代码,演示如何计算轮廓的周长:
import cv2# 读取图像
image = cv2.imread("image.jpg")# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 遍历轮廓
for contour in contours:# 计算轮廓周长perimeter = cv2.arcLength(contour, True)# 打印轮廓周长print("Contour perimeter:", perimeter)
在上述代码中,首先读取了一张图像,并对其进行了灰度化和二值化处理。然后使用cv2.findContours()
函数找到图像中的轮廓。返回的contours
是一个包含所有轮廓的列表。接下来,遍历轮廓列表,并使用cv2.arcLength()
函数计算每个轮廓的周长。最后打印了每个轮廓的周长。需要注意的是,cv2.arcLength()
函数计算的是轮廓的周长,而不是对象的周长。因此,在使用该函数之前,需要对图像进行预处理,如灰度化、二值化等,以确保轮廓能够正确识别。
2.5 轮廓近似
在OpenCV中,可以使用cv2.approxPolyDP()
函数对轮廓进行近似处理。轮廓近似可以将复杂的轮廓形状简化为更简单的几何形状,如直线或曲线。cv2.approxPolyDP()
函数接受一个轮廓作为输入,并返回一个近似的轮廓。该函数的语法如下:
approx = cv2.approxPolyDP(curve, epsilon, closed)
其中,curve
是一个包含轮廓点的数组,epsilon
是指定近似精度的参数,closed
是一个布尔值,指示轮廓是否是闭合的。如果轮廓是闭合的,则closed
为True
;如果轮廓是开放的,则closed
为False
。将轮廓形状近似到另外一种由更少点组成的轮廓形状,新轮廓的点的数目由我们设定的准确度来决定。实现这一功能主要使用的是Douglas-Peucker算法(你可以到维基百科获得更多此算法的细节)。为了帮助理解,假设我们需要在一幅图像中查找一个矩形,但是由于图像的种种原因,我们不能得到一个完美的矩形,而是一个(坏形状),如下图所示:
现在就可以使用这个函数来近似这个形状了。这个函数的第二个参数叫epsilon,它是从原始轮廓到近似轮廓的最大距离。它是一个准确度参数。选择一个好的epsilon 对于得到满意结果非常重要。
epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
下面第二幅图中的绿线是当epsilon = 10% 时得到近似轮廓,第三幅图是当epsilon = 1% 时得到的近似轮廓。第三个参数设定弧线是否闭合。
以下是一个示例代码,演示如何对轮廓进行近似处理:
import cv2# 读取图像
image = cv2.imread("image.jpg")# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 遍历轮廓
for contour in contours:# 近似轮廓epsilon = 0.01 * cv2.arcLength(contour, True)approx = cv2.approxPolyDP(contour, epsilon, True)# 绘制近似轮廓cv2.drawContours(image, [approx], 0, (0, 255, 0), 2)
在上述代码中,首先读取了一张图像,并对其进行了灰度化和二值化处理。然后使用cv2.findContours()
函数找到图像中的轮廓。返回的contours
是一个包含所有轮廓的列表。接下来,遍历轮廓列表,并使用cv2.arcLength()
函数计算每个轮廓的周长。然后根据周长计算一个近似精度epsilon
,并使用cv2.approxPolyDP()
函数对轮廓近似处理。最后使用cv2.drawContours()
函数绘制近似轮廓。需要注意的是,轮廓近似处理是一种对轮廓进行简化的方法,可以减少轮廓点的数量,从而降低计算的复杂性。但近似精度epsilon
的选择需要根据具体情况进行调整,过大的epsilon
会导致近似结果不准确,而过小的epsilon
会导致近似结果过于复杂。因此,在使用cv2.approxPolyDP()
函数进行轮廓近似处理时,需要根据实际情况选择合适的epsilon
值。
2.6 凸包
在计算机视觉中,凸包(Convex Hull)是指一个包围一组点的最小凸多边形。凸多边形是一个所有内角均小于180度的多边形。凸包与轮廓近似相似,但不同,然有些情况下它们给出的结果是一样的。OpenCV中提供了cv2.convexHull()
函数来计算给定点集的凸包,同时检测一个曲线是否具有凸性缺陷并能纠正缺陷。一般来说,凸性曲线总是凸出来的或者至少是平的。如果有地方凹下去了,就叫做凸性缺陷。例如下图中的手。红色曲线显示了手的凸包,凸性缺陷被双箭头标出来了。
关该cv2.convexHull()函数的语法如下:
hull = cv2.convexHull(points, clockwise, returnPoints)
其中,points
是一个包含点集的数组,clockwise
是一个布尔值,用于指定凸包的顺序,如果为True
,则返回的凸包按顺时针方向排序;如果为False
,则返回的凸包按逆时针方向排序;returnPoints
是一个布尔值,用于指定返回的凸包是点的坐标还是索引,默认为True
,表示返回点的坐标。
要获得上图的凸包,下面的命令就够了:
hull = cv2.convexHull(cnt)
但是如果你想获得凸性缺陷,需要把returnPoints 设置为False。以上面的矩形为例,首先我们找到他的轮廓cnt。现在我把returnPoints 设置为True 查找凸包,我得到下列值:
[[[234 202]], [[ 51 202]], [[ 51 79]], [[234 79]]],其实就是矩形的四个角点。现在把returnPoints 设置为False,我得到的结果是[[129],[ 67],[ 0],[142]],他们是轮廓点的索引。例如cnt[129] = [[234, 202]]这与前面我们得到结果的第一个值是一样的。
以下是一个示例代码,演示如何使用cv2.convexHull()
函数计算凸包:
import cv2
import numpy as np# 创建一组点
points = np.array([[10, 10], [10, 100], [100, 10], [100, 100], [50, 50]])# 计算凸包
hull = cv2.convexHull(points)# 绘制凸包
image = np.zeros((200, 200, 3), dtype=np.uint8)
cv2.polylines(image, [hull], True, (0, 255, 0), 2)# 显示图像
cv2.imshow("Convex Hull", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
在上述代码中,首先创建了一个包含5个点的数组points
。然后使用cv2.convexHull()
函数计算凸包,并将结果保存在hull
中。接下来,创建一个空白图像image
,并使用cv2.polylines()
函数绘制凸包。最后,显示图像。
需要注意的是,cv2.convexHull()
函数返回的凸包是一个包含点的数组,可以通过cv2.polylines()
函数绘制凸包。另外,可以使用cv2.isContourConvex()
函数检查一个轮廓是否是凸的。如果返回True
,则表示轮廓是凸的;如果返回False
,则表示轮廓是非凸的。凸包在计算机视觉中有广泛的应用,如图像分割、形状匹配等。凸包可以帮助我们简化复杂的形状,并提取出形状的关键特征。
2.7 凸性检测
函数cv2.isContourConvex() 可以可以用来检测一个曲线是不是凸的。它只能返回True 或False。没什么大不了的。
k = cv2.isContourConvex(cnt)
2.8 边界矩形
通常有两类边界矩形:直边界矩形、旋转边界矩形。
直边界矩形
一个直矩形(就是没有旋转的矩形)。它不会考虑对象是否旋转。所以直边界矩形的面积不是最小的。可以使用函数cv2.boundingRect() 查找得到。(x,y)为矩形左上角的坐标,(w,h)是矩形的宽和高。
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
旋转边界矩形
这个边界矩形是积最小的,因为它考虑了对象的旋转。用到的函数为cv2.minAreaRect()。返回的是一个Box2D 结构,其中包含矩形左上角角点的坐标(x,y),矩形的宽和高(w,h)以及旋转角度。但是要绘制这个矩形需要矩形的4 个顶点,可以通过函数cv2.boxPoints() 获得。
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
把这两中边界矩形显示在下图中,其中绿色的为直矩形,红的为旋转矩形。
2.9 最小外接圆
函数cv2.minEnclosingCircle() 可以帮我们找到一个对象的外接圆。它是所有能够包括对象的圆中面积最小的一个。
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,255,0),2)
2.10 椭圆拟合
使用的函数为cv2.ellipse(),返回值其实就是旋转边界矩形的内切圆。
ellipse = cv2.fitEllipse(cnt)
im = cv2.ellipse(im,ellipse,(0,255,0),2)
2.11 直线拟合
我们可以根据一组点拟合出一条直线,同样我们也可以为图像中的白色点拟合出一条直线。
rows,cols = img.shape[:2]
[vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
img = cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)
相关文章:

OpenCV-Python(21):轮廓特征及周长、面积凸包检测和形状近似
2. 轮廓特征 轮廓特征是指由轮廓形状和结构衍生出来的一些特征参数。这些特征参数可以用于图像识别、目标检测和形状分析等应用中。常见的轮廓特征包括: 面积:轮廓所包围的区域的面积。周长:轮廓的周长,即轮廓线的长度。弧长&…...

连接progressql报错Cannot load JDBC driver class ‘org.postgresql.Driver‘,亲测有效!!!
Jmeter连接progressql报错Cannot load JDBC driver class ‘org.postgresql.Driver’ 1.到官方下载驱动注意:根据项目的JDK版本来下载对应的驱动Download | pgJDBC 2.将postgresql-42.2.27.jar复制到lib目录下面, 然后重新启动 连接driver信息如下&#…...
SQLAlchemy快速入门
安装依赖 pip install sqlalchemy pip install pymysql创建数据库和表 # 创建数据库 drop database if exists sqlalchemy_demo; create database sqlalchemy_demo character set utf8mb4; use sqlalchemy_demo;# 创建表 drop table if exists user; create table user (id …...

java 纯代码导出pdf合并单元格
java 纯代码导出pdf合并单元格 接上篇博客 java导出pdf(纯代码实现) 后有一部分猿友叫我提供一下源码,实际上我的源码已经贴在帖子上了,都是同样的步骤,只是加多一点设置就可以了。今天我再次上传一下相对情况比较完整…...

Linux自己的应用商店yum
💫Linux系统如何安装软件 在Linux系统中我们可以通过多种方式安装软件,常见方式有以下三种: 1.源代码安装 2.rpm包安装 3.使用yum软件包管理器安装 早期人们通过下载软件源代码,然后再经过交叉编译等一系列工作下…...

集成电路模拟设计——【基于Serdes 应用的 串化/解串器 时钟与数据恢复电路CDR】
串化/解串器 & 时钟与数据恢复电路CDR(可提供实现过程、仿真波形与具体参数细节 本文内容摘要背景串化/解串器全速树形串化器半速树形串化器全速移位寄存器串化器多级树形解串器 PLL型CDR整体架构实现结果 Bang-Bang型CDR整体架构 PS/PI型CDR电路PS电路设计PI电…...

OpenWrt 编译入门(小白版)
编译环境 示例编译所用系统为 Ubuntu 22.04,信息如下 编译时由于网络问题,部分软件包可能出现下载问题,还请自备网络工具或尝试重新运行命令 编译步骤 下图为官网指示 编译环境设置(Build system setup) 这里根据我…...

嵌入式视频播放器(mplayer)
1.文件准备: MPlayer-1.0rc2.tar.bz2 libmad-0.15.1b.tar.gz 直接Git到本地 git clone https://gitee.com/zxz_FINE/mplayer_tarball.git 2.文件夹准备: src存放解压后的源码文件,target_Mplayer存放编译安装的目标文件 mkdir src targe…...

对房价数据集进行处理和数据分析
大家好,我是带我去滑雪,每天教你一个小技巧! 房价数据集通常包含各种各样的特征,如房屋面积、地理位置、建造年份等。通过对数据进行处理和分析,可以更好地理解这些特征之间的关系,以及它们对房价的影响程度…...

BERT的学习
BERT 1.前言 self-supervised learning是一种无监督学习的特殊形式,算法从数据本身生成标签或者目标,然后利用这些生成的目标来进行学习。(也就是说数据集的标签是模型自动生成的,不是由人为提供的。)例如࿰…...

数据结构OJ实验9-图存储结构和遍历
A. 图综合练习--构建邻接表 题目描述 已知一有向图,构建该图对应的邻接表。 邻接表包含数组和单链表两种数据结构,其中每个数组元素也是单链表的头结点,数组元素包含两个属性,属性一是顶点编号info,属性二是指针域n…...

20231226在Firefly的AIO-3399J开发板上在Android11下调通后摄像头ov13850
20231226在Firefly的AIO-3399J开发板上在Android11下调通后摄像头ov13850 2023/12/26 8:22 开发板:Firefly的AIO-3399J【RK3399】 SDK:rk3399-android-11-r20211216.tar.xz【Android11】 Android11.0.tar.bz2.aa【ToyBrick】 Android11.0.tar.bz2.ab And…...

0101包冲突导致安装docker失败-docker-云原生
文章目录 1 前言2 报错3 解决结语 1 前言 最近在学习k8s,前置条件就是要安装指定版本的docker,命令如下 yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7 containerd.io-1.4.62 报错 file /usr/libexec/docker/cli-plugins/docker-buildx fr…...
【力扣100】17.电话号码的字母组合
添加链接描述 class Solution:def letterCombinations(self, digits: str) -> List[str]:# 思路是使用回溯算法if not digits:return []phone {2:[a,b,c],3:[d,e,f],4:[g,h,i],5:[j,k,l],6:[m,n,o],7:[p,q,r,s],8:[t,u,v],9:[w,x,y,z]}def backtrack(con,dig):# 收获if le…...

2023。
一月 从头开始 二月 准备复试&初试成绩 三月 最开心 过了两个生日(这机率,幸运儿) 考研也成功上岸!nnuGISer! 四月 和室友去了趟武汉 五月 拍毕业照 六月 人生高光时刻 省创!上台领奖!考研…...
出现 Cause: java.sql.SQLException: Field ‘id‘ doesn‘t have a default value解决方法
目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 在驱动Springboot项目的时候,出现如下问题: org.springframework.dao.DataIntegrityViolationException: ### Error updating database. Cause: java.sql...

Linux--批量自动装机
实验环境 随着某公司业务不断发展,服务器主机的数量也迅速增长,对于功能变更或新采购的服务器, 需要重新安装CentOS7操作系统,为了提高服务器装机效率,要求基于PXE网络实现全自动无人值 守批量安装。 需求描述 > 服…...

病理HE学习贴(自备)
目录 正常结构 癌症HE 在线学习 以胃癌的学习为例 正常结构 1:胃粘膜正常结构和细胞分化 ●表面覆盖小凹上皮细胞(主要标志物:MUC5AC)以保护黏膜。 ●胃底腺固有腺体由黏液颈细胞(MUC6)、主细胞(Pepsinogen l)和壁细胞(Proton pump α-subunit)组…...
关于协同过滤算法在物联网的应用-基于用户行为数据和物联网设备数据,以此提供个性化的智能家居控制推荐服务
关于协同过滤算法在物联网领域的应用的一个案例是基于用户行为数据和物联网设备数据,为用户提供个性化的智能家居控制推荐服务。 具体实现如下: 数据收集:收集用户对智能家居设备的使用行为数据,包括设备的打开、关闭、调节等操…...

计算机网络(6):应用层
每个应用层协议都是为了解决某一类应用问题,而问题的解决又往往是通过位于不同主机中的多个应用进程之间的通信和协同工作来完成的。 应用层的具体内容就是规定应用进程在通信时所遵循的协议。 应用层的许多协议都是基于客户服务器方式。即使是对等通信方式&#x…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...

Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...

VASP软件在第一性原理计算中的应用-测试GO
VASP软件在第一性原理计算中的应用 VASP是由维也纳大学Hafner小组开发的一款功能强大的第一性原理计算软件,广泛应用于材料科学、凝聚态物理、化学和纳米技术等领域。 VASP的核心功能与应用 1. 电子结构计算 VASP最突出的功能是进行高精度的电子结构计算ÿ…...