math - 为什么有 3 个相互冲突的 OpenCV 相机标定公式?

标签 math opencv formula camera-calibration

我在使用 OpenCV 用于相机校准目的的各种坐标参数化时遇到问题。问题在于,关于图像畸变公式的三种不同信息来源显然给出了涉及的参数和方程的三种非等价描述:

(1) 在他们的书“Learning OpenCV ...” Bradski 和 Kaehler 中写了关于镜头畸变的内容(第 376 页):

xcorrected = x * ( 1 + k1 * r^2 + k2 * r^4  + k3 * r^6 ) + [ 2 * p1 * x * y + p2 * ( r^2 + 2 * x^2 ) ],

ycorrected = y * ( 1 + k1 * r^2 + k2 * r^4  + k3 * r^6 ) + [ p1 * ( r^2 + 2 * y^2 ) + 2 * p2 * x * y ],

其中 r = sqrt( x^2 + y^2 )。

假设,(x, y) 是未校正的捕获图像中的像素坐标,对应于坐标为 (X, Y, Z) 的世界点对象,引用相机帧,为此

xcorrected = fx * ( X / Z ) + cx    and     ycorrected = fy * ( Y / Z ) + cy,

其中 fx、fy、cx 和 cy 是相机的内在参数。因此,从捕获的图像中获取 (x, y),我们可以获得所需的坐标 ( xcorrected, ycorrected ),通过应用上述前两个校正表达式来生成捕获的世界场景的未失真图像。

然而...

(2) 当我们查看相机校准和 3D 重建部分下的 OpenCV 2.0 C 引用条目时,出现了复杂情况。为了便于比较,我们从所有世界点(X、Y、Z)坐标开始,这些坐标都是相对于相机的引用系表示的,就像在 #1 中一样。因此,变换矩阵 [ R | t ] 无关紧要。

在C引用中,是这样表述的:

x' = X / Z,

y' = Y / Z,

x'' = x' * ( 1 + k1 * r'^2 + k2 * r'^4  + k3 * r'^6 ) + [ 2 * p1 * x' * y' + p2 * ( r'^2 + 2 * x'^2 ) ],

y'' = y' *  ( 1 + k1 * r'^2 + k2 * r'^4  + k3 * r'^6 ) + [ p1 * ( r'^2 + 2 * y'^2 )  + 2 * p2 * x' * y' ],

其中 r' = sqrt( x'^2 + y'^2 ),最后是

u = fx * x'' + cx,

v = fy * y'' + cy.

如您所见,这些表达式与#1 中的表达式不等价,结果是两组校正后的坐标 ( xcorrected, ycorrected ) 和 ( u, v ) 不相同。为什么矛盾?在我看来,第一组更有意义,因为我可以为其中的每个 x 和 y 赋予物理意义,而当相机聚焦时,我发现 x' = X/Z 和 y' = Y/Z 没有物理意义长度不完全为 1。此外,我们无法计算 x' 和 y',因为我们不知道 (X, Y, Z)。

(3) 不幸的是,当我们引用英特尔的开源计算机视觉库引用手册的镜头失真部分(第 6-4 页)中的文字时,事情变得更加模糊,其中部分陈述:

"设(u,v)为真实像素图像坐标,即理想投影坐标,(ũ,ṽ)为对应的真实观察(失真)图像坐标。同理,(x,y)为ideal (distortion-free) and ( x ̃, y ̃ ) are real (distorted) image physical coordinates. 考虑到两个扩展项给出以下内容:

x ̃  =  x * ( 1 +  k1 * r^2 + k2 * r^4 ) + [ 2 p1 * x * y + p2 * ( r^2 + 2 * x^2 ) ] 

y ̃  =  y * ( 1 +  k1 * r^2 + k2 * r^4 ] + [ 2 p2 * x * y + p2 * ( r^2 + 2 * y^2 ) ],

其中 r = sqrt( x^2 + y^2 )。 ...

“因为 u ̃ = cx + fx * u 和 v ̃ = cy + fy * v , … 结果系统可以改写如下:

u ̃  = u + ( u – cx ) * [ k1 * r^2 + k2 * r^4 + 2 * p1 * y + p2 * ( r^2 / x + 2 * x ) ]

v ̃  = v + ( v – cy ) * [ k1 * r^2 + k2 * r^4 + 2 * p2 * x + p1 * ( r^2 / y + 2 * y ) ]

后一种关系用于消除相机图像的失真。”

好吧,看起来涉及 x ̃ 和 y ̃ 的表达式与本文顶部给出的涉及 xcorrected 和 ycorrected 的两个表达式一致。然而,根据给定的描述,x ̃ 和 y ̃ 不是指校正后的坐标。我不明白坐标 ( x ̃, y ̃ ) 和 ( u ̃, v ̃ ) 之间的区别,或者就此而言, ( x, y ) 和 ( u, v ) 对之间的区别。从他们的描述来看,他们唯一的区别似乎是 ( x ̃, y ̃ ) 和 ( x, y ) 指的是“物理”坐标,而 ( u ̃, v ̃ ) 和 ( u, v ) 不是。这种区别到底是什么?不都是物理坐标吗?我迷路了!

感谢任何输入!

最佳答案

相机标定没有唯一的公式,它们都是有效的。请注意,第一个包含 r^2、r^4 和 r^6 的常量 K1、K2 和 K3,而其他两个仅包含 r^2 和 r^4 的常量?那是因为它们都是近似模型。第一个可能更准确,因为它有更多参数。

任何时候你看到:

r = sqrt( x^2 + y^2 )

假设 x =(x 坐标像素)-(以像素为单位的相机中心)可能是安全的,因为 r 通常表示距离中心的半径。

顺便说一句,你想做什么?估计相机参数,校正镜头失真,或两者兼而有之?

关于math - 为什么有 3 个相互冲突的 OpenCV 相机标定公式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2862604/

相关文章:

c++ - 检查相机标定效率,用opencv

r - 如何将公式作为参数传递给 r 中的函数?

c++ - 计算浮点 vector 的点积时,灾难性取消是一个问题吗?如果是这样,它通常是如何解决的?

python - 更快的算法来定制给定的数学表达式

javascript - 对零件号进行四舍五入/向上取整以匹配总计值

Safari 上的 JavaScript 错误

swift - 有什么方法可以在Swift中检测形状轮廓而不必分支到OpenCV?

python - TensorFlow 中的高效图像膨胀

vba - Excel 公式或 VBA : Find match's address in separate table with 2 column criteria - No helper columns

c++ - 用已知公式求解缺失变量