opencv基础47 查找图像轮廓cv2.findContours()详解
什么是图像轮廓?
图像轮廓是指图像中物体边缘的连续性曲线。在计算机视觉和图像处理中,轮廓通常被用于检测物体、分割图像以及提取物体特征。
图像轮廓是由一系列连续的像素点组成,这些像素点位于物体边界上。轮廓的特点是在物体和背景之间的边界位置,因此可以用来表示物体的形状和结构。轮廓可以是闭合的,也可以是开放的,具体取决于物体的形状。
图像轮廓的应用场景?
图像轮廓在许多应用场景中都发挥着重要作用,下面列举了一些常见的应用场景:
目标检测与识别: 图像轮廓可以用于检测和定位图像中的物体。通过检测物体的轮廓,可以识别出图像中的不同物体并进行分类。
图像分割: 轮廓可以用来分割图像中的不同区域或物体。通过提取物体的轮廓,可以将图像分成多个不同的部分,方便进一步分析和处理。
医学图像分析: 在医学图像中,轮廓可以用来标记器官、病变或细胞等结构。这对于诊断和治疗决策具有重要意义。
工业自动化: 在工业自动化中,轮廓可以用于检测产品的缺陷、测量尺寸和定位部件,从而实现自动化生产和质量控制。
机器人视觉: 机器人可以利用图像轮廓来感知环境和物体,从而实现自主导航、抓取物体等任务。
计算机辅助设计(CAD): 在CAD领域,图像轮廓可以用于从实际物体中获取几何信息,以便在计算机上进行建模和设计。
虚拟现实与增强现实: 图像轮廓可以用来实时跟踪物体,将虚拟对象与实际场景进行交互,从而创建更加逼真的虚拟现实或增强现实体验。
图像重建与三维建模: 利用物体的轮廓可以进行图像的重建和三维建模,从而生成立体的物体模型。
边缘检测虽然能够检测出边缘,但边缘是不连续的,检测到的边缘并不是一个整体。图像轮廓是指将边缘连接起来形成的一个整体,用于后续的计算。
OpenCV 提供了查找图像轮廓的函数 cv2.findContours()
,该函数能够查找图像内的轮廓信息,而函数 cv2.drawContours()能够将轮廓绘制出来。
图像轮廓是图像中非常重要的一个特征信息,通过对图像轮廓的操作,我们能够获取目标图像的大小、位置、方向等信息。
查找图像轮廓:findContours函数
函数 cv2.findContours()的语法格式为:
image, contours, hierarchy = cv2.findContours( image, mode, method)
式中的返回值为:
- image:与函数参数中的原始图像 image 一致。
- contours:返回的轮廓。
- hierarchy:图像的拓扑信息(轮廓层次)。
式中的参数为:
- image:原始图像。8 位单通道图像,所有非零值被处理为 1,所有零值保持不变。也就是说灰度图像会被自动处理为二值图像。在实际操作时,可以根据需要,预先使用阈值处理等函数将待查找轮廓的图像处理为二值图像。
- mode:轮廓检索模式。
- method:轮廓的近似方法。
函数 cv2.findContours()的返回值及参数的含义比较丰富,下面对上述返回值和参数逐一做出说明。
1. 返回值image
该返回值与参数 image 是一致的,就是原始输入图像。在 OpenCV 4.X 中,该返回值已经被取消。在 OpenCV 4.X 中,函数 cv2.findContours()仅有两个返回值,其语法格式为:
contours, hierarchy = cv2.findContours( image, mode, method)
2. 返回值contours
该返回值返回的是一组轮廓信息,每个轮廓都是由若干个点所构成的。例如,contours[i] 是第 i 个轮廓(下标从 0 开始),contours[i][j]是第 i 个轮廓内的第 j 个点。
图 12-1 所示为提取的轮廓示例,函数 cv2.findContours()提取出左图的 3 个轮廓,每一个轮廓都是由若干个像素点构成的。
下面针对图 12-1 来简单介绍一下 contours 的基本属性。
(1)type 属性
返回值 contours 的 type 属性是 list 类型,list 的每个元素都是图像的一个轮廓,用 Numpy中的 ndarray 结构表示。
例如,使用如下语句获取轮廓 contours 的类型:
print (type(contours))
结果为<class ‘list’>。
使用如下语句获取轮廓 contours 中每个元素的类型:
print (type(contours[0]))
结果为<class ‘numpy.ndarray’>。
(2)轮廓的个数
使用如下语句可以获取轮廓的个数:
print (len(contours))
结果为“3”,表示在图 12-1 中,存在 3 个轮廓。
(3)每个轮廓的点数
每一个轮廓都是由若干个像素点构成的,点的个数不固定,具体个数取决于轮廓的形状。
例如,使用如下语句,可以获取每个轮廓内点的个数:
print (len(contours[0])) #打印第 0 个轮廓的长度(点的个数):4
print (len(contours[1])) #打印第 1 个轮廓的长度(点的个数):60
print (len(contours[2])) #打印第 2 个轮廓的长度(点的个数):184
(4)轮廓内的点
使用如下语句,可以获取轮廓内第 0 个轮廓中具体点的位置属性:
print (contours[0]) #打印第 0 个轮廓中的像素点
contours[0]对应着图 12-1 中右图左下角矩形轮廓的点,输出结果如下:
[[[ 79 270]]
[[ 79 383]]
[[195 383]]
[[195 270]]]
- 返回值hierarchy
图像内的轮廓可能位于不同的位置。比如,一个轮廓在另一个轮廓的内部。在这种情况下,
我们将外部的轮廓称为父轮廓,内部的轮廓称为子轮廓。按照上述关系分类,一幅图像中所有轮廓之间就建立了父子关系。
根据轮廓之间的关系,就能够确定一个轮廓与其他轮廓是如何连接的。比如,确定一个轮廓是某个轮廓的子轮廓,或者是某个轮廓的父轮廓。上述关系被称为层次(组织结构),返回值 hierarchy 就包含上述层次关系。
每个轮廓 contours[i]对应 4 个元素来说明当前轮廓的层次关系。其形式为:
[Next,Previous,First_Child,Parent]
式中各元素的含义为:
-
Next:后一个轮廓的索引编号。
-
Previous:前一个轮廓的索引编号。
-
First_Child:第 1 个子轮廓的索引编号。
-
Parent:父轮廓的索引编号。
如果上述各个参数所对应的关系为空时,也就是没有对应的关系时,则将该参数所对应的值设为“-1”。
使用 print 语句可以查看 hierarchy 的值:
print(hierarchy)
需要注意,轮廓的层次结构是由参数 mode 决定的。也就是说,使用不同的 mode,得到轮廓的编号是不一样的,得到的 hierarchy 也不一样。
-
参数image
该参数表示输入的图像,必须是 8 位单通道二值图像。一般情况下,都是将图像处理为二值图像后,再将其作为 image 参数使用的。 -
参数mode
参数 mode 决定了轮廓的提取方式,具体有如下 4 种:
- cv2.RETR_EXTERNAL:只检测外轮廓。
- cv2.RETR_LIST:对检测到的轮廓不建立等级关系。
- cv2.RETR_CCOMP:检索所有轮廓并将它们组织成两级层次结构。上面的一层为外边界,下面的一层为内孔的边界。如果内孔内还有一个连通物体,那么这个物体的边界仍
然位于顶层。 - cv2.RETR_TREE:建立一个等级树结构的轮廓。
下面分别对这四种情况进行简单的说明。
(1)cv2.RETR_EXTERNAL(只检测外轮廓)
例如,在图 12-2 中仅检测到两个外轮廓,轮廓的序号如图中的数字标注所示。
使用 print 语句可以查看 hierarchy 的值:
print(hierarchy) [[[ 1 -1 -1 -1] [-1 0 -1 -1]]]
其中:
- 输出值“[ 1 -1 -1 -1]”,表示的是第 0 个轮廓的层次。
- 它(即第 0 个轮廓)的后一个轮廓就是第 1 个轮廓,因此第 1 个元素的值是“1”。
- 它的前一个轮廓不存在,因此第 2 个元素的值是“-1”。
- 它不存在子轮廓,因此第 3 个元素的值是“-1”。
- 它不存在父轮廓,因此第 4 个元素的值是“-1”。
- 输出值“[-1 0 -1 -1]”,表示的是第 1 个轮廓的层次。
- 它(即第 1 个轮廓)的后一个轮廓是不存在的,因此第 1 个元素的值是“-1”。
- 它的前一个轮廓是第 0 个轮廓,因此第 2 个元素的值是“0”。
- 它不存在子轮廓,因此第 3 个元素的值是“-1”。
- 它不存在父轮廓,因此第 4 个元素的值是“-1”。
此时,轮廓之间的关系为:
(2)cv2.RETR_LIST(对检测到的轮廓不建立等级关系)
例如,在图 12-3 中检测到三个轮廓,各个轮廓的序号如图中数字的标注所示。
使用 print 语句,可以查看 hierarchy 的值:
print(hierarchy) [[[ 1 -1 -1 -1] [ 2 0 -1 -1] [-1 1 -1 -1]]]
其中:
-
输出值“[ 1 -1 -1 -1]”,表示的是第 0 个轮廓的层次。
-
它(即第 0 个轮廓)的后一个轮廓是第 1 个轮廓,因此第 1 个元素的值是“1”。
-
它的前一个轮廓不存在,因此第 2 个元素的值是“-1”。
-
它不存在子轮廓,因此第 3 个元素的值是“-1”。
-
它不存在父轮廓,因此第 4 个元素的值是“-1”。
-
输出值“[2 0 -1 -1]”,表示的是第 1 个轮廓的层次。
-
它(即第 1 个轮廓)的后一个轮廓是第 2 个轮廓,因此第 1 个元素的值是“2”。
-
它的前一个轮廓是第 0 个轮廓,因此第 2 个元素的值是“0”。
-
它不存在子轮廓,因此第 3 个元素的值是“-1”。
-
它不存在父轮廓,因此第 4 个元素的值是“-1”。
-
输出值“[-1 1 -1 -1]”,表示的是第 2 个轮廓的层次。
-
它(即第 2 个轮廓)的后一个轮廓是不存在的,因此第 1 个元素的值是“-1”。
-
它的前一个轮廓是第 1 个轮廓,因此第 2 个元素的值是“1”。
-
它不存在子轮廓,因此第 3 个元素的值是“-1”。
-
它不存在父轮廓,因此第 4 个元素的值是“-1”。
从上述分析可以看出,当参数 mode 为 cv2.RETR_LIST 时,各个轮廓之间没有建立父子关系。
此时,轮廓之间的关系为:
(3)cv2.RETR_CCOMP(建立两个等级的轮廓)
当参数 mode 为 cv2.RETR_CCOMP 时,建立两个等级的轮廓。上面的一层为外边界,下面的一层为内孔边界。
例如,在图 12-4 中检测到三个轮廓,各轮廓的序号如图中数字的标注所示。
使用 print 语句可以查看 hierarchy 的值:
print(hierarchy)
[[[ 1 -1 -1 -1][-1 0 2 -1][-1 -1 -1 1]]]
其中:
-
输出值“[ 1 -1 -1 -1]”,表示的是第 0 个轮廓的层次。
它(即第 0 个轮廓)的后一个轮廓是第 1 个轮廓,因此第 1 个元素的值是“1”。
它的前一个轮廓不存在,因此第 2 个元素的值是“-1”。
它不存在子轮廓,因此第 3 个元素的值是“-1”。
它不存在父轮廓,因此第 4 个元素的值是“-1”。 -
输出值“[-1 0 2 -1]”,表示的是第 1 个轮廓的层次。
它(即第 1 个轮廓)的后一个轮廓不存在,因此第 1 个元素的值是“-1”。
它的前一个轮廓是第 0 个轮廓,因此第 2 个元素的值是“0”。
它的第 1 个子轮廓是第 2 个轮廓,因此第 3 个元素的值是“2”。
它不存在父轮廓,因此第 4 个元素的值是“-1”。 -
值“[-1 -1 -1 1]”,表示的是第 2 个轮廓的层次。
它(即第 2 个轮廓)的后一个轮廓不存在,因此第 1 个元素的值是“-1”。
它的前一个轮廓也不存在,因此第 2 个元素的值是“-1”。
它不存在子轮廓,因此第 3 个元素的值是“-1”。
它的父轮廓是第 1 个轮廓,因此第 4 个元素的值是“1”。
此时,轮廓关系为:
(4)cv2.RETR_TREE(建立一个等级树结构的轮廓)
例如,在图 12-5 中检测到三个轮廓,各个轮廓的序号如图中的数字标注所示。
使用 print 语句可以查看 hierarchy 的值:
print(hierarchy)
[[[ 1 -1 -1 -1][-1 0 2 -1][-1 -1 -1 1]]]
其中:
-
输出值“[ 1 -1 -1 -1]”,表示的是第 0 个轮廓的层次。
它(即第 0 个轮廓)的后一个轮廓是第 1 个轮廓,因此第 1 个元素的值为“1”。
它的前一个轮廓不存在,因此第 2 个元素的值是“-1”。
它不存在子轮廓,因此第 3 个元素的值是“-1”。
它不存在父轮廓,因此第 4 个元素的值是“-1”。 -
输出值“[-1 0 2 -1]”,表示的是第 1 个轮廓的层次。
它(即第 1 个轮廓)的后一个轮廓不存在,因此第 1 个元素的值是“-1”。
它的前一个轮廓是第 0 个轮廓,因此第 2 个元素的值是“0”。
它的第 1 个子轮廓是第 2 个轮廓,因此第 3 个元素的值是“2”。
它的父轮廓不存在,因此第 4 个元素的值是“-1”。 -
输出值“[-1 -1 -1 1]”,表示的是第 2 个轮廓的层次。
它(即第 2 个轮廓)的后一个轮廓不存在,因此第 1 个元素的值是“-1”。
它的前一个轮廓是不存在的,因此第 2 个元素的值是“-1”。
它的子轮廓是不存在的,因此第 3 个元素的值是“-1”。
它的父轮廓是第 1 个轮廓,因此第 1 个元素的值是“1
此时,轮廓之间的关系为:
需要注意,本例中仅有两层轮廓,所以使用参数 cv2.RETR_CCOMP 和 cv2.RETR_TREE 得到的层次结构是一致的。当有多层轮廓时,使用参数 cv2.RETR_CCOMP 也会得到仅有两层的层次结构;而使用参数 cv2.RETR_TREE 会得到含有多个层次的结构。
6. 参数method
参数 method 决定了如何表达轮廓,可以为如下值:
- cv2.CHAIN_APPROX_NONE:存储所有的轮廓点,相邻两个点的像素位置差不超过 1,即 max(abs(x1-x2),abs(y2-y1))=1。
- cv2.CHAIN_APPROX_SIMPLE:压缩水平方向、垂直方向、对角线方向的元素,只保留该方向的终点坐标。例如,在极端的情况下,一个矩形只需要用 4 个点来保存轮廓信息。
- cv2.CHAIN_APPROX_TC89_L1:使用 teh-Chinl chain 近似算法的一种风格。
- cv2.CHAIN_APPROX_TC89_KCOS:使用 teh-Chinl chain 近似算法的一种风格。
例如,在图 12-6 中,左图是使用参数值 cv2.CHAIN_APPROX_NONE 存储的轮廓,保存了轮廓中的每一个点;右图是使用参数值 cv2.CHAIN_APPROX_SIMPLE 存储的轮廓,仅仅保存了边界上的四个点。
在使用函数 cv2.findContours()查找图像轮廓时,需要注意以下问题:
- 待处理的源图像必须是灰度二值图。因此,在通常情况下,都要预先对图像进行阈值分
割或者边缘检测处理,得到满意的二值图像后再将其作为参数使用。 - 在 OpenCV 中,都是从黑色背景中查找白色对象。因此,对象必须是白色的,背景必须
是黑色的。 - 在 OpenCV 4.x 中,函数 cv2.findContours()仅有两个返回值。
代码示例:
import cv2
o = cv2.imread('lena.png')
cv2.imshow("original",o)
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
#
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
image,contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)print("contours=\n",contours)
print("hierarchy=\n",hierarchy)
运行这段代码后会发现报错,因为我用的是opencv4.5 版本。
报错
提示这个在 OpenCV 4.x 中,函数 cv2.findContours()仅有两个返回值
新代码如下:
import cv2
o = cv2.imread('contours.bmp')gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
#
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)print("hierarchy=\n",hierarchy)
运行结果如下:
hierarchy=[[[ 1 -1 -1 -1][ 2 0 -1 -1][-1 1 -1 -1]]]
原图:
可套用前面讲解值得含义去分析一下结果,如:
输出值“[ 1 -1 -1 -1]”,表示的是第 0 个轮廓的层次。
它(即第 0 个轮廓)的后一个轮廓是第 1 个轮廓,因此第 1 个元素的值为“1”。
它的前一个轮廓不存在,因此第 2 个元素的值是“-1”。
它不存在子轮廓,因此第 3 个元素的值是“-1”。
它不存在父轮廓,因此第 4 个元素的值是“-1”。
试着去理解
[ 2 0 -1 -1]
[-1 1 -1 -1]
相关文章:

