Opencv 计算多幅图像中关键点的三维坐标
我有同一台校准相机拍摄的多张物体图像。假设校准意味着内在和外在参数(我可以在对象旁边放一个棋盘,这样所有参数都可以被检索)。在这些图像上,我可以使用SIFT或SURF以及一些匹配算法找到匹配的关键点,这是基本的OpenCV。但是如何从多幅图像中对这些点进行三维重建呢?这不是一个经典的立体排列,因此有两个以上的图像上有相同的对象点,我想使用尽可能多的提高精度 是否有任何内置的OpenCV函数可以做到这一点Opencv 计算多幅图像中关键点的三维坐标,opencv,computer-vision,stereo-3d,3d-reconstruction,Opencv,Computer Vision,Stereo 3d,3d Reconstruction,我有同一台校准相机拍摄的多张物体图像。假设校准意味着内在和外在参数(我可以在对象旁边放一个棋盘,这样所有参数都可以被检索)。在这些图像上,我可以使用SIFT或SURF以及一些匹配算法找到匹配的关键点,这是基本的OpenCV。但是如何从多幅图像中对这些点进行三维重建呢?这不是一个经典的立体排列,因此有两个以上的图像上有相同的对象点,我想使用尽可能多的提高精度 是否有任何内置的OpenCV函数可以做到这一点 (请注意,这是离线完成的,解决方案不需要快速,但需要健壮)我猜您正在寻找所谓的方法。他们使用
(请注意,这是离线完成的,解决方案不需要快速,但需要健壮)我猜您正在寻找所谓的方法。他们使用来自不同视点的多个图像并返回三维重建(例如点云)。看起来OpenCV在contrib包中有一个模块,但我没有使用它的经验
然而,我曾经和他一起工作。它非常简单,以文本文件的形式返回整个信息(相机校准和点位置),您可以使用Meshlab查看点云。请注意,它使用SIFT关键点和描述符建立通信。我想我已经找到了解决方案。“运动结构”算法处理相机未校准的情况,但在这种情况下,所有内在和外在参数都是已知的 该问题退化为线性最小二乘问题: 我们必须计算单个对象点的坐标:
X = [x, y, z, 1]'
C = [x, y, z]'
X = [[C], [1]]
我们得到了n个图像,它们具有以下变换矩阵:
Pi = Ki * [Ri|ti]
这些矩阵是已知的。对象点投影在图像上的位置
U = [ui, vi]
我们可以在齐次坐标中书写(运算符*表示矩阵乘法、点积和标量乘法):
让我们定义以下内容:
p1i = [p11i, p12i, p13i] (the first row of Pi missing the last element)
p2i = [p21i, p22i, p23i] (the second row of Pi missing the last element)
p3i = [p31i, p32i, p33i] (the third row of Pi missing the last element)
a1i = p14i
a2i = p24i
a3i = p34i
然后我们可以写:
Q = [x, y, z]
wi = p3i * Q + a3i
ui = (p1i * Q + a1i) / wi =
= (p1i * Q + a1i) / (p3i * Q + a3i)
ui * p3i * Q + ui * a3i - p1i * Q - a1i = 0
(ui * p3i - p1i) * Q = a1i - a3i
与vi类似:
这适用于i=1..n。我们可以将其写成矩阵形式:
G * Q = b
G = [[u1 * p31 - p11],
[v1 * p31 - p21],
[u2 * p32 - p12],
[v2 * p32 - p22],
...
[un * p3n - p1n],
[vn * p3n - p2n]]
b = [[a11 - a31 * u1],
[a21 - a31 * v1],
[a12 - a32 * u2],
[a22 - a32 * v2],
...
[a1n - a3n * un],
[a2n - a3n * vn]]
由于G和b是从Pi矩阵和图像点[ui,vi]知道的,因此我们可以计算G的伪逆(称为G_),并计算:
Q = G_ * b
谢谢,我自己设法弄明白了,但你的回答很有帮助!不客气,但通常您可以为SfM方法提供相机内部特性以改善结果(至少bundler能够自行估计,但取决于图像数量,结果更差)…这就是为什么我认为SfM比在对象旁边放置棋盘更容易实现的原因(并且把它放在每个图像中都很明显的位置)…在写这篇文章的时候,我确信它是有意义的,但是多年以后看这篇文章,我不知道这是什么。
G * Q = b
G = [[u1 * p31 - p11],
[v1 * p31 - p21],
[u2 * p32 - p12],
[v2 * p32 - p22],
...
[un * p3n - p1n],
[vn * p3n - p2n]]
b = [[a11 - a31 * u1],
[a21 - a31 * v1],
[a12 - a32 * u2],
[a22 - a32 * v2],
...
[a1n - a3n * un],
[a2n - a3n * vn]]
Q = G_ * b