自动驾驶-机器人-slam-定位面经和面试知识系列05之常考公式推导(02)

这个博客系列会分为C++ STL-面经、常考公式推导和SLAM面经面试题等三个系列进行更新,基本涵盖了自己秋招历程被问过的面试内容(除了实习和学校项目相关的具体细节)。在知乎和牛客(牛客上某些文章上会附上内推码)也会同步更新,全网同号(lonely-stone或者lonely_stone)。
关于高频面试题和C++ STL面经,每次我会更新10个问题左右,每次更新过多,害怕大家可能看了就只记住其中几个点。(在个人秋招面试过程中,面试到后面,发现除了个人项目和实习经历外,个人所记录的内容基本能涵盖面试官能问到的)
(另外个人才疏学浅,如果所分享知识中出现错误,请大家指出,避免误导其他人)

1. 对极约束+H-E-F

如果求职岗位与定位、SLAM这些相关,那对极约束相关的这三个矩阵肯定是必会的,并且推导流程也是要烂熟于心才行。
在这里插入图片描述

以上是我个人习惯的推导示意,大家可以自己手动推一下,然后最后记下来,这样印象要深刻一些。

其中基础矩阵秩只有2,因此F的自由度为7。它自由度比本质矩阵多的原因是多了两个内参矩阵
下面是单应矩阵:p2 = H * p1
在这里插入图片描述

先说结论,基础矩阵F有7个自由度,本质矩阵E有5个自由度,单应性矩阵H有8个自由度。

  • 本质矩阵E=t^R:6-1=5,尺度等价性。怎么理解这里的尺度等价性?本质矩阵是由对极约束定义的。由于对极约束是等式为零的约束,所以对E乘以任意非零常数后,对极约束依然满足。我们把这件事情称为E在不同尺度下是等价的。此外,本质矩阵E的奇异值是[σ,σ,0]T的形式,这是本质矩阵的内在性质。
  • 单应性矩阵H:9-1=8,单应矩阵Homography,通常我们说它都是说二维平面到二维平面的映射,其实Homography是n维射影空间之间最通常的变换的统称,这类变换的一个特征是在齐次坐标的基础上进行,因此它的维数是(n+1)2,它是最通常的,所以我们能想到自由度就是(n+1)2,而齐次坐标存在尺度模糊,所以要在此基础上减掉1,放在2维空间的话就是(2+1)^2 - 1 = 8。
  • 基础矩阵F:9-2=7,尺度等价性 + 秩为2(不满秩),
    在这里插入图片描述

  其中p是像素点坐标。一般解释F是有7个自由度,是说它有个约束秩为2即行列式为0,所以在单应基础上再减1。

2. 多层优化模式的求导

求导这些也可以推一推写一写,看网上其实关于这些比较细节的还不是很多。下面这个推导过程自己可以多熟悉熟悉,具体的代码实现可以看看ORBSLAM3里面的无imu版本实现。
在这里插入图片描述

3. 坐标转换基础

接下来是在坐标系变换里面很重要也是很基础的部分,自己在刚开始实习或者做项目时,总是对坐标转换有些懵圈,有时候感觉可简单了,有时候又感觉不太对。后来就好好理了一下,发现如下图所示的(用向量的方式理解)方法会特别清楚。在后续关于坐标系和位姿的变换时都比较得心应手。(这些可能对有些人来说比较基础简单,之所以把这些也写了出来,是因为自己当初刚开始的时候会有这些麻烦,所以如果能对一两个人有用也可以)
在这里插入图片描述

4. 手写高斯牛顿迭代优化

如果说上面的两点只是有助于自己基础SLAM能力的话(可能面试中不会问的多),那关于手写高斯牛顿迭代优化的基本很多都会问了。
在这里插入图片描述