opencv基础47 查找图像轮廓cv2.findContours()详解
什么是图像轮廓? 图像轮廓是指图像中物体边缘的连续性曲线。在计算机视觉和图像处理中,轮廓通常被用于检测物体、分割图像以及提取物体特征。 图像轮廓是由一系列连续的像素点组成,这些像素点位于物体边界上。轮廓的特点是在物体和背景之间的…...

Splunk Enterprise for mac(可视化数据分析软件)详细安装教程
Splunk Enterprise for Mac是一款可视化数据分析软件,为你提供强大的搜索、 分析和可视化功能,可以帮助您获得有价值的业务情报,从你机器生成的数据。还在等什么?有需要的朋友,欢迎前来下载! 实时监测和搜…...

如何实现环卫项目运营的数字化管理,达到企业降本增效的目的?
数字环卫是指利用数字技术和数据驱动的方法来改善环卫流程和管理。数字环卫的底层逻辑在于利用技术来优化运营、提高效率并降低环卫项目管理成本。如何实现环卫工程运营数字化管理,达到降本增效的目标: 1.数据收集和分析:实施数据收集机制&a…...

React Native连接Zebra斑马打印机通过发送CPCL指令打印(Android 和 iOS通用)
自 2015 年发布以来,React Native 已成为用于构建数千个移动应用程序的流行跨平台移动开发框架之一。通常,我们有开发人员询问如何将 Link-OS SDK 与 React Native 应用程序集成,以便在 Zebra 打印机上打印标签。在本教程中,我们将…...

