视觉SLAM十四讲学习笔记(二)三维空间刚体

哔哩哔哩课程连接:视觉SLAM十四讲ch3_哔哩哔哩_bilibili​

目录

一、旋转矩阵

1 点、向量、坐标系

2 坐标系间的欧氏变换

3 变换矩阵与齐次坐标

二、实践:Eigen(1)

运行报错记录与解决

三、旋转向量和欧拉角

1 旋转向量

2 欧拉角

四、四元数

1 四元数的定义

2 四元数的运算

3 用四元数表示旋转

4 四元数到旋转矩阵的转换

五、实践:Eigen(2)

useGeometry

visualizeGeometry

总结


前言

问题用两个方程描述:

本文将介绍视觉 SLAM 的基本问题之一:一个刚体在三维空间中的运动是如何描述的。

将介绍旋转矩阵、四元数、欧拉角的意义,以及它们是如何运算和转换的。在实践部分,将介绍线性代数 库 Eigen。它提供了 C++ 中的矩阵运算,并且它的 Geometry 模块还提供了四元数等刚体运动的描述。Eigen 的优化非常完善,但是它的使用方法有一些特殊的地方。

一、旋转矩阵

1 点、向量、坐标系

三维空间由三个轴组成,所以一个空间点的位置可以由三个坐标指定。不过,刚体不光有位置,还有自身的姿态。相机也可以看成三维空间的刚体,于是位置是指相机在空间中的哪个地方,而姿态则是指相机的朝向。

  • 点存在于三维空间之中
  • 点和点可以组成向量
  • 点本身由原点指向它的向量所描述

向量

  • 带指向性的箭头
  • 可以进行加法、减法等运算

坐标系:由三个正交的拍组成

  • 构成线性空问的一组基
  • 左手系和右手系

定义坐标系后、向量可以由坐标表示,如果我们确定一个坐标系,也就是一个线性空间的基 (e1, e2, e3), 那就可以谈论向量 a 在这组基下的坐标了:

向量的运算可以由坐标运算来表达,内积(可以描述向量间的投影关系)可以写成:

外积外积的方向垂直于这两个向量,大小为 |a| |b|sin <a, b>,是两个向量张成的四边形的有向面积

引入了 符号,把 a 写成一个矩阵。事实上是一个反对称矩阵(Skew-symmetric),你可以将 记成一个反对称符号。外积只对三维向量存在定义,还能用外积表示向量的旋转。

坐标系间的欧氏变换

在SLAM中:

  • 固定的世界坐标系和移动的机器人坐标系
  • 机器人坐标系随着机器人运动而改变,每个时刻都有新的坐标系

描述两个坐标系之间的旋转关系,再加上平移,统称为坐标系之间的变换关系。

上图为坐标变换。对于同一个向量 p,它在世界坐标系下的坐标 pw 和在相机坐标系下的 pc 是不同的。这个变换关系由坐标系间的变换矩阵 T 来描述。

相机运动是一个刚体运动,它保证了同一个向量在各个坐标系下的长度和夹角都不会发生变化。这种变换称为欧氏变换

设某个单位正交基 (e1, e2, e3) 经过一次旋转,变成了 (e 1 , e 2 , e 3 )。那么,对于同一个向量 a(注意该向量并没有随着坐标系的旋转而发生运动),它在两个坐标系下的坐标为 [a1, a2, a3] T [a 1 , a 2 , a 3 ] T。 根据坐标的定义,有:

对上面等式左右同时左乘那么左边的系数变成了单位矩阵,所以:

把中间的阵定义成一个矩阵 R。这个矩阵由两组基之间的内积组成,刻画了旋转前后同一个向量的坐标变换关系。只要旋转是一样,那么这个矩阵也一样。矩阵 R 描述了旋转本身,因此又称为旋转矩阵,有以下性质:

  • 行列式为1
  • 正交阵
  • 对于同一个旋转变化,对应唯一的旋转矩阵
  • 旋转矩阵的充要条件:行列式为 1 的正交矩阵
  • 集合定义:SO(n) 是特殊正交群(Special Orthogonal Group)。

