【问题标题】:Computing 3D coordinates of keypoints in multiple images计算多幅图像中关键点的 3D 坐标
【发布时间】:2016-11-14 09:25:23
【问题描述】:

我有多个由同一个校准相机拍摄的物体图像。假设校准意味着内在和外在参数(我可以在对象旁边放置一个棋盘格,因此可以检索所有参数)。在这些图像上,我可以使用 SIFT 或 SURF 和一些匹配算法找到匹配的关键点,这是基本的 OpenCV。但是如何从多个图像中对这些点进行 3D 重建呢?这不是经典的立体排列,所以有超过 2 张图像具有相同的对象点,我想尽可能多地使用以提高准确性。

是否有任何内置的 OpenCV 函数可以做到这一点?

(注意这是离线完成的,解决方案不需要很快,但要健壮)

【问题讨论】:

    标签: opencv computer-vision stereo-3d 3d-reconstruction


    【解决方案1】:

    我想我已经找到了解决方案。运动算法的结构处理相机未校准的情况,但在这种情况下,所有内部和外部参数都是已知的。

    问题退化为线性最小二乘问题:

    我们必须计算单个对象点的坐标:

    X = [x, y, z, 1]'
    C = [x, y, z]'
    X = [[C], [1]]
    

    我们得到 n 张图像,它们具有以下变换矩阵:

    Pi = Ki * [Ri|ti]
    

    这些矩阵已知。物点投影在图像上

    U = [ui, vi] 
    

    我们可以写齐次坐标(运算符 * 表示矩阵乘法、点积和标量乘法):

    [ui * wi, vi * wi, wi]' = Pi * X
    
    Pi = [[p11i, p12i, p13i, p14i],
          [p21i, p22i, p23i, p24i],
          [p31i, p32i, p33i, p34i]]
    

    让我们定义以下内容:

    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 也一样:

    (vi * p3i - p2i) * Q = a2i - a3i
    

    这适用于 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]]
    

    由于 Gb 是从 Pi 矩阵已知的,并且图像点 [ui, vi],我们可以计算出G的伪逆(称为G_),并计算:

    Q = G_ * b
    

    【讨论】:

    • 在写这篇文章的时候,我确信它是有道理的,但是多年后看,我不知道这是什么。
    【解决方案2】:

    我猜你正在寻找所谓的Structur from motion 方法。他们使用来自不同视点的多个图像并返回 3D 重建(例如点云)。看起来 OpenCV 在 contrib 包中有一个 SfM 模块,但我没有使用它的经验。

    但是,我曾经使用bundler。它非常简单,并将整个信息(相机校准和点位置)作为文本文件返回,您可以使用 Meshlab 查看点云。请注意,它使用 SIFT 关键点和描述符来建立对应关系。

    【讨论】:

    • 谢谢,我自己弄明白了,但你的回答很有帮助!
    • 不客气,但通常您可以为 SfM 方法提供相机内在函数以改进结果(至少 bundler 能够自己估计它们,但根据图像的数量,结果会更糟) ...这就是为什么我认为 SfM 对您来说比在您的对象旁边放置一个棋盘更容易(并将其放置在每个图像中都很明显)...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 2022-01-15
    相关资源
    最近更新 更多