使用 Simulink 进行 STM32 编程
目录 介绍 所需材料 步骤 1:在MATLAB中设置STM32-MAT软件路径步骤 2:在STM32CubeMX中创建一个项目步骤 3:配置时钟和 GPIO 引脚步骤 4:项目经理并生成代码步骤 5:在 Simulink 中创建模型步骤 6:在模型中插…...
走出迷宫的最少步数and第一条出路
题面 题目描述 一个迷宫由 R 行 C 列格子组成,有的格子里有障碍物,不能走;有的格子是空地,可以走。 给定一个迷宫,求从左上角走到右下角最少需要走多少步(数据保证一定能走到)。只能在水平方向或垂直方向走,…...
MediaCodec创建对应解码器
媒体编解码API使用示例 //获取相关格式文件的内容信息,如轨道数量、获取MIME信息、视频的高度与宽度、语言格式、播放总时长等 MediaExtractor mediaExtractor new MediaExtractor(); try {mediaExtractor.setDataSource(path); // 设置数据源 } catch (IOExcept…...

使用eXosip+ffmpeg、ffplay命令行实现sip客户端
文章目录 前言一、关键实现1、主要流程2、解决端口冲突(1)、出现原因(2)、解决方法 3、解析sdp(1)、定义实体(2)、解析视频(3)、解析音频 4、命令行推拉流&am…...

