06 单目初始化器 Initializer

news2024/12/23 22:16:21

06 单目初始化器 Initializer

单目 SLAM 初始化相关,双目和 RGBD 不会使用这个类

单目相机运动得到两帧图像,调用该类,当满足一定条件时认为初始化成功,否则重新初始化。

6.1 成员变量/函数

在这里插入图片描述

用 reference frame 来初始化,这个 reference frame 就是 SLAM 正式开始的第一帧;用 current frame,也就是用 SLAM 逻辑上的第二帧来初始化整个 SLAM,得到最开始两帧之间的 R \boldsymbol{R} R t \boldsymbol{t} t,以及点云。

成员函数/变量访问控制意义
Initializer(...)public构造函数,用 reference frame 来初始化
bool Initialize(...)public用 current frame,得到最开始两帧之间的 R \boldsymbol{R} R t \boldsymbol{t} t,以及点云
vector<cv::KeyPoint> mvKeys1private存储 reference frame 中的特征点
vector<cv::KeyPoint> mvKeys2private存储 current frame 中的特征点
vector<Match> mvMatches12private记录 Reference 到 Current 匹配上的特征点对
vector<bool> mvbMatched1private记录 Reference Frame 的每个特征点在 Current Frame 是否有匹配的特征点
cv::Mat mKprivate相机内参
float mSigma, mSigma2private测量误差
int mMaxIterationsprivateRANSAC 迭代次数
vector<vector<size_t> > mvSetsprivate二维容器 N × 8 N\times8 N×8
每一层保存 RANSAC 计算 H 和 F 矩阵所需的八对点
得分大于0.4
得分小于0.4
Initialize
提取特征点
FindHomography
FindFundamental
ComputeH21:计算单应矩阵 H
CheckHomography: 根据H矩阵计算重投影误差,误差求和即得分
ComputeF21: 计算基础矩阵F
CheckFundamental:计算投影误差,累积求和即得分
根据得分比例,选择用单应矩阵H或基础矩阵F
ReconstructH
ReconstructF
分解H,得到四种解
CheckRT,按照预定条件,确定最优解
分解F,得到四种解
CheckRT,按照预定条件,确定最优解
确定最优解
若满足要求则初始化成功

6.2 初始化函数 Initialize()

主函数 Initialize() 根据两帧间的匹配关系恢复帧间运动并计算地图点位姿。

在这里插入图片描述

6.3 计算基础矩阵 F \boldsymbol{F} F 和单应矩阵 H \boldsymbol{H} H

6.3.1 RANSAC 算法

RANSAC 算法的核心是减少每次迭代所需的采样点数。从原理上来说,计算 F F F 矩阵最少只需要 7 对匹配点,计算 H H H 矩阵最少只需要 4 对匹配点。ORB-SLAM2 中为了编程方便,每次迭代使用 8 对匹配点计算 F F F H H H

6.3.2 八点法计算 F \boldsymbol{F} F 矩阵: ComputeF21()

在这里插入图片描述

对极约束

p 2 T F p 1 = 0 \boldsymbol{p}_2^T \boldsymbol{F} \boldsymbol{p}_1=0 p2TFp1=0

其中 p 1 、 p 2 \boldsymbol{p}_1、\boldsymbol{p}_2 p1p2 为对应特征点。

( u 2 , v 2 , 1 ) ( f 11 f 12 f 13 f 21 f 22 f 23 f 31 f 32 f 33 ) ( u 1 v 1 1 ) = 0 \left(u_2, v_2, 1\right)\left(\begin{array}{lll} \mathrm{f}_{11} & \mathrm{f}_{12} & \mathrm{f}_{13} \\ \mathrm{f}_{21} & \mathrm{f}_{22} & \mathrm{f}_{23} \\ \mathrm{f}_{31} & \mathrm{f}_{32} & \mathrm{f}_{33} \end{array}\right)\left(\begin{array}{c} \mathrm{u}_1 \\ \mathrm{v}_1 \\ 1 \end{array}\right)=0 (u2,v2,1) f11f21f31f12f22f32f13f23f33 u1v11 =0

为方便计算先展开前两项,并记为 a 、 b 、 c a、b、c abc

