Exemple #1
0
/**
 *	OptimizePair:
 *		Input:
 *			cam1 - the first camera (already optimized)
 *          cam2 - the second camera with its intrinsic matrix initialized
 *			dR - an initial relative 3x3 camera rotation matrix
 *          set1 - SIFT features in the first image
 *          set2 - SIFT features in the second image
 *          aryInlier - the homography iniliers
 *
 *		Ouput:
 *          cam2 - update cam2's optimized focal length and pose
 */
void OptimizeSingle( const CCamera& cam1, CCamera& cam2,
					double* dR,
					const CFeatureArray& set1,
					const CFeatureArray& set2, 
					const MatchArray& aryInlier )
{
	// Step 1. Initialize the camera pose of cam2

	// cam2's relative rotation to cam1
	CvMat matR = cvMat( 3, 3, CV_64F, dR );

	// cam1's absolute rotation
	double dRod1[3];
	CvMat matRod1 = cvMat( 3, 1, CV_64F, dRod1 );
	cam1.GetPose( dRod1 );

	double dRot1[9];
	CvMat matRot1 = cvMat( 3, 3, CV_64F, dRot1 );
	cvRodrigues2( &matRod1, &matRot1 );

	// compose R and Rot1 to get cam2's initial absolute rotation
	cvMatMul( &matR, &matRot1, &matR );

	double dRod2[3];
	CvMat matRod2 = cvMat( 3, 1, CV_64F, dRod2 );

	cvRodrigues2( &matR, &matRod2 );
	cam2.SetPose( dRod2 );

	// Step 2. Now we can perform bundle adjustment for cam2
	CBundleAdjust ba( 1, BA_ITER );
	ba.SetCamera( &cam2, 0 );

	// set points
	for( int i=0; i<aryInlier.size(); ++i )
	{
		const CFeature* ft1 = set1[ aryInlier[i].first ];
		const CFeature* ft2 = set2[ aryInlier[i].second ];

		double dir[3];
		cam1.GetRayDirectionWS( dir, cvPoint2D64f( ft1->x, ft1->y ) );
		
		// the 3d position
		CvPoint3D64f pt3 = cvPoint3D64f( dir[0]*radius, dir[1]*radius, dir[2]*radius );

		ba.SetPointProjection( pt3, 0, cvPoint2D64f( ft2->x, ft2->y ) );
	}

	ba.DoMotion();

	ba.GetAdjustedCamera( &cam2, 0 );
}
Exemple #2
0
/**
 *	OptimizePair:
 *		Input:
 *			cam1 - the first camera with its intrinsic matrix and pose initialized ([R|T]=[I|0])
 *          cam2 - the second camera with its intrinsic matrix initialized
 *			dR - an initial relative 3x3 camera rotation matrix
 *          set1 - SIFT features in the first image
 *          set2 - SIFT features in the second image
 *          aryInlier - the homography iniliers
 *
 *		Ouput:
 *			cam1 - update cam1's optimized folcal length
 *          cam2 - update cam2's optimized focal length and pose
 */
