Example #1
0
ARFloat Tracker::arModifyMatrix2(ARFloat rot[3][3], ARFloat trans[3], ARFloat cpara[3][4], ARFloat vertex[][3],
        ARFloat pos2d[][2], int num) {
    ARFloat factor;
    ARFloat a, b, c;
    ARFloat a1, b1, c1;
    ARFloat a2, b2, c2;
    ARFloat ma, mb, mc;
    ARFloat combo[3][4];
    ARFloat hx, hy, h, x, y;
    ARFloat err, minerr;
    int t1, t2, t3, tt1, tt2, tt3;
    ARFloat tfact[5] = { 0.96f, 0.98f, 1.0f, 1.02f, 1.04f };
    ARFloat modtrans[3], mmodtrans[3];
    int s1, s2, s3, ss1, ss2, ss3;
    int i, j;

    arGetAngle(rot, &a, &b, &c);

    a2 = a;
    b2 = b;
    c2 = c;
    factor = (ARFloat) (40.0 * M_PI / 180.0);
    for (j = 0; j < 15; j++) {
        minerr = 1000000000.0;
        for (t1 = -1; t1 <= 1; t1++) {
            for (t2 = -1; t2 <= 1; t2++) {
                for (t3 = -1; t3 <= 1; t3++) {
                    for (tt1 = -2; tt1 <= 2; tt1++) {
                        for (tt2 = -2; tt2 <= 2; tt2++) {
                            for (tt3 = -2; tt3 <= 2; tt3++) {

                                a1 = a2 + factor * t1;
                                b1 = b2 + factor * t2;
                                c1 = c2 + factor * t3;
                                modtrans[0] = trans[0] * tfact[tt1 + 2];
                                modtrans[1] = trans[1] * tfact[tt2 + 2];
                                modtrans[2] = trans[2] * tfact[tt3 + 2];

                                arGetNewMatrix(a1, b1, c1, modtrans, NULL, cpara, combo);

                                err = 0.0;
                                for (i = 0; i < num; i++) {
                                    hx = combo[0][0] * vertex[i][0] + combo[0][1] * vertex[i][1] + combo[0][2]
                                            * vertex[i][2] + combo[0][3];
                                    hy = combo[1][0] * vertex[i][0] + combo[1][1] * vertex[i][1] + combo[1][2]
                                            * vertex[i][2] + combo[1][3];
                                    h = combo[2][0] * vertex[i][0] + combo[2][1] * vertex[i][1] + combo[2][2]
                                            * vertex[i][2] + combo[2][3];
                                    x = hx / h;
                                    y = hy / h;

                                    err += (pos2d[i][0] - x) * (pos2d[i][0] - x) + (pos2d[i][1] - y)
                                            * (pos2d[i][1] - y);
                                }

                                if (err < minerr) {
                                    minerr = err;
                                    ma = a1;
                                    mb = b1;
                                    mc = c1;
                                    mmodtrans[0] = modtrans[0];
                                    mmodtrans[1] = modtrans[1];
                                    mmodtrans[2] = modtrans[2];

                                    s1 = t1;
                                    s2 = t2;
                                    s3 = t3;
                                    ss1 = tt1;
                                    ss2 = tt2;
                                    ss3 = tt3;
                                }
                            }
                        }
                    }
                }
            }
        }

        if (s1 == 0 && s2 == 0 && s3 == 0 /*&& ss1 == 0 && ss2 == 0 && ss3 == 0*/)
            factor *= 0.5;
        a2 = ma;
        b2 = mb;
        c2 = mc;
        trans[0] = mmodtrans[0];
        trans[1] = mmodtrans[1];
        trans[2] = mmodtrans[2];
    }

    arGetRot(ma, mb, mc, rot);

    return minerr / num;
}
Example #2
0
ARFloat
Tracker::arModifyMatrix(ARFloat rot[3][3], ARFloat trans[3], ARFloat cpara[3][4],
        ARFloat vertex[][3], ARFloat pos2d[][2], int num)
{
    ARFloat a, b, c;
    ARFloat a2, b2, c2;
    ARFloat ma, mb, mc;
    int t1, t2, t3;
    int s1, s2, s3;
    int i, j, k;
    ARFloat minerr;

    I32 _hx, _hy, _h;
    I32 _err, _minerr;
    U32 _ures;
    I32 _a1,_b1,_c1;
    I32 _a2,_b2,_c2;
    I32 _ma, _mb, _mc;

    //	PROFILE_BEGINSEC(profiler, MODIFYMATRIX)

    FIXED_VEC3D *_vertex = (FIXED_VEC3D*)malloc(num*sizeof(FIXED_VEC3D)),
    *_pos2d = (FIXED_VEC3D*)malloc(num*sizeof(FIXED_VEC3D)),
    _combo[3], _vec1, _vec2, _trans;
    I32 _combo3[3];

    FIXED_VEC3D _cpara[3];
    I32 _cpara3[3];

    _vec1.z = 0;

    _trans.x = FIXED_Float_To_Fixed_n(trans[0], 12);
    _trans.y = FIXED_Float_To_Fixed_n(trans[1], 12);
    _trans.z = FIXED_Float_To_Fixed_n(trans[2], 12);

    for(j=0; j<3; j++)
    {
        _cpara[j].x = FIXED_Float_To_Fixed_n(cpara[j][0], 12);
        _cpara[j].y = FIXED_Float_To_Fixed_n(cpara[j][1], 12);
        _cpara[j].z = FIXED_Float_To_Fixed_n(cpara[j][2], 12);
        _cpara3[j] = FIXED_Float_To_Fixed_n(cpara[j][3], 12);
    }

    for(j=0; j<num; j++)
    {
        _vertex[j].x = FIXED_Float_To_Fixed_n(vertex[j][0], BITS);
        _vertex[j].y = FIXED_Float_To_Fixed_n(vertex[j][1], BITS);
        _vertex[j].z = FIXED_Float_To_Fixed_n(vertex[j][2], BITS);

        _pos2d[j].x = FIXED_Float_To_Fixed_n(pos2d[j][0], BITS);
        _pos2d[j].y = FIXED_Float_To_Fixed_n(pos2d[j][1], BITS);
        _pos2d[j].z = 0;
    }

    arGetAngle( rot, &a, &b, &c );

    // _cpara and _trans are constant, which allows us to calcualte _combo3 beforehand...
    //
    for(j=0; j<3; j++)
    {
        FIXED_VEC3_DOT(_cpara+j, &_trans, _combo3+j, 12);
        _combo3[j] += _cpara3[j];
        _combo3[j] >>= 4;
    }

    //	PROFILE_BEGINSEC(profiler, MODIFYMATRIX_LOOP)

    a2 = a;
    b2 = b;
    c2 = c;
    //factor = (ARFloat)(10.0*M_PI/180.0);

    //I32 fix_a2, fix_b2, fix_c2;
    I32 fix_factor = FIXED_Float_To_Fixed_n((10.0*M_PI/180.0), 12);
    I32 fix_a[3], fix_b[3], fix_c[3];

    _a2 = FIXED_Float_To_Fixed_n(a2, 12);
    _b2 = FIXED_Float_To_Fixed_n(b2, 12);
    _c2 = FIXED_Float_To_Fixed_n(c2, 12);

    for( j = 0; j < 10; j++ ) {
        _minerr = 0x40000000; // value

        fix_a[0] = _a2 - fix_factor; fix_a[1] = _a2; fix_a[2] = _a2 + fix_factor;
        fix_b[0] = _b2 - fix_factor; fix_b[1] = _b2; fix_b[2] = _b2 + fix_factor;
        fix_c[0] = _c2 - fix_factor; fix_c[1] = _c2; fix_c[2] = _c2 + fix_factor;

        for(t1=-1;t1<=1;t1++) {
            for(t2=-1;t2<=1;t2++) {
                for(t3=-1;t3<=1;t3++) {

                    _a1 = fix_a[t1+1];
                    _b1 = fix_b[t2+1];
                    _c1 = fix_c[t3+1];

                    //PROFILE_BEGINSEC(profiler, GETNEWMATRIX)
                    arGetNewMatrix12(_a1, _b1, _c1, _trans, NULL, _cpara, _cpara3, _combo, _combo3, profiler);
                    //PROFILE_ENDSEC(profiler, GETNEWMATRIX)

                    for(k=0; k<3; k++)
                    {
                        _combo[k].x >>= 4;
                        _combo[k].y >>= 4;
                        _combo[k].z >>= 4;
                        //_combo3[k] >>= 4;
                    }

                    _err = 0;
                    for( i = 0; i < num; i++ ) {
                        FIXED_VEC3_DOT(_combo+0, _vertex+i, &_hx, BITS);
                        _hx += _combo3[0];

                        FIXED_VEC3_DOT(_combo+1, _vertex+i, &_hy, BITS);
                        _hy += _combo3[1];

                        FIXED_VEC3_DOT(_combo+2, _vertex+i, &_h, BITS);
                        _h += _combo3[2];

                        // old method of doing two divides
                        // there is no reason at all to use this anymore
                        //
                        //FIXED_DIV2(_hx, _h, _vec1.x, BITS);
                        //FIXED_DIV2(_hy, _h, _vec1.y, BITS);


#ifndef _USE_DIV_TABLE_
                        // new method of doing one correct division
                        // and two multiplications. as accurate as two divisions but faster
                        //
                        I64 _rev = ((I64)1<<(BITS+32))/_h;
                        _vec1.x = (I32)((_hx*_rev)>>32);
                        _vec1.y = (I32)((_hy*_rev)>>32);
#endif

#ifdef _USE_DIV_TABLE_
                        // latest method of using a lookup table for division
                        // extremely fast (+30%) but less accurate
                        if((_h>>8)>=DIV_TABLE_MIN && (_h>>8)<DIV_TABLE_MAX)
                        {
                            I32 _revT4 = DIV_TABLE_FIXEDx4_FROM_FIXED(_h<<8);
                            I32 __x = imul(_hx, _revT4, 18);
                            I32 __y = imul(_hy, _revT4, 18);

#ifdef DEBUG_DIV_RANGE
                            int dx = __x-_vec1.x>0 ? __x-_vec1.x : _vec1.x-__x;
                            int dy = __y-_vec1.y>0 ? __y-_vec1.y : _vec1.y-__y;
                            if(dx>dbgInfo.dxMax) dbgInfo.dxMax = dx;
                            if(dy>dbgInfo.dyMax) dbgInfo.dyMax = dy;

                            if(dx/256.0f > 1.0f)
                            dx = dx;
                            if(dy/256.0f > 1.0f)
                            dy = dy;
#endif
                            _vec1.x = __x;
                            _vec1.y = __y;
                        }
                        else
                        {
                            I64 _rev = ((I64)1<<(BITS+32))/_h;
                            _vec1.x = (I32)((_hx*_rev)>>32);
                            _vec1.y = (I32)((_hy*_rev)>>32);
                        }
#endif //_USE_DIV_TABLE_
#ifdef DEBUG_DIV_RANGE
                        if(_h<dbgInfo.hMin) dbgInfo.hMin = _h;
                        if(_h>dbgInfo.hMax) dbgInfo.hMax = _h;
                        if(_hx<dbgInfo.hxMin) dbgInfo.hxMin = _hx;
                        if(_hx>dbgInfo.hxMax) dbgInfo.hxMax = _hx;
                        if(_hy<dbgInfo.hyMin) dbgInfo.hyMin = _hy;
                        if(_hy>dbgInfo.hyMax) dbgInfo.hyMax = _hy;
                        if(_hy>dbgInfo.hyMax) dbgInfo.hyMax = _hy;
#endif

                        FIXED_VEC2_SUB(_pos2d+i, &_vec1, &_vec2);
                        FIXED_VEC2_LENGTH_SQ(&_vec2, &_ures, BITS);
                        _err += _ures;
                    }

                    if( _err < _minerr ) {
                        _minerr = _err;
                        _ma = _a1;
                        _mb = _b1;
                        _mc = _c1;
                        s1 = t1; s2 = t2; s3 = t3;
                    }
                }
            }
        }

        if(s1 == 0 && s2 == 0 && s3 == 0)
        fix_factor >>= 1;

        _a2 = _ma;
        _b2 = _mb;
        _c2 = _mc;
    }
double arsModifyMatrix( double rot[3][3], double trans[3], ARSParam *arsParam,
                        double pos3dL[][3], double pos2dL[][2], int numL,
                        double pos3dR[][3], double pos2dR[][2], int numR )
{
    double    factor;
    double    a, b, c;
    double    a1, b1, c1;
    double    a2, b2, c2;
    double    ma = 0.0, mb = 0.0, mc = 0.0;
    double    combo[3][4];
    double    hx, hy, h, x, y;
    double    err, minerr;
    int       t1, t2, t3;
    int       s1 = 0, s2 = 0, s3 = 0;
    int       i, j;
    
    arGetAngle( rot, &a, &b, &c );
    
    a2 = a;
    b2 = b;
    c2 = c;
    factor = 10.0*MD_PI/180.0;
    for( j = 0; j < 10; j++ ) {
        minerr = 1000000000.0;
        for(t1=-1;t1<=1;t1++) {
        for(t2=-1;t2<=1;t2++) {
        for(t3=-1;t3<=1;t3++) {
            a1 = a2 + factor*t1;
            b1 = b2 + factor*t2;
            c1 = c2 + factor*t3;
            err = 0.0;

            arGetNewMatrix( a1, b1, c1, trans, NULL, arsParam->matL, combo );
            for( i = 0; i < numL; i++ ) {
                hx = combo[0][0] * pos3dL[i][0]
                   + combo[0][1] * pos3dL[i][1]
                   + combo[0][2] * pos3dL[i][2]
                   + combo[0][3];
                hy = combo[1][0] * pos3dL[i][0]
                   + combo[1][1] * pos3dL[i][1]
                   + combo[1][2] * pos3dL[i][2]
                   + combo[1][3];
                h  = combo[2][0] * pos3dL[i][0]
                   + combo[2][1] * pos3dL[i][1]
                   + combo[2][2] * pos3dL[i][2]
                   + combo[2][3];
                x = hx / h;
                y = hy / h;
                err += (pos2dL[i][0] - x) * (pos2dL[i][0] - x)
                     + (pos2dL[i][1] - y) * (pos2dL[i][1] - y);
            }

            arGetNewMatrix( a1, b1, c1, trans, arsParam->matL2R, arsParam->matR, combo );
            for( i = 0; i < numR; i++ ) {
                hx = combo[0][0] * pos3dR[i][0]
                   + combo[0][1] * pos3dR[i][1]
                   + combo[0][2] * pos3dR[i][2]
                   + combo[0][3];
                hy = combo[1][0] * pos3dR[i][0]
                   + combo[1][1] * pos3dR[i][1]
                   + combo[1][2] * pos3dR[i][2]
                   + combo[1][3];
                h  = combo[2][0] * pos3dR[i][0]
                   + combo[2][1] * pos3dR[i][1]
                   + combo[2][2] * pos3dR[i][2]
                   + combo[2][3];
                x = hx / h;
                y = hy / h;

                err += (pos2dR[i][0] - x) * (pos2dR[i][0] - x)
                     + (pos2dR[i][1] - y) * (pos2dR[i][1] - y);
            }

            if( err < minerr ) {
                minerr = err;
                ma = a1;
                mb = b1;
                mc = c1;
                s1 = t1; s2 = t2; s3 = t3;
            }
        }
        }
        }

        if( s1 == 0 && s2 == 0 && s3 == 0 ) factor *= 0.5;
        a2 = ma;
        b2 = mb;
        c2 = mc;
    }

    arGetRot( ma, mb, mc, rot );

    return minerr / (numL+numR);
}
Example #4
0
ARFloat Tracker::arGetTransMatSub(ARFloat rot[3][3], ARFloat ppos2d[][2], ARFloat pos3d[][3], int num,
        ARFloat conv[3][4], Camera *pCam)
//ARFloat *dist_factor, ARFloat cpara[3][4] )
{
    ARMat *mat_a, *mat_b, *mat_c, *mat_d, *mat_e, *mat_f;
    ARFloat trans[3];
    ARFloat wx, wy, wz;
    ARFloat ret;
    int i, j;

    mat_a = Matrix::alloc(num * 2, 3);
    mat_b = Matrix::alloc(3, num * 2);
    mat_c = Matrix::alloc(num * 2, 1);
    mat_d = Matrix::alloc(3, 3);
    mat_e = Matrix::alloc(3, 1);
    mat_f = Matrix::alloc(3, 1);

    if (arFittingMode == AR_FITTING_TO_INPUT) {
        for (i = 0; i < num; i++) {
            arCameraIdeal2Observ_std(pCam, ppos2d[i][0], ppos2d[i][1], &pos2d[i][0], &pos2d[i][1]);
        }
    } else {
        for (i = 0; i < num; i++) {
            pos2d[i][0] = ppos2d[i][0];
            pos2d[i][1] = ppos2d[i][1];
        }
    }

    for (j = 0; j < num; j++) {
        wx = rot[0][0] * pos3d[j][0] + rot[0][1] * pos3d[j][1] + rot[0][2] * pos3d[j][2];
        wy = rot[1][0] * pos3d[j][0] + rot[1][1] * pos3d[j][1] + rot[1][2] * pos3d[j][2];
        wz = rot[2][0] * pos3d[j][0] + rot[2][1] * pos3d[j][1] + rot[2][2] * pos3d[j][2];
        mat_a->m[j * 6 + 0] = mat_b->m[num * 0 + j * 2] = pCam->mat[0][0];
        mat_a->m[j * 6 + 1] = mat_b->m[num * 2 + j * 2] = pCam->mat[0][1];
        mat_a->m[j * 6 + 2] = mat_b->m[num * 4 + j * 2] = pCam->mat[0][2] - pos2d[j][0];
        mat_c->m[j * 2 + 0] = wz * pos2d[j][0] - pCam->mat[0][0] * wx - pCam->mat[0][1] * wy - pCam->mat[0][2] * wz;
        mat_a->m[j * 6 + 3] = mat_b->m[num * 0 + j * 2 + 1] = 0.0;
        mat_a->m[j * 6 + 4] = mat_b->m[num * 2 + j * 2 + 1] = pCam->mat[1][1];
        mat_a->m[j * 6 + 5] = mat_b->m[num * 4 + j * 2 + 1] = pCam->mat[1][2] - pos2d[j][1];
        mat_c->m[j * 2 + 1] = wz * pos2d[j][1] - pCam->mat[1][1] * wy - pCam->mat[1][2] * wz;
    }
    Matrix::mul(mat_d, mat_b, mat_a);
    Matrix::mul(mat_e, mat_b, mat_c);
    Matrix::selfInv(mat_d);
    Matrix::mul(mat_f, mat_d, mat_e);
    trans[0] = mat_f->m[0];
    trans[1] = mat_f->m[1];
    trans[2] = mat_f->m[2];

    /*trans[0] = 3.96559f;
     trans[1] = 27.0546f;
     trans[2] = 274.627f;*/

    {
        ARFloat a, b, c;
        arGetAngle(rot, &a, &b, &c);

        //trans[0] = -13.5f;
        //trans[1] = 45.7f;
        //trans[2] = 303.0f;
        //arGetRot( -90.5f*3.1415f/180.0f, 120.3f*3.1415f/180.0f, 31.2f*3.1415f/180.0f, rot );

        ret = arModifyMatrix(rot, trans, pCam->mat, pos3d, pos2d, num);

        arGetAngle(rot, &a, &b, &c);
        a = a;
    }

    // double begin
    //
    /*for( j = 0; j < num; j++ ) {
     wx = rot[0][0] * pos3d[j][0]
     + rot[0][1] * pos3d[j][1]
     + rot[0][2] * pos3d[j][2];
     wy = rot[1][0] * pos3d[j][0]
     + rot[1][1] * pos3d[j][1]
     + rot[1][2] * pos3d[j][2];
     wz = rot[2][0] * pos3d[j][0]
     + rot[2][1] * pos3d[j][1]
     + rot[2][2] * pos3d[j][2];
     mat_a->m[j*6+0] = mat_b->m[num*0+j*2] = pCam->mat[0][0];
     mat_a->m[j*6+1] = mat_b->m[num*2+j*2] = pCam->mat[0][1];
     mat_a->m[j*6+2] = mat_b->m[num*4+j*2] = pCam->mat[0][2] - pos2d[j][0];
     mat_c->m[j*2+0] = wz * pos2d[j][0]
     - pCam->mat[0][0]*wx - pCam->mat[0][1]*wy - pCam->mat[0][2]*wz;
     mat_a->m[j*6+3] = mat_b->m[num*0+j*2+1] = 0.0;
     mat_a->m[j*6+4] = mat_b->m[num*2+j*2+1] = pCam->mat[1][1];
     mat_a->m[j*6+5] = mat_b->m[num*4+j*2+1] = pCam->mat[1][2] - pos2d[j][1];
     mat_c->m[j*2+1] = wz * pos2d[j][1]
     - pCam->mat[1][1]*wy - pCam->mat[1][2]*wz;
     }
     Matrix::mul( mat_d, mat_b, mat_a );
     Matrix::mul( mat_e, mat_b, mat_c );
     Matrix::selfInv( mat_d );
     Matrix::mul( mat_f, mat_d, mat_e );
     trans[0] = mat_f->m[0];
     trans[1] = mat_f->m[1];
     trans[2] = mat_f->m[2];

     ret = arModifyMatrix( rot, trans, pCam->mat, pos3d, pos2d, num );*/
    //
    // double end

    Matrix::free(mat_a);
    Matrix::free(mat_b);
    Matrix::free(mat_c);
    Matrix::free(mat_d);
    Matrix::free(mat_e);
    Matrix::free(mat_f);

    for (j = 0; j < 3; j++) {
        for (i = 0; i < 3; i++)
            conv[j][i] = rot[j][i];
        conv[j][3] = trans[j];
    }

    return ret;
}
double arModifyMatrix( double rot[3][3], double trans[3], double cpara[3][4],
                             double vertex[][3], double pos2d[][2], int num )
{
    double    factor;
    double    a, b, c;
    double    a1, b1, c1;
    double    a2, b2, c2;
    double    ma = 0.0, mb = 0.0, mc = 0.0;
    double    combo[3][4];
    double    hx, hy, h, x, y;
    double    err, minerr;
    int       t1, t2, t3;
    int       s1 = 0, s2 = 0, s3 = 0;
    int       i, j;

    arGetAngle( rot, &a, &b, &c );

    a2 = a;
    b2 = b;
    c2 = c;
    factor = 10.0*MD_PI/180.0;
    for( j = 0; j < 10; j++ ) {
        minerr = 1000000000.0;
        for(t1=-1;t1<=1;t1++) {
        for(t2=-1;t2<=1;t2++) {
        for(t3=-1;t3<=1;t3++) {
            a1 = a2 + factor*t1;
            b1 = b2 + factor*t2;
            c1 = c2 + factor*t3;
            arGetNewMatrix( a1, b1, c1, trans, NULL, cpara, combo );

            err = 0.0;
            for( i = 0; i < num; i++ ) {
                hx = combo[0][0] * vertex[i][0]
                   + combo[0][1] * vertex[i][1]
                   + combo[0][2] * vertex[i][2]
                   + combo[0][3];
                hy = combo[1][0] * vertex[i][0]
                   + combo[1][1] * vertex[i][1]
                   + combo[1][2] * vertex[i][2]
                   + combo[1][3];
                h  = combo[2][0] * vertex[i][0]
                   + combo[2][1] * vertex[i][1]
                   + combo[2][2] * vertex[i][2]
                   + combo[2][3];
                x = hx / h;
                y = hy / h;

                err += (pos2d[i][0] - x) * (pos2d[i][0] - x)
                     + (pos2d[i][1] - y) * (pos2d[i][1] - y);
            }

            if( err < minerr ) {
                minerr = err;
                ma = a1;
                mb = b1;
                mc = c1;
                s1 = t1; s2 = t2; s3 = t3;
            }
        }
        }
        }

        if( s1 == 0 && s2 == 0 && s3 == 0 ) factor *= 0.5;
        a2 = ma;
        b2 = mb;
        c2 = mc;
    }

    arGetRot( ma, mb, mc, rot );

/*  printf("factor = %10.5f\n", factor*180.0/MD_PI); */

    return minerr/num;
}