通过前面的相机标定,我们能够获得一些参数模型。但是这些相机的参数矩阵到底是什么意思?怎样才能够判断是否正确?误差都会来自哪里?这里就必须要通过具体实验来加深认识。采集带相机参数的图片具有一定难度,幸好我之前有着不错的积累—这里一共有两款数据集,一款来自《OpenCV计算机视觉编程攻略》第3版,家里面好像还有一款微单可以进行采集,这样我们可以进行交叉比对,看一看获得的参数是否符合实际情况:


数据集1 来自《OpenCV计算机视觉编程攻略》第3版
        
数据集2来自家中“国民床单”
既然是做实验,我想初步计划一下。首先是要明确我能够获得那些东西?然后是比较这些东西是否真的像书上说的那样符合实际?然后我会添加一些干扰,看一看在有错误数据的情况,这些东西如何变化?最后是一个小结。
1、明确我能够获得那些东西?
通过前面的代码,我们大概是准备获得这样的东西:
<?xml version="1.0"?>
<opencv_storage>
<Intrinsic type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    1.3589305122261344e+003 0. 5.7505355544729957e+002 
    0. 1.3565816672769690e+003 6.0423226535731465e+002 
    0. 0. 1.
   </data>
</Intrinsic>

<Distortion type_id="opencv-matrix">
  <rows>1</rows>
  <cols>14</cols>
  <dt>d</dt>
  <data>
    9.5113243912423840e+001 1.4262144540955842e+003
    5.2119492051277685e-003 2.8847713358900241e-003
    1.2859720255043484e+002 9.5182218776001392e+001
    1.4741397414456521e+003 6.8332022963370434e+002 0. 0. 0. 0. 0. 0.</data></Distortion>
</opencv_storage>


从结果上看,我将获得这两个矩阵。前面那个是相机内参矩阵,后面那个是外参数。那么在一组图片中,内参肯定是不变的;后面外参肯定是变化的。但是这里也有很多疑问。


那么具体来看结果,对于第一组图片来说,我们获得的结果为:
<?xml version="1.0"?>
<opencv_storage>
<Intrinsic type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    4.0927176647992695e+002 0. 2.3724719115090161e+002 
    0. 4.0870629848642727e+002 1.7128731207874495e+002 
    0. 0. 1.
   </data></Intrinsic>
<Distortion type_id="opencv-matrix">
  <rows>1</rows>
  <cols>14</cols>
  <dt>d</dt>
  <data>
    1.8631118716959048e+001 -5.0639175384902096e+001
    -5.2453807582033300e-003 -9.2620440694993842e-003
    5.2367454865598742e+000 1.9002289932447418e+001
    -4.8948501055979285e+001 -6.5115263545215851e-001 0. 0. 0. 0. 0. 0.</data></Distortion>
</opencv_storage>


<?xml version="1.0"?>
<opencv_storage>
<Intrinsic type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    3.9136489375791234e+003 0. 2.6879080836687035e+003 
    0. 3.9811430968074164e+003 1.9454067884808153e+003 
    0. 0. 1.
  </data></Intrinsic>
<Distortion type_id="opencv-matrix">
  <rows>1</rows>
  <cols>14</cols>
  <dt>d</dt>
  <data>
    2.5259392493942739e-002 -3.2418875955674309e-001
    3.6376246418718853e-004 3.2526045276898190e-003
    -8.1692713459156296e-002 2.5694845194956913e-002
    4.7826938999253371e-001 -1.3315729771950511e+000 0. 0. 0. 0. 0. 0.</data></Distortion>
</opencv_storage>

对于第二组图片来说:

2、这些东西是否真的像书上说的那样符合实际?

对于第一套图片来说,看它的内参矩阵:
<data>
    4.0927176647992695e+002 0. 2.3724719115090161e+002 
    0. 4.0870629848642727e+002 1.7128731207874495e+002 
    0. 0. 1.
</data>


解析一下,fx = fy = 409 ;U0=237  V0 = 171,这个是代码计算值。从实际情况上来看,
标准中间为 268,178,这个和237,171是比较符合的。

对于其它信息


这个焦距和我们计算出来的东西差距较大,如何比对?进一步研究,获得这个相机的参数:

可以获得,它的传感器尺寸为23.5mm X 15.7mm,那么像素宽度分别为0.0438(=23.5/536)和0.044,反过来算焦距为17.9,这个比较接近。

书中给出的资料肯定是自己选择过的,那么我们自己重新采集一套图片来说,那么它的固有参数为:


获得的结果:

  <data>
    3.9136489375791234e+003 0. 2.6879080836687035e+003 
    0. 3.9811430968074164e+003 1.9454067884808153e+003 
    0. 0. 1.
  </data>


翻译一下,fx = 3913.6 fy=3981.1 U0=2687.9 V0=1945.4
先看U V,5456/2 = 2728 3632/2=1816,这样的话,差距在1.5%,这个差距看上去比较大,但是相对值比书中提供的数据要小。
而对于焦距来说,像素宽度分别为0.00425(=23.2/5456)和0.0386
算出来焦距为16.64和16.88,这个和16的差距也是比较合适的。


3、添加一些干扰,容错性如何?

最好的方法,是在有固定相机的情况下,重新采集一套图片,这个对于读者来说,如果有兴趣,可以来做。

4、小结

