OpenCV -在水中使用静态图像校准相机



我有一个相机垂直安装在水下的水箱,向下看。在坦克的底部有一个平坦的网格(距离摄像机约2米)。我希望能够在底部放置标记,并使用计算机视觉来知道它们在现实生活中的确切位置。

所以,我需要从像素映射到mm。如果我没弄错的话,cv::calibrateCamera(…)就是这样做的,但它依赖于在相机前面移动一个图案。我只有场景的静态图片,并且相机从未相对于网格移动。因此,我只有一个"单一"的图像来查找参数。我如何使用网格做到这一点?

谢谢。

有趣的问题!"可爱"的部分是对水玻璃界面折射的内在参数的影响,即与空气中相同的镜头相比,增加焦距(或者相反,减少视野)。理论上,你可以在空气中校准,然后校正折射率的差异,但直接在水中校准可能会给你更准确的结果。

知道你们的精度要求吗?你是否验证了你的镜头/传感器组合足以满足它们(有足够的余量)?要回答这个问题,您需要估计(通过从镜头和传感器规格计算,或通过实验使用分辨率图表)您是否可以在图像中解析应用程序所需的最小距离。

从你问题的措辞来看,我认为你只对单一平面上的测量感兴趣。因此,您只需要(a)消除非线性(枪管或针垫)透镜畸变和(b)估计感兴趣的平面和图像之间的单应性。一旦有了后者,就可以通过矩阵乘法直接将未失真的图像坐标转换为世界坐标。此外,如果(如我想象的那样)感兴趣的平面大致平行于图像平面,那么保持整个视野聚焦应该没有任何问题。

当然,为了使所有这些工作如预期的那样,您应该确保罐底在您的应用程序的测量公差范围内是真正平坦的。否则,你实际上是在处理一个3D问题,需要相应地修改你的程序。

实际过程在很大程度上取决于储罐的大小,而您没有明确指出这一点。如果它足够小,可以制造一个棋盘状的可移动校准目标,那就去做吧。你可能想看看另一个答案的建议。下面我将讨论一个更有趣的例子,你的水箱很大,比如游泳池的大小。

我将继续在池底的规则网格中粘贴校准标记。我可能会选择像这样的格子状的标记,也许我自己用一台好的激光打印机在塑料上打印出来,背面有粘合剂(假设你可以永远把它们留在那里)。你应该计划有相当多的,比如,一个8x8或10x10的网格,覆盖尽可能多的视野的相机在其操作位置和姿势。为了帮助排列网格,你可以使用一个合适的风扇角度的激光线投影仪,或者一个激光笔连接到一个旋转的支持。请注意,没有必要将它们固定在一个精确的X-Y网格中(这可能很复杂,取决于池的大小),只需要知道它们相对于任意选择(但固定)的三个网格的位置。换句话说,你可以把它们近似地连接到一个网格的底部,然后尽可能精确地测量三个极端角彼此之间的距离,从而建立一个基本三角形,然后测量所有其他角到三角形顶点的距离,最后用一点三角学来重建它们的真实位置。这基本上是一个测量问题,根据你的精度要求和预算,你可能想要注册一个当地友好的专业测量师(和他们的工具)来尽可能精确地完成它。

一旦你有了你的网格,你可以填充池,拿你的相机,对焦和f-stop镜头根据应用程序的需要。从现在起,你不能再碰焦距和光圈了,否则会受到校准错误的惩罚——曝光只能由曝光时间控制,所以要确保有足够的光线。关闭所有的自动对焦和自动光圈功能,如果有的话。如果相机有一个非刚性的镜头支架(例如DLSR),你将需要某种机械装置来确保镜头-机身对保持刚性。考虑到可用的照明和传感器,f值越近越好,这样就有足够的景深可用。然后拍摄网格的几张照片(~ 10),移动和旋转相机,并且比您预期的操作距离离平面更近和更远。你会想要在一些图像中"看到"网格的一些重要的透视缩短——这是精确校准焦距所必需的。在存储图像时,避免使用JPG和任何其他有损压缩格式-使用无损PNG或TIFF。

一旦您有了图像,您可以手动标记和识别图像中的检查标记。对于像这样的一次性项目,我不会打扰自动识别,只需手动执行(例如在Matlab中,甚至在Photoshop或Gimp中)。为了帮助识别标记,你可以在标记旁边打印一个数字。一旦你有了手动标记,你可以将它们自动细化到亚像素精度,例如使用cv::findCornerSubpix。

你差不多完成了。将所有图像中实际角的"参考"测量位置和观察到的角提供给您最喜欢的相机校准程序,例如cv::calibrateCamera。您使用相机的标称焦距(转换为像素)进行初始估计,并使用零失真。如果一切顺利,您将获得相机的内在参数,您将保留它,以及相机在所有图像中的姿势,您将扔掉。

现在,您可以根据应用程序的需要在最终设置中安装相机,并进一步拍摄网格图像。像以前一样标记和细化角的位置。使用校准返回的畸变参数来消除其图像位置的畸变。最后计算真实标记的参考位置(以米为单位)与其未失真位置之间的单应性,然后完成。

HTH

要校准相机,您确实需要棋盘的多个图像(或这里找到的其他模式之一)。你能做的,是在水外校准相机或做一次校准序列。

一旦你有了这些信息(焦距,镜头中心,失真等)。可以使用solvePNP函数来估计单板的方向。这个估计为您提供了从相机到电路板的距离。

另一种完全不同的选择可能是找到相机使用的镜头类型,然后手动填写数据。我还没有试过,所以我不确定这会有多好。

相关内容

  • 没有找到相关文章

最新更新