#include <iostream>
#include <opencv2/opencv.hpp>
#include <Eigen/Core>
#include <Eigen/Dense>
#include <chrono>using namespace std;
using namespace Eigen;
using namespace cv;int main(int argc, char **argv){double ar = 1.0, br = 2.0, cr = 1.0; // 真实参数结果double ae = 2.0, be = -1.0, ce = 5.0; //初始参数值int N = 100; // 数据点对个数double w_sigma = 1.0; // 噪声sigma值double inv_sigma = 1.0 / w_sigma; cv::RNG rng;      // opencv随机数产生器// step1.产生数据vector<double> x_data, y_data;for(int i = 0; i < N; ++i){double x = i / 100.0;x_data.push_back(x);double y = exp(ar * x * x + br * x + cr) + rng.gaussian(w_sigma);y_data.push_back(y);}// step2.开始Gauss-Newton迭代int iteration = 100;double cost = 0, lastCost = 0;chrono::steady_clock::time_point t1 = chrono::steady_clock::now();for(int iter = 0; iter < iteration; ++iter){Matrix3d H = Matrix3d::Zero();    // H = J^T * W^(-1) * JVector3d b = Vector3d::Zero();    // biascost  = 0;for(int i = 0; i < N; ++i){double xi = x_data[i], yi = y_data[i]; // 第i个数据点double error = yi - exp(ae * xi * xi + be * xi + ce);Vector3d J;J(0) = - xi * xi * exp(ae * xi * xi + be * xi + ce);J(1) = -xi * exp(ae * xi * xi + be * xi + ce);J(2) = - exp(ae * xi * xi + be * xi + ce);H += inv_sigma * inv_sigma * J * J.transpose();b += - inv_sigma * inv_sigma * J * error;cost += error * error;}// 求解线性方程组 Hx = bVector3d dx = H.ldlt().solve(b);if(isnan(dx[0])){cout << "result is nan!" <<endl;break;}if(iter > 0 && cost >= lastCost){cout << "cost:" << cost << ">= last cost" << lastCost << ", break." <<endl;break;}ae += dx[0];be += dx[1];ce += dx[2];lastCost = cost;cout << "total cost:" << cost << ", \t\t update:" << dx.transpose() << "\t\t estimated params:" << ae << " " << be << " " << ce <<endl;}chrono::steady_clock::time_point t2 = chrono::steady_clock::now();chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>(t2-t1);cout << "solve time cost = " << time_used.count() << " seconds." << endl;cout << "estimated abc = " << ae << " " <<  be << " " << ce <<endl;return 0;
}

5. 手写扩展卡尔曼滤波进行参数估计

利用扩展卡尔曼滤波进行参数估计的问题当时被问的还不多,可能是自己更多是做BA的原因。记得是在面试滴滴提前批的时候就被问了这个题,结果不出意料,答得马马虎虎。后续我补全了一下。

问题:估计方程y=ax+b中的a和b参数
解答:在这个例子中,我们创建了一个 KalmanFilter 类,其中 a_ 和 b_ 是我们要估计的参数,p_ 是估计的协方差,processVariance_ 和 measurementVariance_ 是过程噪声和测量噪声的方差。
我们使用了一些模拟数据(可以替换为实际观测数据),并在每个数据点上调用 update 方法来更新我们对参数 a 和 b 的估计。

#include <iostream>
#include <vector>class KalmanFilter {
public:KalmanFilter(double a, double b, double processVariance, double measurementVariance): a_(a), b_(b), p_(1.0), processVariance_(processVariance), measurementVariance_(measurementVariance) {}void update(double x, double y) {// Predictiondouble prediction = a_ * x + b_;double predictionError = y - prediction;// Updatedouble gain = p_ * x / (x * x * p_ + measurementVariance_);a_ += gain * predictionError;b_ += gain * (y - prediction - a_ * x);p_ = (1 - gain * x) * p_ + processVariance_;}double getA() const { return a_; }double getB() const { return b_; }private:double a_, b_, p_;double processVariance_, measurementVariance_;
};int main() {// Simulate some datastd::vector<std::pair<double, double>> data = {{1, 2},{2, 4},{3, 6},{4, 8},// Add more data points as needed};KalmanFilter kf(0, 0, 0.01, 0.1); // Initial guesses for a, b and variancesfor (const auto& point : data) {double x = point.first;double y = point.second;kf.update(x, y);std::cout << "Estimated a: " << kf.getA() << ", Estimated b: " << kf.getB() << std::endl;}return 0;
}

这个题仅做参考,个人水平有限。

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

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

相关文章

