SLAM十四讲ch3课后习题

1.验证旋转矩阵是正交矩阵。

2.验证四元数旋转某个点后,结果是一个虚四元数(实部为零),所以仍然对应到一个三维空间点

注意:目前市面上所有的博客都说旋转四元数的逆是共轭除以模的平方 ,这么算很正确但是计算量很大并且复杂化了。我们前面说到,旋转四元数通常是单位四元数。这是因为旋转四元数的定义要求其模长(或长度)为1。这样的要求确保了当四元数用于表示三维空间中的旋转时,不会引入缩放(即保持物体的大小不变)。

前面ch3的博客中的部分截图

      所以,既然我们假设 ( q_r ) 是一个单位四元数,那么它的逆就等于它的共轭。因此,旋转后的四元数仍然是一个虚四元数。

        但如果 ( q_r ) 不是单位四元数,那么它的逆不是简单的共轭,而是共轭除以模的平方。

 

3.假设我有一个大的 Eigen 矩阵,我想把它的左上角 3 × 3 的块取出来,然后赋值为I_3*3。请编程实现此事。

        要在 Eigen 中实现将一个大的矩阵的左上角 3x3 的块赋值为 3x3 单位矩阵I,可以使用 Eigen 提供的块操作功能。下面是一个示例代码:

#include <iostream>
#include <Eigen/Dense>

int main() {
    // 创建一个大小为 5x5 的矩阵
    Eigen::MatrixXd mat = Eigen::MatrixXd::Random(5, 5);

    std::cout << "原始矩阵:" << std::endl;
    std::cout << mat << std::endl;

    // 将左上角 3x3 的子矩阵赋值为单位矩阵
    mat.block<3, 3>(0, 0) = Eigen::Matrix3d::Identity();

    std::cout << "修改后的矩阵:" << std::endl;
    std::cout << mat << std::endl;

    return 0;
}

代码说明:

1.

Eigen::MatrixXd mat = Eigen::MatrixXd::Random(5, 5);

创建一个随机的 5x5 矩阵。

2.

mat.block<3, 3>(0, 0)

使用 block 函数选择矩阵的一个子块。这里的 <3, 3> 表示块的大小,(0, 0) 表示块的起始位置(左上角)。

3.

Eigen::Matrix3d::Identity()

生成一个 3x3 的单位矩阵。

4.将这个单位矩阵赋值给 mat.block<3, 3>(0, 0),即修改原矩阵左上角的 3x3 子矩阵。

4.设有小萝卜一号和小萝卜二号位于世界坐标系中。小萝卜一号的位姿为:q1 = [0.35, 0.2, 0.3, 0.1], t2 = [0.3, 0.1, 0.1]Tq 的第一项为实部。请你把 q 归一化后再进行计算)。这里的 q t 表达的是 Tcw,也就是世界到相机的变换关系。小萝卜二 号的位姿为 q2 = [0.5, 0.4, 0.1, 0.2], t = [0.1, 0.5, 0.3]T。现在,小萝卜一号看到某个点在自身的坐标系下,坐标为 p = [0.5, 0, 0.2]T,求该向量在小萝卜二号坐标系下的坐标。请编程实现此事

所需的知识基础详细请见我之前ch3的博客中1.2中的欧式变换部分:

视觉SLAM ch3—三维空间的刚体运动icon-default.png?t=N7T8https://blog.csdn.net/Johaden/article/details/141023487

解题思路

步骤 1: 归一化四元数 q1

四元数 q1 的归一化可以通过计算其模长并除以模长来完成。

步骤 2: 构建变换矩阵

四元数可以用来表示旋转,而平移向量 t 可以用来表示平移。变换矩阵 T 是一个 4x4 的矩阵,它由四元数对应的旋转矩阵和平移向量构成。具体形式如下:

T=\begin{bmatrix} R & t\\0 & 1 \end{bmatrix}

其中 R 是由四元数转换来的旋转矩阵。

步骤 3: 构建变换矩阵 T12

为了从一个坐标系转换到另一个坐标系,我们可以利用以下等式:

这里 (T1w)^{-1} 表示小萝卜一号坐标系到世界坐标系的变换,而 T2w 表示世界坐标系到小萝卜二号坐标系的变换。

步骤 4: 应用变换 T12 到点 p 上

将点 p 转换成齐次坐标形式 [p_x, p_y, p_z, 1],然后乘以变换矩阵 T12,得到的结果就是点 p 在小萝卜二号坐标系下的坐标。

#include <iostream>
#include <Eigen/Dense>
#include<Eigen/Core>
#include<Eigen/Geometry>

using namespace std;
using namespace Eigen;

