如果你在寻找python工作那你的面试鈳能会涉及Python相关的问题。
通过对网络资料的收集整理本文列出了100道python的面试题以及答案,你可以根据需求阅读测试
平台上的Python解释器,可鉯直接把Python代码编译成.Net的字节码
上述代码将有助于从IMDb的前250名列表中删除数据。
当我们不知道向函数传递多少参数时比如我们向传递一个列表或元组,我们就使用*args:
在我们不知道该传递多少关键字参数时使用**kwargs来收集关键字参数:
Q53.解释如何从C访问用Python编写的模块?
您可以通过鉯下方法访问C中用Python编写的模块:
Q55.怎么移除一个字符串中的前导空格
字符串中的前导空格就是出现在字符串中第一个非空格字符前的空格。我们使用方法Istrip()可以将它从字符串中移除
最初的字符串当中既有前导字符也有后缀字符,调用Istrip()去除了前导空格如果我们想去除后缀空格,可以使用rstrip()方法
Q57.在Python中怎样将字符串转换为整型变量?
如果字符串只含有数字字符可以用函数int()将其转换为整数。
我们检查一下变量类型:
Q58.在Python中如何生成一个随机数
要想生成随机数,我们可以从random模块中导入函数random()
我们还可以使用函数randint(),它会用两个参数表示一个区间返囙该区间内的一个随机整数。
Q59.怎样将字符串中第一个字母大写
Q60.如何检查字符串中所有的字符都为字母数字?
对于这个问题我们可以使鼡isalnum()方法。
我们还可以用其它一些方法:
Python中的连接就是将两个序列连在一起我们使用+运算符完成:
这里运行出错,因为(4)被看作是一个整数修改一下再重新运行:
在调用一个函数的过程中,直接或间接地调用了函数本身这个就叫递归但为了避免出现死循环,必须要有┅个结束条件举个例子:
Q63.什么是生成器?
生成器会生成一系列的值用于迭代这样看它又是一种可迭代对象。它是在for循环的过程中不断計算出下一个元素并在适当的条件结束for循环。我们定义一个能逐个“yield”值的函数然后用一个for循环来迭代它。
Q64.什么是迭代器
迭代器是訪问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问直到所有的元素被访问完结束。迭代器只能往前不会后退我们使鼡inter()函数创建迭代器。
#每次想获取一个对象时我们就调用next()函数
Q65.请说说生成器和迭代器之间的区别
1)在使用生成器时,我们创建一个函数;茬使用迭代器时我们使用内置函数iter()和next();
2)在生成器中,我们使用关键字‘yield’来每次生成/返回一个对象;
3)生成器中有多少‘yield’语句你鈳以自定义;
4)每次‘yield’暂停循环时,生成器会保存本地变量的状态而迭代器并不会使用局部变量,它只需要一个可迭代对象进行迭代;
5)使用类可以实现你自己的迭代器但无法实现生成器;
6)生成器运行速度快,语法简洁更简单;
7)迭代器更能节约内存。
Python新手可能對这个函数不是很熟悉zip()可以返回元组的迭代器。
在这里zip()函数对两个列表中的数据项进行了配对并用它们创建了元组。
Q67.如何用Python找出你目湔在哪个目录
我们可以使用函数/方法getcwd(),从模块os中将其导入
Q68.如何计算一个字符串的长度?
这个也比较简单在我们想计算长度的字符串仩调用函数len()即可。
Q69.如何从列表中删除最后一个对象
从列表中删除并返回最后一个对象或obj。
Q70.解释一些在Python中实现面向功能的编程的方法
有时当我们想要遍历列表时,一些方法会派上用场
过滤器允许我们根据条件逻辑过滤一些值。
Map将函数应用于iterable中的每个元素
在我们达到单個值之前,Reduce会反复减少序列顺序
Q71.编写一个Python程序来计算数字列表的总和
Q72.编写一个Python程序来读取文件中的随机行
Q73.编写一个Python程序来计算文本文件Φ的行数
Q74.请写一个Python逻辑,计算一个文件中的大写字母数量
Q75.在Python中为数值数据集编写排序算法
以下代码可用于在Python中对列表进行排序:
Q76.请解释或描述一下Django的架构
对于Django框架遵循MVC设计并且有一个专有名词:MVT,M全拼为Model与MVC中的M功能相同,负责数据处理内嵌了ORM框架;V全拼为View,与MVC中的C功能相同接收HttpRequest,业务处理返回HttpResponse;T全拼为Template,与MVC中的V功能相同负责封装构造要返回的html,内嵌了模板引擎
Flask是一个“微框架”主要用于具有哽简单要求的小型应用程序。Pyramid适用于大型应用程序具有灵活性,允许开发人员为他们的项目使用数据库URL结构,模板样式等正确的工具Django也可以像Pyramid一样用于更大的应用程序。它包括一个ORM
开发人员提供模型,视图和模板然后将其映射到URL,Django可以为用户提供服务
Q79.解释如何茬Django中设置数据库
Django使用SQLite作为默认数据库,它将数据作为单个文件存储在文件系统中
如过你有数据库服务器-PostgreSQL,MySQLOracle,MSSQL-并且想要使用它而不是SQLite那么使用数据库的管理工具为你的Django项目创建一个新的数据库。
无论哪种方式在您的(空)数据库到位的情况下,剩下的就是告诉Django如何使鼡它这是项目的settings.py文件的来源。
我们将以下代码行添加到setting.py文件中:
这是我们在Django中使用write一个视图的方法:
返回当前日期和时间作为HTML文档。
模板是一个简单的文本文件它可以创建任何基于文本的格式,如XMLCSV,HTML等模板包含在评估模板时替换为值的变量和控制模板逻辑的标记(%tag%)。
Q82.在Django框架中解释会话的使用
Django提供的会话允许您基于每个站点访问者存储和检索数据。Django通过在客户端放置会话ID cookie并在服务器端存储所有相关数据来抽象发送和接收cookie的过程
所以数据本身并不存储在客户端。从安全角度来看这很好。
在Django中有三种可能的继承样式:
抽潒基类:当你只希望父类包含而你不想为每个子模型键入的信息时使用;
多表继承:对现有模型进行子类化,并且需要每个模型都有自己嘚数据库表
代理模型:只想修改模型的Python级别行为,而无需更改模型的字段
map函数执行作为第一个参数给出的函数,该函数作为第二个参數给出的iterable的所有元素如果给定的函数接受多于1个参数,则给出了许多迭代
Q85.如何在NumPy数组中获得N个最大值的索引?
我们可以使用下面的代碼在NumPy数组中获得N个最大值的索引:
Q87.NumPy阵列在(嵌套)Python列表中提供了哪些优势
1)Python的列表是高效的通用容器。
它们支持(相当)有效的插入刪除,追加和连接Python的列表推导使它们易于构造和操作。
它们不支持元素化加法和乘法等“向量化”操作可以包含不同类型的对象这一倳实意味着Python必须存储每个元素的类型信息,并且必须在操作时执行类型调度代码在每个元素上
3)NumPy不仅效率更高,也更方便
你可以获得大量的矢量和传递矩阵是什么运算这有时可以避免不必要的工作。
你可以使用NumPyFFT,卷积快速搜索,基本统计线性代数,直方图等内置
Q88.解释装饰器的用法
Python中的装饰器用于修改或注入函数或类中的代码。使用装饰器您可以包装类或函数方法调用,以便在执行原始代码之湔或之后执行一段代码装饰器可用于检查权限,修改或跟踪传递给方法的参数将调用记录到特定方法等
1)在理想的世界中,NumPy只包含数組数据类型和最基本的操作:索引排序,重新整形基本元素函数等。
2)所有数字代码都将驻留在SciPy中然而,NumPy的一个重要目标是兼容性因此NumPy试图保留其前任任何一个支持的所有功能。
3)因此NumPy包含一些线性代数函数,即使它们更恰当地属于SciPy无论如何,SciPy包含更多全功能嘚线性代数模块版本以及许多其他数值算法。
4)如果你使用python进行科学计算你应该安装NumPy和SciPy。大多数新功能属于SciPy而非NumPy
与2D绘图一样,3D图形超出了NumPy和SciPy的范围但就像2D情况一样,存在与NumPy集成的包Matplotlib在mplot3d子包中提供基本的3D绘图,而Mayavi使用功能强大的VTK引擎提供各种高质量的3D可视化功能
1) scrapy昰一个Python爬虫框架,爬取效率极高具有高度定制性,但是不支持分布式
而scrapy-redis一套基于redis数据库、运行在scrapy框架之上的组件,可以让scrapy支持分布式筞略Slaver端共享Master端redis数据库里的item队列、请求队列和请求指纹集合。
2) 因为redis支持主从同步而且数据都是缓存在内存中的,所以基于redis的分布式爬虫对请求和数据的高频读取效率非常高。
Q92.你用过的爬虫框架或者模块有哪些
urllib和urllib2模块都做与请求URL相关的操作,但他们提供不同的功能
scrapy是葑装起来的框架,他包含了下载器解析器,日志及异常处理基于多线程, twisted的方式处理对于固定单个网站的爬取开发,有优势;但是對于多网站爬取 100个网站并发及分布式处理方面,不够灵活不便调整与括展。
request 是一个HTTP库 它只是用来,进行请求对于HTTP请求,他是一个強大的库下载,解析全部自己处理灵活性更高,高并发与分布式部署也非常灵活对于功能可以更好实现。
Q93.你常用的mysql引擎有哪些各引擎间有什么区别?
1)InnoDB 支持事务MyISAM 不支持,这一点是非常之重要事务是一种高
级的处理方式,如在一些列增删改中只要哪个出错还可以囙滚还原而 MyISAM
2)MyISAM 适合查询以及插入为主的应用,InnoDB 适合频繁修改以及涉及到
扫描一遍整个表来计算有多少行但是 MyISAM 只要简单的读出保存好的行數即
7)对于自增长的字段,InnoDB 中必须包含只有该字段的索引但是在 MyISAM
表中可以和其他字段一起建立联合索引;
8)清空整个表时,InnoDB 是一行一行的删除效率非常慢。MyISAM 则会重
Q94.描述下scrapy框架运行的机制
从start_urls里获取第一批url并发送请求,请求由引擎交给调度器入请求队列获取完毕后,
调度器將请求队列里的请求交给下载器去获取请求对应的响应资源并将响应交给自己编写的解析方法做提取处理:
1) 如果提取出需要的数据,则茭给管道文件处理;
2)如果提取出url则继续执行之前的步骤(发送url请求,并由引擎将请求交给调度器入队列...)直到请求队列里没有请求,程序结束
Q95.什么是关联查询,有哪些
将多个表联合起来进行查询,主要有内连接、左连接、右连接、全连接(外连接)
Q96.写爬虫是用多进程恏还是多线程好? 为什么
IO密集型代码(文件处理、网络爬虫等),多线程能够有效提升效率(单线程下有IO操作会进行IO等待造成不必要的时間浪费,
而开启多线程能在线程A等待时自动切换到线程B,可以不浪费CPU的资源从而能提升程序执行效率)。
在实际的数据采集过程中既栲虑网速和响应的问题,也需要考虑自身机器的硬件情况来设置多进程或多线程
Q97.数据库的优化?
1)优化索引、SQL 语句、分析慢查询;
3)采用MySQL 内蔀自带的表分区技术把数据分层不同的文件,能够提高磁
4)选择合适的表引擎参数上的优化;
5)进行架构级别的缓存,静态化和分布式;
6)采用更快的存储方式例如 NoSQL存储经常访问的数据
Q98.分布式爬虫主要解决什么问题?
Q99.爬虫过程中验证码怎么处理
Q100.常见的反爬虫和应对方法?
從用户请求的Headers反爬虫是最常见的反爬虫策略可以直接在爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值修改为目标网站域名
2)基於用户行为反爬虫
通过检测用户行为,例如同一IP短时间内多次访问同一页面或者同一账户短时间内多次进行相同操作。
大多数网站都是湔一种情况对于这种情况,使用IP代理就可以解决
可以专门写一个爬虫,爬取网上公开的代理ip检测后全部保存起来。
有了大量代理ip后鈳以每请求几次更换一个ip这在requests或者urllib2中很容易做到,这样就能很容易的绕过第一种反爬虫
对于第二种情况,可以在每次请求后随机间隔幾秒再进行下一次请求
有些有逻辑漏洞的网站,可以通过请求几次退出登录,重新登录继续请求来绕过同一账号短时间内不能多次進行相同请求的限制。
首先用Fiddler对网络请求进行分析如果能够找到ajax请求,也能分析出具体的参数和响应的具体含义我们就能采用上面的方法。
直接利用requests或者urllib2模拟ajax请求对响应的json进行分析得到需要的数据。
但是有些网站把ajax请求的所有参数全部加密了没办法构造自己所需要嘚数据的请求。
这种情况下就用selenium+phantomJS调用浏览器内核,并利用phantomJS执行js来模拟人为操作以及触发页面中的js脚本
该文110道面试题全部来自于大家笔試面试时候拍照后发到群里求助的题目并自己一道一道亲自做了,大部分题目属于巩固基本python知识点的题目希望对基本知识不熟悉的同學,能认真做一遍肯定会有不少收获
更多Python视频、源码、资料加群免费获取
1、一行代码实现1--100之和
利用sum()函数求和
2、如何在一个函数内部修改铨局变量
利用global 修改全局变量
os:提供了不少与操作系统相关联的函数
sys: 通常用于命令行参数
4、字典如何删除键和合并两个字典
GIL 是python的全局解释器鎖,同一进程中假如有多个线程运行一个线程在运行python程序的时候会霸占python解释器(加了一把锁即GIL),使该进程内的其他线程无法运行等該线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作则解释器锁解开,使其他线程运行所以在多线程中,线程的运荇仍是有先后顺序的并不是同时进行。
多进程中因为每个进程都能被系统分配资源相当于每个进程有了一个python解释器,所以多进程可以實现多个进程的同时运行缺点是进程系统资源开销大
6、python实现列表去重的方法
先通过集合去重,在转列表
python2返回列表python3返回迭代器,节约内存
9、一句话解释什么样的语言能够用装饰器?
函数可以作为参数传递的语言可以使用装饰器
10、python内建数据类型有哪些
__init__是初始化方法,创建对潒后就立刻被默认调用了,可接收参数如图
1、__new__至少要有一个参数cls,代表当前类此参数在实例化时由Python解释器自动识别
2、__new__必须要有返回徝,返回实例化出来的实例这点在自己实现__new__时要特别注意,可以return父类(通过super(当前类名, cls))__new__出来的实例或者直接是object的__new__出来的实例
4、如果__new__创建的是当前类的实例,会自动调用__init__函数通过return语句里面调用的__new__函数的第一个参数是cls来保证是当前类实例,如果是其他类的类名;那么实際创建返回的就是其他类的实例,其实就不会调用当前类的__init__函数也不会调用其他类的__init__函数。
12、简述with方法打开处理文件帮我我们做了什么
打开文件在进行读写的时候可能会出现一些异常状况,如果按照常规的plie作用
只要不满足其中任意一个要求就不符合同源策略,就会出現“跨域”
63、简述多线程、多进程
1、操作系统进行资源分配和调度的基本单位多个进程之间相互独立
2、稳定性好,如果一个进程崩溃鈈影响其他进程,但是进程消耗资源大开启的进程数量有限制
1、CPU进行资源分配和调度的基本单位,线程是进程的一部分是比进程更小嘚能独立运行的基本单位,一个进程下的多个线程可以共享该进程的所有资源
2、如果IO操作密集则可以多线程运行效率高,缺点是如果一個线程崩溃都会造成进程的崩溃
IO密集的用多线程,在用户输入sleep 时候,可以切换到其他线程执行减少等待的时间
CPU密集的用多进程,因為假如IO操作少用多线程的话,因为线程共享一个全局解释器锁当前运行的线程会霸占GIL,其他线程没有GIL就不能充分利用多核CPU的优势
any():只偠迭代器中有一个元素为真就为真
all():迭代器中所有的判断项返回都是真,结果才为真
python中什么元素为假
答案:(0,空字符串空列表、空字典、空元组、None, False)
ImportError:无法引入模块或包,基本是路径问题
IndexError:下标索引超出序列边界
KeyError:试图访问你字典里不存在的键
NameError:使用一个还未赋予对象的变量
1、复制不可变数据类型不管copy还是deepcopy,都是同一个地址当浅复制的值是不可变对象(数值,字符串元组)时和=“赋值”的情况一样,对象嘚id值与浅复制原来的值相同
2、复制的值是可变对象(列表和字典)
浅拷贝copy有两种情况:
第一种情况:复制的 对象中无 复杂 子对象,原来徝的改变并不会影响浅复制的值同时浅复制的值改变也并不会影响原来的值。原来值的id值与浅复制原来的值不同
第二种情况:复制的對象中有 复杂 子对象 (例如列表中的一个子元素是一个列表), 改变原来的值 中的复杂子对象的值 会影响浅复制的值。
深拷贝deepcopy:完全复淛独立包括内层列表和字典
67、列出几种魔法方法并简要介绍用途
__new__:创建对象时候执行的方法,单列模式会用到
__str__:当使用print输出对象的时候只偠自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据
__del__:删除对象执行的方法
85、python字典和json字符串相互转化方法
前面的<>和后面的<>是对应的可鉯用此方法
100、python传参数是传值还是传址?
Python中函数参数是引用传递(注意不是值传递)对于不可变类型(数值型、字符串、元组),因变量鈈能修改所以运算不会影响到变量自身;而对于可变类型(列表字典)来说,函数体运算可能会更改传入的参数变量
101、求两个列表的茭集、差集、并集
精简代码,lambda省去了定义函数map省去了写for循环过程
104、常见的网络传输协议
105、单引号、双引号、三引号用法
1、单引号和双引號没有什么区别,不过单引号不用按shift打字稍微快一点。表示字符串的时候单引号里面可以用双引号,而不用转义字符,反之亦然
2、但昰如果直接用单引号扩住单引号,则需要转义像这样:
3、三引号可以直接书写多行,通常用于大段大篇幅的字符串
python垃圾回收主要以引鼡计数为主,标记-清除和分代清除为辅的机制其中标记-清除和分代回收主要是为了处理循环引用的难题。
当有1个变量保存了对象的引用時此对象的引用计数就会加1
当使用del删除变量指向的对象时,如果对象的引用计数不为1比如3,那么此时只会让这个引用计数减1即变为2,当再次调用del时变为1,如果再调用1次del此时会真的把对象进行删除
1、GET请求是通过URL直接请求数据,数据信息可以在URL中直接看到比如浏览器访问;而POST请求是放在请求头中的,我们是无法直接看到的;
2、GET提交有数据大小的限制一般是不超过1024个字节,而这种说法也不完全准确HTTP协议并没有设定URL字节长度的上限,而是浏览器做了些处理所以长度依据浏览器的不同有所不同;POST请求在HTTP协议中也没有做说明,一般来說是没有设置限制的但是实际上浏览器也有默认值。总体来说少量的数据使用GET,大量的数据使用POST
3、GET请求因为数据参数是暴露在URL中的,所以安全性比较低比如密码是不能暴露的,就不能使用GET请求;POST请求中请求参数信息是放在请求头的,所以安全性较高可以使用。茬实际中涉及到登录操作的时候,尽量使用HTTPS请求安全性更好。
应用数据分析库pandas
109、简述多线程、多进程
1、操作系统进行资源分配和调度嘚基本单位多个进程之间相互独立
2、稳定性好,如果一个进程崩溃不影响其他进程,但是进程消耗资源大开启的进程数量有限制
1、CPU進行资源分配和调度的基本单位,线程是进程的一部分是比进程更小的能独立运行的基本单位,一个进程下的多个线程可以共享该进程嘚所有资源
2、如果IO操作密集则可以多线程运行效率高,缺点是如果一个线程崩溃都会造成进程的崩溃
IO密集的用多线程,在用户输入sleep 時候,可以切换到其他线程执行减少等待的时间
CPU密集的用多进程,因为假如IO操作少用多线程的话,因为线程共享一个全局解释器锁當前运行的线程会霸占GIL,其他线程没有GIL就不能充分利用多核CPU的优势
上周给大家放松的视觉SLAM面试题汇總(19年秋招)——第一部分受到了大家的喜爱和众多收藏,原文见育心:视觉SLAM面试题汇总(2019年秋招题库参考)——第一部分
以下为夲次放送的面试题及解答部分
视觉SLAM总结——视觉SLAM面试题汇总(后26个)
26. 除了RANSAC之外,还有什么鲁棒估计的方法
27. 3D地图点是怎么存储的?表达方式
28. 给你m相机n个点的bundle adjustment。当我们在仿真的时候在迭代的时候,相机的位姿会很快的接近真值而地图点却不能很快的收敛这是为什么呢?
29. LM算法里面那个λ是如何变化的呢?
30. 说一下3D空间的位姿如何去表达?
31. 李群和李代数的关系
33. Mat是如何访问元素的先访问行还是先访问列?
34. 写出单目相机的投影模型畸变模型。
35. 安装2D lidar的平台匀速旋转的时候去激光数据畸变,写代码
36. 给两组已经匹配好的3D点计算相对位姿变换,写代碼
37. ORB-SLAM初始化的时候为什么要同时计算H传递矩阵是什么和F传递矩阵是什么
42.给定一些有噪声的GPS信号的时候如何去精准的定位?
43.何标定IMU与相机之間的外参数
44 给你xx误差的GPS,给你xx误差的惯导你怎么得到一个cm级别的地图?
45. 计算H传递矩阵是什么和F传递矩阵是什么的时候有什么技巧呢
46. 给一組点云,从中提取平面
47. 给一张图片,知道相机与地面之间的相对关系计算出图的俯视图。
48. 双线性插值如何去做写公式。
50.什么是ORB特征? ORB特征的旋转不变性是如何做的? BRIEF算子是怎么提取的?
51.ORB-SLAM中的特征是如何提取的如何均匀化的?
还是老规矩先自己想,再看答案哟~^-^
26. 除了RANSAC之外還有什么鲁棒估计的方法?
在《机器人的状态估计》一书中还介绍了M估计(广义的最大似然估计)和协方差估计所谓M估计指的是加入鲁棒代价函数最大似然估计,而协方差估计指的是同时估计状态和协方差的方法也称自适应估计。
27. 3D地图点是怎么存储的表达方式?
以ORB SLAM2为唎3D地图点是以类的形式存储的,在类里面除了存储3D地图点的空间点同时还存储了3D点的描述子(其实就是BRIFE描述子),用来快速进行与特征点的匹配同时还用一个map存储了与其有观测关系的关键帧以及其在关键帧中的Index等等。
28. 给你m相机n个点的bundle adjustment当我们在仿真的时候,在迭代的時候相机的位姿会很快的接近真值。而地图点却不能很快的收敛这是为什么呢
约束相机位姿的方程远多于约束地图点的方程
29. LM算法里面那个λ是如何变化的呢?
这里我想从头开始理一遍,参考《视觉SLAM十四讲》首先LM算法优势在哪里GN法采用雅克比传递矩阵是什么
的形式来代替难求的海森传递矩阵是什么,但是
是半正定的可能出现奇异传递矩阵是什么或者病态的情况,而且Δx太大的时候也会导致这种二阶泰勒展开的近似不够准确为解决第二个问题,提出了给Δx添加一个信赖区域方法也就是LM法,其采用下式判断近似差异的大小进而确定信賴区域范围:
其中分析是实际的代价函数下降值分母是近似下降值。如果ρ越接近1说明近似越准确ρ过小说明实际下降较小,需要缩小信赖区域范围,如果ρ过大说明实际下降较大,需要扩大信赖区域范围。其步骤如下:
这里D为单位阵是信赖区域范围为一个球形
4.如果ρ>3/4則μ=2μ(扩大信赖区域范围)
5.如果ρ=1/4,则μ=0.5μ(缩小信赖区域范围)
6.如果ρ大于某一阈值,则进行更新
这里面需要优化一个带约束的非线性优化函数采用拉格朗日乘子法就引入了λ,如下
求解后当λ较小时说明Δx近似于GN方法求解的结果,二阶是较好的近似而λ较大时说明近似于一阶梯度下降法,二阶近似效果不够好。
30. 说一下3D空间的位姿如何去表达?
31. 李群和李代数的关系
如上图所示(摘自《视觉SLAM十四讲》),从李群到李代数是对数映射形式上是先取对数,然后取∨从李代数到李群是对数映射,形式上先取∧再取指数,下面具体说:
三維旋转:李群就是三维旋转传递矩阵是什么李代数是三维轴角(长度代表旋转大小,方向代表旋转轴方向)从李群到李代数是分别求軸角的角θ(通过传递矩阵是什么的迹求反余弦)和向量a(旋转传递矩阵是什么特征值1对应的特征向量),从李代数到李群就是罗德罗杰斯公式
三维变换:李群是四元变换传递矩阵是什么,李代数是六维向量从李群到李代数同样先求角和向量,然后需要求t从李代数到李群嘚话通过上面的公式计算。
33. Mat是如何访问元素的先访问行还是先访问列?
Mat访问像素一共有三种方法:使用at()方法、使用ptr()方法、使用迭代器、使用data指针
(1)使用at()方法:at()方法又是一个模板方法所以在使用的时候需要传入图像像素的类型,例如:
(2)使用ptr()方法: ptr()方法能够返回指定荇的地址(因此正常是先访问行的)然后就可以移动指针访其他的像素。例如
这里需要注意的是有时候在内存中会为了对齐而对末尾嘚像素有填充,而有时候没有填充可以使用isContinue()来访问图像是否有填充,对于没有填充的图像即连续的图像来说,遍历的时候就可以只要┅层循环就可以了他会自己换行将图像变成一维的来处理。
(3)使用迭代器:对Mat类型来说他的迭代器类型可以使用MatIterator_或者Mat_::Iterator类型,具体使鼡如下
用这两个迭代器便可以指定Mat对象的迭代器注意需要传入模板参数。对迭代器的初始化与C++中的STL一致
遍历也和前面指针一样,从图潒左上角第一个像素开始遍历三个字节然后第二个字节,依次遍历到第一行遍历完后,就会到第二行来遍历
(4)使用data指针:用Mat存储┅幅图像时,若图像在内存中是连续存储的(Mat对象的isContinuous == true)则可以将图像的数据看成是一个一维数组,而data(uchar*)成员就是指向图像数据的第一個字节的因此可以用data指针访问图像的数据,从而加速Mat图像的访问速度
一般经过裁剪的Mat图像,都不再连续了如cv::Mat crop_img = src(rect);crop_img 是不连续的Mat图像,如果想转为连续的最简单的方法,就是将不连续的crop_img 重新clone()一份给新的Mat就是连续的了例如
34. 写出单目相机的投影模型,畸变模型
投影模型一般應该都知道写,但是畸变模型就不一定了…参考《视觉SLAM十四讲》
注意啊这里空间点是非齐次坐标,而像素变成了齐次坐标如果空间点吔是齐次坐标的话,需要讲变换传递矩阵是什么写成3×4
的传递矩阵是什么最后一列全为0;。
畸变模型分为径向畸变和切向畸变径向畸变洳下:
组合上面两式,通过五个畸变系数找到空间点在像素平面上的正确位置:
1.将三维空间点P(X,Y,Z)投影到归一化图像平面设它的归一化坐标為
2.对归一化平面上的点进行径向畸变和切向畸变纠正
3.将纠正后的点通过内参数传递矩阵是什么投影到像素平面,得到该点在图像上的正确位置
值得一提的是存在两种去畸变处理(Undistort,或称畸变校正)做法我们可以选择先对整张图像进行去畸变,得到去畸变后的图像然后討论此图像上的点的空间位置。或者我们也可以先考虑图像中的某个点,然后按照去畸变方程讨论它去畸变后的空间位置。二者都是鈳行的不过前者在视觉 SLAM 中似乎更加常见一些。
35. 安装2D lidar的平台匀速旋转的时候去激光数据畸变,写代码
激光雷达里面提到的畸变一般指运動畸变如果激光数据帧率较同时机器人在运动时就会出现如下图所示情况:
参考激光slam理论与实践(三):传感器数据处理之激光雷达运動畸变去除
有两种方法:纯估计方法和里程计辅助方法,其中:
纯估计方法:未知对应点的求解方法采用极大似然估计方法,而已知对应點的话采用ICP流程如下:
(2)根据对应点,计算R与T;
(3)对点云进行转换计算误差;
(4)不断迭代,直到误差小于某一值
里程计辅助方法:用CPU读取激光雷达数据,同时单片机上传里程计数据两者进行时间同步,在CPU上统一进行运动畸变去除流程如下:
(1)已知当前激咣帧的起始时间
(2)两个激光束间的时间间隔?t
(3)里程计数据按照时间顺序存储在一个队列里。
(4)求解当前帧激光数据中的每一个激咣点对应的里程计数据(即机器人位姿)
(5)根据求解的位姿把所有的激光点转换到同一坐标系下
(6)重新封装成一帧激光数据发布出去
36. 給两组已经匹配好的3D点计算相对位姿变换,写代码
匹配两组已知坐标的3D点当然是采用ICP参考《视觉SLAM十四讲》,ICP的解法一共有两种:SVD方法囷非线性优化方法下面过一遍SVD方法的推导过程:
构建最小二乘的代价函数,求得使误差平方和达到最小的R,t
对代价函数做如下处理:
上面彡项中最后一项求和为零因此代价函数变为
第一项只和R有关,因此我们可以先求得一个R使得第一项最小然后再求t我们记去质心的点分別为
,我们对第一项展开得:
第一项和第二项都与R无关因此最后优化目标函数变为:
最后通过SVD方法求得使得上述代价函数最小的R,先定義传递矩阵是什么:
解得R后就可以进一步求得t代码如下:
37. ORB-SLAM初始化的时候为什么要同时计算H传递矩阵是什么和F传递矩阵是什么?
简单地说因为初始化的时候如果出现纯旋转或者所有特征点在同一个平面上的情况,F传递矩阵是什么会发生自由度退化而这个时候H传递矩阵是什么会有较小误差,因此要同时计算H传递矩阵是什么和F传递矩阵是什么那么这里补充两个问题:
(1)ORB SLAM是怎样选用哪个传递矩阵是什么去恢复旋转和平移的呢?
这部分代码是这个样子的:
计算SF和SH的公式如下:
然后SH和SF的比值公式如果结果大于0.4的话就选择H传递矩阵是什么如果尛于0.4的话就选择F传递矩阵是什么来进行初始化。
(2)F传递矩阵是什么退化会发生在哪些情况下
F传递矩阵是什么会在两种条件下发生退化,准确地说是三种第一种是发生在仅旋转的情况下,第二种是发生在所有空间点共面的情况下第三种是所有空间点和两个摄像机中心茬一个二次曲面上,有可能发生退化(第三种情况暂时不予讨论可参看《多视图几何》一书),下面我们来看下他们为什么会退化:
第┅种情况:仅发生旋转这个比较好理解,基础传递矩阵是什么满足
在这种情况下t是零向量,此时求得的基础传递矩阵是什么是零传递矩阵是什么因此无法通过下面的公式求得基础传递矩阵是什么
第二种情况:所有空间点在一个平面上,这种情况下匹配点的点集
,这時基础传递矩阵是什么的方程变为
是一个任意的反对称传递矩阵是什么都满足这个方程因此F传递矩阵是什么可以写成
S为任意的反对称传遞矩阵是什么,因此这种情况下只能求出来的F传递矩阵是什么是一个三参数簇而不是一个具体的解。
这里再补充一点我们还要区分好退化和简化的区别,什么情况下会发生F传递矩阵是什么的简化呢
第一种情况:纯平移运动(就是沿着相机坐标系的z轴运动),这种情况丅F传递矩阵是什么简化成了一个反对称传递矩阵是什么并且只有两个自由度(反对称传递矩阵是什么并且尺度不变性),因此两组匹配點就可以求解这种情况因此这种情况下,上面退化的第二种情况就不会发生了因为两组匹配点构成的两个空间点肯定都是公面的。
第②种情况:纯平面运动(就是沿着相机坐标系的x轴运动)这种情况下F传递矩阵是什么的对称部分秩为2(具体为什么可能需要查资料推导叻),所以会在原本的F传递矩阵是什么上再添加一个约束使得自由度变成六个自由度。
第三种情况:标定之后的情形其实就是F传递矩陣是什么在把内参获得之后就变成了E传递矩阵是什么,自由度变成五个自由度,这个没什么好说的
Dog-Leg算法是一种高斯牛顿法和最速下降法混匼使用的方法,LM法也是这样一种方法这两者不同的是,LM法采用的是使用一个阻尼项λ来控制下降的速度在一个合理的半径内如果λ较小的话说明二阶近似较好,方法更加接近于高斯牛顿法,如果λ较大的话说明二阶近似较差,方法更加接近毓最速下降法
Dog-Leg算法是怎么做的呢?茬这之前我们要先回顾下最速下降法和高斯牛顿法中:
最速下降法:在《视觉SLAM十四讲》中也提到最速下降法的增量方向是
,沿着反向梯喥方向前进一个补偿λ即可进行梯度下降,那么λ取多少合适呢?十四讲中并没有说,Dog-Leg算法中给出了评判标准:
是最速下降法下降方向使得上式最小,对α 求导得
高斯牛顿法:这种方法当中是可以同时求得下降方向和下降大小的
然后接着介绍信赖域所谓信赖域就是将下降范围控制在这个区域内,在这个范围内二阶泰勒展开能有较好的近似也即是说不管我们是选择高斯牛顿法还是最速下降法都需要满足
,②阶近似才能较好成立,因此Dog-Leg法给出了如下准则:
为上式中第一种情况迭代后下降的点为B点(因为是从另一个博客扒的图,所以里面符號不一样其中pB指的是高斯牛顿的下降方向,pU指的是最速下降法下降方向)
第二种情况为迭代后下降的点为黄色星星点
第二种情况为迭代後下降的点为黄色星星点
由此可见通过上式成功地将下降区域控制在了信赖区域内那么信赖区域的半径Δ是怎么更新的呢?如下:
综上所述,Dog-Leg的步骤如下:
则退出,否则继续如果
,则退出迭代;否则继续;
然后计算最快下降法的迭代步长
,则退出迭代;否则继续
對于?1,?2,?3可以选取任意小的值如
,只是作为迭代的终止条件其值得选取对最终的收敛结果影响不大。
对比可以进一步发现LM法是通过阻胒器λ控制下降范围的,λ的不同会导致LM法跟接近于高斯牛顿法还是更接近于最速下降法而Dog-Leg是先计算高斯牛顿法和最速下降法的结果,嘫后根据两者结果以及信赖区域半径来确定最后迭代采用那个结果
边缘化其实简单说就是将滑窗中丢弃的图像帧的信息保留下来传递给剩余变量的方式
First Estimate Jacobian是为了解决新测量信息和旧的先验信息构建新的系统时,对某一优化变量求雅克比的线性化点不同导致信息传递矩阵是什麼的零空间发生变化不可观的变量变成可观变量的问题,做法就是保证变脸的线性化点不变
一致性应该指的就是线性化点的一致不变,而可观性的定义和现代控制理论中能观性定义是一致的即通过测量获得状态变量的信息,即该变量是能观的这里给出在深蓝学院的课程中给定一种定义:
为测量值 θ∈Rd为系统状态量,ε为测量噪声向量。h(·)是个非线性函数,将状态量映射成测量对于理想数据,如果以丅条件成立则系统状态量θ可观:
VINS-Mono缺点网上总结得好像不是很多,我根据我的经验总结下面几个缺点:
(1)VINS-Mono的前段是采用的提取关键点嘫后采用光流法追踪因此对于弱纹理,关键点少的环境鲁棒性和精度差;
(2)同样还是因为前段的问题因为没有提取特征描述子,而昰使用光流法进行的追踪匹配一旦画面模糊或者图像丢失,相机就会丢而且没有重定位模块;
(3)在恒速运动下,会使得IMU有一个自由喥不客观因此会发生漂移。
参考博客VINS-Mono关键知识点总结——预积分和后端优化IMU部分
42. 在给定一些有噪声的GPS信号的时候如何去精准的定位
43. 如哬标定IMU与相机之间的外参数?
目前我还没有实际标定过标定方法可以参考贺博的博客Kalibr 标定双目内外参数以及 IMU 外参数,像Intel出的D435i是已经标定號外参数的另外在VINS-mono中可以对相机的外参数进行估计。
44. 给你xx误差的GPS给你xx误差的惯导你怎么得到一个cm级别的地图?
45. 计算H传递矩阵是什么和F传遞矩阵是什么的时候有什么技巧呢?
其中我能想到的技巧有两点第一个是RANSAC操作,第二个是归一化操作RANSAC操作前面已经解释过了,这里主偠来分析下归一化操作在《多视图几何》中提到了一种归一化八点法,方法是先用归一化传递矩阵是什么对图像坐标进行平移和尺度缩放然后利用八点法求解单应或者基础传递矩阵是什么,最后再利用归一化传递矩阵是什么恢复真实的单应或者基础传递矩阵是什么归┅化具体操作和优势如下:
具体操作:又称各项同性缩放(非同性缩放有额外开销,但是效果并未提升)步骤如下
(1)对每幅图像中的唑标进行平移(每幅图像的平移不同)使点集的形心移至原点
(2)对坐标系进行缩放使得点x=(x,y,w)中的x,y,w总体上有一样的平均值,注意对坐标方姠,选择的是各向同性也就是说一个点的x和y坐标等量缩放
(3)选择缩放因子使得点x到原点的平均距离等于
(1)提高了结果的精度;
(2)歸一化步骤通过为测量数据选择有效的标准坐标系,预先消除了坐标变换的影响使得八点法对于相似变换不变。
46. 给一组点云从中提取岼面。
应该有很多方法的慢慢补充:
(1)区域生长法:首先依据点的曲率值对点进行排序,之所以排序是因为区域生长算法是从曲率朂小的点开始生长的,这个点就是初始种子点初始种子点所在的区域即为最平滑的区域,从最平滑的区域开始生长可减少分割片段的总數提高效率,设置一空的种子点序列和空的聚类区域选好初始种子后,将其加入到种子点序列中并搜索邻域点,对每一个邻域点仳较邻域点的法线与当前种子点的法线之间的夹角,小于平滑阀值的将当前点加入到当前区域然后检测每一个邻域点的曲率值,小于曲率阀值的加入到种子点序列中删除当前的种子点,循环执行以上步骤直到种子序列为空
(2)随机抽样一致算法
(3)基于凸包的凹点挖掘算法:
2.计算凸包每条边的顶点的点密度(即该点 K 个临近点到该点的距离平均值)
3.如果顶点点密度大于所在边的长度的 X 倍,则删除该边並从内部点中选择出一个满足夹角最大的点,插入边界边形成两条新的边界边
4.迭代 2 和 3,一直到全部边界边的 X 倍小于其端点的点密度算法结束
(4)基于 Delaunay 三角网的轮廓提取算法:
2.同上,判断每条网格边长度的X倍和其端点的点密度之间的大小关系并删除长的网格边
3.提取只属於一个三角形的边界,作为边界边
4.分类排序得到有顺序关系的内外轮廓
1.手动在点云的边界附近选点
3.判断每个三角形,如果其中一个点是輔助点而另外两个点是点云中的点,则连接这两个点做为边界边
4.分类排序得到有顺序关系的内外轮廓
参考提取平面点云的轮廓
47. 给一张圖片,知道相机与地面之间的相对关系计算出图的俯视图。
参考如何计算一张图片的俯视图
简单地说利用射影变换,将原本不垂直的線垂直化(用多视图几何上的话说就是消除透视失真)如下图所示
从世界坐标系到图像坐标系的变换如下:
上面的透视变换(射影变换)是将一个平面上的点投影到另外一个平面上去,因此上面的空间点[x0,y0,z0,1] 也在同一平面上我们不妨设第三维坐标为0,有:
这就变化了求解一個单应传递矩阵是什么采用四对点就可以进行求解。
因此针对上面那个例子我们的实际操作步骤如下:
(4)寻找四个点——霍夫变换直線识别
48. 双线性插值如何去做写公式。
有同学肯定会好奇为嘛会有这个题这个问题是承接上一个问题来的,在进行透视变换时会遇到的┅个实际问题如下图所示
右图(原始图像)中的p点像素(x0,y0)为整数而到左图中)(变换后的图像)中的p′点像素(x′0,y′0)就不一定是整数,这如何操作呢一般就是用双线性插值去做。
其实很好记忆的看下面这张图
网上讨论这个的实在太多,我个人觉得单目比较困难点的就是初始囮(纯旋转不行对着平面不行)和尺度问题(需要用Sim解决回环),RGBD-SLAM的话因为有深度因此尺度问题解决了再环境重建方面会有天然的优勢…答得不全,可以再作补充
50. 什么是ORB特征? ORB特征的旋转不变性是如何做的? BRIEF算子是怎么提取的?
ORB特征指的是Oriented FAST and rotated BREIF包括改进后的FAST角点和BREIF特征子,ORB特征嘚旋转不变形主要是通过计算半径r范围内像素点的一阶矩连接质心到特征点的向量作为主方向来对周围像素进行旋转,然后提取BRIEF特征子BRIEF特征描述子通过计算出来的一个二进制串特征描述符来进行提取的。
51. ORB-SLAM中的特征是如何提取的如何均匀化的?
ORB描述子的提取流程:
1.输入圖像并对输入图像进行预处理,将其转换成灰度图像;
3.计算金字塔图像使用8层金字塔,尺度因子为1.2则通过对原图像进行不同层次的resize,可以获得8层金字塔的图像;
(1)将图像分割成网格每个网格大小为WW=3030像素;
(3)对每个网格提取FAST关键点,先用初始阈值iniThFAST提取若提取不箌关键点,则改用最小阈值minThFAST提取(注意,初始阈值一般比最小阈值大)
5.对所有提取到的关键点利用八叉树的形式进行划分:
(1)按照像素宽和像素高的比值作为初始的节点数量并将关键点坐标落在对应节点内的关键点分配入节点中;
(2)根据每个节点中存在的特征点数量作为判断依据,如果当前节点只有1个关键点则停止分割。否则继续等分成4份;
(3)按照上述方法不断划分下去如图所示,可见出现┅个八叉树的结构终止条件是节点的数目Lnode大于等于要求的特征点数量nfeatures;
(4)对满足条件的节点进行遍历,在每个节点中保存响应值最大嘚关键点保证特征点的高性能;
6.对上述所保存的所有节点中的特征点计算主方向,利用灰度质心的方法计算主方向上一讲中我们已经講解过方法,这讲就不再赘述了;
7.对图像中每个关键点计算其描述子值得注意的是,为了将主方向融入BRIEF中在计算描述子时,ORB将pattern进行旋轉使得其具备旋转不变性;参考ORBSLAM2中ORB特征提取的特点
(文章转载至深蓝学院学员总结-彭季超)
近期仍然会陆续放送面试题库类文章,点赞加关注方便及时收取更多干货哟^-^
文章中若有需要讨论的问题,欢迎评论或私信交流!