数字图像处理【15】特征检测——SIFT特征检测

一、引入SIFT算法

上一篇文章我们重温学习了Harris角点检测算法的基本原理,但在实际生产使用Harris检测角点的时候,会发现一个问题,就是用于检测的输入图像的尺寸大小会直接影响到Harris的检测结果。这是为什么呢?主要是Harris角点检测是基于像素梯度去分析检测,输入图像的空间变小,像素间的内容被放大,进而影响到图像梯度,最终导致检测结果就会失败。

如上图所示, 原本一个角点的图像像素,对其进行局部放大后变成由多个像素组成。现在对其进行Harris角点检测,结果会变成了边缘。这就是Harris角点检测存在的一个缺陷,那如何处理呢?

由此引出当今广泛使用的特征检测算法: SIFT(Scale-Invariant Feature Transform)尺度不变特征变换。SIFT是一种广泛使用的计算机视觉算法,用于图像特征提取和描述。SIFT可以检测和描述局部特征,使其对旋转、缩放等操作具有较强的鲁棒性。该方法于1999年由加拿大教授David G.Lowe提出,2004年加以优化后并申请了专利,专利在2020年到期,现在在各大图像处理库中都可以免费使用了。

SIFT优缺点

SIFT算法不仅只有尺度不变性,当图像旋转,改变图像亮度,移动拍摄位置时,仍可得到较好的检测效果,它可以从原理上解决Harris角点检测受空间尺度影响这一缺陷。其优点总结如下:

  1. SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化保持不变性,对视角变化、仿射变换、噪声也保持一定程度的稳定性;

  2. 独特性高,易区分,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配;

  3. 多量性,即使是单个物体或者少数几个物体也可以产生大量的SIFT特征向量;

  4. 可扩展性,可以很方便的与其他形式的特征向量进行联合;

优点很多,但缺点也是很明显的:

  • 实时性不高,因为要对输入图像进行多个尺度的下采样和插值等操作;

  • 对边缘光滑的目标无法准确提取特征(比如边缘平滑的图像,检测出的特征点过少,对圆更是无能为力)

二、尺度空间和SIFT金字塔

在介绍SIFT的算法原理之前,首先我们要先搞清什么是尺度空间和SIFT金字塔。

尺度空间和图像金字塔

尺度空间是图像在不同尺度(距离)下的连续表示。其中最常见的是使用高斯核对图像进行卷积。高斯滤波可以平滑图像,从而消除图像中的细微细节。随着高斯滤波核尺度的增加,图像变得越来越平滑,直到只剩下最基本的特征。

图像金字塔是尺度空间的一种具体实现方式。它是由一系列不同分辨率的图像组成,这些图像以金字塔的形状排列如下图所示。(有点似OpenGL的mipmap图层的概念)其中根据每层构成图像方式的不同,分成各种不同的图像金字塔。

其中我转载的这篇文章 【转载】OpenCV图像金字塔,能很好的说明什么是图像金字塔,特别是最的总结:

其实图像的尺度空间可以理解为 模拟人眼远近视觉效果的一种方式。这一理论主要基于人眼在观察不同距离的物体时,对物体细节和整体轮廓的感知能力会发生变化。具体来说,图像的尺度空间是指图像经过几个不同高斯核后形成的模糊图片的集合,这些图片模拟了人眼在不同距离观察物体时的视觉效果。

  • 尺度:在图像处理中,尺度指的是图像内容的粗细程度,用于模拟观察者距离物体的远近程度。当观察者距离物体较远时,只能看到物体的大概轮廓;而当距离较近时,则能更清晰地看到物体的细节,如纹理、表面的粗糙度等。
  • 尺度空间:因此,图像的尺度空间就是一幅图像在不同尺度(即不同模糊程度)下的表示集合。这些表示通过应用不同参数的高斯核进行高斯滤波得到,从而模拟了人眼在不同距离下对物体的感知。

反正记住一点,尺度不是指图像分辨率尺寸,是模拟人眼远近观察的空间距离。或者再用一个更容易理解的举例,就是模拟人类不同的近视眼度数!

在前面我们就解析到Harris角点检测存在的问题就是:在不同的尺度空间不能使用相同的窗口检测极值点。对小的角点要用小的窗口,对大的角点只能使用大的窗口。为了解决这个问题我们需要不同的尺度空间滤波器进行操作,其中SIFT 金字塔 就是接下来要重点描述的内容。

