【问题标题】:Computation of Jacobian matrix in cvRodrigues2cvRodrigues2 中雅可比矩阵的计算
【发布时间】:2017-05-07 07:58:51
【问题描述】:

我正在阅读opencv的源代码:cvProjectPoints2cvRodrigues2

cvProjectPoints2中,先用cvRodrigues2( &_r, &matR, &_dRdr );得到雅可比矩阵,然后用rvec(轴角表示)计算像素的偏导数。

if( dpdr_p )
{
    double dx0dr[] =
    {
        X*dRdr[0] + Y*dRdr[1] + Z*dRdr[2],
        X*dRdr[9] + Y*dRdr[10] + Z*dRdr[11],
        X*dRdr[18] + Y*dRdr[19] + Z*dRdr[20]
    };
    double dy0dr[] =
    {
        X*dRdr[3] + Y*dRdr[4] + Z*dRdr[5],
        X*dRdr[12] + Y*dRdr[13] + Z*dRdr[14],
        X*dRdr[21] + Y*dRdr[22] + Z*dRdr[23]
    };
    double dz0dr[] =
    {
        X*dRdr[6] + Y*dRdr[7] + Z*dRdr[8],
        X*dRdr[15] + Y*dRdr[16] + Z*dRdr[17],
        X*dRdr[24] + Y*dRdr[25] + Z*dRdr[26]
    };
    for( j = 0; j < 3; j++ )
    {
        double dxdr = z*(dx0dr[j] - x*dz0dr[j]);
        double dydr = z*(dy0dr[j] - y*dz0dr[j]);
        double dr2dr = 2*x*dxdr + 2*y*dydr;
        double dcdist_dr = k[0]*dr2dr + 2*k[1]*r2*dr2dr + 3*k[4]*r4*dr2dr;
        double dicdist2_dr = -icdist2*icdist2*(k[5]*dr2dr + 2*k[6]*r2*dr2dr + 3*k[7]*r4*dr2dr);
        double da1dr = 2*(x*dydr + y*dxdr);
        double dmxdr = fx*(dxdr*cdist*icdist2 + x*dcdist_dr*icdist2 + x*cdist*dicdist2_dr +
                           k[2]*da1dr + k[3]*(dr2dr + 2*x*dxdr));
        double dmydr = fy*(dydr*cdist*icdist2 + y*dcdist_dr*icdist2 + y*cdist*dicdist2_dr +
                           k[2]*(dr2dr + 2*y*dydr) + k[3]*da1dr);
        dpdr_p[j] = dmxdr;
        dpdr_p[dpdr_step+j] = dmydr;
    }
    dpdr_p += dpdr_step*2;
}

dRdr的形状为3*9,从dRdr的索引使用方式来看:

X*dRdr[0] + Y*dRdr[1] + Z*dRdr[2], //-> dx0dr1
X*dRdr[9] + Y*dRdr[10] + Z*dRdr[11], //-> dx0dr2
X*dRdr[18] + Y*dRdr[19] + Z*dRdr[20] //-> dx0dr3

雅可比矩阵似乎是:

dR1/dr1, dR2/dr1, ..., dR9/dr1,
dR1/dr2, dR2/dr2, ..., dR9/dr2,
dR1/dr3, dR2/dr3, ..., dR9/dr3,

但据我所知,雅可比矩阵的形状应该是 9*3,因为它是 R(1~9) w.r.t r(1~ 3)

dR1/dr1, dR1/dr2, dR1/dr3,
dR2/dr1, dR2/dr2, dR2/dr3,
...
...
dR9/dr1, dR9/dr2, dR9/dr3,

正如docs of cvRodrigues2 所说:

jacobian – 可选输出 Jacobian 矩阵,3x9 或 9x3,它是 输出数组分量的偏导数矩阵 关于输入数组组件。

所以我误解了代码和文档吗?还是代码使用其他约定?或者它是一个错误(不太可能......)?

【问题讨论】:

  • 应该澄清文档中的“3x9 或 9x3”部分..
  • 你在数学定义上确实是对的,我会查一下那部分是什么意思
  • 关于此主题的任何更新?当我使用 cv2.Rodrigues() 函数时,我遇到了同样的问题。当我传递一个旋转向量时,我得到一个旋转矩阵作为输出和一个 3x9 雅可比而不是 9x3。

标签: opencv math matrix derivative


【解决方案1】:

如果您查看文档:

src – Input rotation vector (3x1 or 1x3) or rotation matrix (3x3).
dst – Output rotation matrix (3x3) or rotation vector (3x1 or 1x3), respectively.
jacobian – Optional output Jacobian matrix, 3x9 or 9x3, which is a matrix of partial derivatives of the output array components with respect to the input array components.

如您所见,您可以切换源和目标位置(从数学上讲,这将完全是换位),代码没有考虑到它。

因此,您确实得到了转置雅可比行列式,因为您切换了第一个参数位置(从它们类型的默认位置)。再次切换它们,你会得到正常的雅可比行列式!

【讨论】:

  • “因为你切换了第一个参数位置”是什么意思?在我的示例代码中,src 是 rvec (3x1),dst 是 rmat (3x3)。如果您的 switch 意思是“交换 src 和 dst”,则不会使 Jacob-mat 转置,但据我所知,矩阵的每个元素都从 dR/dr 更改为 dr/dR。跨度>
  • 尝试执行并发布结果。它不会根据文档确定将 dR/dr 更改为 dr/dR,因为它们明确声明 3x3 或 3x1,并且不会将一个替换为另一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-24
  • 2020-07-14
  • 1970-01-01
  • 2018-02-07
  • 2014-11-25
  • 2023-04-02
相关资源
最近更新 更多