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

news2024/10/6 4:13:31

哔哩哔哩课程连接:视觉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/visualizeGeometry

2. 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://www.coloradmin.cn/o/1444096.html

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

相关文章

OpenCV-35 查找轮廓

一、 什么是图像轮廓 图像轮廓是具有相同颜色或灰度的连续点的曲线&#xff0c;轮廓在形状分析和物体的检测识别中很有用。 用于图形分析物体的识别和检测 注意点&#xff1a; 为了检测的准确性&#xff0c;需要先对图像进行二值化或Canny操作。画轮廓时会修改输入的图像&a…

fast.ai 深度学习笔记(六)

深度学习 2&#xff1a;第 2 部分第 12 课 原文&#xff1a;medium.com/hiromi_suenaga/deep-learning-2-part-2-lesson-12-215dfbf04a94 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 来自 fast.ai 课程的个人笔记。随着我继续复习课程以“真正”理解它&#xff0c;…

【EAI 016】VIMA: General Robot Manipulation with Multimodal Prompts

论文标题&#xff1a;VIMA: General Robot Manipulation with Multimodal Prompts 论文作者&#xff1a;Yunfan Jiang, Agrim Gupta, Zichen Zhang, Guanzhi Wang, Yongqiang Dou, Yanjun Chen, Li Fei-Fei, Anima Anandkumar, Yuke Zhu, Linxi Fan 作者单位&#xff1a;Stanfo…

什么是ROAS以及它如何衡量广告活动的有效性

有没有想过您的广告活动效果如何&#xff1f;想想 ROAS&#xff0c;即广告支出回报率。ROAS衡量的是每花一美元广告所产生的收入。虽然 ROAS 是一个强大的指标&#xff0c;可以为我们提供丰富的见解&#xff0c;但不应孤立地考虑它。本文将带你了解什么是 ROAS 以及它如何衡量广…

Qt中程序发布及常见问题

1、引言 当我们写好一个程序时通常需要发布给用户使用&#xff0c;那么在Qt中程序又是如何实现发布的呢&#xff0c;这里我就来浅谈一下qt中如何发布程序&#xff0c;以及发布程序时的常见问题。 2、发布过程 2.1、切换为release模式 当我们写qt程序时默认是debug模式&#x…

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏17(附项目源码)

本节最终效果演示 文章目录 本节最终效果演示系列目录前言制作木板UI直接复制和工具一样的即可检查背包是否有指定数量的空插槽 源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇…

解决Typora导出HTML不显示图片

解决Typora导出HTML不显示图片 产生原因 Typora导出HTML不显示图片&#xff0c;可能时图片存放在我们的硬盘中。 我们可以将markdown中的图片转化为base64格式&#xff0c;嵌入到html中。 解决步骤 首先&#xff0c;下载 TyporaToBase64.jar 密码:45jq 其次&#xff0c;将…

【数据库】索引的使用

【数据库】索引的使用 前言出发示例创建表Explain 查看sql执行计划where 查询解析无索引有索引 where oderBy 查询解析无索引有索引 总结 前言 在数据库设计过程中&#xff0c;常需要考虑性能&#xff0c;好的设计可以大大提高sql 语句的增删改查速度。在表的创建过程中&…

flask+python企业产品订单管理系统938re

在设计中采用“自下而上”的思想&#xff0c;在创新型产品提前购模块实现了个人中心、个体管理、发布企业管理、投资企业管理、项目分类管理、产品项目管理、个体投资管理、企业投资管理、个体订单管理、企业订单管理、系统管理等的功能性进行操作。最终&#xff0c;对基本系统…

Linux---网络基础

计算机中的常见概念 协议&#xff08;Protocol&#xff09;&#xff1a; 协议是计算机网络中用于通信的规则和约定的集合。它规定了数据传输的格式、序列、错误检测和纠正方法等。常见的网络协议包括TCP/IP、HTTP、FTP等。 IP地址&#xff08;IP Address&#xff09;&#xf…