void OptimizePair( CCamera& cam1, CCamera& cam2,
				  double* dR,
				  const CFeatureArray& set1,
				  const CFeatureArray& set2, 
				  const MatchArray& aryInlier )
{
	CBundleAdjust ba( 2, BA_ITER );

	// Step 1. To perform bundle adjustment, we initialize cam1 and cam2 
	//         as [K][I|0} and [K][R|0] respectively and optimize R using 
	//         bundle adjustment.
	double dRod[3];
	CvMat matRod = cvMat( 3, 1, CV_64F, dRod );
	CvMat matR = cvMat( 3, 3, CV_64F, dR );

	cvRodrigues2( &matR, &matRod );
	cam2.SetPose( dRod );

	// Set cameras
	ba.SetCamera( &cam1, 0 );
	ba.SetCamera( &cam2, 1 );

	// Step 2. We still need to create a set of 3D points. From each homography inlier, 
	//         a 3D point can be initialized by locating it on the ray that goes through 
	//         its projection.	
	for( int i=0; i<aryInlier.size(); ++i )
	{
		const CFeature* ft1 = set1[ aryInlier[i].first ];
		const CFeature* ft2 = set2[ aryInlier[i].second ];

		double dir[3];
		cam1.GetRayDirectionWS( dir, cvPoint2D64f( ft1->x, ft1->y ) );
		
		// the initialized 3d position
		CvPoint3D64f pt3 = cvPoint3D64f( dir[0]*radius, dir[1]*radius, dir[2]*radius );

		// set the 3d point and its projections in both images
		ba.SetPointProjection( pt3, 0, cvPoint2D64f( ft1->x, ft1->y ) );
		ba.SetPointProjection( pt3, 1, cvPoint2D64f( ft2->x, ft2->y ) );
	}

	// perform bundle adjustment
	ba.DoMotionAndStructure();

	// retrieve the optimized cameras
	ba.GetAdjustedCamera( &cam1, 0 );
	ba.GetAdjustedCamera( &cam2, 1 );
}
Exemple #3
0
osg::Geode* myKeyboardEventHandler::Uncertainty()
{
    osg::Geode* geode = new osg::Geode();
    osg::Geometry* pointsGeom = new osg::Geometry();

    osg::Vec3Array* vertices = new osg::Vec3Array;

    CvMat *temp,*temp2,*temp3;
    temp=cvCreateMatHeader(6,6,CV_32FC1);
    CvMat *_temp = cvCreateMat (6,6,CV_32FC1);
    temp2=cvCreateMat(3,6,CV_32FC1);
    temp3=cvCreateMat(3,3,CV_32FC1);
    CvMat* vect=cvCreateMat (6,1,CV_32FC1);
    CvMat* res6=cvCreateMat (6,1,CV_32FC1);
    //CvMat* vect2=cvCreateMat(1,6,CV_32FC1);
    //CvPoint2D64f proj ;
    //CvMat* m = cvCreateMat(3,1,CV_32FC1);
    float *fstate;
    fstate= pSlam->X->data.fl;
    float xc,yc,zc,theta,phi,rho;

    for (unsigned int i = 0 ; i < pSlam->visible.size(); i++)
    {
        if(pSlam->visible[i]==true)
        {
            xc=fstate[pSlam->modelSD+6*i];
            yc=fstate[pSlam->modelSD+6*i+1];
            zc=fstate[pSlam->modelSD+6*i+2];
            theta=fstate[pSlam->modelSD+6*i+3];
            phi=fstate[pSlam->modelSD+6*i+4];
            rho=fstate[pSlam->modelSD+6*i+5];


            cvGetSubRect( pSlam->P,temp,cvRect(pSlam->modelSD+i*6,pSlam->modelSD+i*6,6,6) );

            for (int part=0; part<40; part++){
//                cvmSet(vect,0,0,pSlam->randomVector(-.005,.005));
//                cvmSet(vect,1,0,pSlam->randomVector(-.005,.005));
//                cvmSet(vect,2,0,pSlam->randomVector(-.005,.005));
//                cvmSet(vect,3,0,pSlam->randomVector(-.05,0.05));
//                cvmSet(vect,4,0,pSlam->randomVector(-.05,0.05));
//                cvmSet(vect,5,0,pSlam->randomVector(-1,1));
                cvmSet(vect,0,0,pSlam->randomVector(-12.6,12.6));
                cvmSet(vect,1,0,pSlam->randomVector(-12.6,12.6));
                cvmSet(vect,2,0,pSlam->randomVector(-12.6,12.6));
                cvmSet(vect,3,0,pSlam->randomVector(-12.6,12.6));
                cvmSet(vect,4,0,pSlam->randomVector(-12.6,12.6));
                cvmSet(vect,5,0,pSlam->randomVector(-12.6,12.6));
                cvZero(_temp);
                pSlam->Cholesky(temp,_temp);
                cvMatMul(_temp,vect,res6);

                double ox, oy, oz;
                pSlam->InverseDepth2Depth(cvmGet(res6,0,0)+xc,
                                          cvmGet(res6,1,0)+yc,
                                          cvmGet(res6,2,0)+zc,
                                          cvmGet(res6,3,0)+theta,
                                          cvmGet(res6,4,0)+phi,
                                          cvmGet(res6,5,0)+rho,
                                          &ox,&oy,&oz );

                //CvMat* nullmat = 0;

                if (ox> -100000 && ox<10000 &&
                    oy> -100000 && oy<10000 &&
                    oz> -100000 && oz<10000)
                {
                    CvPoint3D64f point = cvPoint3D64f(ox,oy,oz);
                    vertices->push_back(osg::Vec3(ox,oy,oz));
                }
            }
        }
    }

    // pass the created vertex array to the points geometry object.
    pointsGeom->setVertexArray(vertices);
    // create the color of the geometry, one single for the whole geometry.
    // for consistency of design even one single color must added as an element
    // in a color array.
    osg::Vec4Array* colors = new osg::Vec4Array;
    // add a white color, colors take the form r,g,b,a with 0.0 off, 1.0 full on.
    colors->push_back(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
    // pass the color array to points geometry, note the binding to tell the geometry
    // that only use one color for the whole object.
    pointsGeom->setColorArray(colors);
    pointsGeom->setColorBinding(osg::Geometry::BIND_OVERALL);

    // set the normal in the same way color.
    osg::Vec3Array* normals = new osg::Vec3Array;
    normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
    pointsGeom->setNormalArray(normals);
    pointsGeom->setNormalBinding(osg::Geometry::BIND_OVERALL);


    // create and add a DrawArray Primitive (see include/osg/Primitive).  The first
    // parameter passed to the DrawArrays constructor is the Primitive::Mode which
    // in this case is POINTS (which has the same value GL_POINTS), the second
    // parameter is the index position into the vertex array of the first point
    // to draw, and the third parameter is the number of points to draw.
    pointsGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS,0,vertices->size()));


    // add the points geometry to the geode.
    geode->addDrawable(pointsGeom);
    // Create a new StateSet with default settings:
    osg::StateSet* stateOne = new osg::StateSet();
    osg::Point *  point = new osg::Point();
    point->setSize(1.0);
    stateOne->setAttributeAndModes(point,osg::StateAttribute::ON);
    geode->setStateSet(stateOne);
    return geode;
}
Exemple #4
0
osg::Geode* myKeyboardEventHandler::PlotEllipse3D(CvMat *X, CvMat *P, osg::Vec4Array* colors )
{
    osg::Geode* geode = new osg::Geode();
    osg::Geometry* pointsGeom = new osg::Geometry();
    osg::Vec3Array* vertices = new osg::Vec3Array;
    CvMat *temp;
    temp=cvCreateMatHeader(3,3,CV_32FC1);
    CvMat *_temp = cvCreateMat (3,3,CV_32FC1);
    CvMat* vect=cvCreateMat (3,1,CV_32FC1);
    CvMat* res6=cvCreateMat (3,1,CV_32FC1);
    //CvMat* vect2=cvCreateMat(1,6,CV_32FC1);
    //CvPoint2D64f proj ;
    //CvMat* m = cvCreateMat(3,1,CV_32FC1);
    float *fstate;
    fstate= X->data.fl;
    float xc,yc,zc;
    xc=fstate[0];
    yc=fstate[1];
    zc=fstate[2];

    cvGetSubRect( P,temp,cvRect(0,0,3,3) );

//    for (int part=0; part<100; part++){
    for(float t = 0; t<2*3.14159; t+=0.1)
        for (float p = -3.14159/2; p<3.14159;p+=0.1)
        {
        cvmSet(vect,0,0,7.8*cos(p)*cos(t));
        cvmSet(vect,1,0,7.8*cos(p)*sin(t));
        cvmSet(vect,2,0,7.8*sin(p));
        cvZero(_temp);
        pSlam->Cholesky(temp,_temp);
        cvMatMul(_temp,vect,res6);

        double ox=cvmGet(res6,0,0)+xc;
        double oy=cvmGet(res6,1,0)+yc;
        double oz=cvmGet(res6,2,0)+zc;

        if (ox> -100000 && ox<10000 &&
            oy> -100000 && oy<10000 &&
            oz> -100000 && oz<10000)
        {
            CvPoint3D64f point = cvPoint3D64f(ox,oy,oz);
            vertices->push_back(osg::Vec3(ox,oy,oz));
        }
    }

    // pass the created vertex array to the points geometry object.
    pointsGeom->setVertexArray(vertices);

    // pass the color array to points geometry, note the binding to tell the geometry
    // that only use one color for the whole object.
    pointsGeom->setColorArray(colors);
    pointsGeom->setColorBinding(osg::Geometry::BIND_OVERALL);

    // set the normal in the same way color.
    osg::Vec3Array* normals = new osg::Vec3Array;
    normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
    pointsGeom->setNormalArray(normals);
    pointsGeom->setNormalBinding(osg::Geometry::BIND_OVERALL);


    // create and add a DrawArray Primitive (see include/osg/Primitive).  The first
    // parameter passed to the DrawArrays constructor is the Primitive::Mode which
    // in this case is POINTS (which has the same value GL_POINTS), the second
    // parameter is the index position into the vertex array of the first point
    // to draw, and the third parameter is the number of points to draw.
    pointsGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS,0,vertices->size()));


    // add the points geometry to the geode.
    geode->addDrawable(pointsGeom);
    // Create a new StateSet with default settings:
    osg::StateSet* stateOne = new osg::StateSet();
    osg::Point *  point = new osg::Point();
    point->setSize(1.0);
    stateOne->setAttributeAndModes(point,osg::StateAttribute::ON);
    geode->setStateSet(stateOne);
    return geode;

}
Exemple #5
0
void cvComputeRQDecomposition(CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ, CvMat *matrixQx, CvMat *matrixQy, CvMat *matrixQz, CvPoint3D64f *eulerAngles)
{
	
	CvMat *tmpMatrix1 = 0;
	CvMat *tmpMatrix2 = 0;
	CvMat *tmpMatrixM = 0;
	CvMat *tmpMatrixR = 0;
	CvMat *tmpMatrixQ = 0;
	CvMat *tmpMatrixQx = 0;
	CvMat *tmpMatrixQy = 0;
	CvMat *tmpMatrixQz = 0;
	double tmpEulerAngleX, tmpEulerAngleY, tmpEulerAngleZ;
	
	CV_FUNCNAME("cvRQDecomp3x3");
    __CV_BEGIN__;
	
	/* Validate parameters. */
	if(matrixM == 0 || matrixR == 0 || matrixQ == 0)
		CV_ERROR(CV_StsNullPtr, "Some of parameters is a NULL pointer!");
	
	if(!CV_IS_MAT(matrixM) || !CV_IS_MAT(matrixR) || !CV_IS_MAT(matrixQ))
		CV_ERROR(CV_StsUnsupportedFormat, "Input parameters must be a matrices!");
	
	if(matrixM->cols != 3 || matrixM->rows != 3 || matrixR->cols != 3 || matrixR->rows != 3 || matrixQ->cols != 3 || matrixQ->rows != 3)
		CV_ERROR(CV_StsUnmatchedSizes, "Size of matrices must be 3x3!");
	
	CV_CALL(tmpMatrix1 = cvCreateMat(3, 3, CV_64F));
	CV_CALL(tmpMatrix2 = cvCreateMat(3, 3, CV_64F));
	CV_CALL(tmpMatrixM = cvCreateMat(3, 3, CV_64F));
	CV_CALL(tmpMatrixR = cvCreateMat(3, 3, CV_64F));
	CV_CALL(tmpMatrixQ = cvCreateMat(3, 3, CV_64F));
	CV_CALL(tmpMatrixQx = cvCreateMat(3, 3, CV_64F));
	CV_CALL(tmpMatrixQy = cvCreateMat(3, 3, CV_64F));
	CV_CALL(tmpMatrixQz = cvCreateMat(3, 3, CV_64F));
	
	cvCopy(matrixM, tmpMatrixM);
	
	/* Find Givens rotation Q_x for x axis. */
	/*
	      ( 1  0  0 )
	 Qx = ( 0  c -s ), cos = -m33/sqrt(m32^2 + m33^2), cos = m32/sqrt(m32^2 + m33^2)
		  ( 0  s  c )
	 */
	
	double x, y, z, c, s;
	x = cvmGet(tmpMatrixM, 2, 1);
	y = cvmGet(tmpMatrixM, 2, 2);
	z = x * x + y * y;
	assert(z != 0); // Prevent division by zero.
	c = -y / sqrt(z);
	s = x / sqrt(z);
	
	cvSetIdentity(tmpMatrixQx);
	cvmSet(tmpMatrixQx, 1, 1, c);
	cvmSet(tmpMatrixQx, 1, 2, -s);
	cvmSet(tmpMatrixQx, 2, 1, s);
	cvmSet(tmpMatrixQx, 2, 2, c);
	
	tmpEulerAngleX = acos(c) * 180.0 / CV_PI;
	
	/* Multiply M on the right by Q_x. */
	
	cvMatMul(tmpMatrixM, tmpMatrixQx, tmpMatrixR);
	cvCopy(tmpMatrixR, tmpMatrixM);
	
	assert(cvmGet(tmpMatrixM, 2, 1) < CV_VERYSMALLDOUBLE && cvmGet(tmpMatrixM, 2, 1) > -CV_VERYSMALLDOUBLE); // Should actually be zero.
	
	if(cvmGet(tmpMatrixM, 2, 1) != 0.0)
		cvmSet(tmpMatrixM, 2, 1, 0.0); // Rectify arithmetic precision error.
	
	/* Find Givens rotation for y axis. */
	/*
	      ( c  0  s )
	 Qy = ( 0  1  0 ), cos = m33/sqrt(m31^2 + m33^2), cos = m31/sqrt(m31^2 + m33^2)
	      (-s  0  c )
	 */
	
	x = cvmGet(tmpMatrixM, 2, 0);
	y = cvmGet(tmpMatrixM, 2, 2);
	z = x * x + y * y;
	assert(z != 0); // Prevent division by zero.
	c = y / sqrt(z);
	s = x / sqrt(z);
	
	cvSetIdentity(tmpMatrixQy);
	cvmSet(tmpMatrixQy, 0, 0, c);
	cvmSet(tmpMatrixQy, 0, 2, s);
	cvmSet(tmpMatrixQy, 2, 0, -s);
	cvmSet(tmpMatrixQy, 2, 2, c);
	
	tmpEulerAngleY = acos(c) * 180.0 / CV_PI;
	
	/* Multiply M*Q_x on the right by Q_y. */
	
	cvMatMul(tmpMatrixM, tmpMatrixQy, tmpMatrixR);
	cvCopy(tmpMatrixR, tmpMatrixM);
	
	assert(cvmGet(tmpMatrixM, 2, 0) < CV_VERYSMALLDOUBLE && cvmGet(tmpMatrixM, 2, 0) > -CV_VERYSMALLDOUBLE); // Should actually be zero.
	
	if(cvmGet(tmpMatrixM, 2, 0) != 0.0)
		cvmSet(tmpMatrixM, 2, 0, 0.0); // Rectify arithmetic precision error.
	
	/* Find Givens rotation for z axis. */
	/*
	      ( c -s  0 )
	 Qz = ( s  c  0 ), cos = -m22/sqrt(m21^2 + m22^2), cos = m21/sqrt(m21^2 + m22^2)
	      ( 0  0  1 )
	 */
	
	x = cvmGet(tmpMatrixM, 1, 0);
	y = cvmGet(tmpMatrixM, 1, 1);
	z = x * x + y * y;
	assert(z != 0); // Prevent division by zero.
	c = -y / sqrt(z);
	s = x / sqrt(z);
	
	cvSetIdentity(tmpMatrixQz);
	cvmSet(tmpMatrixQz, 0, 0, c);
	cvmSet(tmpMatrixQz, 0, 1, -s);
	cvmSet(tmpMatrixQz, 1, 0, s);
	cvmSet(tmpMatrixQz, 1, 1, c);
	
	tmpEulerAngleZ = acos(c) * 180.0 / CV_PI;
	
	/* Multiply M*Q_x*Q_y on the right by Q_z. */
	
	cvMatMul(tmpMatrixM, tmpMatrixQz, tmpMatrixR);
	
	assert(cvmGet(tmpMatrixR, 1, 0) < CV_VERYSMALLDOUBLE && cvmGet(tmpMatrixR, 1, 0) > -CV_VERYSMALLDOUBLE); // Should actually be zero.
	
	if(cvmGet(tmpMatrixR, 1, 0) != 0.0)
		cvmSet(tmpMatrixR, 1, 0, 0.0); // Rectify arithmetic precision error.
	
	/* Calulate orthogonal matrix. */
	/*
	 Q = QzT * QyT * QxT
	 */
	
	cvTranspose(tmpMatrixQz, tmpMatrix1);
	cvTranspose(tmpMatrixQy, tmpMatrix2);
	cvMatMul(tmpMatrix1, tmpMatrix2, tmpMatrixQ);
	cvCopy(tmpMatrixQ, tmpMatrix1);
	cvTranspose(tmpMatrixQx, tmpMatrix2);
	cvMatMul(tmpMatrix1, tmpMatrix2, tmpMatrixQ);
	
	/* Solve decomposition ambiguity. */
	/*
	 Diagonal entries of R should be positive, so swap signs if necessary.
	 */
	
	if(cvmGet(tmpMatrixR, 0, 0) < 0.0) {
		cvmSet(tmpMatrixR, 0, 0, -1.0 * cvmGet(tmpMatrixR, 0, 0));
		cvmSet(tmpMatrixQ, 0, 0, -1.0 * cvmGet(tmpMatrixQ, 0, 0));
		cvmSet(tmpMatrixQ, 0, 1, -1.0 * cvmGet(tmpMatrixQ, 0, 1));
		cvmSet(tmpMatrixQ, 0, 2, -1.0 * cvmGet(tmpMatrixQ, 0, 2));
	}
	if(cvmGet(tmpMatrixR, 1, 1) < 0.0) {
		cvmSet(tmpMatrixR, 0, 1, -1.0 * cvmGet(tmpMatrixR, 0, 1));
		cvmSet(tmpMatrixR, 1, 1, -1.0 * cvmGet(tmpMatrixR, 1, 1));
		cvmSet(tmpMatrixQ, 1, 0, -1.0 * cvmGet(tmpMatrixQ, 1, 0));
		cvmSet(tmpMatrixQ, 1, 1, -1.0 * cvmGet(tmpMatrixQ, 1, 1));
		cvmSet(tmpMatrixQ, 1, 2, -1.0 * cvmGet(tmpMatrixQ, 1, 2));
	}

	/* Enforce det(Q) = 1 */ 
	if (cvDet(tmpMatrixQ) < 0) 
	{
		for (int i = 0; i < 3; i++) 
		{
			for (int j = 0; j < 3; j++) 
			{
				cvmSet(tmpMatrixQ, j, i, -cvmGet(tmpMatrixQ, j, i)); 
			}
		}
	}
	
	/* Save R and Q matrices. */
	
	cvCopy(tmpMatrixR, matrixR);
	cvCopy(tmpMatrixQ, matrixQ);
	
	if(matrixQx && CV_IS_MAT(matrixQx) && matrixQx->cols == 3 || matrixQx->rows == 3)
		cvCopy(tmpMatrixQx, matrixQx);
	if(matrixQy && CV_IS_MAT(matrixQy) && matrixQy->cols == 3 || matrixQy->rows == 3)
		cvCopy(tmpMatrixQy, matrixQy);
	if(matrixQz && CV_IS_MAT(matrixQz) && matrixQz->cols == 3 || matrixQz->rows == 3)
		cvCopy(tmpMatrixQz, matrixQz);
	
	/* Save Euler angles. */
	
	if(eulerAngles)
		*eulerAngles = cvPoint3D64f(tmpEulerAngleX, tmpEulerAngleY, tmpEulerAngleZ);
	
	__CV_END__;
	
	cvReleaseMat(&tmpMatrix1);
	cvReleaseMat(&tmpMatrix2);
	cvReleaseMat(&tmpMatrixM);
	cvReleaseMat(&tmpMatrixR);
	cvReleaseMat(&tmpMatrixQ);
	cvReleaseMat(&tmpMatrixQx);
	cvReleaseMat(&tmpMatrixQy);
	cvReleaseMat(&tmpMatrixQz);

}