如何验证网络摄像头校准的正确性?

问题描述 投票:46回答:2

我对相机校准技术完全不了解......我正在使用OpenCV棋盘技术...我正在使用Quantum的网络摄像头......

这是我的观察和步骤..

  1. 我保持每个国际象棋方面= 3.5厘米。这是一个7 x 5的棋盘,有6 x 4个内角。我在距离网络摄像头1到1.5米的距离拍摄了10张不同视角/姿势的图像。
  2. 我正在按照Bradski学习OpenCV中的C代码进行校准。我的校准代码是 cvCalibrateCamera2(object_points,image_points,point_counts,cvSize(640,480),intrinsic_matrix,distortion_coeffs,NULL,NULL,CV_CALIB_FIX_ASPECT_RATIO);
  3. 在调用此函数之前,我将沿着内部矩阵的对角线的第一个和第二个元素作为一个,以保持焦距的比率恒定并使用CV_CALIB_FIX_ASPECT_RATIO
  4. 随着棋盘距离的变化,fxfy正在变化,fx:fy几乎等于1. cxcy值按200到400的顺序。当我改变时,fxfy的数量级为300-700。距离。
  5. 目前我把所有的失真系数都归零,因为我没有得到包括失真系数在内的好结果。我的原始图像看起来比未失真的图像更漂亮!!

我正确地进行了校准吗?我应该使用除CV_CALIB_FIX_ASPECT_RATIO之外的任何其他选项吗?如果是的话,哪一个?

opencv computer-vision camera-calibration
2个回答
113
投票

嗯,你在寻找“帅气”还是“准确”?

相机校准是计算机视觉中极少数主题之一,其中精确度可以直接量化为物理术语,并通过物理实验进行验证。通常的教训是:(a)你的数字与你投入的努力(和金钱)一样好,而且(b)真正的准确性(与想象相反)是昂贵的,所以你应该提前弄清楚什么您的应用程序确实需要精确的方式。

如果您查看甚至非常便宜的镜头/传感器组合(百万像素范围及以上)的几何规格,很明显亚小时毫米校准精度在理论上可以在桌面空间体积内实现。只需计算出(从相机传感器的规格表中)一个像素跨越的立体角 - 你的钱包可以达到的空间分辨率让你眼花缭乱。然而,实际上实现可接受的理论精确度的东西需要工作。

以下是一些建议(根据个人经验),以获得本土设备的良好校准体验。

  1. 如果您的方法使用平面目标(“棋盘”或类似物),请制作一个好的目标。选择一个非常平坦的背衬(对于你提到的5毫米厚或更厚的窗户玻璃的尺寸是非常好的,虽然明显脆弱)。验证其与另一边缘(或更好的是激光束)的平坦度。在厚纸上打印图案,不会太容易拉伸。在胶合之前在背衬上打印之后将其放置并验证方形边确实非常接近正交。廉价的喷墨或激光打印机不是为了严格的几何精度而设计的,不要盲目相信它们。最佳做法是使用专业的印刷店(即使是Kinko也会比大多数家用打印机做得好得多)。然后使用喷涂胶水将图案非常小心地贴在背衬上,然后用软布慢慢擦拭,以避免气泡和拉伸。等待一天或更长时间胶水固化,胶纸压力达到长期稳定状态。最后用一个好的卡尺和一个放大镜测量角落位置。对于“平均”平方大小,您可能会得到一个单一数字,但它必须是实际测量值的平均值,而不是希望祈祷者。最佳做法是实际使用测量位置表。
  2. 观察你的温度和湿度变化:纸张从空气中吸收水分,背衬膨胀和收缩。令人惊讶的是,在没有引用环境条件(或目标响应)的情况下,您可以找到多少报告亚毫米校准精度的文章。不用说,他们大多是废话。与普通金属板相比,玻璃的较低温度膨胀系数是优选前者作为背衬的另一个原因。
  3. 毋庸置疑,您必须禁用相机的自动对焦功能(如果有):聚焦物理移动镜头内的一块或多块玻璃,从而(略微)改变视野和(通常很多)镜头失真和主要观点。
  4. 将相机放在稳定的支架上,不会轻易振动。根据应用需要聚焦(并且如果它有光圈,则停止镜头)(不是校准 - 校准程序和目标必须根据应用程序的需要而设计,而不是相反)。之后甚至不要想到触摸相机或镜头。如果可能的话,避免使用“复杂”镜片 - 例如变焦镜头或非常广角的镜头。鱼眼镜头或变形镜头需要的模型比OpenCV提供的模型复杂得多。
  5. 拍摄大量的测量和图片。您需要每个图像数百个测量(角点)和数十个图像。在数据方面,越多越好。一个10x10的棋盘格是我考虑的绝对最小值。我通常在20x20工作。
  6. 拍照时请调整校准音量。理想情况下,您希望测量值均匀分布在您将要使用的空间体积中。最重要的是,确保在一些图片中相对于焦轴显着地调整目标角度 - 校准您需要“看到”一些真实透视缩短所需的焦距。为获得最佳效果,请使用可重复的机械夹具移动目标。一个好的是单轴转盘,它将为您提供一个优秀的先前模型,用于目标的运动。
  7. 拍照时最大限度地减少振动和相关的运动模糊。
  8. 使用良好的照明。真。令人惊讶的是,我经常看到人们在游戏后期意识到你需要光子来校准任何相机:-)使用漫射环境照明,并将其从视野两侧的白卡上反弹。
  9. 观察您的角落提取代码正在做什么。在图像顶部绘制检测到的角落位置(例如,在Matlab或Octave中),并判断它们的质量。使用严格阈值提前删除异常值比在信任包调整代码中信任robdentier更好。
  10. 如果可以的话,限制你的模型。例如,如果您没有充分的理由相信您的镜头在图像中明显偏离中心,请不要尝试估计主要点,只需在第一次尝试时将其固定在图像中心。主点位置通常很难被观察到,因为它固有地与非线性失真的中心以及与目标到相机的平移的图像平面平行的分量混淆。要做到正确,需要精心设计的程序,产生三个或更多场景的独立消失点,并非常好地包围非线性失真。同样地,除非你有理由怀疑镜头焦轴是否真的倾斜了w.r.t.传感器平面,将摄像机矩阵的(1,2)分量固定为零。一般来说,使用最简单的模型来满足您的测量和您的应用需求(这就是Ockam的剃须刀)。
  11. 当你的优化器校准解决方案具有足够低的RMS误差(十分之几像素,通常也参见下面的Josh答案)时,绘制残差的XY模式(所有图像中每个角的predict_xy - measured_xy)并看看它是否是以(0,0)为中心的圆形云。异常值的“团块”或残余云的非圆度是尖叫的警告,即某些东西是非常错误的 - 可能是由于角落检测或匹配不良导致的异常值,或者是不合适的镜头失真模型。
  12. 拍摄额外的图像以验证解决方案的准确性 - 使用它们来验证镜头失真是否实际被移除,并且校准模型预测的平面单应性实际上与从测量角落恢复的平面单应性相匹配。