Android APP 音视频(03)CameraX预览与MediaCodec编码

说明&#xff1a; 此CameraX预览和编码实操主要针对Android12.0系统。通过CameraX预览获取yuv格式数据&#xff0c;将yuv格式数据通过mediacodec编码输出H264码流&#xff08;使用ffmpeg播放&#xff09;&#xff0c;存储到sd卡上。 1 CameraX 和 MediaCodec简介 1.1 CameraX…

【CN】Argo 持续集成和交付(一)

1.简介 Argo 英 [ˈɑ:ɡəu] 美 [ˈɑrˌɡo] Kubernetes 原生工具&#xff0c;用于运行工作流程、管理集群以及正确执行 GitOps。 Argo 于 2020 年 3 月 26 日被 CNCF 接受为孵化成熟度级别&#xff0c;然后于 2022 年 12 月 6 日转移到毕业成熟度级别。 argoproj.github.i…

基于Xejen框架实现的C# winform鼠标点击器、电脑按键自动点击器的软件开发及介绍

功能演示 文章开始之前&#xff0c;仍然是先来个视频&#xff0c;以便用户知道鼠标连点器的基本功能 软件主界面 多功能鼠标连点器 快速点击&#xff1a; 痕即鼠标点击器可以设定每秒点击次数&#xff0c;让您轻松应对高频点击需求。 切换时长&#xff0c;即每次动作之间的间…

0719_驱动3 printk使用方法

一、printk使用方法 1.应用层打印使用printf&#xff0c;内核层使用printk 2.如何查看内核层中printk如何使用 3.在内核空间执行grep "printk" * -nR 4.在内核空间执行vi -t KERN_INFO 5.printk有8中打印级别&#xff08;0-7&#xff09;&#xff0c;打印级别用来过滤…

数据结构(Java):反射枚举Lambda表达式

目录 1、反射 1.1 反射的定义 1.2 反射机制的原理 1.3 反射相关类 1.4 Class类 1.4.1 相关方法 1.4.1.1 常用获得类相关的方法 ​编辑 1.4.1.2 常用获得类中属性相关的方法 1.4.1.3 获得类中构造器相关的方法 1.4.1.4 获得类中方法相关的方法 1.4.2 获取Class对象 1.…

linux进程——虚拟地址空间——重新认识进程!!!

前言&#xff1a; 本节内容就将进入linux进程里面的又一个大板块&#xff0c; 博主认为这个板块和PCB的板块是平级——两者独立&#xff1b;之前友友们可能认为进程分为PCB和代码与数据。 但是本节过后&#xff0c; 我们可以对进程重新定义——进程 &#xff08;PCB&#xff0…

深入理解计算机系统 CSAPP 家庭作业11.8

