Calculating Jacobi matrix in cvRodrigues2

I am reading the opencv source code : cvProjectPoints2

, cvRodrigues2

.

The cvProjectPoints2

Jacobian matrix is ​​first used cvRodrigues2( &_r, &matR, &_dRdr );

and then used to compute the partial derivative of the pixels wrt rvec (axis representation).

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;
}

      

Form dRdr

3 * 9 and from how the indices are used 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

      

the Jacobian matrix looks like this:

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

      

But as far as I know, the Jacobi matrix should have the form 9 * 3 , since its derivatives from R (1 ~ 9) wrt r (1 ~ 3) :

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

      

As the docscvRodrigues2

says:

jacobian - An optional Jacobian matrix, 3x9 or 9x3, which is the partial derived matrix of the array's output elements with relative to the array's input elements.

So I don't understand the code and docs? Or is this code using a different convention? Or is it a bug (hardly ...)?

+3


source to share


1 answer


If you look at the docs:

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.

      



As you can see, you can switch the source and target locations (mathematically, this would be exactly a transposition) , but the code doesn't account for it.

Therefore, you have a transposed Jacobian because you switched the first arguments (from the default locations for their types). Switch them again and you have a normal Jacobian!

+1


source







All Articles