SIFT金字塔

SIFT金字塔,即尺度不变特征变换金字塔,是SIFT算法中的一个重要组成部分。它主要用于在不同尺度空间上查找图像中的关键点(特征点),并计算出这些关键点的方向。SIFT金字塔的构建过程主要涉及高斯金字塔(Gaussian Pyramid)的构建,以及在此基础上构建的差分金字塔(Difference of Gaussian,DoG金字塔)。

SIFT金字塔的构建其实就是高斯金字塔+DoG金字塔的融合,其构建过程如下:

  1. 初始化:将原始图像作为高斯金字塔的第一组(Octave)的第一层(Interval)。
  2. 高斯滤波迭代:对第一层的图像进行高斯滤波,滤波过程中,高斯核的σ值可以取固定值,如SIFT算法中常用的σ=1.6。得到第二层图像后,将σ乘以一个比例系数k(如k=√2),得到新的σ值,用于对上一层图像进行高斯滤波,得到下一层图像。重复此过程(通常执行4~5次操作),直到生成N层图像。在同一组内,每层图像的尺寸相同,但σ值逐渐增大,图像逐渐模糊。
  3. 降采样升组:将第一组的倒数第三层图像进行降采样(通常是行列各减半)得到第二组的第一层图像。然后开始对第二组进行步骤2的高斯迭代。第二组的图像尺寸是第一组的一半。
  4. 同组进行DoG:对于高斯金字塔的每一组,将相邻两层图像进行相减操作(下一层减上一层),得到差分图像。即每组(Octave)有N层高斯图像,有N-1层DoG图像。

为了让尺度体现其连续性,在高斯金字塔简单降采样的基础上加上了不同卷积核系数的高斯滤波,将图像金字塔每层的一张图像使用不同参数做高斯模糊,使得金字塔的每层含有多张高斯模糊图像,将金字塔每层多张图像合称为一组(Octave),金字塔的每一层相当于每一组图像,每组含有多层Interval高斯图像,Interval-1的DoG高斯差分图像。我们可以通过高斯差分图像看出图像上的像素值变化情况。(如果没有变化,也就没有特征。)DoG图像可以捕捉图像的局部特征,可以用于目标检测和边缘检测等任务。

到此,我们就构建好SIFT金字塔,后续Sift特征点的提取都是在SIFT金字塔上进行的。

三、SIFT算法原理

SIFT算法的实质主要涉及四个步骤,逐一把Sift搞清楚。

  1. 尺度空间的极值(初步)检测
  2. 关键点(极值点)的精确定位
  3. 关键点(极值点)的主方向匹配
  4. 关键点的特征描述

3.1 尺度空间的极值检测

在构建 Sift的DoG金字塔 之后,就可以在不同的尺度空间和 2D 平面中搜索局部最大值了。对于图像中的一个像素点而言,它需要与自己周围的 8 邻域,以及同级的尺度空间中上下两层相邻的 2x9 个领域点相比。如果是局部最大值,它就可能是一个关键点。基本上来说关键点是图像在相应尺度空间中的最好代表。如下图所示:

3.2 关键点的精确定位

以上方法检测到的极值点是离散空间的极值点,并不是精确的极值点位置,同时DoG对边界非常敏感(因为DoG算法会产生较强的边缘响应)所以我们必须要去除因为是边界而产生的极值点,以增强匹配稳定性、提高抗噪声能力。我们可以通过拟合三维二次函数来精确确定关键点的位置和尺度,去除低对比度的关键点和边界关键点都会被去除掉,剩下的就是我们感兴趣的关键点了。

  • 关键点的精确定位

利用已知的离散空间点插值得到的连续空间点的方法叫做子像素插值/亚像素插值(Sub-pixel Interpolation)。是利用尺度空间的泰勒级数展开(对是的又是Taylor展开)来获得极值的准确位置。

其一般的数学表达公式为:

公式1

其中,https://i-blog.csdnimg.cn/blog_migrate/9357eca8547659bc88543a51608016e5.jpeg。求导并让方程等于零,得出拟合的位置点:

公式2

把它再代入回公式1中,即可得到其拟合的极值点位置的(灰度)值表达式:

公式3

