OpenCV:以毫米为单位测量两个球之间的距离 - 如何提高准确度

时间:2013-05-04 20:09:33

标签: opencv

我也在opencv.org的Q& A论坛上发布了这个主题,但我不知道有多少专家正在阅读这个论坛 - 所以请原谅我,我也在这里尝试。

我正在学习OpenCV,我目前的任务是测量两个躺在盘子上的球之间的距离。我的下一步是比较几个摄像头和分辨率,以了解分辨率,噪声,失真等的重要性以及这些参数对精度的影响程度。如果社区对结果感兴趣,我很乐意在他们准备好后分享结果!使用广角镜头将相机放置在印版上方。板的宽度和高度(1500 x 700 mm)和球的半径(40 mm)是已知的。

到目前为止我的步骤:

  1. 相机校准
  2. 使图像失真(由于广角镜头,失真很高)
  3. findHomography:我使用板的角点作为输入(未失真图像中的4个点)和角点以毫米为单位(从左下角的0,0开始,到达1500,700)右上角)
  4. 使用HoughCircles在未失真的图像中找到球
  5. 在圆心点上应用perspectiveTransform =>圆心点现在以毫米为单位
  6. 计算两个中心点的距离:d = sqrt((x1-x2)^ 2 +(y1-y2)^ 2)
  7. 结果:距离为300 mm时误差约为4 mm,距离1000 mm时误差约为25 mm但如果我测量的是印在板上的矩形误差小于0.2 mm ,所以我猜校准和非失真效果很好。

    我想到了这一点并找出了三个可能的原因:

    1. findHomography应用于直接位于板上的点,而球的中心点应在赤道高度 =>中测量。如何改变findHomography的结果来改变它,即“移动”飞机?以mm为单位的半径是已知的。
    2. 误差随着球到光学中心距离的增加而增加,因为相机不会从顶部看到球,因此图像的2D投影中心点与3D世界中的中心点不同 - 我我们会进一步投射到图像的边界。 =>是否有任何几何操作我可以在找到的中心应用以更正值?
    3. 在非失真期间可能会丢失信息,因为我会产生一个新的无失真图像并回到像素精度,尽管我在失真矩阵中有许多浮点值。 我应该在扭曲的图像中搜索球并仅使用失真矩阵转换中心点吗?但我不知道这项任务的代码是什么。
    4. 我希望有人可以帮助我改进这一点,我希望这个话题对其他OpenCV启动者来说很有意思。

      谢谢和最诚挚的问候!

1 个答案:

答案 0 :(得分:10)

这里有一些想法可以帮助你......但绝不是“答案”。

首先是一个简单的。如果您在距离为D的特定平面上以毫米为单位校准了图像,则r更接近的点将显得比它们更大。要从测量坐标到实际坐标,请使用

Actual = measured * (D-r)/D

因此,由于球体的中心在平面上方的半径为r,因此上述公式应该回答您问题的第1部分。

关于第二个问题:如果你考虑一下,你看到的球体中心应该在“球体中心平面”的正确位置,即使你从一个角度看它。给自己画一张照片来说服自己就是这样。

第三个问题:如果在失真图像中找到球体的坐标,您应该能够使用perspectiveTransform将它们转换为校正后的图像。这可能会略微提高准确性 - 但我对您看到的错误大小感到惊讶。最大距离(1000mm)处的单个像素有多大?

修改

你问过椭圆投影等。基本上,如果你把相机的光学中心看作光源,并将球的阴影看作平面作为你的“2D图像”,你可以画一幅画刚刚击中球的两侧的射线,并确定不同的角度:

enter image description here

很容易看出P(A和B的中点)与C(球体中心的投影)不同。多一点触发将显示错误C - (A+B)/2x增加而减少D。如果您知道A和B,则可以从以下公式计算C(给定D)的正确位置:

C = D * tan( (atan(B/D) + atan(A/D)) / 2 )

当D较小和/或x较大时,误差变大。注意D是从镜头到物平面的垂直(最短)距离。

仅当相机的作用类似于“真实镜头”时才有效 - 换句话说,没有枕形失真,图像平面中的矩形映射到传感器上的矩形。上面结合你自己的想法,以适应未经修正的('像素')空间,然后转换与perspectiveTransform找到的中心,应该让你一直到那里。

看看你能做些什么!