28
投票

这是一个相当晚的答案,但对于那些来自谷歌的人来说:

检查校准精度的正确方法是使用OpenCV提供的重投影错误。我不确定为什么在答案或评论中没有提到这个,你不需要手工计算 - 这是calibrateCamera的返回值。在Python中,它是第一个返回值(后跟相机矩阵等)。

重投影误差是使用固有系数投影点的位置与实际图像中的点之间的RMS误差。通常你应该期望RMS误差小于0.5px - 我可以通过机器视觉相机常规地获得0.1px左右。重投影错误用于许多计算机视觉文件中,没有一种更容易或更准确的方法来确定您的校准有多好。

除非你有一个立体声系统,否则你只能在三维空间中的某个位置找到射线而不是一个点。然而,由于可以计算出每个平面校准图像的姿势,因此可以计算每个棋盘角应落在图像传感器上的位置。校准过程(或多或少)尝试计算出这些光线下落的位置,并使所有不同校准图像上的误差最小化。在Zhang的原始论文和随后的评估中,大约10-15个图像似乎就足够了;此时,随着添加更多图像,错误不会显着减少。

其他软件包如Matlab将为您提供每个内在函数的误差估计,例如:焦距,投影中心。我一直无法让OpenCV吐出那些信息,但也许它就在某处。相机校准现在已经在Matlab 2014a中得到了解决,但你仍然可以掌握相机校准工具箱,它非常受计算机视觉用户的欢迎。

http://www.vision.caltech.edu/bouguetj/calib_doc/

视觉检查是必要的,但在处理结果时是不够的。最简单的事情就是世界上的直线在你未失真的图像中变得笔直。除此之外,仅通过查看输出图像,无法确定您的相机是否经过良好校准。

弗朗西斯科提供的例程很好,遵循这一点。我用架子板作为我的飞机,图案印在海报纸上。确保图像曝光良好 - 避免镜面反射!我使用的是标准的8x6模式,我尝试过更密集的模式但是我没有看到这种精确度的提高,因为它有所不同。

我认为这个答案对于大多数想要校准相机的人来说已经足够了 - 除非你试图校准像Fisheye这样的异国情调,或者你出于教育原因这样做,否则OpenCV / Matlab就是你所需要的。 Zhang的方法被认为足够好,几乎所有计算机视觉研究都使用它,而且大多数都使用Bouguet的工具箱或OpenCV。

© www.soinside.com 2019 - 2024. All rights reserved.