a = f 11 ∗ u 2 + f 21 ∗ v 2 + f 31 b = f 12 ∗ u 2 + f 22 ∗ v 2 + f 32 c = f 13 ∗ u 2 + f 23 ∗ v 2 + f 33 \begin{aligned} & a=f_{11} * u_2+f_{21} * v_2+f_{31} \\ & b=f_{12} * u_2+f_{22} * v_2+f_{32} \\ & c=f_{13} * u_2+f_{23} * v_2+f_{33} \end{aligned} a=f11u2+f21v2+f31b=f12u2+f22v2+f32c=f13u2+f23v2+f33

则上面的矩阵可记为

[ a b c ] [ u 1 v 1 1 ] = 0 \left[\begin{array}{lll} a & b & c \end{array}\right]\left[\begin{array}{c} u_1 \\ v_1 \\ 1 \end{array}\right]=0 [abc] u1v11 =0
展开

a ∗ u 1 + b ∗ v 1 + c = 0 a * u_1+b * v_1+c=0 au1+bv1+c=0

代入 a 、 b 、 c a、b、c abc

u 1 u 2 f 11 + u 1 v 2 f 21 + u 1 f 31 + v 1 u 2 f 12 + v 1 v 2 f 22 + v 1 f 32 + u 2 f 13 + v 2 f 23 + f 33 = 0 \mathrm{u}_1 \mathrm{u}_2 \mathrm{f}_{11}+\mathrm{u}_1 \mathrm{v}_2 \mathrm{f}_{21}+\mathrm{u}_1 \mathrm{f}_{31}+\mathrm{v}_1 \mathrm{u}_2 \mathrm{f}_{12}+\mathrm{v}_1 \mathrm{v}_2 \mathrm{f}_{22}+\mathrm{v}_1 \mathrm{f}_{32}+\mathrm{u}_2 \mathrm{f}_{13}+\mathrm{v}_2 \mathrm{f}_{23}+\mathrm{f}_{33}=0 u1u2f11+u1v2f21+u1f31+v1u2f12+v1v2f22+v1f32+u2f13+v2f23+f33=0

由于尺度不变性(可同时除 f 33 f_{33} f33),只有八个未知数,至少需要八对点

( u 1 1 u 2 1 u 1 1 v 2 1 u 1 1 v 1 1 u 2 1 v 1 1 v 2 1 v 1 1 u 2 1 v 2 1 1 u 1 2 u 2 2 u 1 2 v 2 2 u 1 2 v 1 2 u 2 2 v 1 2 v 2 2 v 1 2 u 2 2 v 2 2 1 ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ u 1 8 u 2 8 u 1 8 v 2 8 u 1 8 v 1 8 u 2 8 v 1 8 v 2 8 v 1 8 u 2 8 v 2 8 1 ) ( f 11 f 12 f 13 f 21 f 22 f 23 f 31 f 32 f 33 ) = 0 \left(\begin{array}{ccccccccc} \mathrm{u}_1^1 \mathrm{u}_2^1 & \mathrm{u}_1^1 \mathrm{v}_2^1 & \mathrm{u}_1^1 & \mathrm{v}_1^1 \mathrm{u}_2^1 & \mathrm{v}_1^1 \mathrm{v}_2^1 & \mathrm{v}_1^1 & \mathrm{u}_2^1 & \mathrm{v}_2^1 & 1 \\ \mathrm{u}_1^2 \mathrm{u}_2^2 & \mathrm{u}_1^2 \mathrm{v}_2^2 & \mathrm{u}_1^2 & \mathrm{v}_1^2 \mathrm{u}_2^2 & \mathrm{v}_1^2 \mathrm{v}_2^2 & \mathrm{v}_1^2 & \mathrm{u}_2^2 & \mathrm{v}_2^2 & 1 \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\ \mathrm{u}_1^8 \mathrm{u}_2^8 & \mathrm{u}_1^8 \mathrm{v}_2^8 & \mathrm{u}_1^8 & \mathrm{v}_1^8 \mathrm{u}_2^8 & \mathrm{v}_1^8 \mathrm{v}_2^8 & \mathrm{v}_1^8 & \mathrm{u}_2^8 & \mathrm{v}_2^8 & 1 \end{array}\right)\left(\begin{array}{c} \mathrm{f}_{11} \\ \mathrm{f}_{12} \\ \mathrm{f}_{13} \\ \mathrm{f}_{21} \\ \mathrm{f}_{22} \\ \mathrm{f}_{23} \\ \mathrm{f}_{31} \\ \mathrm{f}_{32} \\ \mathrm{f}_{33} \end{array}\right)=0 u11u21u12u22u18u28u11v21u12v22u18v28u11u12u18v11u21v12u22v18u28v11v21v12v22v18v28v11v12v18u21u22u28v21v22v28111 f11f12f13f21f22f23f31f32f33 =0

