【立体视觉(五)】之立体匹配与SGM算法
【立体视觉(五)】之立体匹配与SGM算法
- 一、立体匹配
- 一)基本步骤
- 二)局部立体匹配
- 三)全局立体匹配
- 四)评价标准
- 1. 均方误差(RMS)
- 2. 错误匹配率百分比(PBM)
- 二、半全局(SGM)立体匹配
- 一)代价计算
- 二)代价聚合
- 三)视差计算
- 四)视差优化
- 三、深度图或三维点云计算
- 一)通过视差计算深度
- 二)通过深度计算点云
立体视觉是指利用物体或场景的平面信息得到三维信息,即实现“立体”的结果。维度信息的变换决定了其复杂性。因此,得到精确的结果需要经过一系列严格的步骤。在进行立体匹配之前,需要熟悉相机成像模型,进行相机标定和图像校正。为了简化问题,这里以依然最简单的双目立体视觉进行学习。
主要参考两本硕士学位论文进行学习,建议看原文,文献在文末。
一、立体匹配
立体匹配是立体视觉的中间关节,也是核心环节。采集的图像在经过摄像机标定,图像校正等预处理步骤后,立体匹配直接对预处理结果进行处理。
根据立体匹配基础理论可知,立体匹配就是寻找同一点在不同投影面的投影点,根据极线形成的约束可知,某一投影点对应的匹配点必定位于该点对应的极线上。
在同一场景中,左摄像机拍摄得到的视图整体偏右,右摄像机拍摄得到的视图整体偏左,因此根据左视图寻找右视图对应的匹配点的寻找方向应偏左。通常设定视差搜索范围 d m a x d_{max} dmax,搜索过程在 [ 0 , d m a x ] [0,d_{max}] [0,dmax] 范围内进行。
在立体匹配之前,需要满足两个基本条件。
(1)唯一性。一个视图的每个点在另一个视图中最多只有一个点与之对应,也就是视差值唯一。
(2)连续性。图像中大部分点的视差平滑,表现在视差就是连续的。
一)基本步骤
由于实际场景的复杂性,在立体匹配过程中,会受到遮挡、光线、噪声、弱纹理等诸多因素的影响,这给相关研究带来了诸多不便。学者们经过潜心研究,将立体匹配算法进行系统总结,并分为四个基本步骤来研究。
(1)代价计算:根据图像属性特征,如像素值,色彩等信息,计算出点和点之间的相似度。两个点越相似,说明是匹配点的可能性越大。
(2)代价聚合:代价聚合是立体匹配中十分重要的一个步骤。在初步的代价计算后,得到的结果不够准确,因此需要考虑邻近像素间的关系,涉及的范围不同,累加的方式不同,立体匹配的效率及效果都会不同。
(3)视差计算:对于选定的视差范围,会对应着不同的匹配代价值,从中选取最小的值作为最优解,这就是对应的匹配点。
(4)视差优化:确定视差后,可以根据邻近视差值通过曲线拟合方式细化视差,剔除匹配错误点,然后根据相邻像素灰度值相似原理进行填充,让视差图更加平滑。
根据匹配像素的考虑范围可以将匹配方法大致分为局部(Local Matching)、全局(Global Matching)和半全局(Semi-Global Matching)立体匹配。
- 代价计算
计算匹配代价阶段,是沿着极线,在参考图像上搜索该极线上的像素点,并计算其不同的视差值与待匹配像素点之间的匹配代价值,直到视差值搜索范围达到最大视差值,并将得到的匹配代价值存储到一个三维的匹配代价矩阵中,这个矩阵也称为视差空间图,图中每个三维坐标点代表着各个匹配代价 C ( x , y , d ) C(x, y, d) C(x,y,d)。
-
代价聚合
全局立体匹配由于在匹配代价阶段以及后续的视差计算阶段做了较为复杂的处理,加上视差计算是通过最优化理论以选择最优视差值,所以不需要进行代价聚合这一步。代价聚合是局部立体匹配算法关键步骤,特别是基于区域的匹配算法。
通常是将待匹配像素点作为中心像素,将其邻域像素点的匹配代价作为一定的约束条件,或者累加后取均值赋值与该像素点,作为该像素点的匹配代价,这便是代价聚合过程,其实是增加了邻域像素点的约束,相比于单个像素点信息,增加了图像的信息,便相当于增加了匹配代价的鲁棒性。
-
视差计算
视差计算阶段,全局匹配算法和局部匹配算法是不同的。
全局匹配算法:由于前期的匹配代价阶段,是采用的计算较复杂、可靠性较高的相似性测度函数,就单个像素点的匹配代价来说,相比局部匹配算法,匹配代价鲁棒性更强,所以在视差计算阶段,是直接利用最优化理论知识,对匹配代价函数取最小值,以求得视差值。
局部匹配算法:代价聚合阶段之后,采用赢家通吃(WTA,Winner takes all) 的思想:在匹配代价空间中,选择累加代价的最小值对应的点作为为同名匹配点,而该匹配点对应的视差值即为该像素点的最终视差。
-
视差优化
因为过程中受到的噪声干扰等因素影响,导致得到的视差图质量不高,或者因为匹配算法的限制产生许多误匹配点等。视差优化可以通过左右一致性检测、小连通区域检测、视差填充、中值滤波等方式,对视差图做进一步优化平滑处理,从而提高匹配精度。
二)局部立体匹配
在计算某一像素的匹配代价时,以该像素为中心选择一个局部范围,考虑局部范围内所有像素,采用某一规则计算该像素对应的匹配代价,在有效视差范围内,对于不同视差,对应着不同的匹配代价,最小的匹配代价对应的视差即为中心像素的视差。
d ( x 0 , y 0 ) d( x_0 , y_0) d(x0,y0) 为坐标 ( x 0 , y 0 ) (x0 , y0 ) (x0,y0) 的像素对应的视差, d m a x d_{max} dmax 为视差搜索范围的上限, W W W 为选择的局部范围, c o s t cost cost 为代价函数,对于不同的计算规则,代价函数形式不同。
该类型算法的匹配流程:
局部匹配在进行代价计算时,假设整张图片颜色相似,完全忽略了光线的影响,而当光线变化大时,得到的整张图亮度有很明显的差异,从而对颜色有较大的影响。在进行代价聚合时,假设邻近区域视差相近或相同,这对前后背景相差太大或明显出现断层的区域不成立。
匹配代价的大小可以采用数学方法(主要是函数)进行衡量。采取的方法不同,得到的精度及结果都会不同,因此有必要根据图像属性选择合适的度量方法。
设 W W W 为待匹配窗口, d d d 代表视差, I L I_L IL和 I R I_R IR表示某点在相应图中对应的灰度值, C ( x , y , d ) C(x, y, d) C(x,y,d)代表在位置 ( x , y ) (x, y) (x,y)视差为 d d d 时候的匹配值。
- 代价计算最简单的方式就是像素绝对差(Absolute Difference, AD)算法
常用的其它数学度量方法还有:
- 绝对差和(Sum of Absolute Difference, SAD)
- 差平方和(Sum of Squared difference, SSD)
- 归一化互相关(NCC)
绝对差和与差平方和都是通过像素的灰度信息计算代价,计算简便,实现简单,但是光线条件会极大地影响匹配结果。归一化互相关属于归一化度量法,在灰度基础上增加了归一化的约束,这可以有效地降低噪声的影响,但是相应地,平方和开方增加了大量的运算,而且四舍五入会影响结果的精度。效果较好的局部匹配算法有自适应归一化互相关算法,大范围立体匹配,引导图像滤波等。
三)全局立体匹配
局部匹配算法侧重于计算局部范围内像素相关性,选取最小视差作为最终视差,与其不同的是,全局匹配算法不进行代价聚合,它是在匹配代价的基础上,加入平滑约束条件,通过全局能量函数的形式将二者结合,然后对该函数求最优解来获取视差。 能量函数的通用表达式如:
D D D 为视差函数, E E E 为最终结果值, E d a t a ( D ) E_{data}(D) Edata(D) 为数据项, E s m o o t h ( D ) E_{smooth}(D) Esmooth(D)为平滑项,𝜆为可变参数,用来调整平滑项占的比例大小。显然,数据项代表匹配程度,平滑项则是附加约束,与可变参数进行配合,用来使能量函数最小化。
𝑑𝑝代表像素 p p p 的视差, C ( p , d p ) C(p , d_p) C(p,dp) 为像素 p p p 在视差为𝑑𝑝时的匹配值,Ω L _L L代表左图全部像素。
N 为附近像素集合。 s ( d p , d q ) s(d_p ,d_q) s(dp,dq) 表示为了进行平滑处理,对周围像素的惩罚函数,如果视差相差小,那么相应的惩罚也很小,如果较大,那么惩罚也大。
如果像素 q q q 和像素 p p p 视差相等,那么不进行惩罚,如果不相等,那么进行惩罚。
全局匹配算法根据研究方法可以大致分为三种:
(1)图割(Graph Cut)
图割是典型的全局立体匹配方法。首先建立网格图,然后进行分割求解,最后生成视差图。其中,网格图的建立至关重要,直接影响到后续的图割。图割法得到的结果虽然有较高的精确度,但是计算量很大,因此效率不高。
(2)置信传播(Belief Propagation)
将立体匹配问题转换为马尔科夫随机场问题,用概率的方式进行求解,这就是置信传播方法。能量函数的计算方法如式:
D 表示像素p 代价,W 表示别的像素与p 之间的相关性。
(3)动态规划(Dynamic Programming)
动态规划常用于在二维平面求解最优解。动态规划算法在对单路径的扫描线求取能量函数最小值时,可以达到多项式时间复杂度。立体匹配正是利用这一点寻找视差搜索的最优路径,对应的能量函数的计算方法如式:
𝐸(𝜃)为𝜃范围内的视差值,𝐸(𝜃1, 𝜃2, 𝜃3, ⋯ , 𝜃𝑛 )为𝜃1, 𝜃2, 𝜃3, ⋯ , 𝜃𝑛对应视差。
可以看出,对于全局匹配算法而言,全局能量函数十分重要,由于考虑到了全局信息,得到的结果相对局部算法而言更精确,但是更加耗时,效率不高。
半全局立体匹配(在下面展开)
局部匹配算法匹配速度快,但是精度低,与之相反的是,全局匹配算法精度高,但是效率低。学者Hirschmuller在经过认真研究后,结合二者优势,创造性地提出了半全局立体匹配算法。该算法力求在提高精度的同时兼顾效率。实质上该算法是动态规划思想的应用,只是在具体实现上与一般的动态规划思路不同。在进行代价聚合时,其先得到直线路径代价计算的结果,然后对各个路径的结果进行合并,近似代替二维。该算法整体上仍然采用全局算法框架,构建能量函数,实现全局最优。
四)评价标准
立体匹配算法的优劣主要是时间及精确度这两个指标。其中,时间严格来说是从摄像机采集图像到输出最终视差图这段时间,但是考虑到不同设备差异带来的时间差,通常假设图像已经采集,因此时间是从左右视图到经过一系列计算获得视差图这段时间,较好量化。然而,对于匹配效果,每个人得到的直观感觉不同,因此有必要通过特定的数据平台去衡量匹配结果。
Middlebury Stereo Evaluation 是由知名学者Scharstein、Szeliski 和Hirschmuller 等共同创建的测试网站,供立体匹配相关研究人员用来评估匹配效果。将改进算法得到的视差图提交到该网站,对照标准视差图评估自身算法,就可以得到算法的错误匹配率,并且可以与其它算法进行比较。其中,衡量结果主要用到均方误差(Root MeanSquare, RMS)和错误匹配率百分比(Percentage of Bad Matching, PBM)方法。
1. 均方误差(RMS)
2. 错误匹配率百分比(PBM)
计算得到的像素点在(𝑥, 𝑦)的的视差是𝑑 c _c c (𝑥, 𝑦),该位置对应的标准视差值为𝑑 T _T T (𝑥, 𝑦),N 为图像像素总个数,𝛿 d _d d为不匹配的阈值。
RMS 是将研究算法的结果生成的视差对比标准视差图的视差,然后做差,如果超出阈值就是错误匹配,PBM 则是统计匹配错误的像素占全部像素的比率。
二、半全局(SGM)立体匹配
SGM 算法结合了局部和全局算法的优势,兼顾精度及效率。SGM 算法严格遵循立体匹配步骤,其中代价计算所使用的互信息及代价聚合采用的一维路径聚合近似代替二维最优是其特色。
该算法的匹配过程:基于互信息的代价计算、多路代价聚合及视差计算及视差优化。
一)代价计算
在提出SGM 算法时,考虑到用互信息的很大原因在于互信息对光照变化不敏感,采用这一方法,在后续结果中,可以较少地考虑光线因素,这无疑降低了研究难度。
在讨论图像匹配性时,首先应探究像素之间匹配强度,将像素点视为随机量,这样问题转化为随即量之间匹配强度,在信息论中,这可以用互信息的概念来表达。假设存在随机变量A 和B,互信息是用来反映A 和B 之间的相关性。在图像处理中也会经常用它来表示图像之间的相关性。A 和B 之间的互信息用数学符号表示如式所示。
互信息可以用熵的形式来表示
H 表示熵,一个变量表示该变量对应的熵,两个变量表示二者的联合熵。作为一个抽象概念,其可以简单理解为不确定性的概率表达形式,因为一个随机变量的熵越大,不确定性也越大。
两张图各自的熵及联合熵可以用来表示互信息。熵为一张图包含的信息,联合熵为两张图的全部信息。当两张图包含的公共信息越多,那么联合熵就越小,互信息就越大,两张图片关联性就越大。
用𝐼𝐿和𝐼𝑅分别来表示左右两张图的灰度值。 H I L H_{I_L} HIL和 H I R H_{I_R} HIR表示两张图的熵, H I L , I R H_{I_L,I_R} HIL,IR 表示联合熵,则互信息表示为
熵用灰度分布概率P 表达
在使用互信息进行代价计算时,首先需要用其中一张图以视差图为基准进行修正,使得两幅图像的同名点在同一位置。
二)代价聚合
SGM 算法思想上与全局匹配算法一致,都是通过建立能量函数,使结果最优,从而在前一步骤的基础上达到聚合的目的。该算法具体的能量函数如式(3-13)所示。
等号右边首先是数据部分,对视差图D 中全部像素的匹配代价值求和即为该项;紧接着是平滑部分,q 为像素p 的邻域𝑁𝑝内的像素,当像素p 与q 相差不大时,对该像素进行力度为P1 的惩罚;第三项也为平滑项,表示像素p 与q 相差较大时进行力度为P2 的惩罚。第三项的惩罚力度P2 要大于第二项惩罚力度P1,P1 适用于与周围像素点视差相比,视差变化较小的情况,即连续的平面,第三项适用于视差变化大的地方,特别是边缘处,因此也被称为边缘约束惩罚因子。在半全局立体匹配算法中,通常将P1 设置为常量,而P2 根据灰度值的变化进行计算,方法如式
P 2 ′ P_2^′ P2′ 是固定值,𝐼𝑝、𝐼𝑞表示当前像素点的灰度值和与该像素点同一路径的周围像素点的灰度值。对于P1 或者 P 2 ′ P_2^′ P2′ 的取值具有很大的不确定性,通常是根据经验或者重复实验选取合适的数值,而由于处理图像信息不同,对于不同图像,选取的值也不同。这对用同样的方法处理不同数据集,分析实验结果的客观性时有一定影响。一般而言,对于实际场景或物体,视差值变化较大的区域通常是物体的边缘,但是由于光照、噪声等的影响会出现错误匹配,因此,对于惩罚参数通过经验或实验设置都是不合理的。
对式(3-13)进行最优求解是一个非确定性问题。SGM 巧妙地应用一维聚合来实现二维聚合。首先选定某一路径,计算该路径在有效视差范围内的匹配代价,这就是所谓“一维聚合”,然后对所有路径进行类似计算,得到某像素所有路径的匹配代价,将这些匹配代价求和,选取有效视差范围内的最小值,这就是该像素聚合后的匹配代价值。任一像素p 在某条路径r 上的具体计算方法如下所示。
第一项为数据项,C 为匹配代价;第二项为平滑项,将路径代价值与P1 惩罚代价值、P2 惩罚代价值进行比较后,取最小值作为平滑项,第三项是为了防止代价值超过上限而做的调整,每一路径代价上限L:
路径代价总和S :
路径聚合如图
可以看到,有3 种路径聚合方式,分别为4 路径聚合(黑色箭头)、8 路径聚合(黑色+蓝色箭头)、16 路径聚合(金色箭头),路径数越多,效果越好,但是耗时也越长。通常,为了获得高质量视差图,对8 个方向进行路径聚合就足够了
SGM 匹配算法的代价聚合过程是这个算法最独特的一点,将对像素点的二维求解最优解问题巧妙地转换为一维方向上求解最小匹配代价的问题,将多个路径的匹配代价进行求和,是为了提高邻域像素点对像素点的影响,从而对弱纹理和重复纹理区域等匹配难点情况的匹配精度有一定的提高,且多路径聚合的方式,还可以消除传统动态规划聚合方法所产生的图像上条纹噪声,既能达到全局匹配的匹配精度,又能通过这种巧妙的聚合方式,降低算法的复杂度,提高匹配效率。
三)视差计算
SGM 算法作为半全局匹配算法,在视差计算,选择和局部匹配算法一样的赢家通吃(WTA) 算法:当某像素点的所有视差值的匹配代价聚合之后,选择累加代价的最小值对应的点作为为同名匹配点,而该匹配点对应的视差值即为该像素点的最终视差,从而进行相应位置上的存储,这样,视差图便是一个大小与左图像一样的矩阵,每个像素点对应的位置为该像素点的视差值,这便是算法得到的初始视差图。
四)视差优化
得到了初始视差图后,视差优化将进行进一步的处理。因为初始视差图会因为受到噪声影响,出现许多错误视差点,还因为遮挡或者深度不连续性导致的明显的离群点,或者重复纹理区域,出现明显的误匹配点或者视差空洞等情况。
视差优化通常会采用左右一致性法对错误匹配点进行检测。这需要利用了立体匹配中的唯一性约束,即其中一幅图像上的各个像素点只能与另一幅图像上的唯一一个像素点匹配,这样,每一对同名点之间都是一一对应的关系。 将左右图像顺序交换,也同样步骤的计算匹配代价和代价聚合,从而得到右图像对应的视差图,之后再将其与左图对应的初始视差图做阈值比较,找到每个像素点对应的初始视差图上的视差值与右图视差图上的视差值,如果两者之间的差值大于一个像素点的阈值,则该点判为误匹配点,剔除掉即可。
对于小区域内明显的小块误匹配区域或者离群点,视差优化采用剔除小连通区域法,将明显误匹配连通区域内的视差值或离群点视差值,与邻域内的像素点的视差值做比较,并设置阈值,以判断该小块连通区域是否为误匹配,如差值大于阈值则将其剔除。剔除小连通区域法操作较简单,但是将大大地提高视差图的质量,从而提高匹配精度。
SGM 算法在视差优化阶段,对无效视差的填充,分为两种情况进行填充。
- 误匹配产生的无效视差,与其邻域像素点的视差值作比较,将邻域像素的中值作为该无效视差点的视差值,即通过中值滤波完成视差填充。
- 由于遮挡产生的无效视差,遮挡区域通常也是视差不连续区域,也就是说,会存在前后景的区别,前景离相机近,即深度较小,视差值较大,相反,后景则视差值较小,所以,可以通过在左右一致性法检测像素点时,加入视差值判断,若在左视差图上出现了多个匹配点的视差大于右视差图上相应像素点的视差值时,则说明这几个匹配点更接近后景,所以可以将它们判断为遮挡区内。对其邻域的像素点视差值作比较,选择次小值,作为这些遮挡区内的无效视差点的视差值。这一步,可以有效地优化视差图,特别对遮挡区的匹配精度,可以明显提高。
三、深度图或三维点云计算
在前文有提到,极线校正就是经过一系列变换把双目立体视觉几何结构校正为平视双目标准几何结构,即左右相机的成像平面在同一个平面上且是垂直对齐的,如下图所示。
一)通过视差计算深度
获得视差图后,可以根据视差与深度的转换关系计算出深度图以及三维点云。
视差与深度之间,存在转换关系:
D = B f d + ( x 0 r − x 0 l ) D=\frac{Bf}{d+(x_{0r}-x_{0l})} D=d+(x0r−x0l)Bf
D为深度,d为视差,B为基线长度, x 0 r x_{0r} x0r和 x 0 l x_{0l} x0l分别为左右视图主点的列坐标,大多情况下,主点列坐标相同,所以有
D = B f d D=\frac{Bf}{d} D=dBf
二)通过深度计算点云
{ Z = D X = D ( x − x 0 l ) f Y = D ( y − y 0 l ) f \begin{cases} Z=D\\ X=\frac{D(x-x_{0l})}{f}\\ Y=\frac{D(y-y_{0l})}{f}\\ \end{cases} ⎩ ⎨ ⎧Z=DX=fD(x−x0l)Y=fD(y−y0l)
这几个关系都可以根据上面的图,由相似三角形关系推导出来。
参考
[1] 高聪聪. 基于SGM的立体匹配算法研究[D].西安电子科技大学,2022
[2] 吴玉晗. 基于双目立体视觉的立体匹配算法研究[D].电子科技大学,2022
[3] 立体匹配入门指南(8):视差图、深度图、点云
[4] 【立体视觉(一)】之成像原理与相机畸变
[5] 【立体视觉(二)】之对极几何与关键矩阵
[6] 【立体视觉(三)】之张正友标定法原理篇
[7] 【立体视觉(四)】之极线校正与双目视觉
相关文章:
【立体视觉(五)】之立体匹配与SGM算法
【立体视觉(五)】之立体匹配与SGM算法 一、立体匹配一)基本步骤二)局部立体匹配三)全局立体匹配四)评价标准1. 均方误差(RMS)2. 错误匹配率百分比(PBM) 二、半全局(SGM)立体匹配一)代价计算二&a…...
苹果系统_安装matplotlib__pygame,以pycharm导入模块
为了更便捷、连贯的进行python编程学习,尽量在开始安装python软件时,将编辑器、模块一并安装好,这样能避免以后版本冲突的问题。小白在开始安装pycharm、pip、matplotlib往往会遇到一些问题,文中列示其中部分bug,供大家…...
常用颜色的英文和十六进制
以下颜色都是按照下面格式所写 # size:文字大小(1~7);color:文字颜色 <font size5 colorred>红 red #ff0000</font>红 red #ff0000 橙 orange #ffa500 黄 yellow #ffff00 草绿 springgreen #00FF7F 绿…...
计算机网络第二章思考题
1. 调制与编码分别有何作用? 调制(Modulation)和编码(Coding)是通信系统中的两个关键概念,它们分别具有不同的作用和功能: 调制(Modulation): 作用ÿ…...
Xcode、终端、Mason、nvim.debug环境路径
Xcode: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include 终端: /Library/Developer/CommandLineTools/usr/include Mason: /Users/donny/.local/share/nvim/mason/packages/clangd/…...
2023华为OD机试真题-2023(A+B卷)【Java、C++、Go、Python】
【华为OD机试真题-2023(A+B卷)【Java、C++、Go、Python】 该专栏博客已帮助千余名同学通过OD机考 2023年5月,华为OD机考更新为OD统一考试(B卷)。B卷的题目包括两部分: 1.2022年老题库 2.2023新增题目 OD统一考试B卷的题目博主也会及时搜集更新! 以下为OD统一考试(B卷…...
[NISACTF 2022]join-us - 报错注入无列名注入
点击登录,找到注入点 这种框,可以直接爆破关键字,看是否拦截,也可以手动尝试,发现、union、and、or、substr、database等关键字都拦截了 1、学到了:可以用数据库中不存在的表名或者不存在的自定义函数名爆…...
Raid10--Raid01介绍
RAID10 先对磁盘做mirror,然后对整个mirror组做条带化; 比如8块盘 需要分成4个基组,每个基组2块盘; 每个基组先做raid1,再做raid0,4条条带化; 所以: …...
集群服务器
文章目录 项目名:实现集群服务器技术栈通过这项目你学到(或者复习到)实现功能编码环境json环境muduo库boost库MySql数据库登录mysql:查看mysql服务开启了没有?mysql的服务器及开发包库chat,表 allgroup friend groupuser offlinemessage user…...
大数据Doris(五):开始编译 Doris
文章目录 开始编译 Doris 一、下载Doris的安装包 二、解压缩 三、上传配置文件...
Linux软硬链接和动静态库
本文已收录至《Linux知识与编程》专栏! 作者:ARMCSKGT 演示环境:CentOS 7 软硬链接和动静态库 前言正文软硬链接原理使用 文件时间动静态库库介绍静态库静态库制作静态库的使用关于静态链接 动态库动态库制作动态库的使用关于动态链接 补充 最…...
Linux shell编程学习笔记6:查看和设置变量的常用命令
上节我们介绍了变量的变量命名规则、变量类型、使用变量时要注意的事项,今天我们学习一下查看和设置变量的一些常用命令,包括变量的提升,有些命令在之前的实例中已经使用过了。 一、 echo :查看变量的值 语法格式:ech…...
leetcode 416.分割等和子集
416. 分割等和子集 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和…...
Java基于SSM+Vue的平时成绩管理系统
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用Vue技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...
flutter开发实战-webview插件flutter_inappwebview使用
flutter开发实战-webview插件flutter_inappwebview使用 在开发过程中,经常遇到需要使用WebView,Webview需要调用原生的插件来实现。常见的flutter的webview插件是webview_flutter,flutter_inappwebview。之前整理了一下webview_flutter&…...
Selenium 浏览器坐标转桌面坐标
背景: 做图表自动化项目需要做拖拽操作,但是selenium提供的拖拽API无效,因此借用pyautogui实现拖拽,但是pyautogui的拖拽是基于Windows桌面坐标实现的,另外浏览器中的坐标与windows桌面坐标并不是一比一对应的关系&am…...
1.6.C++项目:仿muduo库实现并发服务器之channel模块的设计
项目完整版在: 文章目录 一、channel模块:事件管理Channel类实现二、提供的功能三、实现思想(一)功能(二)意义(三)功能设计 四、代码(一)框架(二…...
Redis代替session 实现登录流程
Redis代替session 实现登录流程 如果使用String,他的value,用多占用一点空间,如果使用哈希,则他的value中只会存储他数据本身,如果不是特别在意内存,其实使用String就可以 设计key的具体细节 在设计这个k…...
理解C++强制类型转换
理解C强制类型转换 文章目录 理解C强制类型转换理解C强制转换运算符1 static_cast1.1. static_cast用于内置数据类型之间的转换1.2 用于指针之间的转换 1.3 用于基类与派生类之间的转换2. const_cast2.1示例12.2 示例2——this指针 3.reinterpret_cast4.dynamic_cast C认为C风格…...
《TCP/IP网络编程》代码实现
文章目录 1. 项目说明1.1 项目特点2. 文件说明2.1 脚本文件2.1.1 `TCP_IP.sln`2.1.2 `xmake.lua`2.1.2.1 编译说明2.1.2.2 运行说明2.1.3 章节说明项目代码已经开源在github上! 微信公众号文章同步发表! 1. 项目说明 根据《TCP/IP网络编程》书籍学习,对其中的代码进行整理,…...
【Python】如何使用PyInstaller打包自己写好的代码
使用PyInstaller打包自己写好的代码 零、需求 最近接到一个小单,需要批量修改文档内容,用Python做好后要打包成exe程序给客户的Win7电脑使用,此时需要用到PyInstaller打包自己的代码,想到还要有给用户试用的需求,所以…...
Java 线程的调度与时间片
🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开兴好久好久😎 📚系列专栏:Java全栈,…...
Java项目-文件搜索工具
目录 项目背景 项目效果 SQLite的下载安装 使用JDBC操作SQLite 第三方库pinyin4j pinyin4j的具体使用 封装pinyin4j 数据库的设计 创建实体类 实现DBUtil 封装FileDao 设计scan方法 多线程扫描 周期性扫描 控制台版本的客户端 图形化界面 设计图形化界面 项目…...
记录开发中遇到关于MySQL的一些问题-MySQL版
本篇文章是记录开发中遇到关于MySQL的一些问题: 希望在这篇文章也能够找到你正在查找的问题,解决问题 Good Luck ! 关于Id 的一些问题 数据库并没有直接写SQL,是通过使用IDEA 同一个公司下的数据库软件生成的(DataGrip…...
2023-10-06 LeetCode每日一题(买卖股票的最佳时机含手续费)
2023-10-06每日一题 一、题目编号 714. 买卖股票的最佳时机含手续费二、题目链接 点击跳转到题目位置 三、题目描述 给定一个整数数组 prices,其中 prices[i]表示第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。 你可以无限次地完成交易&…...
openGauss学习笔记-91 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用MOT外部支持工具
文章目录 openGauss学习笔记-91 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用MOT外部支持工具91.1 gs_ctl(全量和增量)91.2 gs_basebackup91.3 gs_dump91.4 gs_restore openGauss学习笔记-91 openGauss 数据库管理-内存优化表MOT…...
PostgreSQL快速入门
PostgreSQL快速入门:轻松掌握强大的开源数据库 PostgreSQL(简称Postgres)是一款强大、可定制且免费的开源关系型数据库管理系统(RDBMS)。它以其高级功能、可扩展性和安全性而著称,被广泛用于各种规模的项目…...
MATLAB:线性系统的建模与仿真(含完整程序)
目录 前言实验内容一、先看作业题目要求二、作业正文Modeling LTI systemsEstablish model1.tf(sys2)2. tf(sys3)3.zpk(sys1)4. zpk(sys3)5. ss(sys1)6. ss(sys2)7.[num,den] tfdata(sys1)8.[num,den] tfdata(sys2)9.[num,den] tfdata(sys3)10.[num,den] tfdata(sys1,’v’…...
mycat实现mysql读写分离
架构图: 视频地址...
【C++】STL详解(十一)—— unordered_set、unordered_map的介绍及使用
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:C学习 🎯长路漫漫浩浩,万事皆有期待 上一篇博客:【C】STL…...
江门网站建设易搜互联/seo外包服务项目
随着信息技术的快速发展和网络技术的日益完善,人们越来越重视电子商务。校园 二手物品交易系统是校园电子商务的一个典型代表。二手市场从以前的路边旧货市场转 变到网络中,通过二手交易系统实现了二手交易。而校园二手物品交易系统带给学生省 时、省…...
织梦做的网站打开慢/seo数据是什么
Activity的打开方式有两种: 打开Activity的时候需要指定意图Intent1. 显式意图:创建Intent需要明确指定被打开的Activity2. 隐式意图:通过匹配 action,category datamimeType ,flag3.Intent 可以传递8基本数据类型 还可以传递对象 该对象 但是必须 …...
wordpress 隐藏副标题/网络策划与营销
目录前言在上一篇中介绍了Python的序列和String类型的内置方法,本篇继续学习作为序列类型成员之一的List类型的内置方法。软件环境系统UbuntuKylin 14.04软件Python 2.7.3IPython 4.0.0列表List列表是一种容器,存放内存对象的引用。即是任意内存对象的有…...
网站建设域名有哪些类型/百度云盘网页版
1,3,4,5,7,10这样子-------------------------truncate命令是会把自增的字段还原为从1开始的,或者你试试把table_a清空,然后取消自增,保存,再加回自增,这也是自增段还原为…...
测试网站开发/潍坊关键词优化平台
C11中的右值引用 May 18, 2015移动构造函数C98中的左值和右值C11右值引用和移动语义强制移动语义std::move()右值引用和右值的关系完美转发 引用折叠推导规则特殊模板参数推导规则解决完美转发问题引用在C98中有左值和右值的概念,不过这两个概念对于很多程序员并不关…...
正规网站建设费用/宁波seo网络推广优质团队
说明:获取的数据是操作系统整体的资源占用情况,不是当前 java进程占用的资源1. 获取系统CPU占用情况 :import java.lang.management.ManagementFactory;import com.sun.management.OperatingSystemMXBean;private static OperatingSystemMXBe…...