6

我正在尝试构建一个跟踪器(手跟踪个人项目),因此我需要使用 Plucker 坐标将 2d 点反向投影到 3d 线。(如光线追踪)

作为输入,我有一个点的二维坐标和投影矩阵。

网络上有关采摘器坐标的信息概述了它们为何有用,但没有论文分析性地描述上述过程。(他们只是提到他们将项目反向投影到采摘线,没有任何进一步的描述)

有人可以指出我正确的方向吗?

4

3 回答 3

6

显然这背后没有什么魔力,我一直在寻找一个公式/定理,该公式/定理立即从我的“输入”到采摘器坐标中产生,而没有这样的东西。

作为输入,我们有

  • (投影)点的二维坐标
  • 投影矩阵

使用这两个输入,我们可以将此 2d 点反向投影到射线(3D 线)。这条 3D 线的所有 3D 点都投影到同一个 2D 点。光线默认通过相机中心(或投影中心等)。

有关必要的方程式,请参阅

一般的想法是,为了定义一条线,您需要 2 个点。我们选择找到(使用上述来源的方程式)

  • 相机中心(所有投影光线默认通过此点)
  • 射线@无穷大的一个点(这很好,因为无穷远处的一个点也是线的方向向量 -> 稍后需要用于采摘线表示)

(我们可以找到相机中心和另一个任意点,但是我们需要一个额外的步骤来通过减去这两个点的坐标来找到线的方向。)

综上所述,我们发现

  • 相机中心 (p)
  • 线的方向(d)(点@无穷大)(无穷远处的点等价于方向)

这些足以表示一条线,但是当我们必须在算法中计算例如 3D 点到这条线的距离时,这种表示并不是最优的。这就是为什么找到这个表示之后(没有魔法可以立即给我们 plucker 行),我们将 line-representation 更改为 plucker-line-representation

Plucker 线只是需要的线的另一种表示:

  • 线的方向(我们已经有了!!! -> d -> 指向无穷远)
  • 线的“矩”(m),很容易从前面的表示中计算出来:

    m=p^d (^ -> 叉积)

我希望这能为将来需要它的任何人清除问题,我认为这是一件非常容易的事情,但一开始事情可能并不那么明显。

对于一个实际场景,为什么要使用这种 plucker-line-representation,请检查

于 2012-09-15T12:58:20.990 回答
2

供将来使用 Matlab / Octave 语法参考!

Plücker坐标中两点的连接可表示为

% line = point join point
function L=join(A, B)
L=[
        A(1)*B(2)-A(2)*B(1);
        A(1)*B(3)-A(3)*B(1);
        A(1)*B(4)-A(4)*B(1);
        A(2)*B(3)-A(3)*B(2);
        A(2)*B(4)-A(4)*B(2);
        A(3)*B(4)-A(4)*B(3)
];
end % function

这些是反对称矩阵的 6 个不同值

Lx=B*A'-A*B'

可以找到反投影射线上的一个点

X=pinv(P)*x

在哪里

x=[u v 1]'

是像素位置 (u,v) 处的图像点,并且

pinv(P)

投影矩阵的伪逆。

可以找到相机中心作为投影矩阵的零空间

C=null(P);
C=C/C(4)

因此,背投影射线的普吕克坐标为

L=join(X,C)

对于那些对定向投影几何感兴趣的人:如果您将投影矩阵归一化如下

% Get length of principal ray
m3n=norm(P(3,1:3));
% Enforce positivity of determinant
if (det(P(:,1:3))<0)
    m3n=-m3n;
end % if
% Normalize
P=P/m3n;

那么左 3x3 矩阵的行列式是正的(即右手系统),L 将从 C 指向 X。

更新:前几天,一位同事问我要一个矩阵形式的解决方案。如果将以下矩阵与图像点 [x0 x1 x2]' 相乘,则可以直接得到 Plücker 坐标:

A=[
  - p12*p23 + p13*p22, + p02*p23 - p03*p22, + p03*p12 - p02*p13  
  + p11*p23 - p13*p21, - p01*p23 + p03*p21, + p01*p13 - p03*p11  
  - p11*p22 + p12*p21, + p01*p22 - p02*p21, + p02*p11 - p01*p12  
  - p10*p23 + p13*p20, + p00*p23 - p03*p20, + p03*p10 - p00*p13  
  + p10*p22 - p12*p20, - p00*p22 + p02*p20, + p00*p12 - p02*p10  
  - p10*p21 + p11*p20, + p00*p21 - p01*p20, + p01*p10 - p00*p11  
]