回收子进程是书本537页的内容 在tiny.c文件加以下代码,记得重新编译哦 书中提到CGI是在动态内容中的,所以题目的意思应该是在动态内容里面回收 void handler1(int sig) {int olderrno errno;while (waitpid(-1,NULL,0)>0){Sio_puts("Handler reaped child\n");…

【秋招突围】2024届秋招笔试-OPPO笔试题-第一套-三语言题解(Java/Cpp/Python)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新 OPPO 春秋招笔试题**汇总&#xff5e; &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; ✨ 笔试合集传送们 -> &#x1f9f7;春秋招笔试合集 &#x1f380; 01.K小姐的快…

DVWA中命令执行漏洞细说

在攻击中&#xff0c;命令注入是比较常见的方式&#xff0c;今天我们细说在软件开发中如何避免命令执行漏洞 我们通过DVWA中不同的安全等级来细说命令执行漏洞 1、先调整DVWA的安全等级为Lower,调整等级在DVWA Security页面调整 2、在Command Injection页面输入127.0.0.1&…

【计算机网络】物理层(第2章)大纲(共70+页)

最后只复习了1.5天&#xff0c;应用层简单过了一遍。 本来是mindmap的&#xff0c;但是太大了只能导出成提纲了&#xff0c;凑合看吧orz。 如果你找我要源文件&#xff0c;最好是在2024年&#xff0c;不然我可能就找不到了&#xff08;&#xff09;。

C# Task.WaitAll 的用法

目录 简介 1.WaitAll(Task[], Int32, CancellationToken) 2.WaitAll(Task[]) 3.WaitAll(Task[], Int32) 4.WaitAll(Task[], CancellationToken) 5.WaitAll(Task[], TimeSpan) 结束 简介 Task.WaitAll 是 C# 中用于并行编程的一个的方法&#xff0c;它属于 System.Threa…

蓝牙耳机百元之内怎么选?四款百元精品爆款蓝牙耳机盘点

在蓝牙耳机的海洋中&#xff0c;百元价位仿佛是一片神秘的绿洲&#xff0c;既诱人又充满未知&#xff0c;如何在众多选项中挑选出真正的精品呢&#xff1f;蓝牙耳机百元之内怎么选&#xff1f;这是许多消费者的共同疑问&#xff0c;带着这个疑问&#xff0c;作为蓝牙耳机发烧党…

2024101读书笔记|《飞花令·冬》——三冬雪压千年树,四月花繁百尺藤

2024101读书笔记|《飞花令冬》——三冬雪压千年树&#xff0c;四月花繁百尺藤 《飞花令冬&#xff08;中国文化古典诗词品鉴&#xff09;》素心落雪 编著&#xff0c;飞花令得名于唐代诗人韩翃《寒食》中的名句“春城无处不飞花”&#xff0c;类似于行酒令&#xff0c;是文人们…

在Mac上恢复永久删除的Excel文件,有效方法学习!

丢失 Mac 上的重要 Excel 文件可能是一场噩梦&#xff0c;尤其是如果它们被永久删除的话。相信我&#xff0c;这种感觉是没人愿意经历的。但不要惊慌&#xff1b;您可以选择恢复这些文件。无论是通过垃圾箱删除还是由于系统错误意外丢失&#xff0c;都有多种方法可以恢复您的数…

STM32嵌入式人工智能边缘计算应用教程

目录 引言环境准备边缘计算系统基础代码实现&#xff1a;实现嵌入式人工智能边缘计算系统 4.1 数据采集模块 4.2 数据处理与推理模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;边缘计算与优化问题解决方案与优化收尾与总结 1. 引言 嵌入式人工智…

深度学习的前沿主题:GANs、自监督学习和Transformer模型

&#x1f48e; 欢迎大家互三&#xff1a;2的n次方_ &#x1f48e;1. 介绍 深度学习在人工智能领域中占据了重要地位&#xff0c;特别是生成对抗网络&#xff08;GANs&#xff09;、自监督学习和Transformer模型的出现&#xff0c;推动了图像生成、自然语言处理等多个领域的创…

Docker Desktop安装(通俗易懂)

1、官网 https://www.docker.com/products/docker-desktop/ 2、阿里云镜像 docker-toolbox-windows-docker-for-windows安装包下载_开源镜像站-阿里云 1. 双击安装文件勾选选项 意思就是&#xff1a; Use WSL 2 instead of Hyper-V (recommended) : 启用虚拟化&#xff0c;…

2024年【非高危行业生产经营单位主要负责人解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 非高危行业生产经营单位主要负责人及安全管理人员安全生产知识和管理能力考试报名是安全生产模拟考试一点通生成的&#xff0c;非高危行业生产经营单位主要负责人及安全管理人员安全生产知识和管理能力证模拟考试题库…

基于DMASM镜像的DMDSC共享存储集群部署

DMv8镜像模式共享存储集群部署 环境说明 操作系统&#xff1a;centos7.6 服务器&#xff1a;2台虚拟机 达梦数据库版本&#xff1a;达梦V8 安装前准备工作 参考文档《DM8共享存储集群》-第11、12章节 参考文档《DM8_Linux服务脚本使用手册》 1、系统环境(all nodes) 1…

Go-Zero 数据库实战:配置、建模与业务逻辑一体化

前言 在之前的几篇文章中&#xff0c;我们深入学习了Go-Zero框架的实战应用&#xff0c;包括模板定制化、API定义、抽奖算法设计等内容。本文将继续探索Go-Zero框架的实践技巧&#xff0c;并介绍一些与数据库操作相关的主题。 在现代应用程序开发中&#xff0c;对数据库的操作…