旋转矩阵可以描述相机的旋转。由于旋转矩阵为正交阵,它的逆(即转置)描述了一个相反的旋转。

考虑平移,设平移向量为 t ,旋转矩阵为 R ,则

变换矩阵与齐次坐标

齐次坐标:齐次坐标是用N+1个数来表示N维坐标的一种方式。

变换矩阵Transform Matrix):如果T是一个把Rn映射到Rm的线性变换,且x是一个具有n个元素的 列向量 ,那么我们把m×n的矩阵A,称为T的变换矩阵。

假设进行了两次变换:R1, t1 R2, t2,满足:

  • b = R1a + t1

  • c = R2b + t2

但是从 a c 的变换为: c = R2 (R1a + t1) + t2.

引入齐次坐标和变换矩阵重写:

关于变换矩阵 T,它具有比较特别的结构:左上角为旋转矩阵,右侧为平移向量,左下角为 0 向量,右下角为 1。这种矩阵又称为特殊欧氏群(Special Euclidean Group):

在不引起歧义的情况下,我们以后不区别齐次坐标与普通的坐标的符号,默认我们使用的是符合运算法则的那一种。

二、实践:Eigen(1)

本章需要虚拟机或ubuntu系统,自行安装。下载配套资源,记录在视觉SLAM十四讲学习笔记(一)初识SLAM-CSDN博客

打开文件夹ch3

Eigen安装:

sudo apt-get install libeigen3-dev

装好后可以ls查看头文件库

ls /usr/include/eigen3/

Eigen是一个纯用头文件搭建起来的库,没有源文件。这意味着只能找到它的头文件,而没有类似.so或.a的二进制文件。在使用时,只需引入Eigen的头文件即可,不需要链接库文件。

然后就可以在你的程序引用#include <Eigen/Core>。

cmake .

make

下面一段代码实际联系Eigen的使用:

#include <iostream>
using namespace std;
#include <ctime>
// Eigen 部分
#include <Eigen/Core>
// 稠密矩阵的代数运算(逆,特征值等)
#include <Eigen/Dense>#define MATRIX_SIZE 50/****************************
* 本程序演示了 Eigen 基本类型的使用
****************************/int main( int argc, char** argv )
{// Eigen 中所有向量和矩阵都是Eigen::Matrix,它是一个模板类。它的前三个参数为:数据类型,行,列// 声明一个2*3的float矩阵Eigen::Matrix<float, 2, 3> matrix_23;// 同时,Eigen 通过 typedef 提供了许多内置类型,不过底层仍是Eigen::Matrix// 例如 Vector3d 实质上是 Eigen::Matrix<double, 3, 1>,即三维向量Eigen::Vector3d v_3d;// 这是一样的Eigen::Matrix<float,3,1> vd_3d;// Matrix3d 实质上是 Eigen::Matrix<double, 3, 3>Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero(); //初始化为零// 如果不确定矩阵大小,可以使用动态大小的矩阵Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > matrix_dynamic;// 更简单的Eigen::MatrixXd matrix_x;// 这种类型还有很多,我们不一一列举// 下面是对Eigen阵的操作// 输入数据(初始化)matrix_23 << 1, 2, 3, 4, 5, 6;// 输出cout << matrix_23 << endl;// 用()访问矩阵中的元素for (int i=0; i<2; i++) {for (int j=0; j<3; j++)cout<<matrix_23(i,j)<<"\t";cout<<endl;}// 矩阵和向量相乘(实际上仍是矩阵和矩阵)v_3d << 3, 2, 1;vd_3d << 4,5,6;// 但是在Eigen里你不能混合两种不同类型的矩阵,像这样是错的// Eigen::Matrix<double, 2, 1> result_wrong_type = matrix_23 * v_3d;// 应该显式转换Eigen::Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d;cout << result << endl;Eigen::Matrix<float, 2, 1> result2 = matrix_23 * vd_3d;cout << result2 << endl;// 同样你不能搞错矩阵的维度// 试着取消下面的注释,看看Eigen会报什么错// Eigen::Matrix<double, 2, 3> result_wrong_dimension = matrix_23.cast<double>() * v_3d;// 一些矩阵运算// 四则运算就不演示了,直接用+-*/即可。matrix_33 = Eigen::Matrix3d::Random();      // 随机数矩阵cout << matrix_33 << endl << endl;cout << matrix_33.transpose() << endl;      // 转置cout << matrix_33.sum() << endl;            // 各元素和cout << matrix_33.trace() << endl;          // 迹cout << 10*matrix_33 << endl;               // 数乘cout << matrix_33.inverse() << endl;        // 逆cout << matrix_33.determinant() << endl;    // 行列式// 特征值// 实对称矩阵可以保证对角化成功Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver ( matrix_33.transpose()*matrix_33 );cout << "Eigen values = \n" << eigen_solver.eigenvalues() << endl;cout << "Eigen vectors = \n" << eigen_solver.eigenvectors() << endl;// 解方程// 我们求解 matrix_NN * x = v_Nd 这个方程// N的大小在前边的宏里定义,它由随机数生成// 直接求逆自然是最直接的,但是求逆运算量大Eigen::Matrix< double, MATRIX_SIZE, MATRIX_SIZE > matrix_NN;matrix_NN = Eigen::MatrixXd::Random( MATRIX_SIZE, MATRIX_SIZE );Eigen::Matrix< double, MATRIX_SIZE,  1> v_Nd;v_Nd = Eigen::MatrixXd::Random( MATRIX_SIZE,1 );clock_t time_stt = clock(); // 计时// 直接求逆Eigen::Matrix<double,MATRIX_SIZE,1> x = matrix_NN.inverse()*v_Nd;cout <<"time use in normal inverse is " << 1000* (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms"<< endl;// 通常用矩阵分解来求,例如QR分解,速度会快很多time_stt = clock();x = matrix_NN.colPivHouseholderQr().solve(v_Nd);cout <<"time use in Qr decomposition is " <<1000*  (clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms" << endl;return 0;
}

运行报错记录与解决

在学习SlamBook2-ch3中对Eigen矩阵运算包内容时,编写好相关代码后make报错:

[ 50%] Building CXX object CMakeFiles/eigenMatrix.dir/eigenMatrix.cpp.o
/home/yang/slam/SLAMBook/ch3/useEigen/useEigen/src/eigenMatrix.cpp:6:10: fatal error: Eigen/Core: 没有那个文件或目录#include <Eigen/Core>^~~~~~~~~~~~
compilation terminated.
CMakeFiles/eigenMatrix.dir/build.make:62: recipe for target 'CMakeFiles/eigenMatrix.dir/eigenMatrix.cpp.o' failed
make[2]: *** [CMakeFiles/eigenMatrix.dir/eigenMatrix.cpp.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/eigenMatrix.dir/all' failed
make[1]: *** [CMakeFiles/eigenMatrix.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

因为在当初安装eigen库时,系统默认安装到了 /usr/include/eigen3/Eigen 路径下,根据CmakeLists中的路径无法定位到Eigen库文件文件夹所在的位置,从而报错。

解决方法:
使用下面命令将eigen的安装路径映射到/usr/include路径下:

sudo ln -s /usr/include/eigen3/Eigen /usr/include/Eigen

三、旋转向量和欧拉角

旋转向量

矩阵表示方式至少有以下缺点:

  1. SO(3) 的旋转矩阵有九个量,但一次旋转只有三个自由度。因此这种表达方式是冗余的。同理,变换矩阵用十六个量表达了六自由度的变换。
  2.  旋转矩阵自身带有约束:它必须是个正交矩阵,且行列式为 1。变换矩阵也是如此。当我们想要估计或优化一个旋转矩阵/变换矩阵时,这些约束会使得求解变得更困难。

对于坐标系的旋转,任意旋转都可以用一个旋转轴和一个旋转角来刻画。于是,我们可以使用一个 向量,其方向与旋转轴一致,而长度等于旋转角。这种向量,称为旋转向量(或轴角,Axis-Angle)。这种表示法只需一个三维向量即可描述旋转。同样,对于变换矩阵,我们使用一个旋转向量和一个平移向量即可表达一次变换。这时的维数正好是六维。

角轴与旋转矩阵的不同:

  • 旋转矩阵:九个量,有正交性约来和行列式值约束
  • 角轴:三个量,没有约衷

注意它们只是表达方式的不同,但表达的东西可以是同一个。角轴也就是后面要介绍的李代数。

假设有一个旋转轴为 n,角度为 θ 的旋转,显然,它对应的旋转向量为 θn。由旋转向量到旋转矩阵的过程由罗德里格斯公式Rodrigues’s Formula )表明,由于推导过程比较复杂,本文不作描述,只给出转换的结果

旋转矩阵转轴角:

角度:

轴:

转轴 n 是矩阵 R 特征值 1 对应的特征向量。求解此方程,再归一化,就得到了旋转轴。

欧拉角

欧拉角提供了一种非常直观的方式来描述旋转——它使用了三个分离的转角,把一个旋转分解成三次绕不同轴的旋转。可以定义 ZY ZZY X 等等旋转方式。如果讨论更细一些,还需要区分每次旋转是绕固定轴旋转的,还是绕旋转之后的轴旋转的,这也会给出不一样的定义方式。

  • 将腕转分解为三次不同轴上的转动,以便理解
  • 例如:按Z-Y-X顺序转动
  • 轴可以是定轴或动轴,顺序亦可不同,因此存在许多种定义方式不同的欧拉角
  • 常见的有 yaw-pilch-roll(偏航-怕仰-滚转)角等等

ZY X 转角相当于把任意旋转分解成以下三个轴上的转角:

  1. 绕物体的 Z 轴旋转,得到偏航角 yaw
  2. 旋转之后Y 轴旋转,得到俯仰角 pitch
  3. 旋转之后X 轴旋转,得到滚转角 roll。

万向锁(Gimbal Lock)

ZYX顺序中,若Pitch为正负90度,则第三次旋转和第一次绕同一个轴,使得系统丢失了一个自由度――存在奇异性问题。

程序中直接使用欧拉角表达姿态,同样不会在滤波或优化中使用欧拉角表达旋转(因为它具有奇异性)。不过,若你想验证自己算法是否有错时,转换成欧拉角能够快速辨认结果的正确与否。

  • 由于万向锁,欧拉角不适于插值和达代,往往只用于人机交互中。
  • 可以证明,用三个实数来表达三维旋转时,会不可避免地碰到奇异性问题。
  • SLAM程序中很少直接使用欧拉角表达姿态

四、四元数

1 四元数的定义

四元数是 Hamilton 找到的一种扩展的复数它既是紧凑的,也没有奇异性。一个四元数 q 拥有一个实部和三个虚部。本书把实部写在前面(也有地方把实部写在后面),像这样:

这里,s 称为四元数的实部,而 v 称为它的虚部。如果一个四元数虚部为 0,称之为实四元数。反之,若它的实部为 0,称之为虚四元数

能用单位四元数表示三维空间中任意一个旋转,不过这种表达方式和复数有着微妙的不同。在复数中,乘以 i 意味着旋转 90 度。这是否意味着四元数中,乘 i 就是绕 i 轴旋转 90 度?那么,ij = k 是否意味着,先绕 i 90 度,再绕 j 90 度,就等于绕 k 转90 度?正确的事情应该是,乘以 i 应该对应着旋转 180 度,这样才能保证 ij = k 的性质。而 i 2 = 1,意味着绕i 轴旋转 360 度后,你得到了一个相反的东西。这个东西要旋转两周才会和它原先的样子相等。

假设某个旋转是绕单位向量 n = [nx, ny, nz] T 进行了角度为 θ 的旋转,那么这个旋转的四元数形式为:

反之,亦可从单位四元数中计算出对应旋转轴与夹角:

在四元数中,任意的旋转都可以由两个互为相反数的四元数表示。同理,取 θ 0,则得到一个没有任何旋转的实四元数:

2 四元数的运算

那么,它们的运算可表示如下。

加减法

乘法:

如果写成向量形式并利用内外积运算,乘法表达会更加简洁:

在该乘法定义下,两个实的四元数乘积仍是实的,这与复数也是一致的。然而,注意到,由于最后一项外积的存在,四元数乘法通常是不可交换的,除非 va vb R 3中共线,那么外积项为零。

共轭:

模长:

可以验证,两个四元数乘积的模即为模的乘积。这保证单位四元数相乘后仍是单位四元数。

逆:

如果 q 为单位四元数,逆和共轭就是同一个量。同时,乘积的逆有和矩阵相似的性质:

数乘与点乘:

用四元数表示旋转

这相当于把四元数的三个虚部与空间中的三个轴相对应。然后,用四元数 q 表示旋转:

可以验证,计算结果的实部为 0,故为纯虚四元数。其虚部的三个分量表示旋转后 3D 点的坐标。

四元数到旋转矩阵的转换

把四元数转换为矩阵的最直观方法,是先把四元数 q 转换为轴角 θ n,然后再根据罗德里格斯公式转换为矩阵。

反之,由旋转矩阵到四元数的转换如下。假设矩阵为 R = {mij}, i, j [1, 2, 3],其对应的四元数 q 由下式给出:

值得一提的是,由于 q q 表示同一个旋转,事实上一个 R 对应的四元数表示并不是惟一的。同时,除了上面给出的转换方式之外,还存在其他几种计算方法。实际编程中,当 q0 接近 0 时,其余三个分量会非常大,导致解不稳定,此时再考虑使用其他的方式进行转换。

五、实践:Eigen(2)

useGeometry

打开文件夹useGeometry,步骤和二、实践:Eigen(1) 一致

visualizeGeometry

打开文件夹visualizeGeometry,打开Readme.txt,文件内容如下:

1. How to compile this program:* use pangolin: slambook/3rdpart/Pangolin or download it from github: https://github.com/stevenlovegrove/Pangolin* install dependency for pangolin (mainly the OpenGL): 
sudo apt-get install libglew-dev* compile and install pangolin
cd [path-to-pangolin]
mkdir build
cd build
cmake ..
make 
sudo make install * compile this program:
mkdir build
cd build
cmake ..
make * run the build/visualizeGeometry2. How to use this program:The UI in the left panel displays different representations of T_w_c ( camera to world ). It shows the rotation matrix, tranlsation vector, euler angles (in roll-pitch-yaw order) and the quaternion.
Drag your left mouse button to move the camera, right button to rotate it around the box, center button to rotate the camera itself, and press both left and right button to roll the view. 
Note that in this program the original X axis is right (red line), Y is up (green line) and Z in back axis (blue line). You (camera) are looking at (0,0,0) standing on (3,3,3) at first. 3. Problems may happen:
* I found that in virtual machines there may be an error in pangolin, which was solved in its issue: https://github.com/stevenlovegrove/Pangolin/issues/74 . You need to comment the two lines mentioned by paulinus, and the recompile and reinstall Pangolin, if you happen to find this problem. If you still have problems using this program, please contact: gaoxiang12@mails.tsinghua.edu.cn

根据文件操作即可,这部分我没有去实践,大家可以自行探索。


总结

以上就是今天要讲的内容,本文仅仅简单介绍了Eigen 来表示矩阵、向量, 随后引申至旋转矩阵与变换矩阵的计算。Eigen是一个 C++ 开源线性代数库。它提供了快速的有关矩阵的线性代数运算,还包括解方程等功能。许多上层的软件库也使用 Eigen 进行矩阵运算,包括 g2oSophus 等。

无论是四元数、旋转矩阵还是轴角,它们都可以用来描述同一个旋转。应该在实际中选择最为方便的形式,而不必拘泥于某种特定的样子。

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

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

相关文章

【OrangePi Zero2 智能家居】需求及项目准备

一、需求及项目准备 二、系统框图 三、硬件接线 四、语音模块配置 五、模块测试 一、需求及项目准备 语音接入控制各类家电&#xff0c;如客厅灯、卧室灯、风扇Socket网络编程&#xff0c;实现Sockect发送指令远程控制各类家电烟雾警报监测&#xff0c; 实时检查是否存在煤气…

谷粒商城【成神路】-【6】——商品维护

目录 &#x1f9c2;1.发布商品 &#x1f953;2.获取分类关联品牌 &#x1f32d;3.获取分类下所有分组和关联属性 &#x1f37f;4.商品保存功能 &#x1f9c8;5.sup检索 &#x1f95e;6.sku检索 1.发布商品 获取用户系统等级~&#xff0c;前面生成了后端代码&#xff…

前端面试题——二叉树遍历

前言 二叉树遍历在各种算法和数据结构问题中都有广泛的应用&#xff0c;如二叉搜索树、表达式的树形表示、堆的实现等。同时也是前端面试中的常客&#xff0c;掌握好二叉树遍历算法对于一名合格的前端工程师来说至关重要。 概念 二叉树遍历&#xff08;Binary Tree Traversa…

自然语言处理(NLP)—— 基本概念

自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;是人工智能和语言学领域的一个分支&#xff0c;它涉及到计算机和人类&#xff08;自然&#xff09;语言之间的相互作用。它的主要目标是让计算机能够理解、解释和生成人类语言的数据。NLP结…

73. 矩阵置零(Java)

目录 题目描述&#xff1a;输入&#xff1a;输出&#xff1a;代码实现&#xff1a; 题目描述&#xff1a; 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 输入&#xff1a; matrix [[1,1,1],[1,0,…

Linux操作系统基础(九):Linux用户与权限

文章目录 Linux用户与权限 一、文件权限概述 二、终端命令&#xff1a;组管理 三、终端命令&#xff1a;用户管理 1、创建用户 、 设置密码 、删除用户 2、查看用户信息 3、su切换用户 4、sudo 4.1、给指定用户授予权限 4.2、使用 用户 zhangsan登录, 操作管理员命令…

汉服租赁网站:Java技术的文化应用

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Matplotlib核心:掌握Figure与Axes

详细介绍Figure和Axes&#xff08;基于Matplotlib&#xff09; &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333; 一、Figure&#xff08;图形&#xff09;&#x1f333;&#x1f341;1. 创建Figure&#x1f341;&#x1f341;2. 添加Axes&am…

【浙大版《C语言程序设计实验与习题指导(第4版)》】实验7-1-6 求一批整数中出现最多的个位数字(附测试点)

定一批整数&#xff0c;分析每个整数的每一位数字&#xff0c;求出现次数最多的个位数字。例如给定3个整数1234、2345、3456&#xff0c;其中出现最多次数的数字是3和4&#xff0c;均出现了3次。 输入格式&#xff1a; 输入在第1行中给出正整数N&#xff08;≤1000&#xff0…

揭秘 LLM 推理:全面解析 LLM 推理性能的关键因素

一、背景介绍 自 OpenAI 一年前发布 ChatGPT 以来&#xff0c;大型语言模型&#xff08;LLM&#xff09;领域经历了前所未有的快速发展。在短短一年时间内&#xff0c;涌现出了数以百计的 LLM 模型&#xff0c;包括开源模型如 LLaMA、Mistral、Yi、Baichuan、Qwen&#xff0c;…

WSL下如何使用Ubuntu本地部署Vits2.3-Extra-v2:中文特化修复版(新手从0开始部署教程)

环境&#xff1a; 硬&#xff1a; 台式电脑 1.cpu:I5 11代以上 2.内存16G以上 3.硬盘固态500G以上 4.显卡N卡8G显存以上 20系2070以上 本案例英伟达4070 12G 5.网络可连github 软&#xff1a; Win10 专业版 19045以上 WSL2 -Ubuntu22.04 1.bert-Vits2.3 Extra-v2:…

Gemini VS GPT-4,当前两大顶级AI模型实测

随着谷歌在AI军备竞赛中急起直追&#xff0c;“有史以来最强大模型”Gemini Advanced终于上线&#xff0c;AI爱好者们总算等来了一款号称能够匹敌GPT-4的大语言模型。 月费19.99美元&#xff08;包含Google One订阅&#xff09;的Gemini Advanced实际表现如何&#xff1f;究竟…

cad基础学习

基础操作与设置 切换工作空间 调整鼠标 界面右击&#xff0c;选项 选项中找到显示&#xff0c;十字光标调到最大 当然也可以输入命令op,回车。它会自动打开这个界面 画一个直线 上面选直接&#xff0c;单击俩个点&#xff0c;画出一个直线。然后空格收尾&#xff0c;这就画出…

disql备份还原

disql备份还原 前言 本文档根据官方文档&#xff0c;进行整理。 一、概述 在 disql 工具中使用 BACKUP 语句你可以备份整个数据库。通常情况下&#xff0c;在数据库实例配置归档后输入以下语句即可备份数据库&#xff1a; BACKUP DATABASE BACKUPSET db_bak_01;语句执行完…

C++多态:定义、实现及原理/继承关系中的虚函数表

目录​​​​​​​ 一、多态的定义及实现 1.1多态的概念​​​​​​​ 1.2多态的构成条件 1.3virtual虚函数 1.4虚函数的重写 二、override和final 三、抽象类 3.1概念 3.2接口继承和实现继承 四、多态的原理 4.1虚函数表 4.2 多态的原理 4.3动态绑定与静态绑定…

蓝桥杯---分小组

9名运动员参加比赛,需要分3组进行预赛. 有哪些分组的方案呢? 我们标记运动员为 A,B,C .... I 下面的程序列出了所有的分组方法。 该程序的正常输出为:

乐观锁,CAS,ABA问题,synchronized锁升级过程

常见的锁策略 乐观锁 vs 悲观锁 乐观锁&#xff1a;乐观锁假设认为数据一般情况下不会产生并发冲突&#xff0c;所以在数据进行提交更新的时候&#xff0c;才会正式对数据是否产生并发冲突进行检测&#xff0c;如果发现并发冲突了&#xff0c;则返回用户错误的信息&#xff0c…

XEX数字货币交易平台:量化交易策略与市场趋势解析

量化交易&#xff0c;一个结合金融市场知识与计算机科学的领域&#xff0c;通过执行一系列复杂的算法策略&#xff0c;自动化地进行交易决策。它的常见策略包括动量交易、对冲策略、算法套利等&#xff0c;旨在通过分析历史数据和市场模式来预测未来趋势&#xff0c;从而实现盈…

【python5】闭包/装饰器,

文章目录 1.闭包和装饰器&#xff1a;函数里return就是闭包2.解析eeprom&#xff1a;如下是二进制文件&#xff0c;C8是一个字节3.json/configparser/optparse&#xff1a;json.dumps&#xff08;将字典转化为字符串&#xff0c;将json信息写进文件&#xff09;&#xff0c;jso…

每日五道java面试题之java基础篇(六)

第一题&#xff1a;Java 创建对象有哪⼏种⽅式&#xff1f; Java 中有以下四种创建对象的⽅式: new 创建新对象通过反射机制采⽤ clone 机制通过序列化机制 前两者都需要显式地调⽤构造⽅法。对于 clone 机制,需要注意浅拷⻉和深拷⻉的区别&#xff0c;对于序列化机制需要明…