Пример #1
0
//==============================================
// Baseを原点とした場合のTargetの相対位置を取得
//==============================================
void cARTK::getMarkerPos( Vector3 *pvec3MarkerPos, int iPattIndexBase, int iPattIndexTarget )
{
	double		dInvBaseTransMat[3][4];
	double		dTargetTransMat[3][4];

	arUtilMatInv( m_sMarkerInfo[iPattIndexBase].dTransMat, dInvBaseTransMat );
	arUtilMatMul( dInvBaseTransMat, m_sMarkerInfo[iPattIndexTarget].dTransMat, dTargetTransMat );

	pvec3MarkerPos->x = (float)dTargetTransMat[0][3];
	pvec3MarkerPos->y = (float)dTargetTransMat[1][3];
	pvec3MarkerPos->z = (float)dTargetTransMat[2][3];
	Vector3Transform( pvec3MarkerPos, pvec3MarkerPos, m_matRotX );

	pvec3MarkerPos->x *= (float)m_dViewScaleFactor;
	pvec3MarkerPos->y *= (float)m_dViewScaleFactor;
	pvec3MarkerPos->z *= (float)m_dViewScaleFactor;
}
osg::MatrixTransform* Worker::mt2mtCoordinates(osg::MatrixTransform* mtA, osg::MatrixTransform* mtB)
{
	double matrix1[3][4]; double matrix2[3][4];	// Auxiliar double matrix to calculate distances between OSG objects(matrixTransforms).
	double matrixA[3][4]; double matrixB[3][4]; 	// mtA and mtB in double matrix format.
	osg::MatrixTransform* mtAfromB;
	mtAfromB = new osg::MatrixTransform();
  
	matrixTransform2matrixDouble(mtA,matrixA);
	matrixTransform2matrixDouble(mtB,matrixB);
// 	if (osgArt->getMarker1()->valid() || osgArt->getMarker2()->valid())
// 	{
	  arUtilMatInv(matrixA, matrix1);// Now matrix1 is the inverse of matrixA
	  arUtilMatMul(matrix1, matrixB, matrix2);
	  matrixDouble2matrixTransform(matrix2, mtAfromB);
	  return mtAfromB;
// 	}
// 	else
// 	{
// 	  std::cout<<"The ARToolKit marks are out of camera vision. Please show the 2 marks to the camera."<<std::endl;
// 	  distance2mole1=9999;
// 	}
}
Пример #3
0
static void calib(void)
{
    ICPHandleT *icpHandleL;
    ICPHandleT *icpHandleR;
    ICPDataT    icpData;
    ARdouble    initMatXw2Xc[3][4];
    ARdouble    initTransL2R[3][4], matL[3][4], matR[3][4], invMatL[3][4];
    ARdouble    transL2R[3][4];
    ARdouble    err;
    int         i;

    if( (icpHandleL = icpCreateHandle(paramL.mat)) == NULL ) {
        ARLOG("Error!! icpCreateHandle\n");
        return;
    }
    icpSetBreakLoopErrorThresh( icpHandleL, 0.00001 );
    if( (icpHandleR = icpCreateHandle(paramR.mat)) == NULL ) {
        ARLOG("Error!! icpCreateHandle\n");
        return;
    }
    icpSetBreakLoopErrorThresh( icpHandleR, 0.00001 );

    for( i = 0; i < calibImageNum; i++ ) {
        if( icpGetInitXw2Xc_from_PlanarData(paramL.mat, calibData[i].screenCoordL, calibData[i].worldCoordL, calibData[i].numL, calibData[i].initMatXw2Xcl) < 0 ) {
            ARLOG("Error!! icpGetInitXw2Xc_from_PlanarData\n");
            return;
        }
        icpData.screenCoord = calibData[i].screenCoordL;
        icpData.worldCoord  = calibData[i].worldCoordL;
        icpData.num = calibData[i].numL;
    }

    if( icpGetInitXw2Xc_from_PlanarData(paramL.mat, calibData[0].screenCoordL, calibData[0].worldCoordL, calibData[0].numL, initMatXw2Xc) < 0 ) {
        ARLOG("Error!! icpGetInitXw2Xc_from_PlanarData\n");
        return;
    }
    icpData.screenCoord = calibData[0].screenCoordL;
    icpData.worldCoord  = calibData[0].worldCoordL;
    icpData.num = calibData[0].numL;
    if( icpPoint(icpHandleL, &icpData, initMatXw2Xc, matL, &err) < 0 ) {
        ARLOG("Error!! icpPoint\n");
        return;
    }
    if( icpGetInitXw2Xc_from_PlanarData(paramR.mat, calibData[0].screenCoordR, calibData[0].worldCoordR, calibData[0].numR, matR) < 0 ) {
        ARLOG("Error!! icpGetInitXw2Xc_from_PlanarData\n");
        return;
    }
    icpData.screenCoord = calibData[0].screenCoordR;
    icpData.worldCoord  = calibData[0].worldCoordR;
    icpData.num = calibData[0].numR;
    if( icpPoint(icpHandleR, &icpData, initMatXw2Xc, matR, &err) < 0 ) {
        ARLOG("Error!! icpPoint\n");
        return;
    }
    arUtilMatInv( matL, invMatL );
    arUtilMatMul( matR, invMatL, initTransL2R );

    if( icpCalibStereo(calibData, calibImageNum, paramL.mat, paramR.mat, initTransL2R, transL2R, &err) < 0 ) {
        ARLOG("Calibration error!!\n");
        return;
    }
    ARLOG("Estimated transformation matrix from Left to Right.\n");
    arParamDispExt( transL2R );

    saveParam( transL2R );
}
Пример #4
0
int arGetStereoMatching(AR3DStereoHandle *handle, ARdouble pos2dL[2], ARdouble pos2dR[2], ARdouble pos3d[3])
{
    ARMat   *matP,  *matQ;
    ARMat   *matPt, *matR, *matS, *matT;
    ARdouble   wL[3][4], wR[3][4];

    arUtilMatMul( handle->icpStereoHandle->matXcl2Ul, handle->icpStereoHandle->matC2L, wL );
    arUtilMatMul( handle->icpStereoHandle->matXcr2Ur, handle->icpStereoHandle->matC2R, wR );

    matP  = arMatrixAlloc(4,3);
    matPt = arMatrixAlloc(3,4);
    matQ  = arMatrixAlloc(4,1);
    matR  = arMatrixAlloc(3,3);
    matS  = arMatrixAlloc(3,1);
    matT  = arMatrixAlloc(3,1);

    matP->m[0*3+0] = matPt->m[0*4+0] = wL[0][0] - wL[2][0] * pos2dL[0];
    matP->m[0*3+1] = matPt->m[1*4+0] = wL[0][1] - wL[2][1] * pos2dL[0];
    matP->m[0*3+2] = matPt->m[2*4+0] = wL[0][2] - wL[2][2] * pos2dL[0];
    matP->m[1*3+0] = matPt->m[0*4+1] = wL[1][0] - wL[2][0] * pos2dL[1];
    matP->m[1*3+1] = matPt->m[1*4+1] = wL[1][1] - wL[2][1] * pos2dL[1];
    matP->m[1*3+2] = matPt->m[2*4+1] = wL[1][2] - wL[2][2] * pos2dL[1];

    matP->m[2*3+0] = matPt->m[0*4+2] = wR[0][0] - wR[2][0] * pos2dR[0];
    matP->m[2*3+1] = matPt->m[1*4+2] = wR[0][1] - wR[2][1] * pos2dR[0];
    matP->m[2*3+2] = matPt->m[2*4+2] = wR[0][2] - wR[2][2] * pos2dR[0];
    matP->m[3*3+0] = matPt->m[0*4+3] = wR[1][0] - wR[2][0] * pos2dR[1];
    matP->m[3*3+1] = matPt->m[1*4+3] = wR[1][1] - wR[2][1] * pos2dR[1];
    matP->m[3*3+2] = matPt->m[2*4+3] = wR[1][2] - wR[2][2] * pos2dR[1];
                                                                                                   
    matQ->m[0] = wL[2][3] * pos2dL[0] - wL[0][3];
    matQ->m[1] = wL[2][3] * pos2dL[1] - wL[1][3];
    matQ->m[2] = wR[2][3] * pos2dR[0] - wR[0][3];
    matQ->m[3] = wR[2][3] * pos2dR[1] - wR[1][3];

    arMatrixMul( matR, matPt, matP );
    arMatrixMul( matS, matPt, matQ );
    if( arMatrixSelfInv( matR ) < 0 ) {
        arMatrixFree( matP );
        arMatrixFree( matPt);
        arMatrixFree( matQ );
        arMatrixFree( matR );
        arMatrixFree( matS );
        arMatrixFree( matT );
        return -1;
    }
    arMatrixMul( matT, matR, matS );

    pos3d[0] = matT->m[0];
    pos3d[1] = matT->m[1];
    pos3d[2] = matT->m[2];
                                                                                                   
    arMatrixFree( matP );
    arMatrixFree( matPt);
    arMatrixFree( matQ );
    arMatrixFree( matR );
    arMatrixFree( matS );
    arMatrixFree( matT );
                                                                                                   
    return 0;
}
Пример #5
0
static ARdouble  arGetTransMatMultiSquare2(AR3DHandle *handle, ARMarkerInfo *marker_info, int marker_num,
                                         ARMultiMarkerInfoT *config, int robustFlag)
{
    ARdouble              *pos2d, *pos3d;
    ARdouble              trans1[3][4], trans2[3][4];
    ARdouble              err, err2;
    int                   max, maxArea;
    int                   vnum;
    int                   dir;
    int                   i, j, k;
    //char  mes[12];

    //ARLOG("-- Pass1--\n");
    for( i = 0; i < config->marker_num; i++ ) {
        k = -1;
        if( config->marker[i].patt_type == AR_MULTI_PATTERN_TYPE_TEMPLATE ) {
            for( j = 0; j < marker_num; j++ ) {
                if( marker_info[j].idPatt != config->marker[i].patt_id ) continue;
                if( marker_info[j].cfPatt < config->cfPattCutoff ) continue;
                if( k == -1 ) k = j;
                else if( marker_info[k].cfPatt < marker_info[j].cfPatt ) k = j;
            }
            config->marker[i].visible = k;
            if( k >= 0 ) marker_info[k].dir = marker_info[k].dirPatt;
        }
        else { // config->marker[i].patt_type == AR_MULTI_PATTERN_TYPE_MATRIX
            for( j = 0; j < marker_num; j++ ) {
                // Check if we need to examine the globalID rather than patt_id.
                if (marker_info[j].idMatrix == 0 && marker_info[j].globalID != 0ULL) {
                    if( marker_info[j].globalID != config->marker[i].globalID ) continue;
                } else {
                    if( marker_info[j].idMatrix != config->marker[i].patt_id ) continue;
                }
                if( marker_info[j].cfMatrix < config->cfMatrixCutoff ) continue;
                if( k == -1 ) k = j;
                else if( marker_info[k].cfMatrix < marker_info[j].cfMatrix ) k = j;
            }
            config->marker[i].visible = k;
            if( k >= 0 ) marker_info[k].dir = marker_info[k].dirMatrix;
        }
        //if(k>=0) ARLOG(" *%d\n",i);
    }

    //ARLOG("-- Pass2--\n");
    vnum = 0;
    for( i = 0; i < config->marker_num; i++ ) {
        if( (j=config->marker[i].visible) < 0 ) continue;

        //glColor3f( 1.0, 1.0, 0.0 );
        //sprintf(mes,"%d",i);
        //argDrawStringsByIdealPos( mes, marker_info[j].pos[0], marker_info[j].pos[1] );
        err = arGetTransMatSquare(handle, &marker_info[j], config->marker[i].width, trans2);
        //ARLOG(" [%d:dir=%d] err = %f (%f,%f,%f)\n", i, marker_info[j].dir, err, trans2[0][3], trans2[1][3], trans2[2][3]);
        if( err > AR_MULTI_POSE_ERROR_CUTOFF_EACH_DEFAULT ) {
            config->marker[i].visible = -1;
            if (marker_info[j].cutoffPhase == AR_MARKER_INFO_CUTOFF_PHASE_NONE) marker_info[j].cutoffPhase = AR_MARKER_INFO_CUTOFF_PHASE_POSE_ERROR;
            continue;
        }
        //ARLOG(" *%d\n",i);
        
        // Use the largest (in terms of 2D coordinates) marker's pose estimate as the
        // input for the initial estimate for the pose estimator. 
        if( vnum == 0 || maxArea < marker_info[j].area ) {
            maxArea = marker_info[j].area;
            max = i; 
            for( j = 0; j < 3; j++ ) { 
                for( k = 0; k < 4; k++ ) trans1[j][k] = trans2[j][k];
            }
        }
        vnum++;
    }
    if( vnum == 0 || vnum < config->min_submarker) { 
        config->prevF = 0;
        return -1;
    }
    arUtilMatMul( (const ARdouble (*)[4])trans1, (const ARdouble (*)[4])config->marker[max].itrans, trans2 ); 
    
    arMalloc(pos2d, ARdouble, vnum*4*2);
    arMalloc(pos3d, ARdouble, vnum*4*3);
    
    j = 0; 
    for( i = 0; i < config->marker_num; i++ ) { 
        if( (k=config->marker[i].visible) < 0 ) continue;
        
        dir = marker_info[k].dir;
        pos2d[j*8+0] = marker_info[k].vertex[(4-dir)%4][0];
        pos2d[j*8+1] = marker_info[k].vertex[(4-dir)%4][1];
        pos2d[j*8+2] = marker_info[k].vertex[(5-dir)%4][0];
        pos2d[j*8+3] = marker_info[k].vertex[(5-dir)%4][1];
        pos2d[j*8+4] = marker_info[k].vertex[(6-dir)%4][0];
        pos2d[j*8+5] = marker_info[k].vertex[(6-dir)%4][1];
        pos2d[j*8+6] = marker_info[k].vertex[(7-dir)%4][0];
        pos2d[j*8+7] = marker_info[k].vertex[(7-dir)%4][1];
        pos3d[j*12+0] = config->marker[i].pos3d[0][0];
        pos3d[j*12+1] = config->marker[i].pos3d[0][1];
        pos3d[j*12+2] = config->marker[i].pos3d[0][2];
        pos3d[j*12+3] = config->marker[i].pos3d[1][0];
        pos3d[j*12+4] = config->marker[i].pos3d[1][1];
        pos3d[j*12+5] = config->marker[i].pos3d[1][2];
        pos3d[j*12+6] = config->marker[i].pos3d[2][0];
        pos3d[j*12+7] = config->marker[i].pos3d[2][1];
        pos3d[j*12+8] = config->marker[i].pos3d[2][2];
        pos3d[j*12+9] = config->marker[i].pos3d[3][0];
        pos3d[j*12+10] = config->marker[i].pos3d[3][1];
        pos3d[j*12+11] = config->marker[i].pos3d[3][2];
        j++;
    }
    

    if( config->prevF == 0 ) {
        if( robustFlag ) {
            err = arGetTransMat( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
            if( err >= AR_MULTI_POSE_ERROR_CUTOFF_COMBINED_DEFAULT ) {
                icpSetInlierProbability( handle->icpHandle, 0.8 );
                err = arGetTransMatRobust( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
                if( err >= AR_MULTI_POSE_ERROR_CUTOFF_COMBINED_DEFAULT ) {
                    icpSetInlierProbability( handle->icpHandle, 0.6 );
                    err = arGetTransMatRobust( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
                    if( err >= AR_MULTI_POSE_ERROR_CUTOFF_COMBINED_DEFAULT ) {
                        icpSetInlierProbability( handle->icpHandle, 0.4 );
                        err = arGetTransMatRobust( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
                        if( err >= AR_MULTI_POSE_ERROR_CUTOFF_COMBINED_DEFAULT ) {
                            icpSetInlierProbability( handle->icpHandle, 0.0 );
                            err = arGetTransMatRobust( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
                        }
                    }
                }
            }
        }
        else {
            err = arGetTransMat( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
        }
        free(pos3d);
        free(pos2d);
    }
    else {
        if( robustFlag ) {
            err2 = arGetTransMat( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, trans1 );
            err = arGetTransMat( handle, config->trans, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
            if( err2 < err ) {
                for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                err = err2;
            }
            if( err >= AR_MULTI_POSE_ERROR_CUTOFF_COMBINED_DEFAULT ) {
                icpSetInlierProbability( handle->icpHandle, 0.8 );
                err2 = arGetTransMatRobust( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, trans1 );
                err = arGetTransMatRobust( handle, config->trans, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
                if( err2 < err ) {
                    for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                    err = err2;
                }
                if( err >= AR_MULTI_POSE_ERROR_CUTOFF_COMBINED_DEFAULT ) {
                    icpSetInlierProbability( handle->icpHandle, 0.6 );
                    err2 = arGetTransMatRobust( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, trans1 );
                    err = arGetTransMatRobust( handle, config->trans, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
                    if( err2 < err ) {
                        for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                        err = err2;
                    }
                    if( err >= AR_MULTI_POSE_ERROR_CUTOFF_COMBINED_DEFAULT ) {
                        icpSetInlierProbability( handle->icpHandle, 0.4 );
                        err2 = arGetTransMatRobust( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, trans1 );
                        err = arGetTransMatRobust( handle, config->trans, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
                        if( err2 < err ) {
                            for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                            err = err2;
                        }
                        if( err >= AR_MULTI_POSE_ERROR_CUTOFF_COMBINED_DEFAULT ) {
                            icpSetInlierProbability( handle->icpHandle, 0.0 );
                            err2 = arGetTransMatRobust( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, trans1 );
                            err = arGetTransMatRobust( handle, config->trans, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
                            if( err2 < err ) {
                                for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                                err = err2;
                            }
                        }
                    }
                }
            }
        }
        else {
            err2 = arGetTransMat( handle, trans2, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, trans1 );
            err = arGetTransMat( handle, config->trans, (ARdouble (*)[2])pos2d, (ARdouble (*)[3])pos3d, vnum*4, config->trans );
            if( err2 < err ) {
                for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                err = err2;
            }
        }
        free(pos3d);
        free(pos2d);
    }
    
    if (err < AR_MULTI_POSE_ERROR_CUTOFF_COMBINED_DEFAULT) config->prevF = 1;
    else {
        config->prevF = 0;
        for (i = 0; i < config->marker_num; i++) { 
            if ((k = config->marker[i].visible) < 0) continue;
            if (marker_info[k].cutoffPhase == AR_MARKER_INFO_CUTOFF_PHASE_NONE) marker_info[k].cutoffPhase = AR_MARKER_INFO_CUTOFF_PHASE_POSE_ERROR_MULTI;
        }
    }

    return err;
}
Пример #6
0
int icpStereoPointRobust( ICPStereoHandleT   *handle,
                          ICPStereoDataT     *data,
                          ARdouble              initMatXw2Xc[3][4],
                          ARdouble              matXw2Xc[3][4],
                          ARdouble             *err )
{
    ICP2DCoordT   U;
    ARdouble       *J_U_S;
    ARdouble       *dU, dx, dy;
    ARdouble       *E, *E2, K2, W;
    ARdouble        matXw2Ul[3][4];
    ARdouble        matXw2Ur[3][4];
    ARdouble        matXc2Ul[3][4];
    ARdouble        matXc2Ur[3][4];
    ARdouble        dS[6];
    ARdouble        err0, err1;
    int           inlierNum;
    int           i, j, k;
#if ICP_DEBUG
    int           l;
#endif

    if( data->numL + data->numR < 4 ) return -1;

    inlierNum = (int)((data->numL + data->numR) * handle->inlierProb) - 1;
    if( inlierNum < 3 ) inlierNum = 3;

    if( (J_U_S = (ARdouble *)malloc( sizeof(ARdouble)*12*(data->numL + data->numR) )) == NULL ) {
        ARLOGe("Error: malloc\n");
        return -1;
    }
    if( (dU = (ARdouble *)malloc( sizeof(ARdouble)*2*(data->numL + data->numR) )) == NULL ) {
        ARLOGe("Error: malloc\n");
        free(J_U_S);
        return -1;
    }
    if( (E = (ARdouble *)malloc( sizeof(ARdouble)*(data->numL + data->numR) )) == NULL ) {
        ARLOGe("Error: malloc\n");
        free(J_U_S);
        free(dU);
        return -1;
    }
    if( (E2 = (ARdouble *)malloc( sizeof(ARdouble)*(data->numL + data->numR) )) == NULL ) {
        ARLOGe("Error: malloc\n");
        free(J_U_S);
        free(dU);
        free(E);
        return -1;
    }
    for( j = 0; j < 3; j++ ) {
        for( i = 0; i < 4; i++ ) matXw2Xc[j][i] = initMatXw2Xc[j][i];
    }

    arUtilMatMul( handle->matXcl2Ul, handle->matC2L, matXc2Ul );
    arUtilMatMul( handle->matXcr2Ur, handle->matC2R, matXc2Ur );

    for( i = 0;; i++ ) {
#if ICP_DEBUG
        icpDispMat( "matXw2Xc", &(matXw2Xc[0][0]), 3, 4 );
#endif
        arUtilMatMul( matXc2Ul, matXw2Xc, matXw2Ul );
        arUtilMatMul( matXc2Ur, matXw2Xc, matXw2Ur );

        for( j = 0; j < data->numL; j++ ) {
            if( icpGetU_from_X_by_MatX2U( &U, matXw2Ul, &(data->worldCoordL[j]) ) < 0 ) {
                icpStereoGetXw2XcCleanup("icpGetU_from_X_by_MatX2U",J_U_S,dU,E,E2);
                return -1;
            }
            dx = data->screenCoordL[j].x - U.x;
            dy = data->screenCoordL[j].y - U.y;
            dU[j*2+0] = dx;
            dU[j*2+1] = dy;
            E[j] = E2[j] = dx*dx + dy*dy;
        }   
        for( j = 0; j < data->numR; j++ ) {
            if( icpGetU_from_X_by_MatX2U( &U, matXw2Ur, &(data->worldCoordR[j]) ) < 0 ) {
                icpStereoGetXw2XcCleanup("icpGetU_from_X_by_MatX2U",J_U_S,dU,E,E2);
                return -1;
            }
            dx = data->screenCoordR[j].x - U.x;
            dy = data->screenCoordR[j].y - U.y;
            dU[(data->numL+j)*2+0] = dx;
            dU[(data->numL+j)*2+1] = dy;
            E[data->numL+j] = E2[data->numL+j] = dx*dx + dy*dy;
        }
        qsort(E2, (data->numL + data->numR), sizeof(ARdouble), compE);
        K2 = E2[inlierNum] * K2_FACTOR;
        if( K2 < 16.0 ) K2 = 16.0;

        err1 = 0.0;
        for( j = 0; j < data->numL + data->numR; j++ ) {
            if( E2[j] > K2 ) err1 += K2/6.0;
            else err1 += K2/6.0 * (1.0 - (1.0-E2[j]/K2)*(1.0-E2[j]/K2)*(1.0-E2[j]/K2));
        }
        err1 /= (data->numL + data->numR);
#if ICP_DEBUG
        ARLOG("Loop[%d]: k^2 = %f, err = %15.10f\n", i, K2, err1);
#endif

        if( err1 < handle->breakLoopErrorThresh ) break;
        if( i > 0 && err1 < ICP_BREAK_LOOP_ERROR_THRESH2 && err1/err0 > handle->breakLoopErrorRatioThresh ) break;
        if( i == handle->maxLoop ) break;
        err0 = err1;

        k = 0;
#if ICP_DEBUG
        l = 0;
#endif                        
        for( j = 0; j < data->numL; j++ ) {
            if( E[j] <= K2 ) {
                if( icpGetJ_U_S( (ARdouble (*)[6])(&J_U_S[6*k]), matXc2Ul, matXw2Xc, &(data->worldCoordL[j]) ) < 0 ) {
                    icpStereoGetXw2XcCleanup("icpGetJ_U_S",J_U_S,dU,E,E2);
                    return -1; 
                }
#if ICP_DEBUG
                icpDispMat( "J_U_S", (ARdouble *)(&J_U_S[6*k]), 2, 6 );
#endif                        
                W = (1.0 - E[j]/K2)*(1.0 - E[j]/K2);
                J_U_S[k*6+0] *= W;
                J_U_S[k*6+1] *= W;
                J_U_S[k*6+2] *= W;
                J_U_S[k*6+3] *= W;
                J_U_S[k*6+4] *= W;
                J_U_S[k*6+5] *= W;
                J_U_S[k*6+6] *= W;
                J_U_S[k*6+7] *= W;
                J_U_S[k*6+8] *= W;
                J_U_S[k*6+9] *= W;
                J_U_S[k*6+10] *= W;
                J_U_S[k*6+11] *= W;
                dU[k+0] = dU[j*2+0] * W;
                dU[k+1] = dU[j*2+1] * W;
                k+=2;
#if ICP_DEBUG
                l++;
#endif                        
            }
        }   
#if ICP_DEBUG
        ARLOG("LEFT   IN: %2d, OUT: %2d\n", l, data->numL-l);
#endif
#if ICP_DEBUG
        l = 0;
#endif                        
        for( j = 0; j < data->numR; j++ ) {
            if( E[data->numL+j] <= K2 ) {
                if( icpGetJ_U_S( (ARdouble (*)[6])(&J_U_S[6*k]), matXc2Ur, matXw2Xc, &(data->worldCoordR[j]) ) < 0 ) {
                    icpStereoGetXw2XcCleanup("icpGetJ_U_S",J_U_S,dU,E,E2);
                    return -1; 
                }
#if ICP_DEBUG
                icpDispMat( "J_U_S", (ARdouble *)(&J_U_S[6*k]), 2, 6 );
#endif                        
                W = (1.0 - E[data->numL+j]/K2)*(1.0 - E[data->numL+j]/K2);
                J_U_S[k*6+0] *= W;
                J_U_S[k*6+1] *= W;
                J_U_S[k*6+2] *= W;
                J_U_S[k*6+3] *= W;
                J_U_S[k*6+4] *= W;
                J_U_S[k*6+5] *= W;
                J_U_S[k*6+6] *= W;
                J_U_S[k*6+7] *= W;
                J_U_S[k*6+8] *= W;
                J_U_S[k*6+9] *= W;
                J_U_S[k*6+10] *= W;
                J_U_S[k*6+11] *= W;
                dU[k+0] = dU[(data->numL+j)*2+0] * W;
                dU[k+1] = dU[(data->numL+j)*2+1] * W;
                k+=2;
#if ICP_DEBUG
                l++;
#endif                        
            }
        }   
#if ICP_DEBUG
        ARLOG("RIGHT  IN: %2d, OUT: %2d\n", l, data->numR-l);
#endif

        if( k < 6 ) return -1;

        if( icpGetDeltaS( dS, dU, (ARdouble (*)[6])J_U_S, k ) < 0 ) {
            icpStereoGetXw2XcCleanup("icpGetS",J_U_S,dU,E,E2);
            return -1;
        }

        icpUpdateMat( matXw2Xc, dS );
    }

#if ICP_DEBUG
    ARLOG("*********** %f\n", err1);
    ARLOG("Loop = %d\n", i);
#endif

    *err = err1;
    free(J_U_S);
    free(dU);
    free(E);
    free(E2);

    return 0;
}
static ARdouble  arGetTransMatMultiSquareStereo2(AR3DStereoHandle *handle,
                                               ARMarkerInfo *marker_infoL, int marker_numL,
                                               ARMarkerInfo *marker_infoR, int marker_numR, 
                                               ARMultiMarkerInfoT *config, int robustFlag)

{
    ARdouble                *pos2dL = NULL, *pos3dL = NULL;
    ARdouble                *pos2dR = NULL, *pos3dR = NULL;
    ARdouble                trans1[3][4], trans2[3][4];
    ARdouble                err, err2;
    int                   max, maxArea;
    int                   vnumL, vnumR;
    int                   dir;
    int                   i, j, k;

    for( i = 0; i < config->marker_num; i++ ) {
        k = -1;
        if( config->marker[i].patt_type == AR_MULTI_PATTERN_TYPE_TEMPLATE ) {
            for( j = 0; j < marker_numL; j++ ) {
                if( marker_infoL[j].idPatt != config->marker[i].patt_id ) continue;
                if( marker_infoL[j].cfPatt < 0.50 ) continue;
                if( k == -1 ) k = j;
                else if( marker_infoL[k].cfPatt < marker_infoL[j].cfPatt ) k = j;
            }
            config->marker[i].visible = k;
            if( k >= 0 ) {
                marker_infoL[k].dir = marker_infoL[k].dirPatt;
            }
        }
        else {
            for( j = 0; j < marker_numL; j++ ) {
                if( marker_infoL[j].idMatrix != config->marker[i].patt_id ) continue;
                if( marker_infoL[j].cfMatrix < 0.50 ) continue;
                if( k == -1 ) k = j;
                else if( marker_infoL[k].cfMatrix < marker_infoL[j].cfMatrix ) k = j;
            }
            config->marker[i].visible = k;
            if( k >= 0 ) {
                marker_infoL[k].dir = marker_infoL[k].dirMatrix;
            }
        }

        k = -1;
        if( config->marker[i].patt_type == AR_MULTI_PATTERN_TYPE_TEMPLATE ) {
            for( j = 0; j < marker_numR; j++ ) {
                if( marker_infoR[j].idPatt != config->marker[i].patt_id ) continue;
                if( marker_infoR[j].cfPatt < 0.50 ) continue;
                if( k == -1 ) k = j;
                else if( marker_infoR[k].cfPatt < marker_infoR[j].cfPatt ) k = j;
            }
            config->marker[i].visibleR = k;
            if( k >= 0 ) {
                marker_infoR[k].dir = marker_infoR[k].dirPatt;
            }
        }
        else {
            for( j = 0; j < marker_numR; j++ ) {
                if( marker_infoR[j].idMatrix != config->marker[i].patt_id ) continue;
                if( marker_infoR[j].cfMatrix < 0.50 ) continue;
                if( k == -1 ) k = j;
                else if( marker_infoR[k].cfMatrix < marker_infoR[j].cfMatrix ) k = j;
            }
            config->marker[i].visibleR = k;
            if( k >= 0 ) {
                marker_infoR[k].dir = marker_infoR[k].dirMatrix;
            }
        }
    }

    vnumL = 0;
    for( i = 0; i < config->marker_num; i++ ) {
        if( (j=config->marker[i].visible) == -1 ) continue;

        err = arGetTransMatSquareStereo( handle, &marker_infoL[j], NULL, config->marker[i].width, trans2 );
        if( err > THRESH_1 ) {
            config->marker[i].visible = -1;
//ARLOG("err = %f\n", err);
            continue;
        }

        if( vnumL == 0 || maxArea < marker_infoL[j].area ) {
            maxArea = marker_infoL[j].area;
            max = i; 
            for( j = 0; j < 3; j++ ) { 
                for( k = 0; k < 4; k++ ) trans1[j][k] = trans2[j][k];
            }
        }
        vnumL++;
    }
    vnumR = 0;
    for( i = 0; i < config->marker_num; i++ ) {
        if( (j=config->marker[i].visibleR) == -1 ) continue;

        err = arGetTransMatSquareStereo( handle, NULL, &marker_infoR[j], config->marker[i].width, trans2 );
        if( err > THRESH_1 ) {
            config->marker[i].visibleR = -1;
//ARLOG("err = %f\n", err);
            continue;
        }

        if( (vnumL == 0 && vnumR == 0) || maxArea < marker_infoR[j].area ) {
            maxArea = marker_infoR[j].area;
            max = i; 
            for( j = 0; j < 3; j++ ) { 
                for( k = 0; k < 4; k++ ) trans1[j][k] = trans2[j][k];
            }
        }
        vnumR++;
    }
//ARLOG("vnumL=%d, vnumR=%d\n", vnumL, vnumR);
    if( (vnumL == 0 && vnumR == 0) || (vnumL < config->min_submarker && vnumR < config->min_submarker) ) {
        config->prevF = 0;
//ARLOG("**** NG.\n");
        return -1;
    }


    if(vnumL > 0) {
        arMalloc(pos2dL, ARdouble, vnumL*4*2);
        arMalloc(pos3dL, ARdouble, vnumL*4*3);
    }
    if(vnumR > 0) {
        arMalloc(pos2dR, ARdouble, vnumR*4*2);
        arMalloc(pos3dR, ARdouble, vnumR*4*3);
    }

    j = 0;
    for( i = 0; i < config->marker_num; i++ ) {
        if( (k=config->marker[i].visible) < 0 ) continue;
        dir = marker_infoL[k].dir;
        pos2dL[j*8+0] = marker_infoL[k].vertex[(4-dir)%4][0];
        pos2dL[j*8+1] = marker_infoL[k].vertex[(4-dir)%4][1];
        pos2dL[j*8+2] = marker_infoL[k].vertex[(5-dir)%4][0];
        pos2dL[j*8+3] = marker_infoL[k].vertex[(5-dir)%4][1];
        pos2dL[j*8+4] = marker_infoL[k].vertex[(6-dir)%4][0];
        pos2dL[j*8+5] = marker_infoL[k].vertex[(6-dir)%4][1];
        pos2dL[j*8+6] = marker_infoL[k].vertex[(7-dir)%4][0];
        pos2dL[j*8+7] = marker_infoL[k].vertex[(7-dir)%4][1];
        pos3dL[j*12+0] = config->marker[i].pos3d[0][0];
        pos3dL[j*12+1] = config->marker[i].pos3d[0][1];
        pos3dL[j*12+2] = config->marker[i].pos3d[0][2];
        pos3dL[j*12+3] = config->marker[i].pos3d[1][0];
        pos3dL[j*12+4] = config->marker[i].pos3d[1][1];
        pos3dL[j*12+5] = config->marker[i].pos3d[1][2];
        pos3dL[j*12+6] = config->marker[i].pos3d[2][0];
        pos3dL[j*12+7] = config->marker[i].pos3d[2][1];
        pos3dL[j*12+8] = config->marker[i].pos3d[2][2];
        pos3dL[j*12+9] = config->marker[i].pos3d[3][0];
        pos3dL[j*12+10] = config->marker[i].pos3d[3][1];
        pos3dL[j*12+11] = config->marker[i].pos3d[3][2];
        j++;
    }

    j = 0;
    for( i = 0; i < config->marker_num; i++ ) {
        if( (k=config->marker[i].visibleR) < 0 ) continue;
        dir = marker_infoR[k].dir;
        pos2dR[j*8+0] = marker_infoR[k].vertex[(4-dir)%4][0];
        pos2dR[j*8+1] = marker_infoR[k].vertex[(4-dir)%4][1];
        pos2dR[j*8+2] = marker_infoR[k].vertex[(5-dir)%4][0];
        pos2dR[j*8+3] = marker_infoR[k].vertex[(5-dir)%4][1];
        pos2dR[j*8+4] = marker_infoR[k].vertex[(6-dir)%4][0];
        pos2dR[j*8+5] = marker_infoR[k].vertex[(6-dir)%4][1];
        pos2dR[j*8+6] = marker_infoR[k].vertex[(7-dir)%4][0];
        pos2dR[j*8+7] = marker_infoR[k].vertex[(7-dir)%4][1];
        pos3dR[j*12+0] = config->marker[i].pos3d[0][0];
        pos3dR[j*12+1] = config->marker[i].pos3d[0][1];
        pos3dR[j*12+2] = config->marker[i].pos3d[0][2];
        pos3dR[j*12+3] = config->marker[i].pos3d[1][0];
        pos3dR[j*12+4] = config->marker[i].pos3d[1][1];
        pos3dR[j*12+5] = config->marker[i].pos3d[1][2];
        pos3dR[j*12+6] = config->marker[i].pos3d[2][0];
        pos3dR[j*12+7] = config->marker[i].pos3d[2][1];
        pos3dR[j*12+8] = config->marker[i].pos3d[2][2];
        pos3dR[j*12+9] = config->marker[i].pos3d[3][0];
        pos3dR[j*12+10] = config->marker[i].pos3d[3][1];
        pos3dR[j*12+11] = config->marker[i].pos3d[3][2];
        j++;
    }

    if( config->prevF == 0 ) {
        arUtilMatMul( (const ARdouble (*)[4])trans1, (const ARdouble (*)[4])config->marker[max].itrans, trans2 );
        if( robustFlag ) {
            err = arGetTransMatStereo( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                       (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
            if( err >= THRESH_2 ) {
                icpStereoSetInlierProbability( handle->icpStereoHandle, 0.8 );
                err = arGetTransMatStereoRobust( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                 (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
                if( err >= THRESH_2 ) {
                    icpStereoSetInlierProbability( handle->icpStereoHandle, 0.6 );
                    err = arGetTransMatStereoRobust( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                     (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
                    if( err >= THRESH_2 ) {
                        icpStereoSetInlierProbability( handle->icpStereoHandle, 0.4 );
                        err = arGetTransMatStereoRobust( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                         (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
                        if( err >= THRESH_2 ) {
                            icpStereoSetInlierProbability( handle->icpStereoHandle, 0.0 );
                            err = arGetTransMatStereoRobust( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                             (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
                        }
                    }
                }
            }
        }
        else {
            err = arGetTransMatStereo( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                       (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
        }
    }
    else {
        arUtilMatMul( (const ARdouble (*)[4])trans1, (const ARdouble (*)[4])config->marker[max].itrans, trans2 );
        if( robustFlag ) {
            err2 = arGetTransMatStereo( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                        (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, trans1 );
            err = arGetTransMatStereo( handle, config->trans, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                              (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
            if( err2 < err ) {
                for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                err = err2;
            }
            if( err >= THRESH_2 ) {
                icpStereoSetInlierProbability( handle->icpStereoHandle, 0.8 );
                err2 = arGetTransMatStereoRobust( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                  (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, trans1 );
                err = arGetTransMatStereoRobust( handle, config->trans, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                        (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
                if( err2 < err ) {
                    for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                    err = err2;
                }
                if( err >= THRESH_2 ) {
                    icpStereoSetInlierProbability( handle->icpStereoHandle, 0.6 );
                    err2 = arGetTransMatStereoRobust( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                      (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, trans1 );
                    err = arGetTransMatStereoRobust( handle, config->trans, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                            (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
                    if( err2 < err ) {
                        for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                        err = err2;
                    }
                    if( err >= THRESH_2 ) {
                        icpStereoSetInlierProbability( handle->icpStereoHandle, 0.4 );
                        err2 = arGetTransMatStereoRobust( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                          (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, trans1 );
                        err = arGetTransMatStereoRobust( handle, config->trans, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                                (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
                        if( err2 < err ) {
                            for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                            err = err2;
                        }
                        if( err >= THRESH_2 ) {
                            icpStereoSetInlierProbability( handle->icpStereoHandle, 0.0 );
                            err2 = arGetTransMatStereoRobust( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                              (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, trans1 );
                            err = arGetTransMatStereoRobust( handle, config->trans, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                                                    (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
                            if( err2 < err ) {
                                for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                                err = err2;
                            }
                        }
                    }
                }
            }
        }
        else {
            err2 = arGetTransMatStereo( handle, trans2, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                        (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, trans1 );
            err = arGetTransMatStereo( handle, config->trans, (ARdouble (*)[2])pos2dL, (ARdouble (*)[3])pos3dL, vnumL*4,
                                                              (ARdouble (*)[2])pos2dR, (ARdouble (*)[3])pos3dR, vnumR*4, config->trans );
            if( err2 < err ) {
                for( j = 0; j < 3; j++ ) for( i = 0; i < 4; i++ ) config->trans[j][i] = trans1[j][i];
                err = err2;
            }
        }
    }

    if( vnumL > 0 ) {
        free(pos3dL);
        free(pos2dL);
    }
    if( vnumR > 0 ) {
        free(pos3dR);
        free(pos2dR);
   }

    if( err < THRESH_2 ) {
        config->prevF = 1;
    }
    else {
        config->prevF = 0;
    }

    return err;
}
/* main loop */
static void mainLoop(void)
{
    ARUint8         *dataPtr;
    ARMarkerInfo    *marker_info;
    int             marker_num;
    int             i, j, k;

    /* grab a vide frame */
    if( (dataPtr = (ARUint8 *)arVideoGetImage()) == NULL ) {
        arUtilSleep(2);
        return;
    }
    if( count == 0 ) arUtilTimerReset();
    count++;

    argDrawMode2D();
    argDispImage( dataPtr, 0,0 );

    /* detect the markers in the video frame */
    if( arDetectMarker(dataPtr, thresh, &marker_info, &marker_num) < 0 ) {
        cleanup();
        exit(0);
    }
    arVideoCapNext();

    argDrawMode3D();
    argDraw3dCamera( 0, 0 );
    glClearDepth( 1.0 );
    glClear(GL_DEPTH_BUFFER_BIT);

    /* check for object visibility */
    for( i = 0; i < 2; i++ ) {
        k = -1;
        for( j = 0; j < marker_num; j++ ) {
            if( object[i].patt_id == marker_info[j].id ) {
                if( k == -1 ) k = j;
                else if( marker_info[k].cf < marker_info[j].cf ) k = j;
            }
        }
        object[i].visible = k;

        if( k >= 0 ) {
            arGetTransMat(&marker_info[k],
                          object[i].center, object[i].width,
                          object[i].trans);
            draw( object[i].model_id, object[i].trans );
        }
    }
    argSwapBuffers();

    if( object[0].visible >= 0
     && object[1].visible >= 0 ) {
        double  wmat1[3][4], wmat2[3][4];

        arUtilMatInv(object[0].trans, wmat1);
        arUtilMatMul(wmat1, object[1].trans, wmat2);

        for( j = 0; j < 3; j++ ) {
            for( i = 0; i < 4; i++ ) printf("%8.4f ", wmat2[j][i]);
            printf("\n");
        }
        printf("\n\n");
    }
}
Пример #9
0
static void draw( void )
{
	static int before_visible[2] = {0, 0};
	static int Wire_count = -1;  // 出力する Wire の選択(0〜4)
	static int flag_first1 = 0;  // 一度でも hiro が見つかったら立つ
	int i;
	static double begin[3];
	double wtrans[3][4];
	double gl_para[16];
		
	/* 3Dオブジェクトを描画するための準備 */
	argDrawMode3D();
	argDraw3dCamera(0, 0);

	/* Zバッファなどの設定 */
	glClear( GL_DEPTH_BUFFER_BIT );	// 陰面処理の設定
	glEnable( GL_DEPTH_TEST );		// 陰面処理の適用

	mySetLight();				// 光源の設定
	glEnable( GL_LIGHTING );	// 光源の適用

	/* マーカの出現と消失の処理 */

	/* マーカ1の処理 */
	if( myCheck_appear(before_visible[PTT1_MARK_ID], object[PTT1_MARK_ID].visible) ){
		begin[0] = object[PTT1_MARK_ID].patt_trans[0][3];
		begin[1] = object[PTT1_MARK_ID].patt_trans[1][3];
		begin[2] = object[PTT1_MARK_ID].patt_trans[2][3];

		points[L_P_count].flag_after_change = 0;
	}
	if( myCheck_disappear(before_visible[PTT1_MARK_ID], object[PTT1_MARK_ID].visible) ){
		myCopyTrans( object[PTT1_MARK_ID].patt_trans, points[L_P_count].trans);
		points[L_P_count].start_point[0] = begin[0] - object[PTT1_MARK_ID].patt_trans[0][3];
		points[L_P_count].start_point[1] = -( begin[1] - object[PTT1_MARK_ID].patt_trans[1][3] ); // Y軸はカメラに対して反転しているので
		points[L_P_count].start_point[2] = -( begin[2] - object[PTT1_MARK_ID].patt_trans[2][3] ); // Z軸はカメラに対して反転しているので
		for(i=0; i<3; i++){
			points[L_P_count].end_point[i] = 0.0;
		}
		myMoveBallInit( &points[L_P_count] );

		L_P_count++;
		if(MAX_LINES <= L_P_count){
			L_P_count = 0;
		}
	}


	
	/* マーカ2の出現と消失 */
	if( myCheck_appear(before_visible[PTT2_MARK_ID], object[PTT2_MARK_ID].visible) ){
		for(i=0; i < L_P_count; i++){
			arUtilMatMul( itrans2, points[i].trans, wtrans);
			myCopyTrans( wtrans, points[i].trans);
			
			points[i].flag_after_change = 1;
		}
	}
	if( myCheck_disappear(before_visible[PTT2_MARK_ID], object[PTT2_MARK_ID].visible) ){
		for(i=0; i < L_P_count; i++){
			arUtilMatMul( object[PTT2_MARK_ID].patt_trans, points[i].trans, wtrans);
			myCopyTrans( wtrans, points[i].trans );
		}
	}

	/* 3Dオブジェクトの描画 */

	/* 過去に描いた線分の描画 */
	if(flag_first1 && L_P_count >= 1 && !(object[PTT2_MARK_ID].visible) ){
		mySelectColor( 1.0, 0.0, 0.0); // 材質特性の設定
		glLineWidth( 5.0);
		for(i=0; i < L_P_count; i++){
			glPushMatrix(); // 念のため
				myMatrix( points[i].trans);
				myLineLoop(i, i+1);
			glPopMatrix();  // 念のため
		}
	}

	/* マーカ1(Hiro) が映ったときの処理 */
	if(object[PTT1_MARK_ID].visible){
		flag_first1 = 1;

		/* 現在書いている線分の描画 */
		myMatrix(object[PTT1_MARK_ID].patt_trans);
		mySelectColor( 1.0, 0.8, 0.0); // 材質特性の設定
		glLineWidth( 5.0);

		glBegin( GL_LINES );
			glVertex3f( begin[0] - object[PTT1_MARK_ID].patt_trans[0][3], -( begin[1] - object[PTT1_MARK_ID].patt_trans[1][3] ),
				-( begin[2] - object[PTT1_MARK_ID].patt_trans[2][3] ) );
			glVertex3f( 0.0, 0.0, 0.0 );
		glEnd();

		/* hiro のマーカを縁取り */
		myMatrix(object[PTT1_MARK_ID].patt_trans);
		mySelectColor( 0.0, 0.0, 1.0); // 材質特性の設定
		glLineWidth( 3.0);
		myMarkSquare (PTT1_MARK_ID);
	}

	/* マーカ2(kanji) が表示されているとき */
	
	if(object[PTT2_MARK_ID].visible){
		/* マーカ2の縁取り */
		myMatrix(object[PTT2_MARK_ID].patt_trans);
		mySelectColor( 0.0, 1.0, 0.0); // 材質特性の設定
		glLineWidth( 3.0);
		myMarkSquare (PTT2_MARK_ID);

		/* 座標変換 */
		glLineWidth( 5.0);

		for(i=0; i < L_P_count; i++){
			glPushMatrix();
				mySelectColor( 0.0, 0.0, 1.0); // 材質特性の設定
				argConvGlpara( points[i].trans, gl_para );
				glMultMatrixd( gl_para );
				myLineLoop(i, i+1);
				if( flag_animation){
					myMoveBall( &points[i] );
				}
				else{
					myMoveBall2( &points[i], i );
				}
			glPopMatrix();
		}
	}

	visible_log(PTT_NUM, before_visible);	// 各マーカの visible 状態の記録
	glDisable( GL_LIGHTING );	// 光源の無効化
	glDisable( GL_DEPTH_TEST );	// 陰面処理の無効化
}
Пример #10
0
  void ARBundlePublisher::findTransformToCenter(double camera_to_marker_trans[3][4], int knownPatternCount)	{
	arUtilMatMul(camera_to_marker_trans, tfs[knownPatternCount], master_trans_);
  }
Пример #11
0
int icpCalibStereo( ICPCalibDataT data[], int num,
                    ARdouble matXcl2Ul[3][4], ARdouble matXcr2Ur[3][4], ARdouble initMatL2R[3][4],
                    ARdouble matL2R[3][4],
                    ARdouble *err )
{
    ARdouble       *J, *dU, *dTS;
    ARdouble       *matXw2Xcl;
    ARdouble        matXw2Ul[3][4];
    ARdouble        matXw2Ur[3][4];
    ARdouble        matXcl2Ur[3][4];
    ARdouble        J_UL_S[2][6];
    ARdouble        oldErr;
    ICP3DCoordT   cameraCoordL;
    ICP2DCoordT   screenCoord;
    int           Jrow, Jclm;
    int           dataNum;
    int           i, j, k, l;
    int           i1;
    int           ret = 0;

    if( num <= 0 ) {
        ARLOGe("Data num error!!\n");
        return -1;
    }

    dataNum = 0;
    for( i = 0; i < num; i++ ) {
        if( data[i].numL <= 0 || data[i].numR <= 0 ) {
            ARLOGe("Data num error!!\n");
            return -1;
        }
        dataNum += data[i].numL;
        dataNum += data[i].numR;
    }

    Jrow = dataNum * 2;
    Jclm = (num + 1) * 6;
    //ARLOGe("Jrow = %d, Jclm = %d\n", Jrow, Jclm );
    J = (ARdouble *)malloc(sizeof(ARdouble)*Jrow*Jclm);
    if( J == NULL ) {
        ARLOGe("Out of memory!!\n");
        return -1;
    }
    dU = (ARdouble *)malloc(sizeof(ARdouble)*Jrow);
    if( dU == NULL ) {
        ARLOGe("Out of memory!!\n");
        free(J);
        return -1;
    }
    dTS = (ARdouble *)malloc(sizeof(ARdouble)*Jclm);
    if( dTS == NULL ) {
        ARLOGe("Out of memory!!\n");
        free(J);
        free(dU);
        return -1;
    }
    matXw2Xcl = (ARdouble *)malloc(sizeof(ARdouble)*3*4*num);
    if( matXw2Xcl == NULL ) {
        ARLOGe("Out of memory!!\n");
        free(J);
        free(dU);
        free(dTS);
        return -1;
    }

    for( j = 0; j < 3; j++ ) {
        for( i = 0; i < 4; i++ ) matL2R[j][i] = initMatL2R[j][i];
    }
    for( k = 0; k < num; k++ ) {
        for( j = 0; j < 3; j++ ) {
            for( i = 0; i < 4; i++ ) {
                matXw2Xcl[k*12+j*4+i] = data[k].initMatXw2Xcl[j][i];
            }
        }
    }

    for( l = 0; l < ICP_CALIB_STEREO_MAX_LOOP; l++ ) {
        k = 0;
        for( i = 0; i < Jrow*Jclm; i++ )  J[i] = 0.0;
        for( i = 0; i < Jrow;      i++ ) dU[i] = 0.0;
        arUtilMatMul( (const ARdouble (*)[4])matXcr2Ur, (const ARdouble (*)[4])matL2R, matXcl2Ur );

        *err = 0.0;
        for( j = 0; j < num; j++ ) {
            arUtilMatMul( (const ARdouble (*)[4])matXcl2Ul, (const ARdouble (*)[4])&(matXw2Xcl[j*12]), matXw2Ul );
            arUtilMatMul( (const ARdouble (*)[4])matXcl2Ur, (const ARdouble (*)[4])&(matXw2Xcl[j*12]), matXw2Ur );

            for( i = 0; i <  data[j].numL; i++ ) {
                if( icpGetJ_U_S( J_UL_S, matXcl2Ul, (ARdouble (*)[4])&(matXw2Xcl[j*12]), &(data[j].worldCoordL[i]) ) < 0 ) {
                    ARLOGe("Error icpGetJ_U_S\n");
                    ret = -1;
                    break;
                }
                for( i1 = 0; i1 < 6; i1++ ) {
                    J[(k*2  )*Jclm+(1+j)*6+i1] = J_UL_S[0][i1];
                    J[(k*2+1)*Jclm+(1+j)*6+i1] = J_UL_S[1][i1];
                }

                if( icpGetU_from_X_by_MatX2U( &screenCoord, matXw2Ul, &(data[j].worldCoordL[i]) ) < 0 ) {
                    ARLOGe("Error icpGetU_from_X_by_MatX2U\n");
                    ret = -1;
                    break;
                }
                dU[k*2  ] = data[j].screenCoordL[i].x - screenCoord.x;
                dU[k*2+1] = data[j].screenCoordL[i].y - screenCoord.y;
                *err += dU[k*2]*dU[k*2] + dU[k*2+1]*dU[k*2+1];
                k++;
            }
            if( ret == -1 ) break;

            for( i = 0; i <  data[j].numR; i++ ) {
                if( icpGetJ_U_S( J_UL_S, matXcl2Ur, (ARdouble (*)[4])&(matXw2Xcl[j*12]), &(data[j].worldCoordR[i]) ) < 0 ) {
                    ARLOGe("Error icpGetJ_U_S\n");
                    ret = -1;
                    break;
                }
                for( i1 = 0; i1 < 6; i1++ ) {
                    J[(k*2  )*Jclm+(1+j)*6+i1] = J_UL_S[0][i1];
                    J[(k*2+1)*Jclm+(1+j)*6+i1] = J_UL_S[1][i1];
                }

                if( icpGetU_from_X_by_MatX2U( &screenCoord, matXw2Ur, &(data[j].worldCoordR[i]) ) < 0 ) {
                    ARLOGe("Error icpGetU_from_X_by_MatX2U\n");
                    ret = -1;
                    break;
                }
                dU[k*2  ] = data[j].screenCoordR[i].x - screenCoord.x;
                dU[k*2+1] = data[j].screenCoordR[i].y - screenCoord.y;
                *err += dU[k*2]*dU[k*2] + dU[k*2+1]*dU[k*2+1];

                if( icpGetXc_from_Xw_by_MatXw2Xc( &cameraCoordL, (ARdouble (*)[4])&(matXw2Xcl[j*12]), &(data[j].worldCoordR[i]) ) < 0 ) {
                    ARLOGe("Error icpGetXc_from_Xw_by_MatXw2Xc\n");
                    ret = -1;
                    break;
                }
                if( icpGetJ_U_S( J_UL_S, matXcr2Ur, matL2R, &cameraCoordL ) < 0 ) {
                    ARLOGe("Error icpGetJ_U_S\n");
                    ret = -1;
                    break;
                }
                for( i1 = 0; i1 < 6; i1++ ) {
                    J[(k*2  )*Jclm+i1] = J_UL_S[0][i1];
                    J[(k*2+1)*Jclm+i1] = J_UL_S[1][i1];
                }
                k++;
            }
            if( ret == -1 ) break;
        }
        if( ret == -1 ) break;

        *err /= dataNum;
        ARLOGe("Error = %f\n", *err);
        if( *err < ICP_CALIB_STEREO_BREAK_LOOP_ERROR_THRESH ) break;
        if( l > 0 && *err/oldErr > ICP_CALIB_STEREO_BREAK_LOOP_ERROR_RATIO_THRESH ) break;
        oldErr = *err;

        if( icp2GetTS( dTS, dU, J, Jrow, Jclm ) < 0 ) {
            ARLOGe("Error icp2GetTS\n");
            ret = -1;
            break;
        }

        icpUpdateMat( matL2R, &(dTS[0]) );
        for( j = 0; j < num; j++ ) {
            icpUpdateMat( (ARdouble (*)[4])&(matXw2Xcl[j*12]), &(dTS[6*(j+1)]) );
        }
    }

    free(J);
    free(dU);
    free(dTS);
    free(matXw2Xcl);

    return ret;
}