使用 SVD 分解求出最小二乘解。

cv::Mat u,w,vt;

cv::SVDecomp(A,w,u,vt,cv::SVD::MODIFY_A | cv::SVD::FULL_UV);

cv::Mat Fpre = vt.row(8).reshape(0, 3); // v的最后一列

cv::SVDecomp(Fpre,w,u,vt,cv::SVD::MODIFY_A | cv::SVD::FULL_UV);

w.at<float>(2)=0; // 秩2约束,将第3个奇异值设为0

return  u*cv::Mat::diag(w)*vt;
6.3.3 计算基础矩阵 F \boldsymbol{F} F 及其得分:FindFundamental()

此函数主要流程为:

  • 特征点归一化:Normalize()

  • 调用函数 ComputeF21() 计算基础矩阵,采用 RANSAC 算法,找到评分(卡方检验)最高的解:ComputeH21()CheckHomography()

在这里插入图片描述

6.3.4 计算 H \boldsymbol{H} H 矩阵: ComputeH21()

若场景中的特征点都落在同一平面(墙、地面),则可以用单应矩阵进行运动估计。

在这里插入图片描述

p 2 = H p 1 \boldsymbol{p}_2=\boldsymbol{H} \boldsymbol{p}_1 p2=Hp1

p 1 、 p 2 \boldsymbol{p}_1、\boldsymbol{p}_2 p1p2 为对应特征点。

一般来说,4 对点即可求解

( u 1 1 v 1 1 1 0 0 0 − u 1 1 u 2 1 − v 1 1 u 2 1 0 0 0 u 1 1 v 1 1 1 − u 1 1 v 2 1 − v 1 1 v 2 1 u 1 2 v 1 2 1 0 0 0 − u 1 2 u 2 2 − v 1 2 u 2 2 0 0 0 u 1 2 v 1 2 1 − u 1 2 v 2 2 − v 1 2 v 2 2 u 1 3 v 1 3 1 0 0 0 − u 1 3 u 2 3 − v 1 3 u 2 3 0 0 0 u 1 3 v 1 3 1 − u 1 3 v 2 3 − v 1 3 v 2 3 u 1 4 v 1 4 1 0 0 0 − u 1 4 u 2 4 − v 1 4 u 2 4 0 0 0 u 1 4 v 1 4 1 − u 1 4 v 2 4 − v 1 4 v 2 4 ) ( h 1 h 2 h 3 h 4 h 5 h 6 h 7 h 8 ) = ( u 2 1 v 2 1 u 2 2 v 2 2 u 2 3 v 2 3 u 2 4 v 2 4 ) . \left(\begin{array}{cccccccc} u_1^1 & v_1^1 & 1 & 0 & 0 & 0 & -u_1^1 u_2^1 & -v_1^1 u_2^1 \\ 0 & 0 & 0 & u_1^1 & v_1^1 & 1 & -u_1^1 v_2^1 & -v_1^1 v_2^1 \\ u_1^2 & v_1^2 & 1 & 0 & 0 & 0 & -u_1^2 u_2^2 & -v_1^2 u_2^2 \\ 0 & 0 & 0 & u_1^2 & v_1^2 & 1 & -u_1^2 v_2^2 & -v_1^2 v_2^2 \\ u_1^3 & v_1^3 & 1 & 0 & 0 & 0 & -u_1^3 u_2^3 & -v_1^3 u_2^3 \\ 0 & 0 & 0 & u_1^3 & v_1^3 & 1 & -u_1^3 v_2^3 & -v_1^3 v_2^3 \\ u_1^4 & v_1^4 & 1 & 0 & 0 & 0 & -u_1^4 u_2^4 & -v_1^4 u_2^4 \\ 0 & 0 & 0 & u_1^4 & v_1^4 & 1 & -u_1^4 v_2^4 & -v_1^4 v_2^4 \end{array}\right)\left(\begin{array}{c} h_1 \\ h_2 \\ h_3 \\ h_4 \\ h_5 \\ h_6 \\ h_7 \\ h_8 \end{array}\right)=\left(\begin{array}{c} u_2^1 \\ v_2^1 \\ u_2^2 \\ v_2^2 \\ u_2^3 \\ v_2^3 \\ u_2^4 \\ v_2^4 \end{array}\right) . u110u120u130u140v110v120v130v140101010100u110u120u130u140v110v120v130v1401010101u11u21u11v21u12u22u12v22u13u23u13v23u14u24u14v24v11u21v11v21v12u22v12v22v13u23v13v23v14u24v14v24 h1h2h3h4h5h6h7h8 = u21v21u22v22u23v23u24v24 .

