我也在opencv.org的Q& A论坛上发布了这个主题,但我不知道有多少专家正在阅读这个论坛 - 所以请原谅我,我也在这里尝试。
我正在学习OpenCV,我目前的任务是测量两个躺在盘子上的球之间的距离。我的下一步是比较几个摄像头和分辨率,以了解分辨率,噪声,失真等的重要性以及这些参数对精度的影响程度。如果社区对结果感兴趣,我很乐意在他们准备好后分享结果!使用广角镜头将相机放置在印版上方。板的宽度和高度(1500 x 700 mm)和球的半径(40 mm)是已知的。
到目前为止我的步骤:
结果:距离为300 mm时误差约为4 mm,距离1000 mm时误差约为25 mm但如果我测量的是印在板上的矩形误差小于0.2 mm ,所以我猜校准和非失真效果很好。
我想到了这一点并找出了三个可能的原因:
我希望有人可以帮助我改进这一点,我希望这个话题对其他OpenCV启动者来说很有意思。
谢谢和最诚挚的问候!
答案 0 :(得分:10)
这里有一些想法可以帮助你......但绝不是“答案”。
首先是一个简单的。如果您在距离为D的特定平面上以毫米为单位校准了图像,则r
更接近的点将显得比它们更大。要从测量坐标到实际坐标,请使用
Actual = measured * (D-r)/D
因此,由于球体的中心在平面上方的半径为r
,因此上述公式应该回答您问题的第1部分。
关于第二个问题:如果你考虑一下,你看到的球体中心应该在“球体中心平面”的正确位置,即使你从一个角度看它。给自己画一张照片来说服自己就是这样。
第三个问题:如果在失真图像中找到球体的坐标,您应该能够使用perspectiveTransform
将它们转换为校正后的图像。这可能会略微提高准确性 - 但我对您看到的错误大小感到惊讶。最大距离(1000mm)处的单个像素有多大?
修改强>
你问过椭圆投影等。基本上,如果你把相机的光学中心看作光源,并将球的阴影看作平面作为你的“2D图像”,你可以画一幅画刚刚击中球的两侧的射线,并确定不同的角度:
很容易看出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
找到的中心,应该让你一直到那里。
看看你能做些什么!