看到公式可能会有点奇怪,因为三个公式是可以俄罗斯套娃式的一直迭代下去。这时候就需要一个结束迭代的条件。当拟合的公式在任一维度上的偏移量大于0.5时(即x或y偏移大于下一个离散点的一半),意味着插值中心已经偏移到它的邻近点上,所以必须改变当前关键点的展开位置。

或者能在新的位置上反复插值直到收敛,或者还可以设定一个迭代次数,在超出图像边界的范围,此时这样的点应该删除,算法作者就定义了5次的迭代次数。

另外,D(x)拟合出来的的值过小,也是容易易受噪声的干扰而变得不稳定,所以将D(x)小于某个经验值(作者论文中使用0.03)的极值点删除。

最后,拟合计算技术之后将得到特征点的精确位置(原位置加上拟合的偏移量)以及尺度(https://i-blog.csdnimg.cn/blog_migrate/130a3bcf0c62ce5e111d3c551ebe5bf4.jpeg)。

  • 去除边缘响应

DoG 算法对边界非常敏感,所以我们必须要把边界去除。前面讲Harris 算法除了可以用于角点检测之外其实还可以用于检测边界的。作者就是使用了同样的思路。作者使用 2x2 的 Hessian 矩阵计算主曲率。从 Harris 角点检测的算法中,我们知道当一个特征值远远大于另外一个特征值时检测到的是边界。

Hessian海森矩阵

还记得Harris算法最终的检测表达式吗?𝜆1和𝜆2 就是H矩阵的特征值。

其中R的取值代表不同的检测结果。 

  • 如果两个值都大,且相差不大,则“E函数水平切片椭圆”趋近于圆,区域梯度在两个垂直的方向都有较强集中度,所以是角点区域。而对于其R值,则是要大于0且绝对值较大的时候,我们判断为角点区域。
  • 如果其中一个值远大于另一个值,则,则“E函数水平切片椭圆”趋近于线,区域梯度只在一个方向上有较强集中度,所以是边缘区域。而对于其R值,则是要小于0且绝对值较大的时候,我们判断为边缘区域。
  • 如果两个值都很小,则“E函数水平切片椭圆”趋近于点,区域梯度信息在两个方向都较弱,所以是像素值平坦区域。而对于R值,则是要接近于0的小数且绝对值较小的时候,我们判断为平坦区域。

Sift算法的作者Lowe沿用Harris这部分的理论,即一个特征值远远大于另外一个特征值时检测到的是边界。Sift算法论文中建议边界阈值为 R=10。R大于此阈值就会被剔除。

并且Lowe还确认 D的主曲率和H的特征值成正比。该值在两特征值相等时达最小。

Sift算法论文中建议阈值T为1.2,即时保留关键点,反之认为角点特征对比对低,要被剔除。 

3.3 关键点的主方向匹配

说完关键点的精确定位与筛选之后,接下来就是第三步关键点的方向分配,这一步需要利用图像的局部特征为给每一个关键点分配一个基准方向,后面所有的对输入图像数据的操作,都相当于对关键点的方向、尺度和位置进行变换,使得特征的描述符具有旋转不变性。

至于如何找到关键点的方向,主要是分成如下三个小步骤:

1、确定极值点的领域范围。一般采用二维高斯模型,以关键点为中心,半径为3σ(σ是关键点的尺度)的圆形区域,其中σ乘以1.5是更常见的做法,以更好地覆盖关键点的局部结构。

2、计算该邻域内每个像素点的梯度幅值和梯度方向。梯度幅值和方向的计算公式如下,其中,L(x,y)是图像在点(x,y)处的灰度值,通过高斯核与图像卷积得到。

3、计算出梯度值和方向之后进行直方图统计。将梯度方向的范围(0°~360°)划分为多个方向区间(bin),常用的划分方式有每10°一个bin(共36个bin)或每45°一个bin(共8个bin)。但SIFT算法中常采用每10°一个bin的方式。对于邻域内的每个像素点,根据其梯度方向将其梯度幅值累加到对应的bin中。同时,为了提高稳定性,对每个像素点的梯度幅值进行高斯加权,加权系数随着像素点到关键点的距离增加而减小。

4、最后选择直方图峰值确认主方向。在构建的梯度直方图中,找到峰值对应的方向作为关键点的主方向。这个峰值代表了邻域内图像梯度的主方向,即该关键点的主方向。

辅方向检测(可选):如果梯度直方图中存在另一个峰值,其能量达到或超过主峰值的80%,则将该方向作为关键点的辅方向。这样可以增强匹配的鲁棒性。

至此,将检测出的含有位置、尺度主方向的SIFT关键点。

3.4 关键点的特征描述

上述过程,只是找到关键点并确定了主方向,但SIFT算法核心用途在于图像的匹配,我们需要对关键点进行数学层面的特征描述,也就是算法核心的最后一个步骤,构建关键点的特征描述。

1、计算特征描述的区域范围:特征描述子与特征点所在的尺度有关,因此,特征描述符的求取应在特征点对应的高斯图像上进行。将关键点附近的邻域划分为d*d(Lowe建议d=4)个子区域,区域的大小与关键点主方向分配时相同,即每个区域都有3σ(σ是关键点的尺度)个子像素,考虑到实际计算时,需要采用双线性插值,所需图像窗口边长为3σ · (d+1)。

2、将坐标系旋转到关键点主方向:考虑到旋转因素,将坐标轴旋转对齐到关键点主方向,是为了确保旋转的不变性,如下图所示。所以实际计算所需的图像区域半径为:radius = 3σ · (d+1) · √2 / 2,计算结果向上取整。

3、插值计算每个子区域的八个方向的特征描述:如下图所示,将区域划分为4x4的子区域后,对每一区域内进行 关键点的主方向匹配 一样的操作,然后进行8个bin的直方图统计,获得每个梯度方向的幅值,此时共有4x4x8=128维的描述向量。

4、描述符的标准化:为了进一步提高描述符的鲁棒性,通常会对描述符进行归一化处理。这有助于减少光照变化对描述符的影响,并使得描述符在不同的图像之间更加具有可比性。

得到的描述子向量:https://i-blog.csdnimg.cn/blog_migrate/3582cc03bfdf2882b4b965d340a66bf9.jpeg

归一化后的特征向量:https://i-blog.csdnimg.cn/blog_migrate/ca65cf72861e3ae33460bb5c7aeb9368.jpeg

则归一化后的特征描述向量为:

3.5 关键点特征的匹配

3.1~3.4 其实已经完整阐述了SIFT特征算法的原理,3.5这一步其实是SIFT的应用层面了,就是Sift特征算法如何对两幅图像做识别匹配?这里简单介绍一下其原理。

对模板图(参考图、Reference Image)和目标图(观测图, Observation Image)分别建立关键点描述子的集合。目标的识别就是通过两集合之间的关键点描述子的比对来完成。具有128维的关键点描述子的相似性度量采用的是二维的欧式距离。

模板图中关键点描述子:

实时图中关键点描述子:

任意两描述子相似性度量:

但一幅图可能有不少的关键点特征描述,可以采用穷举法来完成所有关键点的匹配,但是这样耗费的时间实在太多了,一般都采用kd树的数据结构来完成搜索。搜索的内容是以目标图像的关键点为基准,搜索与目标图像的特征点最邻近的原图像特征点和次邻近的原图像特征点。

四、OpenCV的SIFT

现在让我们来看看 OpenCV 中关于 SIFT 的函数吧。让我们从关键点检测和绘制开始吧。首先我们要创建对象。我们可以使用不同的参数,这并不是必须的,关于参数的解释可以查看文档。

int main()
{Mat src = imread("F:\\other\\learncv\\sailuo1.jpg");if (src.empty()) {std::cout << "could not load image ... " << std::endl;return -1;}cv::resize(src, src, Size(src.cols/10, src.rows/10));//imshow("Reference", src);// 初始化Sift检测器int numFeature = 200;Ptr<SIFT> detector = SIFT::create(numFeature);// 对输入图像进行Sift关键点检测std::vector<KeyPoint> keypoints;Mat kpDescriptors;detector->detect(src, keypoints, Mat());detector->compute(src, keypoints, kpDescriptors);// 检测关键点计算描述子。detector->detectAndCompute(src, Mat(), keypoints, kpDescriptors);std::cout << "keypoint Descriptors cols&rows : " << kpDescriptors.cols << kpDescriptors.rows << std::endl;// 绘制关键点Mat kpMat;drawKeypoints(src, keypoints, kpMat);imshow("Sift KeyPoint", kpMat);cv::waitKey(0);return 0;
}

函数 sift.detect() 可以在图像中找到关键点。如果你只想在图像中的一个区域搜索的话,也可以使用第三个参数创建一个掩模图像作为入参。返回的关键点是一个带有很多不同属性的特殊结构体,这些属性中包含它的坐标(x,y),有意义的邻域大小,确定其方向的角度、指定关键点强度的响应等。

 OpenCV提供了绘制关键点的函数:drawKeyPoints(),绘制效果如下:

得到关键点之后,可以再用 sift.compute() 计算描述子。也可以直接使用 sift.detectAndCompute 一次性的把检测关键点和计算描述子的工作都完成。其中我们可以看看keypoint Descriptors 的输出是一个cv::Mat的格式,也就是一个二维矩阵。其大小是关键点数量*128维,如下图所示,所以此二维矩阵就包含塞罗奥特曼的关键点描述了。

所以现在我们得到了关键点,描述符等。那么赶紧看看如何匹配不同图像中的关键点。先别急,我们将在接下来的章节中学习SIFT进阶优化的版本——SURF。

Reference:

图像特征匹配方法——SIFT算法原理及实现-CSDN博客

主页 - OpenCV Python Tutorials (opencv-python-tutorials.readthedocs.io)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/407578.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024最新50道NLP和人工智能领域面试题+答案(中文+英文双版本)

编者按&#xff1a;分享一个很硬核的免费人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 可以当故事来看&#xff0c;轻松学习。 中文版本 自然语言处理 (NLP)已成为语言学、人工智能和计算机科学交叉领域的变革性领域。随着文本数据量的不断增加&…

内网横向移动常用方法

横向移动 #横向移动含义 横向移动是以已经被攻陷的系统为跳板&#xff0c;通过收集跳板机的信息&#xff08;文档&#xff0c;存储的凭证&#xff0c;ipc连接记录等等信息&#xff09;来访问其他域内主机。#常见横向手段 1&#xff0c;通过相同的用户名密码批量ipc连接其他域内…

【学习笔记】Day 22

一、进度概述 1、机器学习常识23-24&#xff0c;以及相关代码复现 2、python 补完计划&#xff08;详见 python 专题&#xff09; 二、详情 23、U-Net 从宏观结构上来讲&#xff08;以下摘自常识23&#xff09;&#xff1a; U-Net 就是 U 形状的网络, 前半部分 (左边…

三星计划今年HBM4设计,2025年初开始样品测试

三星计划今年晚些时候完成首款HBM4内存设备的设计定稿&#xff0c;2025年初开始样品测试 根据nN Elec援引行业消息人士的报道&#xff0c;三星计划在今年晚些时候完成首款HBM4内存设备的设计定稿&#xff0c;并预计将于2025年初开始样品测试。该公司预计将采用其最新一代10纳米…

详细分析 el-progress的基本知识以及用法(附Demo)

目录 前言1. 基本知识2. Demo3. 实战 前言 由于实战项目中有所引用&#xff0c;对此记录基本的知识点&#xff0c;并且以Demo的形式呈现 1. 基本知识 el-progress 是 Element Plus UI 库中的一个进度条组件&#xff0c;用于显示任务的完成情况 可以帮助用户了解某个操作或任…

[数据集][目标检测]工程机械车辆检测数据集VOC+YOLO格式3189张10类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;3189 标注数量(xml文件个数)&#xff1a;3189 标注数量(txt文件个数)&#xff1a;3189 标注…

密码生成器(HTML+CSS+JavaScript)

&#x1f30f;个人博客主页&#xff1a;心.c ​ 前言&#xff1a;前两天写了密码生成器&#xff0c;现在跟大家分享一下&#xff0c;大家如果想使用随便拿&#xff0c;如果哪里有问题还请大佬们给我指出&#xff0c;感谢支持 &#x1f525;&#x1f525;&#x1f525;专题文章&…

Vue3集成高德离线地图实践

1. 离线地图效果预览 2. 地图下载器下载离线地图 根据需要选择地图&#xff0c;我这边选择高德地图&#xff0c;层级选择0-15级别即可&#xff0c;进行下载 3. 放到nginx内网服务器 注意配置允许跨域 4. Vue3核心代码 // main.js // 初始化vue-amap initAMapApiLoader({o…

Android自定义简单TextView

自定义属性 <declare-styleable name"TextView"><!--name 属性名称format 格式&#xff1a;string 文字 color颜色dimension 宽高 字体大小 integer数字reference 资源引用(drawable)--><attr name"YiRanText" format"string"/&…

torchvision中的数据集使用

1.数据集&#xff1a; 自定义数据集transforms中的类 如何将数据集和transforms结合在一起&#xff1f; 以CIFAR10为列 2.CIFAR10数据集的下载与导入 import torchvisiontrain_settorchvision.datasets.CIFAR10(root"./dataset",trainTrue,downloadTrue) test_set…

判别分析2|Bayes判别分析|Fisher判别分析|软件求解

Bayes判别分析 引入先验信息 距离判别只要求知道总体的数字特征&#xff0c;不涉及总体的分布函数 当均值和协方差未知时&#xff0c;就用样本的均值和协方差矩阵做估计值。距离判别方法简单实用&#xff0c;但没有考虑到每个总体出现的机会大小&#xff0c;即先验概率&#…

Git的使用教程及常用语法03

七.如何从版本库中删除文件 第一种方式&#xff1a;直接在工作区删除文件&#xff0c;然后提交 rm ffile1.txt (注意&#xff1a;这个不是git命令&#xff0c;而是linux命令) 看到状态发现&#xff0c;文件file1.txt已经被删除&#xff0c;提示需要提交到暂存区。 因为我们只…

从开发到集成:视频美颜SDK与直播美颜API详解

在本文中&#xff0c;我们将详细探讨视频美颜SDK的开发过程及其与直播美颜API的集成方案&#xff0c;帮助开发者更好地理解和应用这些技术。 一、视频美颜SDK的开发概述 视频美颜SDK是一个用于实时视频处理的开发工具包&#xff0c;提供了包括磨皮、美白、瘦脸、眼睛放大等多…

盘古信息IMS MCM制造协同管理系统:为中小企业数字化转型量身打造的数字化方案

近年来&#xff0c;全球经济的不稳定性&#xff0c;给中小企业的经营和发展带来了巨大的挑战。为提升企业竞争力&#xff0c;中小企业纷纷谋求数字化转型路径&#xff0c;优化生产流程、提高运营效率、降低生产成本&#xff0c;以应对变幻莫测的市场环境。IMS MCM是盘古信息为广…

python爬虫521

爬虫521 记录 记录 最近想学爬虫&#xff0c;尝试爬取自己账号下的文章标题做个词云 csdn有反爬机制 原理我就不说啦 大家都写了 看到大家结果是加cookie 但是我加了还是521报错 尝试再加了referer 就成功了(╹▽╹) import matplotlib import requests from wordcloud impor…

TinaSDKV2.0 自定义系统开发

TinaSDKV2.0 自定义系统开发 什么是自定义系统&#xff1f; TinaSDK Kconfig界面配置 Tina Linux采用 Kconfig 机制对 SDK 和内核进行配置。 Kconfig 是一种固定格式的配置文件。Linux 编译环境中的 menuconfig 程序可以识别这种格式的配置文件&#xff0c;并提取出有效信息…

使用redis模拟cookie-session,例子:实现验证码功能

在前后端分离架构中不建议使用cookie-session机制实现端状态识别 原因&#xff1a; 1.前后端分离存在跨域问题&#xff0c;cookie无法共享 2.后台服务器一旦建立集群&#xff0c;可能导致session数据丢失&#xff0c;即后台有多台服务器&#xff0c;每个服务器存的session不一…

Flutter ListView控件

ListView是flutter中线性排列的可滚动的列表部件。ListView 是最常用的滚动小部件。它在滚动方向上一个接一个地显示其子项。在交叉轴上&#xff0c;子项需要填满 ListView。 如果非空&#xff0c;则 itemExtent 会强制子项在滚动方向上具有给定的范围。 如果非空&#xff0c;…

kafka的一个有趣问题(BUG)

这是我的第104篇原创文章 问题由来 在使用kafka时&#xff0c;创建topic&#xff0c;对某个topic进行扩分区的操作&#xff0c;想必大家肯定都使用过。尤其是集群进行扩容时&#xff0c;对流量较大的topic进行扩分区操作。一般而言&#xff0c;期望的效果是&#xff1a;新扩的分…

【Qt】常用控件QPushButton

常用控件QPushButton QWidget中涉及的各种属性/函数/使用方法&#xff0c;对Qt中的各种控件都是有效的。 QPushButton继承自QAbstractButton。这个类是抽象类&#xff0c;是其他按钮的父类。 QAbstractButton中和QPushButton相关性比较大的属性。 属性说明 text 按钮中的⽂本…