这里为了和 ComputeH21() 一致,也采用八点法。通过 SVD 分解求出 H \boldsymbol{H} H 矩阵。

6.3.5 计算单应矩阵 H \boldsymbol{H} H 及其得分 FindHomography()

过程类似 FindFundamental()

在这里插入图片描述

6.3.6 卡方检验计算置信度得分: CheckFundamental()、CheckHomography()

卡方检验通过构造检验统计量 χ \chi χ 来比较期望结果和实际结果之间的差别,从而得出观察频数极值的发生概率。

χ 2 = Σ ( O − E ) 2 E \chi^2=\Sigma \frac{(\mathrm{O}-\mathrm{E})^2}{\mathrm{E}} χ2=ΣE(OE)2

(1)CheckHomography()

计算重投影误差,也就是计算投影点与对应匹配点的像素距离的平方(计算值与真实值),作为卡方值。

有前面

p 2 = H p 1 \boldsymbol{p}_2=\boldsymbol{H} \boldsymbol{p}_1 p2=Hp1

将帧 1 特征点左乘单应矩阵,得到帧 2 中对应特征点的计算值。反之,则为 p 1 = H − 1 p 2 \boldsymbol{p}_1=\boldsymbol{H}^{-1} \boldsymbol{p}_2 p1=H1p2

// Reprojection error in second image
// x1in2 = H21*x1
// 将图像1中的特征点单应到图像2中
// |u1|   |h11 h12 h13||u2|
// |v1| = |h21 h22 h23||v2|
// |1 |   |h31 h32 h33||1 |
const float w1in2inv = 1.0/(h31*u1+h32*v1+h33);  
const float u1in2 = (h11*u1+h12*v1+h13)*w1in2inv;
const float v1in2 = (h21*u1+h22*v1+h23)*w1in2inv;

const float squareDist2 = (u2-u1in2)*(u2-u1in2)+(v2-v1in2)*(v2-v1in2);  // 计算平方误差

const float chiSquare2 = squareDist2*invSigmaSquare;  // 卡方

if(chiSquare2>th)
    bIn = false;
else
    score += th - chiSquare2;   // 得分

if(bIn)
    vbMatchesInliers[i]=true;
else
    vbMatchesInliers[i]=false;    // 大于阈值,则为外点,置为 false

(2)CheckFundamental()

对于函数 CheckFundamental():理想情况下,有 p 2 T F p 1 = 0 \boldsymbol{p}_2^T \boldsymbol{F} \boldsymbol{p}_1=0 p2TFp1=0,但由于误差存在,左式并不会恒等于零,于是,我们将它的值作为误差。

// Reprojection error in second image
//                        |f11 f12 f13|
// |a1 b1 c1| = |u2 v2 1| |f21 f22 f23|
//                        |f31 f32 f33|

const float a1 = f11*u2+f21*v2+f31;     // 先展开前两项
const float b1 = f12*u2+f22*v2+f32;
const float c1 = f13*u2+f23*v2+f33;


//          |v1|
//|a1 b1 c1||u1|=0?            // 由于误差存在,并不为零,将其作为误差值
//          |1 |
const float num1 = a1*u1+b1*v1+c1;

const float squareDist2 = num1*num1/(a1*a1+b1*b1);  // 平方误差

const float chiSquare2 = squareDist2*invSigmaSquare;

if(chiSquare2>th)
    bIn = false;