int main() {
    // 步骤 1: 归一化四元数 q1
    Quaterniond q1(0.35, 0.2, 0.3, 0.1);
//创建了一个 Quaterniond 类型的对象 q1,它表示一个四元数。四元数的构造函数接受四个参数,按照实部、虚部的顺序传入。在这里,实部为 0.35,虚部依次为 0.2, 0.3, 0.1。
    q1.normalize();  //q1.normalize(); 将 q1 归一化,使得它的模等于 1。

    // 步骤 2: 构建变换矩阵 T1w 和 T2w
    Vector3d t1(0.3, 0.1, 0.1);
    Vector3d t2(-0.1, 0.5, 0.3);  //分别表示小萝卜一号和小萝卜二号的平移向量。

    Matrix4d T1w = Matrix4d::Identity();
    Matrix4d T2w = Matrix4d::Identity();
    T1w.block<3, 3>(0, 0) = q1.toRotationMatrix(); //q1.toRotationMatrix() 将四元数转换为对应的旋转矩阵。
    //T1w.block<3, 3>(0, 0) 选择 T1w 的左上角 3x3 子块,将旋转矩阵赋值给它。
    T1w.block<3, 1>(0, 3) = t1; //T1w.block<3, 1>(0, 3) 选择 T1w 的右上角 3x1 子块,将平移向量 t1 赋值给它。
    T2w.block<3, 3>(0, 0) = Quaterniond(-0.5, 0.4, -0.1, 0.2).toRotationMatrix(); //同样,这里创建了一个新的 Quaterniond 对象来表示小萝卜二号的四元数,并将其转换为旋转矩阵,赋值给 T2w 的左上角 3x3 子块。
    T2w.block<3, 1>(0, 3) = t2;//平移向量 t2 赋值给 T2w 的右上角 3x1 子块。

    // 步骤 3: 构建变换矩阵 T12
    Matrix4d T12 = T2w * T1w.inverse();//T1w.inverse() 计算 T1w 的逆矩阵,表示从相机坐标系到世界坐标系的变换。
    //T2w * T1w.inverse() 计算从小萝卜一号到小萝卜二号坐标系的变换矩阵 T12。

    // 步骤 4: 应用变换 T12 到点 p 上
    Vector3d p(0.5, 0, 0.2);
    Vector4d p_homogeneous(p.x(), p.y(), p.z(), 1.0);//将点 p 转换为齐次坐标形式 p_homogeneous,添加了一个额外的维度,其值为 1。
    Vector4d p_transformed = T12 * p_homogeneous;
    //使用变换矩阵 T12 将点 p 从齐次坐标形式转换到小萝卜二号坐标系下的坐标。

    // 输出结果
    cout << "Transformed point in Robot 2 coordinate system: "
         << p_transformed.head<3>() << endl;//p_transformed.head<3>() 返回前三个元素,即 x, y, z 坐标。

    return 0;
}
之前ch3中的博客截图

        上面的截图表示,即使p_homogeneous(p.x(), p.y(), p.z(), 1.0)中最后那个1.0不写,理论上来说,Eigen库会将三维向量自动拓展为齐次坐标形式。

### 关于《视觉SLAM十四》第七章习题解答与解析 #### SIFT 和 SURF 特征点及其与 ORB 的比较 SIFT (Scale-Invariant Feature Transform) 是一种用于图像处理和计算机视觉领域中的尺度不变特征变换算法。该方法通过检测图像中的关键点并描述这些关键点周围的局部外观来实现对不同视角下的同一物体的有效识别[^2]。 SURF (Speeded-Up Robust Features) 则是在保持了SIFT鲁棒性的基础上提高了计算速度的一种改进版本。它利用积分图快速估计Hessian矩阵行列式的近似值以定位兴趣点,并采用haar小波响应构建方向直方图来进行描述子提取。 ORB (Oriented FAST and Rotated BRIEF) 结合了FAST角点检测器的速度优势以及旋转不变性,同时还引入了多层金字塔结构支持跨尺度匹配。相比于前两者而言,ORB具有更高的效率,在实际应用中更受欢迎;然而其对于光照变化敏感度较高,且在复杂背景下表现可能不如SIFT/SURF稳定。 ```python import cv2 from matplotlib import pyplot as plt def detect_features(image_path, method='orb'): img = cv2.imread(image_path, 0) if method.lower() == 'sift': detector = cv2.SIFT_create() elif method.lower() == 'surf': detector = cv2.xfeatures2d_SURF.create(400) else: detector = cv2.ORB_create() keypoints, descriptors = detector.detectAndCompute(img, None) return keypoints, descriptors kp_sift, des_sift = detect_features('image.jpg', 'sift') plt.figure(figsize=(10, 5)) plt.subplot(121), plt.imshow(cv2.drawKeypoints(gray,kp,None)), plt.title('Original Image'), plt.axis('off') plt.show() ``` #### 相机内参的物理意义及分辨率加倍对其影响 相机内部参数主要包括焦距(focal length),主点坐标(principal point coordinates),像素宽高比(pixel aspect ratio)等几个方面。其中: - **焦距**决定了成像平面距离镜头中心的距离; - **主点位置**(cx,cy)表示投影后的光轴交点位于图像上的具体位置; - **像素尺寸**(dx,dy)反映了传感器上每一个感光单元的实际大小。 当相机分辨率为原来的两倍时(假设为线性增加),即宽度和高度都变为之前的二倍,则新的像素数量将是原来四倍。此时为了维持相同的视场角(field of view),理论上应该调整焦距至原值的一半才能使得拍摄范围不发生变化。但是由于大多数情况下我们希望保留原有的光学特性而不改变硬件配置,因此通常会相应修改fx,fy这两个代表水平/垂直方向有效焦距的比例因子,使其也扩大一倍从而补偿因放大带来的视野缩小效应[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值