我们隔壁村是出名的高科技应用示范村,远近闻名。比如说,在家家户户安装太阳能发电设备,不仅解决了居民供电问题,还把多余的电卖出去,创收。又比如说,最先引进大数据创新应用,以解决农民工就业问题。效果怎么样暂且不说,但是这种向前言看起的精神的就值得学习。话说回来,隔壁村的村主任姓周,名建国。平时去他们村串门,都是周主任喊话。这次周主任听说我修好了我们村口的摄像头,特地找到我,聊了聊他们村的科技引进项目。其中一个重大课题就是解决村里巡逻车的自动测距问题。测什么距离呢?测量房屋建筑距离路边的距离。为什么要测这个距离,其实主要还是为了美丽乡村建设,要有新的气象。周主任问我有没有兴趣接下来。做成了之后,将会把我的大名贴在村口显眼的位置,已告天下。我思考了0.8932秒,果断接下了这个活。我做这个的目的就是为了出名。
双目标定
一、实验条件
二、实验内容
三、实验步骤
四、实验代码及图片
五、实验结果
01实验条件
主要的实验器材都在下面这两幅图中了
主要的实验器材在如下清单中显示
02实验内容
主要的实验内容包括:
1.搭建整个实验平台,观察摄像机拍照情况
2.标定网络摄像机,求取相机参数
3.求取两个相机的位置关系参数
4.构建三维深度图像
5.向周主任汇报
03实验步骤
(3.1)搭建实验平台
首先,我按照某康网络相机拍照的基本流程,搭建了平台。
摄像机采用电源适配器通电,两个摄像机目视平行放置。
数据传输采用1米长网线跟笔记本电脑链接。
根据某康开放的API,自己搭建了一个相机连接采集MFC窗口,窗口具有预览功能。
点击预览按钮,左侧窗口可以实时预览我老家农家小院储物间的内景。
单击抓图按钮,保存图像。由于我在代码里把路径写死了,所以,没有配置路径的窗口。
(3.2)标定相机
标定板的实际尺寸参考如下图所示。实际长度是,每个单元格的长度是2厘米。
(3.2.1)拍摄标定图片
我从拍摄的所有图片中,挑选了20幅作为标定用图。左边相机产生的图如下所示
右边相机标定图如下所示
很明显,左右两个相机的分辨率是不一样的。
(3.2.2)图片预处理
就像我们在前一篇博客种介绍的那样《第三更,单目相机标定实践(完整过程)》,把左右两边的图像都同时缩放到相同的分辨率。
相应的,把待矫正图片也做尺寸缩小处理。
(3.2.3)标定参数求取
具体理论内容可以参考另外两篇博客
《相机参数标定(camera calibration)及标定结果如何使用》
《第二更,相机参数标定基础:从小孔成像开始到单双目标定》
这里只说一说具体的步骤,详细的代码会在第四章贴出来。
这一部分可以参考《第三更,单目相机标定实践(完整过程)》,里面有详细过程。本博客一会把详细代码贴出来。
(a)读取所有标定图
采用cv2.imread(img_path)方法,非常之简单。
(b)寻找角点
寻找角点,采用cv2.drawChessboardCorners(),也是现成的。大家可以看下我的找角点结果,非常完美。
先看左边
再看右边
(c)计算参数矩阵
我们带着问题来看计算过程。
问:为什么需要拍摄那么多图片,一张不行吗?
博主在另外两篇博客当中也提到,根据张征友标定法,只需要求得B矩阵和H矩阵就可以换算出参数矩阵。而B矩阵和H矩阵的求解是通过最大似然估计来优化得到的。详细可参考:
https://www-users.cs.umn.edu/~hspark/CSci5980/zhang.pdf
那么优化过程必然是需要多幅图像共同作用的。在上面的文献中,作者给出了多少图像是合适的,这里不再赘述。
将上面步骤产生的所有角点都组合起来,作为函数输入,可以实现求解:
cv2.calibrateCamera()
返回结果中,就包含内参和畸变参数。
另外,标定的过程,实际上就是一个矩阵关系的转换过程。什么意思呢?
举个例子,根据实际的标定板模样,我在电脑里假定了一个多长多宽的假想标定板图像,而标定的过程就是,所有拍摄到的图像中的标定板,都应该往我假定的标定板靠。如果对不上,那么就有系数上的关系,这个系数上的关系就是我们要标定的参数。
这个理解在程序中也有体现。
(d)求取双相机关系矩阵
根据我们在理论那一章的总结,这一步主要是求取相机之间的关系矩阵,包括,旋转R,平移T,本质矩阵E和基础矩阵F。
cv2.stereoCalibrate()
需要注意的是,里面的最后一个参数flag,当去不同的值,其结果也不一样。这不是本文的重点,可自行上网搜索。
(3.3)矫正及距离求解
在矫正和距离求解的时候,首先对图像做畸变矫正。这个画面很美,无法直视。不过放大了看,该水平的,还是水平了。我想主要是因为两个相机不一样,导致的吧,后续会深入研究一下。
(3.4)求取距离深度图
这里主要用到两个函数
cv2.StereoBM_create().compute()
这个函数主要是用作立体匹配,具体的匹配算法可以参考其他博客,本文主要偏重于实验。
cv2.reprojectImageTo3D()
这个函数主要是根据上面函数产生的匹配差异图,生成3维的深度图。而我们需要的就是Z轴的坐标。先看个效果
我也看不到这是个啥东西。
(3.5)向村支书汇报
看到上面的效果,我陷入了深思。我到底该如何向周主任汇报呢?
首先让我想到的是配一个激光测距仪。
方便实惠。
周主任万一懂技术怎么办?
我再次陷入了沉思。
04实验代码及图片
代码已经上传到了公众号,可以关注下载。
环境的搭建,可以参考另外的博客。我是在tensorflow的环境下跑的。
《深度学习完全攻略!(连载六:CUDA10.1+tensorflow+VS+anaconda3安装)》
博主已经将,所有的图片都上传到了公众号。大家可以下载自己实验研究。
05实验结果
这篇文章偏重于实现,并没有过多的深入研究。而网上很多关于双目标定的文章也大体上差不多,有些比本文做的更详细。
由于本文的实验素材的限制,并不能得到好的结果,但,大致流程是可以用的。如果您有兴趣,可以用自己的图片,直接跑实验即可。
关于标定,到这里就结束了。希望您理解,并知道怎么做了。但是,这里面有很多知识点需要掌握。如果可能,博主会继续考虑更新立体匹配的知识点。
关注获取更多信息