else
    score += thScore - chiSquare2;

if(bIn)
    vbMatchesInliers[i]=true;
else
    vbMatchesInliers[i]=false;
6.3.7 归一化:Normalize()

用均值和一阶距绝对值将关键点归一化,归一化可以使特征点分布均匀,增强计算稳定性。

均值

u ˉ = ( ∑ i = 1 N u i ) / N \bar{u}=(\sum^N_{i=1}u_i)/N uˉ=(i=1Nui)/N
一阶距绝对值

∣ u ˉ ∣ = ∑ i = 0 N ∣ u i − u ˉ ∣ / N |\bar{u}|=\sum_{i=0}^N\left|u_i-\bar{u}\right| / N uˉ=i=0Nuiuˉ/N

归一化坐标

u i ′ = u i − u ˉ ∣ u ˉ ∣ u^{\prime}_i=\frac{u_i-\bar{u}}{|\bar{u}|} ui=uˉuiuˉ

s X = 1 ∣ u ˉ x ∣ sX=\frac{1}{|\bar{u}_x|} sX=uˉx1 s Y = 1 ∣ u ˉ y ∣ sY=\frac{1}{|\bar{u}_y|} sY=uˉy1,那么变换到归一化坐标的变换矩阵为

[ x ′ y ′ 1 ] = [ s X 0 −  mean  X ∗ s X 0 s Y −  mean  Y ∗ s Y 0 0 1 ] [ x y 1 ] \left[\begin{array}{c} x^{\prime} \\ y^{\prime} \\ 1 \end{array}\right]=\left[\begin{array}{ccc} s X & 0 & - \text { mean } X * s X \\ 0 & s Y & - \text { mean } Y * s Y \\ 0 & 0 & 1 \end{array}\right]\left[\begin{array}{l} x \\ y \\ 1 \end{array}\right] xy1 = sX000sY0 mean XsX mean YsY1 xy1

代码

/*
 * @param vKeys             特征点在图像上的坐标
 * @param vNormalizedPoints 特征点归一化后的坐标
 * @param T                 将特征点归一化的矩阵
 */
void Initializer::Normalize(const vector<cv::KeyPoint> &vKeys, vector<cv::Point2f> &vNormalizedPoints, cv::Mat &T)
{
    float meanX = 0;
    float meanY = 0;
    const int N = vKeys.size();

    vNormalizedPoints.resize(N);

    for(int i=0; i<N; i++)
    {
        meanX += vKeys[i].pt.x;
        meanY += vKeys[i].pt.y;
    }

    meanX = meanX/N;
    meanY = meanY/N;    // 均值

    float meanDevX = 0;
    float meanDevY = 0;

    // 将所有vKeys点减去中心坐标,使x坐标和y坐标均值分别为0
    for(int i=0; i<N; i++)
    {
        vNormalizedPoints[i].x = vKeys[i].pt.x - meanX;
        vNormalizedPoints[i].y = vKeys[i].pt.y - meanY;

        meanDevX += fabs(vNormalizedPoints[i].x);
        meanDevY += fabs(vNormalizedPoints[i].y);
    }

    meanDevX = meanDevX/N;
    meanDevY = meanDevY/N;  // 一阶距绝对值

    float sX = 1.0/meanDevX;
    float sY = 1.0/meanDevY;

    // 将x坐标和y坐标分别进行尺度缩放,使得x坐标和y坐标的一阶绝对矩分别为1
    for(int i=0; i<N; i++)   // 得到归一化坐标
    {
        vNormalizedPoints[i].x = vNormalizedPoints[i].x * sX;
        vNormalizedPoints[i].y = vNormalizedPoints[i].y * sY;
    }    

    // 得到归一化坐标的变换矩阵
    // |sX  0  -meanx*sX|
    // |0   sY -meany*sY|
    // |0   0      1    |
    T = cv::Mat::eye(3,3,CV_32F);
    T.at<float>(0,0) = sX;
    T.at<float>(1,1) = sY;
    T.at<float>(0,2) = -meanX*sX;
    T.at<float>(1,2) = -meanY*sY;
}
6.3.8 检验 F \boldsymbol{F} F H \boldsymbol{H} H 分解结果 :CheckRT()