Java:JDK8新特性(Stream流)、File类、递归 --黑马笔记

一、JDK8新特性&#xff08;Stream流&#xff09; 接下来我们学习一个全新的知识&#xff0c;叫做Stream流&#xff08;也叫Stream API&#xff09;。它是从JDK8以后才有的一个新特性&#xff0c;是专业用于对集合或者数组进行便捷操作的。有多方便呢&#xff1f;我们用一个案…

Nginx实战:1-安装搭建

目录 前言 一、yum安装 二、编译安装 1.下载安装包 2.解压 3.生成makefile文件 4.编译 5.安装执行 6.执行命令软连接 7.Nginx命令 前言 nginx的安装有两种方式&#xff1a; 1、yum安装&#xff1a;安装快速&#xff0c;但是无法在安装的时候带上想要的第三方包 2、…

Kafka集群安装与部署

集群规划 准备工作 安装 安装包下载&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1BtSiaf1ptLKdJiA36CyxJg?pwd6666 Kafka安装与配置 1、上传并解压安装包 tar -zxvf kafka_2.12-3.3.1.tgz -C /opt/moudle/2、修改解压后的文件名称 mv kafka_2.12-3.3.1/ kafka…

华为数通方向HCIP-DataCom H12-821题库(单选题:461-480)

第461题 以下关于路由策略特点的描述,错误的是哪一项? A、能够修改路由属性,但是不能改变网络流量经过的路径 B、能通过控制路由器的路由表规模,来节约系统资源 C、能通过控制路由的接收、发布和引入,以提高网络的安全性 D、能通过修改路由属性,对网络数据流量可以合理规…

【计算机网络】进程通信

进程 process 客户和服务器进程 下载文件表示为客户 &#xff0c;上载文件的对等方表示为服务器进程与计算机网络之间的接口 套接字 socket 应用层与传输层之间的接口是建立网络应用程序的可编程接口 API进程寻址 为了标识接收进程 需要两种信息 主机的地址目的主机中的接收进程…

【C++】多态语法概念

目录 一、概念及定义二、虚函数重写的特例三、final和override四、抽象类 一、概念及定义 概念&#xff1a;在继承关系下的不同类&#xff0c;调用同一个函数&#xff0c;产生不同的行为&#xff0c;叫作多态。 图示&#xff1a; 定义&#xff1a;必须通过基类的指针或者引…

fast.ai 深度学习笔记(七)

深度学习 2&#xff1a;第 2 部分第 14 课 原文&#xff1a;medium.com/hiromi_suenaga/deep-learning-2-part-2-lesson-14-e0d23c7a0add 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 来自 fast.ai 课程的个人笔记。随着我继续复习课程以“真正”理解它&#xff0c;…

C++对象继承

继承概念&#xff1a; 首先引入一个生活例子&#xff0c;普通人是一个类对象&#xff0c;学生是一个类对象&#xff0c;普通人拥有的属性学生一定会有&#xff0c;学生拥有的属性普通人不一定有。类比一下&#xff0c;把普通人抽象为A对象&#xff0c;学生抽象为B对象&#xf…

多视图特征学习 Multi-view Feature Learning既可以被看作是一种学习框架,也可以被看作是一种具体的学习算法!

Multi-view Feature Learning 1.多视图特征学习Multi-view Feature Learning的基本介绍总结 1.多视图特征学习Multi-view Feature Learning的基本介绍 多视图特征学习是一种利用多视图数据集来进行联合学习的机器学习方法。多视图数据指的是对同一事物从多种不同的途径或角度进…

Python : 使用python实现学生管理系统的功能,详细注释

一、学生管理系统 学生描述&#xff1a;姓名、年龄、成绩 学生管理系统功能&#xff1a;添加学生信息、删除学生信息、根据姓名修改学生信息、根据姓名查询学生信息、显示所有学生信息、退出系统 二、代码说明 1. 将每一个学生的信息放一个元组中&#xff0c;再把元组添加到列表…