使用标准的OpenCV可以校准鱼眼相机吗?

3
我尝试使用超广角镜头 > 180 度进行相机校准。我使用 OpenCV 3.2 和来自 opencv/samples/cpp/tutorial_code/calib3d/camera_calibration 的相机校准代码,结果得到的图像类似于 this one 中的图像,该图像来源于 this post。我在 youtube.com 上找到了许多人展示如何校准鱼眼相机的视频,例如 this video

我知道超广角镜头相机的校准可能会很棘手。我还发现,在 openCV contrib 中有另一种非标准的鱼眼相机校准模型。

是否可以使用标准 OpenCV 的相机校准模型来校准这样广角的相机,或者我应该使用另一个模型,例如 openCV contrib 中的模型?

3个回答

7
我在几周前也遇到了同样的问题,发现标准模型不能处理我的鱼眼图像( >180 FOV)。然而我在 Github 上找到了一个 pull request,专门解决了这个问题 - https://github.com/opencv/opencv/pull/6801
最终我放弃了标准模型,改用全景模型 - http://docs.opencv.org/trunk/dd/d12/tutorial_omnidir_calib_main.html,效果非常好。
另外提一下,当我研究畸变校正主题时,我发现存在一种常见误解,即由鱼眼镜头产生的鱼眼图像是“畸变”的。事实上,它们可能被畸变了,但产生的图像仅仅是一种投影。就像其他投影一样,鱼眼是将三维世界映射到二维平面的众多方法之一。不利的是,大部分相关文献都称之为“畸变”。鱼眼镜头被有意地设计成可以产生弯曲线条的图像,而标准(即矩形)镜头则会使这些线条变得平直。而“畸变”这个词仅用于负面影响标准(即矩形)镜头的几何像差。
在我这种情况下,尽管我正在研究畸变校正,但最终我并没有对任何畸变进行校正,而只是简单地进行了鱼眼到透视投影 - 你可以在这里找到更多信息:http://paulbourke.net/dome/fish2/ 此外,在拍摄棋盘图像方面,请遵循以下建议 - How to verify the correctness of calibration of a webcam?

@trojek 我没有尝试自己合并拉取请求,但据我所知,您需要重新编译OpenCV源代码,而不仅仅是camera_calibration.cpp(如果我错了,请纠正我)。如果您检查“文件更改”部分-https://github.com/opencv/opencv/pull/6801/files,您将看到拉取请求更改的两个文件是`fisheye.cpp`和`fisheye.hpp`。让我们知道您的进展如何。 - Jack Gold
我改了拉取请求中的这两个文件,但是它们没有起作用。我认为我应该构建OpenCV。 - trojek
是的,请尝试使用在拉取请求中更改的文件从源代码构建OpenCV,并查看是否有效。我还建议使用contrib库构建OpenCV。我很想知道这是否有效,请随时向我们报告。 - Jack Gold
我尝试在更改拉取请求文件后构建OpenCV,但是出现了错误。我决定使用omni_calibration模块。我校准了相机,但是卡在了去畸变图像上。我找到了函数'omnidir :: undistortImage(distorted,undistorted,K,D,_xi,int flags,Knew,imageSize)',但是在文档中找不到参数的解释。您有可以去畸变图像并保存它的代码吗? - trojek
我有点困惑。为了校准图像,我需要什么?我的相机参数文件有几百行。我需要全部还是只需要两个矩阵:相机矩阵和畸变系数? - trojek
显示剩余7条评论

1
我通过OpenCV 3.4.0的cv::fisheye模块(C++,MS Windows)解决了180度FOV鱼眼相机的问题。 我使用cv::fisheye::calibrate制作K和D(相机矩阵和径向畸变系数矩阵)。 然后我使用cv::fisheye::initUndistortRectifyMap为X和Y坐标生成映射。 最后,我使用cv::remap通过从initUndistortRectifyMap获取的映射对来自鱼眼相机的图像进行消除畸变。 这种解决方案有一些限制(OpenCV只消除鱼眼图像的中心部分。边缘被移动到外面),您将获得140-150 FOV作为结果。 我在HERE放置了此限制的详细说明。 如果140-150度FOV适合您,您可以在不做任何修改的情况下使用此模块。

0

我从不同的角度拍了25张照片,但我仍然在校准方面遇到问题。当我使用视场角为150的相机时,我没有任何问题。 - trojek
你有去过棋盘图像的边界吗?你使用了鱼眼校准函数吗?即使在低视场角图像上,有时候也很难获得良好的校准。有时只有一两张图像会大幅增加校准误差。 - TFreitas
我使用了鱼眼函数,并且拍摄了不同角度的照片。如果您确定可以使用纯OpenCV校准模型来校准相机,我可以发送给您我的图像。 - trojek
我认为Jack Gold可能给了你一个更好的答案。我猜我所使用的镜头视野较低,没有那个问题。 - TFreitas
我几乎肯定Jack Gold会给我更好的答案,但我还没有时间去验证它。 - trojek
我使用一个单独的步骤,在这一步骤中,我绘制检测到的棋盘,并确保cv与我一致(有时会出现偏差)。删除棋盘检测明显失误的图像可以显著提高性能! - Jon Watte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接