OpenCV:如何测量两个球之间的距离(单位:毫米)- 如何提高准确性

10

我也在opencv.org的问答论坛中发表了这个话题,但我不知道有多少专家从这里阅读这个论坛 - 所以请原谅我在这里也尝试一下。

我目前正在学习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)

结果:在距离300 mm处约4 mm的误差,在距离1000 mm处约25 mm的误差。但是,如果我测量印在盘子上的矩形,则误差小于0.2 mm,因此我认为校准和去畸变处理良好。

我思考了这个问题,并找出了三个可能的原因:

  1. 对于直接位于板上的点,应用了findHomography算法,而球的中心点应该在赤道高度测量 =>我该如何改变findHomography的结果以实现这一点,即“移动”平面?半径已知(单位为毫米)。
  2. 由于相机不会从顶部看到球,因此随着球距离光学中心的增加,误差也会增加,这样图像的二维投影中心点就不同于三维世界中的中心点,因此我需要将其投影到图像边框。 =>是否有任何几何操作可以应用到找到的中心点上以更正值?
  3. 在去畸变过程中可能会丢失信息,因为我会生成一个新的去畸变图像,并回到像素精度,尽管在畸变矩阵中有许多浮点值。 我应该在畸变图像中搜索球,并仅使用畸变矩阵转换中心点吗?但我不知道如何编写此任务的代码。
  4. 我希望有人能帮助我改进这个问题,也希望这个主题对其他OpenCV初学者有所帮助。

    谢谢并致以最美好的祝愿!

1个回答

11

以下是一些思路,希望能帮助您...虽然这并不是 "终极答案"。

首先是一个简单的问题。如果您在距离为 D 的特定平面上以毫米为单位校准了图像,则比起实际大小更近的点会显得更大。要从测量坐标转换为实际坐标,您可以使用

Actual = measured * (D-r)/D

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

关于第二个问题:如果你思考一下,你看到的球体的中心应该在正确的位置“在球体中心的平面上”,即使你从一个角度观察它。画一张图片来让自己相信这一点。

第三个问题:如果你找到畸变图像中的球体坐标,你应该能够使用perspectiveTransform将它们转换为校正图像。这可能会稍微提高精度-但我对你看到的误差大小感到惊讶。最大距离(1000毫米)的一个像素有多大?

编辑

你问了椭圆形投影等问题。基本上,如果你把相机的光学中心看作是一个光源,把球体的阴影看作是你的“2D图像”,那么你可以画出刚好击中球体边缘的光线的图像,并确定不同的角度:

enter image description here

很容易看出P(A和B的中点)不同于C(球体中心的投影)。更多的三角函数将向你展示误差C - (A + B) / 2随着x的增加而增加,随着D的减小而减小。如果你知道A和B,则可以从以下公式中计算出C的正确位置(给定D):

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

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

仅当相机像一个“真正的镜头”一样运作时,这才有效-换句话说,在图像平面上,没有凸透镜畸变,矩形映射到传感器上的矩形。上述内容与您自己的想法结合起来,将未校正的(“像素”)空间拟合进去,然后使用 perspectiveTransform 转换找到的中心点,应该可以让您成功。

看看您能做些什么吧!


1
非常感谢!你的第一个提示对误差产生了巨大影响。我不知道测试设置目前在哪里,但我知道板离相机大约1200毫米,所以我使用了你的公式来校正圆心的x和y值:现在误差仅为0.3毫米,而不是25毫米!我将改进圆检测(亚像素角点、轮廓等),测量实际距离,然后我的问题就解决了!抱歉,无法投票支持(声望不够)。 - efdev1234
2
很高兴这件事情如此简单!不用担心点赞。你能做的最好的事情就是继续提问,然后开始回答问题。这是一个“回报社区”...当然,即使你不能点赞,也可以接受一个答案(勾选)。不过,你可以等待看看是否有更好的答案出现。 - Floris
我现在进行了更多的测试。我使用了您的公式来校正测量坐标(在第5步之后)。现在,位于左边界和右边界上的两个球之间的距离为1000毫米,几乎没有任何误差(1000.000016)。但是我期望的是:左球的x坐标应该在“0”左右,因为它直接位于我用来初始化findHomography的边界上。但是我得到的是左球为-9.9..,右球为990...的坐标。距离是正确的,但所有坐标似乎都向左移动了...有什么想法吗?再次感谢! - efdev1234
1
当一个球体斜投影到平面上时,椭圆的中心点并不对应于球体的中心点。这个问题的数学计算有些棘手 - 从一个点向球体中心和两个极端点各画三条线,并触及它们与下方平面相交的地方,它们不再等距离。在低角度下获得准确的结果时,这是一个重要的修正。明天会尝试给出方程式。 - Floris
是的,我也这么认为。这就是我在原帖中想表达的第二个问题。我试图找出一个方程,并阅读了几篇论文,例如这篇第2章,但对我来说太棘手了。再次感谢您的帮助! - efdev1234
显示剩余5条评论

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