通过比较,可以发现一下几个特点:
1、书本上采集的图片,其角度范围更为广泛。所以说书上的采集方法对于我们后面做实际采集有指导意义;
2、棋盘的大小和最后是否能够产生良好结果关系不大,所以一个合适大小的棋盘就可以;
此外:
3、特别是对于视野比较广的情况,应该优先想出高效解决方法。我认为视场越大,误差越大;
4、对于大照片的处理,本身就是一个比较复杂的问题:因为像素比较高,所以处理起来比较慢;而又不能通过压缩之类的方法进行预处理,所以会有比较多的问题。目前还有没有很好解决方法;

此外,你还必须考虑标定的过程中失败的情况;还必须考虑采用什么模式能够让标定的效果最好。

感谢阅读至此,希望有所帮助。

基于OpenCV做“三维重建”(3)--相机参数矩阵的更多相关文章

  1. 基于OpenCV做“三维重建”(1)--找到并绘制棋盘

    <OpenCV计算机视觉编程攻略(第3版)>这套书已经出到第3版了,如果你非要我说这本书有多好,我说不出来:只是很多我第一手的例子都是来源于这本书的-相比较OpenCV官方提供的代码,这本 ...

  2. 基于OpenCV做“三维重建”(2)--封装标定过程

    既然已经能够找到了标定点,那么下边的工作就是使用标定结果了.[这本书在这里的内容组织让人莫名其妙]但是通过阅读代码能够很方便地串起来. /*------------------------------ ...

  3. 基于OpenCV做“三维重建”(4)--相机姿态还原和实现三维重建

    v当我们构建成功了viz,就可以使用3维效果给我们提供的便利,进一步进行一些3维的操作. 在这个动画中,注意图片后面的那个黑线,对应的是相机的位置. /*----------------------- ...

  4. 基于OpenCV做“三维重建”(0)-- OpenCV3.2+VIZ6.3.0在vs2012下的编译和使用

    一.问题提出         ViZ对于显示3维的效果图来说,非常有帮助:我在使用OpenCV进行双目测距的过程中,有一些参数希望能够通过可视化的方法显示出来,所以参考了这方面相关的资料.做了一些实验 ...

  5. 学习笔记:使用opencv做双目测距(相机标定+立体匹配+测距).

    最近在做双目测距,觉得有必要记录点东西,所以我的第一篇博客就这么诞生啦~ 双目测距属于立体视觉这一块,我觉得应该有很多人踩过这个坑了,但网上的资料依旧是云里雾里的,要么是理论讲一大堆,最后发现还不知道 ...

  6. 基于 OpenCV 的人脸识别

    基于 OpenCV 的人脸识别 一点背景知识 OpenCV 是一个开源的计算机视觉和机器学习库.它包含成千上万优化过的算法,为各种计算机视觉应用提供了一个通用工具包.根据这个项目的关于页面,OpenC ...

  7. [转载]卡尔曼滤波器及其基于opencv的实现

    卡尔曼滤波器及其基于opencv的实现 源地址:http://hi.baidu.com/superkiki1989/item/029f65013a128cd91ff0461b 这个是维基百科中的链接, ...

  8. 图像矫正-基于opencv实现

    一.引言 上篇文章中四种方法对图像进行倾角矫正都非常有效.Hough变换和Radon相似,其抗干扰能力比较强,但是运算量大,程序执行慢,其改进方法为:我们可以不对整幅图像进行操作,可以在图像中选取一块 ...

  9. 基于Opencv自带BP网络的车标简易识别

    代码地址如下:http://www.demodashi.com/demo/12966.html 记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + 演示效果 1.准备工作 1.1 训练集和测 ...

随机推荐

  1. request之LIstener监听器

    要实现监听request内置对象,必须实现一个接口javax.servlet.ServletRequsetListener. 代码如下: package cn.wangkai.listener; im ...

  2. laravel的日志权限

    命令行脚本运行时报错 UnexpectedValueException  : The stream or file "/Data/PMS/storage/logs/laravel-2019- ...

  3. sqlhelp3

    using System; using System.Collections; using System.Collections.Specialized; using System.Data; usi ...

  4. Delphi 2010 新增功能之: IOUtils 单元(6): TPath(结构体) 的方法与属性

    以后路径相关的处理, 用 IOUtils.TPath 就很方便了. //较常用的方法: TPath.GetTempPath;                  {获取临时文件夹路径} TPath.Ge ...

  5. VisualStudioCode创建的asp.net core控制台程序部署到linux

    1.asp.net core控制台程序 static void Main(string[] args) { ; ) { Console.WriteLine("Hello World!&quo ...

  6. matlab工作空间数据导入simulink

    使用的是其中一种方式: 第一步在工作命令区  ,写命令: 第二步:保证导入simulink区,及from worker设置:  其中注意设置你的采样时间, 第三步设置scop  : 采样时承接数据线上 ...

  7. python pandas库的基本内容

    pandas主要为数据预处理 DataFrame import pandas food_info = pandas.read_csv("路径")  #绝对路径和相对路径都可以 ty ...

  8. linux kettle

    https://blog.csdn.net/zzq900503/article/details/79110810

  9. 10个Python基础练习项目,你可能不会想到练手教程还这么有趣

    美国20世纪最重要的实用主义哲学家约翰·杜威提出一个学习方法,叫做:Learning By Doing,在实践中精进.胡适.陶行知.张伯苓.蒋梦麟等都曾是他的学生,杜威的哲学也影响了蔡元培.晏阳初等人 ...

  10. mac上sed -i 执行失败报错

    比如说我要替换version.txt文件中的version=1.1 为version=1.2,比如test.txt文件内容如下: version=1.1 此时我们会使用sed来替换,如果是涉及比较多的 ...