使用基础矩阵 F \boldsymbol{F} F 分解 R \boldsymbol{R} R t \boldsymbol{t} t,数学上会得到四个可能的解,因此分解后调用函数 Initializer::CheckRT() 检验分解结果,取相机前方成功三角化数目最多的一组解。

在这里插入图片描述

显然只有在第一种解中,点 P \boldsymbol{P} P 在两个相机中均有正深度。

同样地,单应矩阵也需要检验,从而得出符合条件的 R , t \boldsymbol{R,t} Rt

步骤:
① 遍历各匹配点对,调用三角化函数恢复三维点坐标
② 三维点坐标各值都必须为有限实数;
③ 深度值必须为正;
④ 三维点和两帧图像光心夹角需满足一定条件,夹角越大,视差越大,误差越小,三角化结果越准确;
⑤ 三维点的重投影误差需小于设定阈值。

将每种情况下满足要求的三维点的数目记录下来,进一步进行比较,得出最优解:
① 最优解成功三角化的数目明显优于次优解的点数目;
② 最优解的视差大于设定点阈值;
③ 最优解成功三角化的点数目大于设定阈值;
④ 最优解成功三角化点数目占所有特征点数目的 90% 以上。

6.4 三角化

三角测量恢复深度,进而求出三维点坐标。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于yolov2深度学习网络的视频手部检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 输入mp4格式的视频文件进行测试&#xff0c;视频格式为1080p30. 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..........................…

大数据分析案例-基于随机森林算法构建电影票房预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

软连接和硬链接

1.软连接 软连接是一个独立的文件&#xff0c;有独立的inode&#xff0c;也有独立的数据块&#xff0c;它的数据块里面保存的是指向的文件路径-------相当于windows的快捷方式 删除一个软连接 2.硬链接 所谓的建立硬链接&#xff0c;本质就是在特定目录的数据块中新增文件名和…

【大数据】Flink SQL 语法篇(三):窗口聚合(TUMBLE、HOP、SESSION、CUMULATE)

Flink SQL 语法篇&#xff08;三&#xff09;&#xff1a;窗口聚合 1.滚动窗口&#xff08;TUMBLE&#xff09;1.1 Group Window Aggregation 方案&#xff08;支持 Batch / Streaming 任务&#xff09;1.2 Windowing TVF 方案&#xff08;1.13 只支持 Streaming 任务&#xff…

sqli-labs-master靶场训练笔记(1-22|新手村)

2024.1.21 level-1 &#xff08;单引号装饰&#xff09; 先根据提示建立一个get请求 在尝试使用单个单引号测试&#xff0c;成功发现语句未闭合报错 然后反手一个 order by 得到数据库共3列&#xff0c;-- 后面加字母防止浏览器吃掉 -- 操作&#xff08;有些会&#xff09…

Java关于Excel文件的导入导出

人生如梦 荣华富贵 如木槿之花 朝荣夕逝 需求 导出&#xff1a; 能够将库表内的数据导出多个Excel表&#xff0c;并且生成一个压缩包&#xff0c;提供用户下载导入&#xff1a; 能够将一个压缩包内的多个Excel表解压&#xff0c;并获取表内的所有数据 FileUtils 工具类 publi…

GPT-SoVITS 本地搭建踩坑

GPT-SoVITS 本地搭建踩坑 前言搭建下载解压VSCode打开安装依赖包修改内容1.重新安装版本2.修改文件内容 运行总结 前言 传言GPT-SoVITS作为当前与BertVits2.3并列的TTS大模型&#xff0c;于是本地搭了一个&#xff0c;简单说一下坑。 搭建 下载 到GitHub点击此处下载 http…

【三维重建】运动恢复结构(SfM)

运动恢复结构是通过三维场景的多张图像&#xff0c;恢复出该场景的三维结构信息以及每张图片对应的摄像机参数。 欧式结构恢复(内参已知&#xff0c;外参未知) 欧式结构恢复问题&#xff1a; 已知&#xff1a;1、n个三维点在m张图像中的对应点的像素坐标 2、相机内参 求解&…

指针的深入了解6

1.回调函数 回调函数就是一个通过函数指针调用的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另一个函数&#xff0c;当这个指针被用来调用其所指向的函数 时&#xff0c;被调用的函数就是回调函数。回调函数不是由该函数的实现方直接调用&#xff0…

