10

我还在 opencv.org 的问答论坛中发布了这个主题,但我不知道有多少专家正在阅读这个论坛 - 请原谅我也在尝试这里。

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

到目前为止我的步骤:

  1. 相机校准
  2. 使图像不失真(由于广角镜头,失真很高)
  3. findHomography:我使用板的角点作为输入(未失真图像中以像素为单位的 4 个点)和以毫米为单位的角点(从左下角的 0,0 开始,到右上角的 1500,700 )
  4. 使用 HoughCircles 在未失真图像中查找球
  5. 在圆心点上应用透视变换 => 圆心点现在以毫米为单位
  6. 计算两个中心点的距离:d = sqrt((x1-x2)^2+(y1-y2)^2)

结果:距离 300 mm 时误差约为 4 mm,距离 1000 mm 时误差约为 25 mm 但如果我测量的是印在印版上的矩形,则误差小于 0.2 mm,所以我猜测校准和不失真效果很好。

我想了想,想出了三个可能的原因:

  1. findHomography 应用于直接位于板上的点,而球的中心点应在赤道高度测量=> 如何更改 findHomography 的结果以改变这一点,即“移动”平面?以毫米为单位的半径是已知的。
  2. 误差随着球到光学中心的距离的增加而增加,因为相机不会从顶部看到球,所以图像的 2D 投影中的中心点与 3D 世界中的不同 - 我将我们投影进一步到图像的边界。=> 是否有任何几何运算可以应用于找到的中心来校正值?
  3. 在不失真期间,可能会丢失信息,因为我生成了一个新的未失真图像并返回到像素精度,尽管我在失真矩阵中有许多浮点值。我应该在失真图像中搜索球并只用失真矩阵变换中心点吗?但我不知道这个任务的代码是什么。

我希望有人可以帮助我改进这一点,我希望这个主题对其他 OpenCV 初学者来说很有趣。

谢谢和最好的问候!

4

1 回答 1

11

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

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

Actual = measured * (D-r)/D

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

关于第二个问题:如果您考虑一下,即使您从某个角度看,您看到的球心也应该在“球心平面内”的正确位置。给自己画一幅画来说服自己是这样的。

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

编辑

您询问了椭圆投影等。基本上,如果您将相机的光学中心视为光源,并将球在平面上的阴影视为“二维图像”,则可以绘制光线图片刚刚击中球的两侧,并确定不同的角度:

在此处输入图像描述

很容易看出,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,应该可以让您一直到那里。

看看你能用它做什么!

于 2013-05-04T20:28:05.517 回答