因此线的方向是

d =
     p01*p12*x2 - p02*p11*x2 - p01*p22*x1 + p02*p21*x1 + p11*p22*x0 - p12*p21*x0
     p02*p10*x2 - p00*p12*x2 + p00*p22*x1 - p02*p20*x1 - p10*p22*x0 + p12*p20*x0
     p00*p11*x2 - p01*p10*x2 - p00*p21*x1 + p01*p20*x1 + p10*p21*x0 - p11*p20*x0

并且线路时刻是:

m =
     p03*p10*x2 - p00*p13*x2 + p00*p23*x1 - p03*p20*x1 - p10*p23*x0 + p13*p20*x0
     p03*p11*x2 - p01*p13*x2 + p01*p23*x1 - p03*p21*x1 - p11*p23*x0 + p13*p21*x0
     p03*p12*x2 - p02*p13*x2 + p02*p23*x1 - p03*p22*x1 - p12*p23*x0 + p13*p22*x0

显然,可以从表达式中提取出 [x2 x1 x0] 得到矩阵形式。以下 MATLAB 符号代码用于生成此解决方案:

syms p00 p01 p02 p03 p10 p11 p12 p13 p20 p21 p22 p23 real
P=[ p00 p01 p02 p03 
    p10 p11 p12 p13 
    p20 p21 p22 p23 
]

% Some Image Point
syms x0 x1 x2 real 
x=[x0 x1 x2]'

% Source Position
C=null(P)

% Backprojection of x
Xtilde=pinv(P)*x

% Backprojection line (Plücker Matrix)
Lx=simplify(C*Xtilde' - Xtilde*C')

% It's homogeneous...
arbitrary_scale=(p00*p11*p22 - p00*p12*p21 - p01*p10*p22 + p01*p12*p20 + p02*p10*p21 - p02*p11*p20)
Lx=Lx*arbitrary_scale

% Plücker Coordinates:
L=[Lx(1,2) Lx(1,3) Lx(1,4) Lx(2,3) Lx(2,4) Lx(3,4)];
% Direction
d=[-L(3) -L(5) -L(6)]';
% Moment
m=[L(4) -L(2) L(1)]';


% In matrix form
A=[
  - p12*p23 + p13*p22, + p02*p23 - p03*p22, + p03*p12 - p02*p13  
  + p11*p23 - p13*p21, - p01*p23 + p03*p21, + p01*p13 - p03*p11  
  - p11*p22 + p12*p21, + p01*p22 - p02*p21, + p02*p11 - p01*p12  
  - p10*p23 + p13*p20, + p00*p23 - p03*p20, + p03*p10 - p00*p13  
  + p10*p22 - p12*p20, - p00*p22 + p02*p20, + p00*p12 - p02*p10  
  - p10*p21 + p11*p20, + p00*p21 - p01*p20, + p01*p10 - p00*p11  
]

% Verification: (should be zero)
simplify(A*x - L')
于 2014-10-29T07:53:31.220 回答
1

我发布此内容只是为了完整起见,基于 OP 接受的答案中引用的论文中的一些内容、@André Aichert 的答案以及 [1] 的 p493 中的描述。

以下是一个最小工作的 MATLAB 示例,用于构造穿过两点的 Plucker 线AB计算其到点的距离C

A = [0 0 0]';
B = [0 0 5]';
C = [1 1 0]';

L = pluckerline(A,B);

distance = compute_plucker_distance(C, L) % Will output 1.4142

%%-------------------------------------------------------------------------

% Comptes the Plucker line passing through points A and B
function L = pluckerline(A, B)
    l = (B - A) / norm(B - A);
    m = cross(A, l);

    L = [l ; m];
end

%%-------------------------------------------------------------------------

% Comptes the distance between the point P and Plucker line L
function distance = compute_plucker_distance(P, L)
    l = L(1:3);
    m = L(4:end);

    distance = norm(cross(P, l) - m);
end

[1] 萨默,杰拉德,编辑。使用 Clifford 代数进行几何计算:计算机视觉和机器人技术的理论基础和应用。施普林格科学与商业媒体,2013 年。

于 2017-03-12T16:50:44.370 回答