精华内容
下载资源
问答
  • monoSLAM

    千次阅读 2017-03-20 16:51:51
    本质矩阵:essential matrix 基础矩阵:Fundamental matrix 1、基础矩阵的定义和推导过程 注:这里的Pr、Pl代表在两个相机坐标系下的三维坐标。 下面过程将外极线方程中的三维坐标化为成像平面的齐次坐标: ...

    单目相机的优点(和双目相机相比):双目相机测得的深度距离收到基线长度的限制,单目相机就可以解决这个问题。

    参考博客:http://blog.csdn.net/heyijia0327/article/details/50758944  (一定要看,解决了所有疑惑,包括尺度问题,5点法,8点法的由来)

    视觉里程计、SFM、运动估计

    本质矩阵:essential matrix

    基础矩阵:Fundamental matrix

    参考文献:http://www.cnblogs.com/gemstone/archive/2011/12/20/2294805.html

    http://blog.csdn.net/xiao4399/article/details/48037287

    http://sparklinglee.blog.163.com/blog/static/23009012920145183315488/

    https://wenku.baidu.com/view/5b963c00ba1aa8114431d94a.html

    https://en.wikipedia.org/wiki/Essential_matrix


    注意:最后恢复的旋转矩阵是可以确定的,但是恢复的平移矩阵则不一定是正确的,但是和真正的平移矩阵相差一个scale factor

    同理,恢复的三维点也相差一个scale factor。下面是摘自其他作者的原话。

    (1)The scale issue is normal in Mono camera, because for mono camera (or said sfm), the reconstruction matrix can only be back to scale level.


    (2)Visual odometry (also called structure from motion) is the problem of recovering the motion of a camera from the visual input alone.
    This can be done by using single cameras(perspective or omnidirectional), stereo cameras,or multi-camera systems.
    The advantage of using more than one camera is that both the motion and the 3D structure can be computed directly in the absolute scale when the distance between the cameras is known. 
    —— 《Absolute Scale in Structure from Motion from a Single Vehicle Mounted Camera by Exploiting Nonholonomic Constraints》


    (3)It is well known that the shape and motion geometry in SfM problems such as this are subject to arbitrary scaling and that this scale factor cannot be recovered. 
    (The imaging geometry $\beta$ and the rotation are recoverable and not subject to this scaling). 
    —— http://www1.cs.columbia.edu/~jebara/htmlpapers/SFM/node26.html


    1、相机坐标系、图像坐标系、像素坐标系



    相机坐标系:OsXsYsZs

    图像坐标系:O1x1y1

    像素坐标系:与图像坐标系的方向相同;不同的是:

    x方向的单位尺度为像素点的宽度,y方向的单位尺度为像素点的宽度。


    2、相机内参矩阵和外参矩阵

    内参矩阵:

    外参矩阵:包括旋转矩阵和平移矩阵


    3、摄像机矩阵


    4、本质矩阵


    注:这里的Pr、Pl代表在两个相机坐标系下的三维坐标

    下面过程将外极线方程中的三维坐标化为成像平面的齐次坐标:


    注意:pr、pl代表三维点p在左右两个图像坐标系下的齐次坐标。S代表平移向量T的斜对称矩阵(skew symmetric matrix)

     

    5、基础矩阵

    本质矩阵指明了在图像坐标系下左右成像平面对应点的关系。

    但是我们在使用时使用的是像素坐标系(比如在特征检测和匹配都是用像素坐标系),基础矩阵则指明了在像素坐标系下左右成像平面对应点的关系。


    6、本质矩阵和基础矩阵的关系


    7、本质矩阵的性质:

    (1)本质矩阵仅仅由旋转矩阵和平移矩阵确定,与相机的参数无关。

    (2)外极线方程:


    (3)极线与本质矩阵和像素点的对应关系:

    (4)极点与本质矩阵的关系:

    (5)本质矩阵的秩和行列式

    rank(E) = 2

    det(E) = 0

     

    8、基础矩阵性质:

    同本质矩阵一样。


    9、求解基础矩阵、本质矩阵

    本质矩阵5个自由度,可已从两个层面理解:

    (1)旋转矩阵3个、平移矩阵2个(因为平移矩阵乘以一个系数不影响外极线方程的成立)

    (2)体现在数学公式上可以增加如下4个约束,将E的自由度控制在5个:

    (1)det(E)=0

    (2)||E|| = 1(即E乘以一个系数,外极线方程依然成立,可以通过||E||=1限制系数)

    (3)E的一个奇异值为0

    (4)E的另外两个奇异值相等

    基础矩阵的自由度7个:

    (1)det(F) = 0

    (2)||F|| = 1(即F乘以一个系数,外极线方程依然成立,可以通过||F||=1限制系数)

    八点法:

    用八点法求解本质矩阵E的过程可以参考:https://en.wikipedia.org/wiki/Eight-point_algorithm  (the basic algorithm 部分)

    注意:为什么很多文献说最少用8个点?

    这里只考虑E和F的第二个约束,即E和F乘以一个系数,外极线方程依然成立;在求出来之后要做后续处理(近似),使得E和F满足其他的约束条件。

     

    10、本质矩阵求旋转矩阵R和平移矩阵t

    参考:《从本质矩阵恢复运动的方法简单证明》——郁钱

    对本质矩阵E做SVD分解,再根据下面的定理即可得到结果。

    这里S表示平移向量T的斜对成矩阵(skew symmetric matrix)。

    综合定理1.2和推论1.3,可以得出:由本质矩阵即可恢复出2个旋转矩阵和带有一个尺度因子的平移矩阵(如果加上限制条件||T||=1,那么平移矩阵会产生两个)。


    如何从四个R,T的组合中恢找出真正的那个R,T组合?

    把所有特征点的深度计算出来,看深度值是不是都大于0,深度都大于0的那组R,T就是正确的。

     

    11、求解场景点的三维坐标

    参考:http://blog.csdn.net/heyijia0327/article/details/50774104 

    参考:http://sparklinglee.blog.163.com/blog/static/23009012920145183315488/

    注意:如果求出旋转矩阵R和平移矩阵t,并且知道两个图像坐标系中对应点的坐标(x1,y1)和(x2,y2);那么可以根据下面的公式求出对应像点的三维点的坐标。



    12、确定scale的方法

    The absolute scale can then be determined from direct measurements(e.g., measuring the size of an element in the scene),motion constraints,or from the integration with other sensors.

    展开全文
  • monoslam_freakfast-源码

    2021-02-24 02:32:46
    monoslam_freakfast
  • MonoSLAM自动校准 MonoSLAM 自动校准内窥镜相机
  • SLAM和MonoSLAM

    2015-11-18 10:15:36
    原文地址 : SLAM和MonoSLAM MonoSLAM的概念来自于SLAM(wiki),是Robotics中的一种定位算法,全称是Simultaneous Localization and Mapping。 让机器人知道自己在那里(Localization),可以用GPS,但是...

    原文地址 : SLAM和MonoSLAM


    MonoSLAM的概念来自于SLAM(wiki),是Robotics中的一种定位算法,全称是Simultaneous Localization and Mapping。

    让机器人知道自己在那里(Localization),可以用GPS,但是误差有点大(5米左右?),而且还必须在室外。怎么才能让机器人在室内,或者更精确地知道自己的位置呢?SLAM就是一种方法。

    基本的想法是,如果我是一个机器人,我知道两个定点1:(x1,y1)和定点2:(x2,y2),我现在可以看见定点1,测量一下,离它5米,把头向右转过30度角后,可以看见离定点2,测量一下,离它10米。然后解一个三角形,我就知道自己在那里了(Localization),位置准确度和测量精度有关(转角,距离),通常可以控制在很小。

    但是问题又来了,每次我走几步,就得回头看看定点1和定点2,才知道自己在哪里。这一步三回头的走法,真是一件非常二的事情。于是聪明勤劳勇敢的博士生们想出来一个方法,在第一步的时候,一旦我知道自己在哪里,我就添加几个定点:定点3,定点4,定点5……。因为知道自己的坐标,我可以测量出这些新定点离我多远,加上自己的坐标,就知道这些定点在哪里(Mapping)。以后的定位(Localization)就可以用这些新定点。多了这些定点后,以后再走路,哇身边都是定点,腰不酸腿不疼,知道自己在哪里了。

    所以SLAM就是指,同时(Simultaneous)知道自己的位置(Localization)和(And…) 新的定点的位置((feature) Mapping)。因为不管是测量距离,还是计算自己的转角,或记录行走的距离(利用Odometer)都会有noise,而直接计算SLAM,noise会叠加。所以一般SLAM要有一个Kalman Filter的过程。ICRA 10的一篇文章就讨论了为什么需要Filter. (ICRA 10: Why Filter?) .如果对SLAM还有兴趣,可以看看这个Oxford的Summer School

    而MonoSLAM,是Andrew Davison提出来的利用一个摄像头来做SLAM的方法,也叫Real-Time Structure From Motion。在这里,定点变成了visual feature,测量定点的位置转变为match feature, then triangulate. 一个2004年的demo 。当摄像头在空间里忘乎所以地移动时,MonoSLAM都可以利用feature matching,知道摄像头的位置,和那些feature的位置。demo中的右图的黄线,是camera的trajectory。而椭圆表示对于新加的feature的不确定性。paper


    可以看到在demo中,虽然知道摄像头的位置,但是mapping的feature很少很稀疏,这样不好不强大。经过了6年,随着CPU,GPU越来越可怕,人民生活越来越幸福,Andrew Davison这个组终于在CVPR 10搞出了dense live MonoSLAM:利用GPU计算PTAM,然后Mesh成Surfeace。请看demo。有点长,请耐心,最后的小车的激情一跃很精彩。project page

    SLAM和MonoSLAM在网上都有很多现成的code。像MRPT (跨平台),Andrew Davison的SceneLib (Linux),还有C#版本的。

    展开全文
  • monoslam源码matlab SFM-AR-视觉-SLAM 视觉SLAM OKVIS:基于开放关键帧的视觉惯性SLAM RGB-D 视觉 SLAM #####Real-Time Appearance-Based Mapping ...网站上提供了许多演示,其中包含几个 ROS 包 #####视觉SLAM的...
  • EKF_monoSLAM

    2017-09-22 20:27:51
    基于EKF 单目序列SLAM,matlab平台模拟,可用于研究图像追踪 (1-Point RANSAC Inverse Depth EKF-Based Structure from Motion. Matlab code for EKF-Based Structure from Motion / EKF SLAM from a monocular ...
  • Davison's MonoSLAM测试经验

    千次阅读 2015-07-02 11:18:04
    Testing Davison's MonoSLAM 半个月前从Davison的主页上下载了monoSLAM的源码,在ubuntu 6.10(gcc 4.1.2)上编译通过,并运行正常,最近又将它移植到windows平台,主要是考虑以后的兼容使用。其中有一些心得和...

    Testing Davison's MonoSLAM

    半个月前从Davison的主页上下载了monoSLAM的源码,在ubuntu 6.10(gcc 4.1.2)上 编译通过,并运行正常,最近又将它移植到windows平台,主要是考虑以后的兼容使用。其中有一些心得和经验,记录于此。

    1. support usb camera under linux
    Davison的代码只支持1394 camera,在linux下我先为其添加了USB camera支持. 这个工作其实也挺简单,参考 VW34/VWFirewire和 VW34/VWGLOW/Interface/*代码,写了个VWUSBCam接口,其中调用v4l2(2.6 kernel支持)API,这里又参考了spcaview中的代码,再修改一下makefile就行了,也就用了一天时间,麻烦的事情在于makefile的修改,automake生成的东东总是显得过于繁杂,手动修改起来比较烦。
    sequence的工程机理是这样的:底层有一个循环,进行IO操作,不断地读取文件或摄像机数据;一旦得到数据后,发送消息给上层,上层调用响应消息的回调函数,在其中进行数据处理。 这样的循环式操作有一个弊端:CPU占用率一直比较高。特别是读取视频时,没有数据时也会一直在"空转"。不像MS的DirectShow,底层的WDM检测到数据信号时,自动发送消息通知上层,即中断式的操作。不过对于linux下的v4l2编程,目前还没有看到过支持中断方式视频捕获。

    2.port to windows
    移植往往是比较麻烦的工作,linux与windows的平台差异比较大。不过Oxford的VW4是cross platform的,并提供了VC7的project,monoslamglow和scenelib也是完全platform independent,并全用c++实现。这样的工作还是挺好的,我比较喜欢这样的方式,以前写的一些程序也都是这么处理的。
    不过在移植过程中还是有一些问题。我使用的是VC2005,可能是目前最好的 编译器与IDE了,对C++标准支持得很好,毕竟是Lippman领导设计的。这使得monoslam中大量的模板 编译能够顺利通过。
    首先需要 编译glut和glow,是opengl的一些扩展工具,我使用的分别是glut-3.7.6和glow_104, 编译中没有问题。
    其次需要 编译wxWidgets,目前有2.8.3,第一次尝试搞错了一些设计,出了错,便选用了2.6.4,也是一样的问题。后来分析了一下错误,再结合readme,明白了原因:需要设置一些宏,打开或关闭一些选项。顺利通过后也懒得换高版本了,2.6.4够用了。
    现在便可 编译VW34了,直接用其中的VC7 solution,并设置好前面几个库的路径, 编译也可以通过,但在后来 编译MonoSLAMGlow时,却有unresolved link error,显然是找不到库的模块。回头再看 VW34,发现了是因为有一些.cpp文件没有添加进solution,没有 编译进lib,还有就是文件读取的几个template没实例化,手动加上就可以了(虽说简单,但找到错误却不容易,一开始没想到是这些问题~~)。在这里,gcc与vc2005似乎有比较大的差别,gcc似乎不合乎标准。
    最后 编译monoslamglow和scenelib。这两个没有现成的工程,monoslamglow其实就是scenelib中API的简单调用,负责一些界面处理,主要的vSLAM工作在scenelib中完成。直接将这两个模块放到了同一个project中,修改了一些头文件路径和gcc、vc2005的语言差别,最后也能 编译完成,但冒出来很多multiple symbols error,都是来自于 VW34,像是 VW34中已经定义了一些标准C++的库函数,如basic_string, vector之类,细查一下又没有,比较奇怪。google了一下,从VXL(一个比较好的computer vision library, VW34中的VNL便是它的一个模块)的文档中找到了答案:C++ 编译编译选项设置不一致。solution如下:

    Project->Settings->C/C++ Tab->Category: Code Generation->Use run-time library: Multithreaded DLL

    于是 编译就通过了,porting就初步完成了。

    3. fix bugs
    前面完成了移植工作,这只是一部分工作而已。程序在windows上读取Davison提供的test sequence,一会便出错了,而且是比较莫名的错误:基于wxWidget的窗口一重绘便出错。wxWidget的问题?若如此,便很麻烦了,不确定是wxWidget还是opengl或是基于opengl的glut、glow有bug,没精力去研读几十M的代码的~~
    仍然 编译了个debug版本,初步调试了一下,发现只是在窗口重绘时出问题。像一般的界面程序一样,重绘是基于消息的,消息又与回调函数挂钩。在调试中发现调用回调函数的对象指针失效了,这是失败的原因!深入VW32的底层代码,跟踪程序的过程,了解了它的处理方式:从一个带虚函数的EventHandler类派生出窗口子类,再利于EventHandler保存子类的句柄,回调时,由该句柄调用多态调用子类的重绘函数。一切看起来很合理,充分利用了C++的多态性。但EventHandler却在重绘时失效了。不可理解。 好看月前仔细阅读了,了解了C++一些底层的对象模型处理过程,对于虚拟继承内部错综复杂的关系也比较清楚了。很快便想到:基类指针失效应该是由于指针在对象转型时offset调整出了问题。这部分是 编译器的工作,我们无法干预。这便又是gcc与vc2005的一个显著不同!看了一下MonoSLAMGlow类的声明:多重继承!4个类的多重继承!令人生畏的多重继承!其中EventHandler被放在第二个!这些类都有虚函数,很显然,也就会有多个虚函数表,指针调整时也会比较复杂。从理论上来说,EventHandler应该设计成抽象类,并作为公有虚拟基类,这样便不会有上述问题。我采用了一个比较简单的修改方案:将EventHandler设为第一个继承类,因为不是虚拟基类,它的地址便是MonoSLAMGlow的地址(vc2005中是这么处理的),不再需要指针调整,快速、方便而又正确!就是这么一个问题,真是得感谢Lippman,难怪侯捷竭力推荐他的这本书,很有道理。
    紧接着便是第二个错误:运行一会程序会崩溃了。使用debug版本观察了一下,是vector出错了,看似是指针无效。这个错误很难找,整个工程大量使用了vector,无法定位是哪里出了问题。前段时间发现这个问题时,觉得一时难以下手,也正好在忙别的事,就此搁下了。昨晚又拿起来分析了一下,初步判定是monoslamglow中的问题。今天花了一天时间调试,才找到这个问题所在。真是个非常隐晦而又阴暗的错误!当然,也怪我一时疏忽了,话说过来,这种bug若非亲历并尝过艰辛,是不可能想到并很快发现的,虽然我早就知道bug原因和解决方法~~建议使用STL的程序员都好好读读scott meyer的effective stl,唉,其实我已经读过两遍了~~
    这个bug便是vector::erase便得基于vector的所有iterator都失效了!很简单的理由,在effective stl中反复说了好几遍。比如程序中有这样的一段代码:
    for(vector::iterator feat = feature_init_info_vector.begin();
    feat != feature_init_info_vector.end();feat ++)
    {
    if(feat->...){}
    else{
    delete_partially_initialised_feature(feat); // 调用vector::erase
    }
    }
    看似没有问题,delete_partially_initialised_feature erase的是feat的一个副本,feat已经更新了。看过effective stl的人也都会这么说:这是meyer推荐的一个技巧啊,后置++返回旧值。其实不然,erase后,vector内存已经重新分配,以前的iterator都已经失效,因此更新后的feat实际是无效的,在下一次for比较中就会崩溃,错误提示为:incompatible iterator!一个我刚开始始终看不懂的错误。
    修改方法就比较简单了,修改delete_partially_initialised_feature的原型,返回iterator,然后
    feat = delete_partially_initialised_feature(feat)
    即可。
    注:程序中有三处这样的错误,需要一一修改。
    gcc对于这个问题也没有出错。gcc使用的是sgi的stl,不知道底层是如何处理的,按理说不应如此。还可以说明一点的是:Davison(也有可能是其他人)的c++和stl水平不怎么样,不应该犯这样的错误的,嘿嘿!

    update 1 : 2007-04-12
    yet another bug of the same kind : incompatible iterator !
    in Scene_single.cpp, line 301, delete_feature erases an item from feature vector and invalids all the iterators kept previously in the context, so in the next loop, the "incompatible iterator" error will jump out while comparing the iterators !
    solution :
    I subsitude the original prototype of delete_feature below

    bool delete_feature()
    with
    std::vector::iterator delete_feature()

    in fact, the latter conforms to the convention in STL, such as vector::erase, list::erase, etc.

    update 2 : 2007-04-19
    add usb camera support on both linux and windows !
    It's quite interesting to run the demo with real environment.

    4. conclusion
    移植与修改这个程序还是很有意思的,有利于提高自己的程序水平。特别是使我们看到了大师提出的经典与意见是很有用的,经典著作不能不读!
    另外,对于gcc,我也觉得比较有意思,上面发现的一些错误在gcc中完全正常,虽说有些地方不符合标准,但确实好用。还是比较喜欢gcc的。
    写了这么多,觉得可以写封信给Davison了,report bugs to him and ask him to read some classic books on stl :)

    5. forwards
    以后再为monoslam加一个windows上的USB摄像头接口,那就可以做实验了。这倒是比较容易的,对于摄像头采集还是很熟的,今天就到此为止吧。
    我还是比较喜欢在linux下写程序,工具比较丰富,也比较好玩,如emacs,eclipse之类的,只是不如windows中方便,因为vs2005的功能实在太强大了!不过支持开源、支持linux! 发贴者  xuning

    ==========英文原文==========

    Two months ago, I tried Davision's MonoSALM which is very interesting. For research convenience, I successfully ported the project to both linux(ubuntu 6.10 & 7.04, gcc-4.1.2) and windows(WinXP,VS2005) platform with USB camera support. Similar work has been done by Bob Mottram, where he translated the project into c#.


    As some other researchers may be interested in Davison's MonoSLAM, and just like me, want to experience the demo under both windows and linux with USB Camera support. So at here, I took down some of the key tips of my porting experience.

    1.USB camera support
    Davison's original demo only support 1394 camera under linux, but I didn't have one. So first I added USB camera support in order to experience the demo.

    1.1 Under linux -- V4L2 Support
    The following work was done under ubuntu 6.10 & 7.04(gcc-4.1.2), and you many have to change it for some other linux versions.

    Download  v4l2 driver  according to the kernel version and install it properly. Try spacaview(availabel on the same website) to test the USB camera. A list of supported USB camera can be fond  here , which includes almost all the popular USB camera.

    Spcaview is a smart but powerful tool to control the USB camera under linux, and it provides a good encapsulation to V4L2 APIs. I extraced some of the source code and built them into a library(libspcav4l) for easy usage in other applications. My transported project uses this library too.

    The VW34 library used by MonoSLAM provides an abstraction to the manipulation of image source, either from file sequences or video capture device. Its general mechanism looks like this :
    1) A looper runs continuously on the backgournd to read image file or capture video data from the caputre device. Once it gets the image data, it then notify the upper layer(image processing layer) to fetch the data.
    2) The upper layer responds to the notification from the lower loop and process the image data in a callback function registered during the initialization phase.

    One of the drawback of this mechanism is that, the looper runs continuously and takes up a lot of CPU resources. In fact, the approach adopted by windows' WDM driver is much more reasonable and elegant : whenever the video data arrives, WDM notifiles the upper layer to fetch it. That is a interruption approach, not loop approach.

    The related code can be found at VW34/VWGLOW/Interface folder. Refering to VW34/VWFirewire, I added an interface named VWUSBCam, which calls functions in libspcav4l and added VWUSBCam interface to MonoSLAMGlow/monoslamglow*. Now the USB camera works for MonoSLAM!


    1.2 Under Windows -- DirectShow Support
    DShow provides a routine to easily manipulate the usb camera. Same as under linux, I added usb camera support with DShow to VWUSBCam interface.


    2. Poring to Windows
    It's usually troublesome to port a linux application to windows, especially when the application uses many libraries under linux. Fortunately, Oxford's VW34 is designed to be platform independent, and that saved me a lot of time. monoslamglow and scenelib are purely coded with c++, which is also cross-platform.

    STL can be seen everywhere in Davison's MonoSLAM. This is good, for STL is efficient and elegant. But some fatal bugs lurk in the code due to the misusing of STL, for example vector::erase. Scott Meyer's Effective STL is really a good reference to write both effective and robust code with STL.

    As VC6 does not fully support templates, so I chose VS2005 to compile the projects. Some additinal libraries should be prepared first. They are :

    glut-3.7.6 : opengl wraper
    wxWidgets-2.6.4 : wxWidgets support

    Both the two libraries are platform independent and you can get them freely.I compiled and build them into static libraries.

    other libraries used in MonoSLAM :

    glow_104
    scenelib
    vw34

    All the libraries are compiled into static libraries. The compiler may complaint "unresolved link" or some other errors due to the project setting or syntax problem. Just follow these prompts and fix them one by one.
    What I want to mention is that, VW34 wrapps VNL which is part of VXL library, and after successfully compiling of the source code, plenty of "multiple symbols error" prompts may jump out while linking. I checked the VXL's FAQ and found the solution :
    change the project setting in VS2005 as following :
    Project->Settings->C/C++ Tab->Category: Code Generation->Use run-time library: Multithreaded DLL

    Now I have a copy of MonoSLAM runs on windows with USB camera support. Next I fixed some treacherous bugs mainly due to the misusage of STL.

    3. Fix bugs
    Here I listed several most treacherous bugs of MonoSLAM. The amazing thing is that, these bugs keep quiet under linux, due to difference between gcc & vs2005 compiler, as well as the difference between implementations of SGI's and Microsoft's STL.
    But, in my view, they are really bugs, and linux just "hides" them! So I'll list them up and give the solutions respectively.

    3.1. Multiple Inheritance
    The first problem encountered is that, once the main GUI window redrawed, it crashed.
    It is very curisou, and may be cased by the bugs in wxWidget, opengl, glut or glow. And I had on idea of it ~~

    As usual, I debuged the code, and looked deep into the whole mechanism of the paint procedure of monoslamglow. Same as other GUI applications, the mechanism is message driven and call a callback function to redraw the window. After carefully tracking all the variables, I found the handler of the callback object changed during the process which crashed the application!

    The inheritance tree looks like this :

    MonoSLAMGlow
    <-- GlowWindow <-- VWEvents::EventHandler <-- GlowPushButtonReceiver <-- GlowCheckBoxReceiver Multiple inheritance is complicated, especially when vitual inheritance is involved. You can get a idea of how complicate it is from Lippman's  Inside the c++ object model .

    All the four base class has virtual functions. The handler to callback object invalidated when converting to VWEvent::EventHandler polymorphicly. Lippman pointed out that the polymorphism of c++ itself is very complicate which involves adjusting pointer's address and the actual implementation is compiler-dependend.
    I found that the adjusted address of pointer to the derived class had an addrss offset compared to its actual address. So, I adjusted the inheritance order of the base class, that was, put VWEvent::EventHandler at the first place, and the GUI application worked fine!

    3.2. STL's pitfalls : vector::erase
    Scott Meyer pointed out some dark corners of the c++ language and STL's pitfalls in effective stl . And it happened that Davison's MonoSLAM was caught by one of the pitfalls, that was vector::erase !

    After erasing an object from a vector, all the iterators previously pointing to the object in the vector will be invalidate.

    The above rule was emphasized again and again by Meyer. Though simple, yet easy to fall into this pitfall, as MonoSLAM did.

    At first, MonoSLAM crashed for the error "incompatible iterator!" after running for a short while. Curious error, isn't it ? Experience told me that something may be wrong with stl's container, such as vector, map, set, list, etc. But locating the error was rather difficult because stl's container appeared everywhere in the code. After a careful debugging and scrutinizing the code, I found following code :

    for(vector::iterator feat = feature_init_info_vector.begin();
    feat != feature_init_info_vector.end();feat ++)
    {
    if(feat->...){}
    else{
    delete_partially_initialised_feature(feat); // call vector::erase inside
    }
    //...
    }

    similar codes could be found at other places.

    It seemed pretty good from logical sense: go through all the objects in the vector and delete unqualified ones.
    But it was wrong, according to the above rule!

    Once feature_init_info_vector deleted an object, it would reallocate memory and copy the remaining object into new memory. So the feat iterator invalidated after calling delete_partially_initialised_feature, in other words, feat pointed to a old, invalidated memory object, not that in the new allocated feature_init_info_vector! That's why the application complained for "incompatible iterator"!

    The solution is very easy, with Meyer's advice, return a iterator pointing to the new allocated feature_init_info_vector and assign it to feat. Ok, that's done !

    4. Conclusion
    Above is my experience with porting MonoSLAM to windows with USB camera support. Currently, it works well under both linux and windows. There may be some other hidden bugs, I'll fixed them when they emerges.
    展开全文
  • MonoSLAM: Real-Time Single Camera SLAM 對於SLAM一篇經典文 使用單攝影機
  • MonoSLAM: Real-Time Single Camera SLAM 全文总结 Abstract 我们讲述了一个可以通过单目相机恢复快速通过未知场景时的3D轨迹的实时算法。我们把此系统称为MonoSLAM,这是第一个将SFM方法应用到SLAM中的成功应用。...

    本文为博主原创博客,转载请注明出处:https://blog.csdn.net/q_z_r_s

    机器感知
    一个专注于SLAM、三维重建、机器视觉等相关技术文章分享的公众号
    公众号:机器感知

    MonoSLAM: Real-Time Single Camera SLAM 全文总结

    Abstract

    我们讲述了一个可以通过单目相机恢复快速通过未知场景时的3D轨迹的实时算法。我们把此系统称为MonoSLAM,这是第一个将SFM方法应用到SLAM中的成功应用。此方法的核心是,在概率框架下在线创建稀疏但persistent的地图。我们的主要贡献包括主动(active)建图和测量、使用针对相机平滑运动的通用运动模型以及单目特征初始化和特征方位估计的解决方法。总之,这些都是一种非常有效和健壮的算法,可以在标准PC和相机上以30Hz运行。这项工作扩展了机器人系统的范围,其中SLAM可以有效地应用,而且开启了新的领域。我们展示了MonoSLAM在仿人机器人实时3D定位和建图以及手持相机的在线增强现实应用。

    1. INTRODUCTION

    2. RELATED WORK

    2.1 Vision-Based SLAM

    我们工作的一个重点就是简化SLAM对硬件的要求。

    3. METHOD

    3.1 Probabilistic 3D Map

    我们方法的核心概念是基于特征的概率地图,表示当前相机的状态估计及所有感兴趣的特征的快照,还包括这些估计中的不确定性。地图使用状态向量 x ^ \hat{x} x^和协方差矩阵 P P P表示。状态向量 x ^ \hat{x} x^是有相机和特征的状态堆成的, P P P是一个方阵,分别表示如下:
    x ^ = ( x ^ v y ^ 1 y ^ 2 ⋮ ) , P = [ P x x P x y 1 P x y 2 ⋯ P y 1 x P y 1 y 1 P y 1 y 2 ⋯ P y 2 x P y 2 y 1 P y 2 y 2 ⋯ ⋮ ⋮ ⋮ ] (1) \hat{x}=\left(\begin{matrix} \hat{x}_v\\\hat{y}_1\\\hat{y}_2\\\vdots \end{matrix}\right) ,P=\left[\begin{matrix}P_{xx}&P_{xy_1}&P_{xy_2}\cdots\\ P_{y_1x}&P_{y_1y_1}&P_{y_1y_2}\cdots\\ P_{y_2x}&P_{y_2y_1}&P_{y_2y_2}\cdots\\ \vdots&\vdots&\vdots \end{matrix}\right]\tag1 x^=x^vy^1y^2,P=PxxPy1xPy2xPxy1Py1y1Py2y1Pxy2Py1y2Py2y2(1)
    相机状态向量 x v x_v xv由3D位置向量 r W r^W rW,四元数 q R W q^{RW} qRW,速度向量 v W v^W vW以及角速度向量 ω R \omega^R ωR组成,共13个参数:
    x v = ( r W q R W v W ω R ) (2) x_v=\left(\begin{matrix}r^W\\q^{RW}\\v^W\\\omega^R\end{matrix}\right)\tag2 xv=rWqRWvWωR(2)
    本文中,特征状态 y i y_i yi是特征点的3D位置向量。此地图的主要目的是为了能够实时定位,而不作为完整的环境描述,因此我们致力于捕获高质量的稀疏landmarks

    3.2 Natural Visual Landmarks

    使用image patches来作为landmark features,根据相机位置信息,改善匹配性能。使用Shi and Tomasi算子检测角点,这里是用的是灰度图像。对匹配而言,假设每个路标点的图像块像素点都共面——此假设在大多数情况下都可以都可以很好的工作。本文中不更新以作为特征保存的图像模板。

    3.3 System Initialization

    我们选择用一些已知目标放在相机前来对相机进行初始化。

    3.4 Motion Modeling and Prediction

    由于我们并没有任何关于相机运动的先验信息,任何模型都会停止在在某个细节层面,用概率假设表示所建模型和真实模型之间的差异,所以我们选择用常速度,常角速度模型,这并不是说我们认为相机整个过程中是常速运动的,这是针对的是每个time step而言的。

    假设每个time step有未知的加速度 a W a^W aW和角加速度 α W \alpha^W αW噪声,其服从0均值高斯分布,对速度和角速度产生冲击:
    n = ( V W Ω R ) = ( a W Δ t α R Δ t ) (3) n=\left(\begin{matrix}V^W\\\Omega^R\end{matrix}\right) =\left(\begin{matrix}a^W\Delta t\\\alpha^R\Delta t\end{matrix}\right)\tag3 n=(VWΩR)=(aWΔtαRΔt)(3)
    虽然 V W V^W VW Ω R \Omega^R ΩR可能会耦合,但是,现在我们假设 n n n的协方差矩阵是对角阵,这表示它们是不相关的。状态更新如下:

    f v = ( r n e w W q n e w W R V n e w W ω n e w R ) = ( r W + ( v W + V W ) Δ t q W R × q ( ( ω R + Ω R ) Δ t ) v W + V W ω R + Ω R ) (4) f_v=\left(\begin{matrix}r^W_{new}\\q^{WR}_{new}\\V^W_{new}\\\omega^R_{new}\end{matrix}\right)=\left(\begin{matrix}r^W+(v^W+V^W)\Delta t\\q^{WR}\times q((\omega^R+\Omega^R)\Delta t)\\v^W+V^W\\\omega^R+\Omega^R\end{matrix}\right)\tag4 fv=rnewWqnewWRVnewWωnewR=rW+(vW+VW)ΔtqWR×q((ωR+ΩR)Δt)vW+VWωR+ΩR(4)

    其中,姿态使用四元数来表示,四元数又通过角轴 ( ω R + Ω R ) Δ t (\omega^R+\Omega^R)\Delta t (ωR+ΩR)Δt来计算得到。

    在EKF中,相机经过运动方程得到的新的状态估计 f v ( x v , u ) f_v(x_v,u) fv(xv,u)必须伴随着状态不确定性(过程噪声协方差) Q v Q_v Qv的增加。 Q v Q_v Qv通过雅可比计算得到:

    Q v = ∂ f v ∂ n P n ∂ f v T ∂ n (5) Q_v=\frac{\partial f_v}{\partial n}P_n\frac{\partial f_v^T}{\partial n}\tag5 Qv=nfvPnnfvT(5)

    其中, P n P_n Pn是噪声向量的协方差矩阵。运动方程中的不确定性增长速率由 P n P_n Pn决定,它额大小表示我们期望的运动的平滑性。

    3.5 Active Feature Measurement and Map Update

    我们的方法的一个关键部分就是在观测之前,预测每个特征在图像中出现的位置。特征匹配使用NCC进行模板匹配,如果将模板与整幅图像进行匹配,这计算量会很大;预测是一个主动的方法,缩小搜索,提高效率。

    首先,使用相机位姿的状态估计 x v x_v xv、特征位置 y i y_i yi,所以一个点特征相对于相机的位置预计出现在:

    h L R = R R W ( y i W − r W ) (6) h_L^R=R^{RW}(y_i^W-r^W)\tag6 hLR=RRW(yiWrW)(6)

    根据立体几何,特征预计出现在图像中的位置 ( u , v ) (u,v) (u,v),使用标准针孔相机模型:

    h i = ( u v ) = ( u 0 − f k u h L x R h L z R v 0 − f k u h L y R h L z R ) (7) h_i=\left(\begin{matrix}u\\v\end{matrix}\right)=\left(\begin{matrix}u_0-fk_u\frac{h_{L_x}^R}{h_{L_z}^R}\\v_0-fk_u\frac{h_{L_y}^R}{h_{L_z}^R}\end{matrix}\right)\tag7 hi=(uv)=u0fkuhLzRhLxRv0fkuhLzRhLyR(7)

    其中, f k u , f k v , u 0 , v 0 fk_u, fk_v, u_0, v_0 fku,fkv,u0,v0为相机内参。

    在当前的工作中,我们使用的是广角相机,这样就可以同时观测到很多不同视角的特征,它的缺点就是,图像不是透视几何的,例如直线不再是直线。尽管如此,我们在进行特征匹配时使用的还是原始图像,而不是畸变矫正后的图像。值得一提的是,当应用到增强现实的时候,我们使用的是畸变矫正后的图像,因为OpenGL仅支持透视几何相机模型。

    因此,我们使用径向畸变来扭曲透视几何投影坐标 u = ( u , v ) u=(u,v) u=(u,v),来获得最终预测的图像位置 u d = ( u d , v d ) u_d=(u_d,v_d) ud=(ud,vd),所采用的可逆的径向畸变模型如下:
    u d − u 0 = u − u 0 1 + 2 K 1 r 2 v d − v 0 = v − v 0 1 + 2 K 1 r 2 u_d-u_0=\frac{u-u_0}{\sqrt{1+2K_1r^2}}\\ v_d-v_0=\frac{v-v_0}{\sqrt{1+2K_1r^2}} udu0=1+2K1r2 uu0vdv0=1+2K1r2 vv0
    其中, r = ( u − u 0 ) 2 + ( v − v 0 ) 2 r=\sqrt{(u-u_0)^2+(v-v_0)^2} r=(uu0)2+(vv0)2

    分别计算这两步的投影函数对相机和特征的雅可比矩阵,这使得我们可以计算预测特征在图像上的位置的不确定性,用 2 × 2 2\times2 2×2对称协方差矩阵 S i S_i Si表示:
    S i = ∂ u d i ∂ x v P x x ∂ u d i ∂ x v T + ∂ u d i ∂ x v P x y i ∂ u d i ∂ y i T + ∂ u d i ∂ y i P y i x ∂ u d i ∂ x v T + ∂ u d i ∂ y i P y i y i ∂ u d i ∂ y i T + R (8) S_i=\frac{\partial{u_{di}}}{\partial{x_v}}P_{xx}\frac{\partial{u_{di}}}{\partial{x_v}}^T+\frac{\partial{u_{di}}}{\partial{x_v}}P_{xy_i}\frac{\partial{u_{di}}}{\partial{y_i}}^T+\frac{\partial{u_{di}}}{\partial{y_i}}P_{y_ix}\frac{\partial{u_{di}}}{\partial{x_v}}^T+\frac{\partial{u_{di}}}{\partial{y_i}}P_{y_iy_i}\frac{\partial{u_{di}}}{\partial{y_i}}^T+R\tag8 Si=xvudiPxxxvudiT+xvudiPxyiyiudiT+yiudiPyixxvudiT+yiudiPyiyiyiudiT+R(8)
    其中, R R R为观测噪声,与图像分辨率有关。 S i S_i Si允许我们进行主动图像搜索,它表示图像坐标的2D高斯概率密度分布,通过选择一个标准方差阈值,比如 3 σ 3\sigma 3σ来定义一个椭圆搜索窗,特征会在很高的概率下出现在此区域内。

    3.6 Feature Initialization

    单目相机并不能通过特征的观测直接给出特征的位置,因为特征的深度是未知的。估计特征的深度需要相机运动,并从不同的视角观测特征。然而,我们避免在图像中跟踪若干帧的新特征而不试图估计其3D位置的方法,然后用多视几何三角测量来执行minibatch估计初始化特征的深度。

    我们的方法是在地图中初始化一个3D射线,起点为相机的位置,指向特征点。在SLAM地图中表示如下:
    y p i = ( r W h ^ i W ) y_{pi}=\left(\begin{matrix}r^W\\\hat{h}_i^W\end{matrix}\right) ypi=(rWh^iW)
    其中 r i r_i ri是相机位置, h ^ i W \hat{h}_i^W h^iW是描述方向的单位向量。深度假设可以使用粒子滤波来表示。

    在作者后续的论文中可以看到,为了将新的特征点即刻加入到状态向量中,采用了现在应用很多的逆深度方法,这样就可以直接将新观测的到的特征添加到状态更新当中了,而不用等到深度初始完成了才加入。

    3.7 Map Management

    特征提取是使用Shi-Tomasi算子,匹配时使用image patch。在特征提取时,随机选取搜索框,然后在其中寻找特征点,搜索框选取的要求时不能与现有的特征(包括当前帧新提取到的)重叠,因为新产生的一帧图像还不知道上一帧观测到的特征会出现在当前帧的哪个位置,因此这里就是用恒速模型来预测可能出现的位置,这些预测的位置上都不允许再提取特征点。

    3.8 Feature Orientation Estimation

    在初始化特征的时候,用作特征匹配的不是特征描述子,而是image patch,一旦特征初始化完成,那么这个image patch将不再改变,但是这里有一个问题,当相机运动的时候,从不同的视角观测同一个image patch时,会和最初提取到的不一样,最简单的就是旋转了,如果直接计算patch之间的相似度,很可能就认为这两个是不匹配的,所以为了解决旋转不变性的问题,论文中采用了在匹配之前先预测图像可能会被看到的样子,这样就在一定的程度上修正了由于相机运动所造成的视角问题。特征方向估计的变换方程为:
    H = C R [ n T x p I − t n T ] C − 1 (9) H=CR[n^Tx_pI-tn^T]C^{-1}\tag9 H=CR[nTxpItnT]C1(9)
    其中, C C C是相机校正矩阵(透视几何投影), R R R t t t为相机的位姿, n n n是法向量, x p x_p xpimage patch中心在图像上的投影。这个公式没看懂,有懂得大神还请不吝赐教~,或者哪天(估计不会再看了:))我懂了再补上来。

    4. 总结
    • 恒速模型:很有创意
    • 主动搜索:根据恒速模型预测下一时刻的位置,配合搜索区域使用
    • 利用协方差矩阵预测搜索区域,大大加快匹配速度
    • 根据预测的位姿修正模板图像外貌特征
    • 剩下的就是传统的EKF的知识了,predict–>update
    参考文献

    [1] Davison A J , Reid I D , Molton N D , et al. MonoSLAM: Real-Time Single Camera SLAM[J]. IEEE Transactions on Pattern Analysis and Machine Intelligence, 2007, 29(6):1052-1067.

    展开全文
  • monoslam源码matlab SLAM_Resources SLAM 资源的个人页面,以跟进当前的 SLAM 趋势和论文。 灵感来自 还列出了参考页面 我无法创造的东西,我不明白。 ——理查德·费曼 做可能有效的最简单的事情 目录: 算法 初始...
  • 目录说在前面结果编译运行 说在前面 源码:google code ...右键monoSLAM_GUI,属性 创建测试证书,输入密码 选择x86编译 将所有项目的平台目标改为x86 启动 选择Run Simulation 选择AR SLAM好难...
  • MATLAB Implementation of MonoSLAM

    千次阅读 2012-05-25 20:40:09
    MATLAB Implementation of MonoSLAM ENSTA ParisTech - Mobile Robotics Garance Bruneau - Sorya Dubray - Axel Murguet January 16th - February 13th 2012 Version françaiseSlides ...
  • Testing Davison's MonoSLAM

    千次阅读 2012-05-07 10:34:47
    Testing Davison's MonoSLAM 半个月前从Davison的主页上下载了monoSLAM的源码,在ubuntu 6.10(gcc 4.1.2)上编译通过,并运行正常,最近又将它移植到windows平台,主要是考虑以后的兼容使用。其中有一些心得...
  • 【转】SLAM和MonoSLAM

    千次阅读 2014-06-12 17:10:28
    MonoSLAM的概念来自于SLAM(wiki),是Robotics中的一种定位算法,全称是Simultaneous Localization and Mapping。 让机器人知道自己在那里(Localization),可以用GPS,但是误差有点大(5米左右?),而且还...
  • Friday, June 09, 2006 MonoSLAM for Windows I now have a version of ... Davison's MonoSLAM system working on Windows. You can find it here. The translation from C++ to C# took
  • MonoSLAM-2007-Andrew

    2018-11-27 16:21:49
    07年单目slam论文,有需要的拿去,之前自己收集的,。。。
  • SLAM和MonoSLAM-cvchina介绍

    千次阅读 2012-05-07 14:32:36
    MonoSLAM的概念来自于SLAM(wiki),是Robotics中的一种定位算法,全称是Simultaneous Localization and Mapping。 让机器人知道自己在那里(Localization),可以用GPS,但是误差有点大(5米左右?),而且还...
  • 单目视觉SLAM: Monoslam scenelib2 by Davison

    千次阅读 2015-09-07 11:40:36
    scenelib2: Note however that SceneLib is now ... As of 2012, if you are interested in MonoSLAM I would recommendSceneLib2, written by Hanme Kim. This is a great re-implementation, with the same function
  • monoslam:单目SLAM-源码

    2021-06-17 19:11:03
    单反 这是最初由 Andrew Davison 编写的 SceneLib 1.0 的 C# 实现。 它最初创建于 2005/6 年,不再是一个活跃的项目。 识别地标和准确估计自己在空间中的运动的能力传统上是机器人技术中比较困难的问题之一。...
  • 文章极为浅显易懂地介绍了SLAM和MonoSLAM算法的原理,很容易理解。同时它提供了很多相关的资源,入门很有帮助,能够深入了解SLAM的发展。 ---------------------------------   MonoSLAM的概念来自于SLAM(wiki...
  • 单目视觉同步定位与地图创建MonoSLAM----误差累积问题  顾照鹏的论文《基于部分惯性传感器信息的单目视觉同步定位与地图创建方法》提出基于Roll角和Pitch角的MonoSLAM法:  先利用惯性传感器输出的Roll角和Pitch角...
  • MonoSLAM其实只是指SLAM中使用的相机是单目的而已,感觉应该写在PTAM之前作为一种方法可行性探究的展现。没错,它的最主要意义在于证明了只使用单目相机作为唯一输入端也是可以完成tracking与mapping的工作的。 */ ...
  • 基于扩展卡尔曼滤波的单目视觉SLAM,基于ROS-kinetic,使用Gazebo软件仿真,附有键盘控制程序
  • 单目视觉同时定位与建图算法,参考文献Scale Drift-Aware Large Scale Monocular SLAM,上传文件中详细的介绍了如何调试程序,在windows平台下可执行
  • monoslam,scenelib,spcaview

    2015-07-30 17:36:13
    The VW34 library used by MonoSLAM provides an abstraction to the manipulation of image source, either from file sequences or video capture device. The related code can be found at VW34/VWGLOW/...
  • MonoSLAM: Real-Time Single Camera SLAM 这里写目录标题 MonoSLAM: Real-Time Single Camera SLAM 摘要 introduction 相关工作 方法 3.1 三维概率 重点 摘要 背景 解决的问题:在未知的环境中运行的机器人,通过...
  • 1.参考博客 https://blog.csdn.net/xyt723916/article/details/89388188 https://blog.csdn.net/qq_27339501/article/details/109682210 ...感谢以上博客的指点 2.

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 833
精华内容 333
关键字:

monoslam