字符串:getline、删除子串.erase()函数、插入子串.insert()函数

getline具体用法&#xff1a; 1、函数形式 getline ( cin,字符串类型&#xff1a;变量名);//默认以换行符结束 getline (cin, 字符串类型&#xff1a;变量名, ‘指定的结束符’); //指定换行结束符 2注意事项&#xff1a; 1&#xff09;如果在使用getline()之前有使用scanf(…

Java基础--异常

异常 将程序执行中发生的不正常情况称为“异常”&#xff08;语法错误和逻辑错误不是异常&#xff09;。 异常时间分为两大类&#xff1a; 1.Error&#xff08;错误&#xff09;&#xff1a;Java虚拟机无法解决的严重问题。Error 是严重错误&#xff0c;程序会崩溃。 2.Except…

【AI视野·今日NLP 自然语言处理论文速览 第七十七期】Mon, 15 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Mon, 15 Jan 2024 Totally 57 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Machine Translation Models are Zero-Shot Detectors of Translation Direction Authors Michelle Wastl, Ja…

奥威-金蝶BI方案:企业获利能力该这样看

获利能力、偿债能力、营运能力是企业经营发展中需要密切关注的三大基础能力&#xff0c;通常可通过详细的数据分析可视化来获知。那么&#xff0c;怎么分析企业获利能力&#xff1f;奥威-金蝶BI方案做了个示范。 按年看 按月看 一般来说&#xff0c;我们会做成两张报表&#x…

代码随想录算法刷题训练营day20

代码随想录算法刷题训练营day20&#xff1a;LeetCode(654)最大二叉树、LeetCode(617)合并二叉树、LeetCode(700)二叉搜索树中的搜索、LeetCode(700)二叉搜索树中的搜索、LeetCode(98)验证二叉搜索 LeetCode(654)最大二叉树 题目 代码 import java.util.Arrays;/*** Definit…

Java面试架构篇【一览众山小】

文章目录 &#x1f6a1; 简介☀️ Spring&#x1f425; 体系结构&#x1f420; 生命周期 &#x1f341; SpringMVC&#x1f330; 执行流程 &#x1f31c; SpringBoot&#x1f30d; 核心组件&#x1f38d; 自动装配&#x1f391; 3.0升级 &#x1f505; spring Cloud Alibaba&am…

Consul容器服务自动发现和更新

目录 前瞻 什么是服务注册与发现 什么是consul Docker-consul实现过程 Docker-consul集群部署 实验准备 实验流程 前瞻 什么是服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的&#xff0c;不保障高可用性&#xff0c;也不考虑服…

web应用课——(第一讲:html基础标签)

目录 一、html文件结构 二、文本标签 三、图片 四、音频和视频 五、超链接 六、表单 七、列表 八、表格 九、语义标签 十、特殊符号 一、html文件结构 <html>标签&#xff1a;表示一个 HTML 文档的根&#xff08;顶级元素&#xff09;&#xff0c;所以它也被…

可以举一反三的动态规划问题(最短编辑问题)

给定两个字符串 A 和 B&#xff0c;现在要将 A经过若干操作变为 B&#xff0c;可进行的操作有&#xff1a; 删除–将字符串 A 中的某个字符删除。插入–在字符串 A 的某个位置插入某个字符。替换–将字符串 A 中的某个字符替换为另一个字符。 现在请你求出&#xff0c;将 A 变…

掌握 Android JNI 基础

写在前面 最近在看一些底层源码&#xff0c;发现 JNI 这块还是有必要系统的看一下&#xff0c;索性就写一写博客&#xff0c;加深加深印象&#x1f37b; 本文重点聊一聊一些干货&#xff0c;避免长篇大论 JNI 概述 JNI 是什么&#xff1f; 定义&#xff1a;Java Native In…

类和对象 第六部分 继承 第一部分:继承的语法

一.继承的概念 继承是面向对象的三大特性之一 有些类与类之间存在特殊的关系&#xff0c;例如下图&#xff1a; 我们可以发现&#xff0c;下级别的成员除了拥有上一级的共性&#xff0c;还有自己的特性&#xff0c;这个时候&#xff0c;我们可以讨论利用继承的技术&#xff0c;…