dotNet 之网络TCP
**硬件支持型号 点击 查看 硬件支持 详情** DTU701 产品详情 DTU702 产品详情 DTU801 产品详情 DTU802 产品详情 DTU902 产品详情 G5501 产品详情 ARM dotnet 编程 dotNet使用TCP,可以使用Socket和TcpClient 、TcpListener类 2种,对于高级用户&…...
python基础面试题汇总(持续更新),冲击offer
目录 1.概念理解题python内置数据结构,哪些是不可变的python新式类和经典类的区别is和有什么区别Python中变量查找顺序python函数的参数是值传递还是引用传递python垃圾回收机制什么是闭包什么是装饰器,开发中用到举例如何实现只读属性Python中类方法、实…...
Java课题笔记~ AOP编程术语(掌握)
(1) 切面(Aspect) 切面泛指交叉业务逻辑。上例中的事务处理、日志处理就可以理解为切面。常用的切面是通知(Advice)。实际就是对主业务逻辑的一种增强。 (2) 连接点(Jo…...
暑假刷题第23天--8/6
3748. 递增子串 - AcWing题库 #include<iostream> #include<string> const int N200005; int a[N]; using namespace std; int main(){int t;cin>>t;for(int q1;q<t;q){int n;cin>>n;string s;cin>>s;int cnt1;a[1]1;for(int i2;i<n;i){i…...
ArcGIS API for JavaScript 4.x 教程(一) 显示一张地图
了解如何创建和显示带有基本地图图层的地图。 地图包含地理数据层。地图包含一个基本地图层,以及一个或多个数据层(可选)。可以使用地图视图显示地图的特定区域,并设置位置和缩放级别。 本教程将向您展示如何使用地形底图层创建和…...

Python-OpenCV中的图像处理
Python-OpenCV中的图像处理 颜色空间转换物体跟踪获取HSV的值几何变换图像缩放图像平移图像旋转仿射变换透视变换 图像阈值单阈值自适应阈值Otsus二值化 颜色空间转换 在 OpenCV 中有超过 150 中进行颜色空间转换的方法。但是你以后就会 发现我们经常用到的也就两种࿱…...

分清性能测试,负载测试,压力测试这三个的区别
做测试一年多来,虽然平时的工作都能很好的完成,但最近突然发现自己在关于测试的整体知识体系上面的了解很是欠缺,所以,在工作之余也做了一些测试方面的知识的补充。不足之处,还请大家多多交流,互相学习。 …...

前端架构师岗位的工作职责(合集)
前端架构师岗位的工作职责1 职责: 1.制定前端的标准和规范,并推广和应用,提高团队的开发效率; 2.前端架构的框架或核心模块的设计与实现; 3.在前端架构、设计与开发上对团队进行足够的指导; 4.在日常的系统设计与优化上与服务端团队紧密合…...

使用 Amazon ECS Anywhere 在边缘部署 Amazon IoT Greengrass
1.概述 亚马逊云科技提供了完备的IoT服务能力,涵盖设备服务、连接和控制服务以及云端分析服务,是快速构建安全可靠、可扩展的 IoT 平台的常见选择。Amazon IoT Greengrass 边缘运行时和云服务,可帮助您在设备上构建、部署和管理 IoT 应用。A…...

pytorch Stream 多流处理
CUD Stream https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#c-language-extensions 中指出在kenel的调用函数中最后一个可选参数表示该核函数处在哪个流之中。 - 参数Dg用于定义整个grid的维度和尺寸,即一个grid有多少个block。为dim3类型。…...

微信小程序选项卡切换(滑动切换,点击切换)
效果如下:可点击切换,滑动切换 代码如下 这个可以在项目用 index.wxml <view classtopTabSwiper><view classtab {{currentData 0 ? "tabBorer" : ""}} data-current "0" bindtapcheckCurrent>选项一&…...

安路FPGA的赋值报错——移位处理,加括号
authordaisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 在使用移位符号用来当作除以号使用时,发现如下问题 其中 cnt_8K 为偶数和奇数时输出的数据不一样 reg [10:0] cnt_8K; reg [10:0] ram1_addra; always(posedge clk_16M) begin if(ram_out_flag )begin if(…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...