基于OpenCV做“三维重建”(3)--相机参数矩阵
通过前面的相机标定,我们能够获得一些参数模型。但是这些相机的参数矩阵到底是什么意思?怎样才能够判断是否正确?误差都会来自哪里?这里就必须要通过具体实验来加深认识。采集带相机参数的图片具有一定难度,幸好我之前有着不错的积累—这里一共有两款数据集,一款来自《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、对于大照片的处理,本身就是一个比较复杂的问题:因为像素比较高,所以处理起来比较慢;而又不能通过压缩之类的方法进行预处理,所以会有比较多的问题。目前还有没有很好解决方法;
此外,你还必须考虑标定的过程中失败的情况;还必须考虑采用什么模式能够让标定的效果最好。
感谢阅读至此,希望有所帮助。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端