Exemplo n.º 1
0
void apply_planar_homography(float *input, int width, int height, float **H, float bg, int order, float *out, float x0, float y0, int nwidth, int nheight)
{


	if (DEBUG) printf("width: %d height: %d ------>  nwidth: %d  nheight: %d \n", width, height, nwidth, nheight);	

	/// We compute inverse transformation

	if (DEBUG) 
	{

		printf("Matrix: \n");
		print_float_matrix(H,3,3);
	}
	
	float **V = allocate_float_matrix(3,3);

 	luinv(H, V, 3);

	if (DEBUG) 
	{

		printf("Inverse Matrix: \n");
		print_float_matrix(V,3,3);
	}



	float *coeffs;
	float *ref;

	float  cx[12],cy[12],ak[13];

	if (order!=0 && order!=1 && order!=-3 && 
      order!=3 && order!=5 && order!=7 && order!=9 && order!=11)
    	{	
		printf("unrecognized interpolation order.\n");
		exit(-1);
	}

        if (order>=3) {

		coeffs = new float[width*height];
    		finvspline(input,order,coeffs,width,height);
    		ref = coeffs;
    		if (order>3) init_splinen(ak,order);

	} else 
	{
    		coeffs = NULL;
    		ref = input;
  	}

	int xi,yi;
	float xp,yp;
	float res;
	int n1,n2;
	float p=-0.5;

	/// For each point in new image we compute its anti image and interpolate the new value
	for(int i=0; i < nwidth; i++)
		for(int j=0; j < nheight; j++)
	{


		float vec[3];
		vec[0] = (float) i + x0;
		vec[1] = (float) j + y0;
		vec[2] = 1.0f;


		float vres[3];
		float_vector_matrix_product(V, vec ,vres , 3);

		if (vres[2] != 0.0f) 
		{

			vres[0] /= vres[2]; vres[1] /= vres[2];
				
			

			xp =  (float) vres[0];
			yp =  (float) vres[1];

			if (order == 0) { 
	
				xi = (int)floor((double)xp); 
				yi = (int)floor((double)yp);
		
				if (xi<0 || xi>=width || yi<0 || yi>=height)
		 			 res = bg; 
				else res = input[yi*width+xi];
	
     			 } else { 
	
		
				if (xp<0. || xp>=(float)width || yp<0. || yp>=(float)height) res=bg; 
				else {
					//xp -= 0.5; yp -= 0.5;
					int xi = (int)floor((double)xp); 
					int yi = (int)floor((double)yp);
					float ux = xp-(float)xi;
	  				float uy = yp-(float)yi;

					switch (order) 
	   				{
					    	case 1: /* first order interpolation (bilinear) */
	      						n2 = 1;
							cx[0]=ux;	cx[1]=1.f-ux;
							cy[0]=uy; cy[1]=1.f-uy;
							break;
						
						case -3: /* third order interpolation (bicubic Keys' function) */
							n2 = 2;
							keys(cx,ux,p);
							keys(cy,uy,p);
							break;

						case 3: /* spline of order 3 */
							n2 = 2;
							spline3(cx,ux);
							spline3(cy,uy);
							break;

						default: /* spline of order >3 */
							n2 = (1+order)/2;
							splinen(cx,ux,ak,order);
							splinen(cy,uy,ak,order);
							break;
					}
	  
	  				res = 0.; n1 = 1-n2;
	 				if (xi+n1>=0 && xi+n2<width && yi+n1>=0 && yi+n2<height) {
	    				
						int adr = yi*width+xi; 
	    					for (int dy=n1;dy<=n2;dy++) 
	    					  for (int dx=n1;dx<=n2;dx++) 
							res += cy[n2-dy]*cx[n2-dx]*ref[adr+width*dy+dx];
	  				} else 
	
					   	for (int dy=n1;dy<=n2;dy++)
						      for (int dx=n1;dx<=n2;dx++) 
							res += cy[n2-dy]*cx[n2-dx]*v(ref,xi+dx,yi+dy,bg,width,height);
					
      				}

			}	

		

			out[j*nwidth+i] = res;
   			

		}
	
	}


}
Exemplo n.º 2
0
void Odometry::compute()
{
    mutex.wait();

    //read the encoders (deg)
    ienc->getEncoder(0,&encA);
    ienc->getEncoder(1,&encB);
    ienc->getEncoder(2,&encC);
        
    //read the speeds (deg/s)
    ienc->getEncoderSpeed(0,&velA);
    ienc->getEncoderSpeed(1,&velB);
    ienc->getEncoderSpeed(2,&velC);
        
    //remove the offset and convert in radians
    enc[0]= -(encA - encA_offset) * 0.0174532925; 
    enc[1]= -(encB - encB_offset) * 0.0174532925;
    enc[2]= -(encC - encC_offset) * 0.0174532925;
       
    //estimate the speeds
    iCub::ctrl::AWPolyElement el;
    el.data=enc;
    el.time=Time::now();
    encv= encvel_estimator->estimate(el);

    // -------------------------------------------------------------------------------------
    // The following formulas are adapted from:
    // "A New Odometry System to reduce asymmetric Errors for Omnidirectional Mobile Robots"
    // -------------------------------------------------------------------------------------

    //compute the orientation. odom_theta is expressed in radians
    odom_theta = geom_r*(enc[0]+enc[1]+enc[2])/(3*geom_L);

    //build the kinematics matrix
    yarp::sig::Matrix kin;
    kin.resize(3,3);
    kin.zero();
    kin(0,0) = -sqrt(3.0)/2.0;
    kin(0,1) = 0.5;
    kin(0,2) = geom_L;
    kin(1,0) = sqrt(3.0)/2.0;
    kin(1,1) = 0.5;
    kin(1,2) = geom_L;
    kin(2,0) = 0;
    kin(2,1) = -1.0;
    kin(2,2) = geom_L;
    kin      = kin/geom_r;
    yarp::sig::Matrix ikin = luinv(kin);

    //build the rotation matrix
    yarp::sig::Matrix m1;
    m1.resize(3,3);
    m1.zero();
    m1(0,0) = cos (odom_theta);
    m1(0,1) = -sin (odom_theta);
    m1(1,0) = sin (odom_theta);
    m1(1,1) = cos (odom_theta);
    m1(2,2) = 1;

    yarp::sig::Matrix m2;
    m2.resize(3,3);
    m2.zero();
    m2(0,0) = cos (0.0);
    m2(0,1) = -sin (0.0);
    m2(1,0) = sin (0.0);
    m2(1,1) = cos (0.0);
    m2(2,2) = 1;

    yarp::sig::Vector odom_cart_vels;  //velocities expressed in the world reference frame
    yarp::sig::Vector ikart_cart_vels; //velocities expressed in the ikart reference frame
    odom_cart_vels  = m1*ikin*encv;
    ikart_cart_vels = m2*ikin*encv;

    ikart_vel_x     = ikart_cart_vels[1];
    ikart_vel_y     = ikart_cart_vels[0];
    ikart_vel_theta = ikart_cart_vels[2];
    ikart_vel_lin   = sqrt(odom_vel_x*odom_vel_x + odom_vel_y*odom_vel_y);
    
    odom_vel_x      = odom_cart_vels[1];
    odom_vel_y      = odom_cart_vels[0];
    odom_vel_theta  = odom_cart_vels[2];
  
    //these are not currently used
    if (ikart_vel_lin<0.001)
    {
        odom_vel_heading  = 0;
        ikart_vel_heading = 0;
    }
    else
    {
        odom_vel_heading  = atan2(odom_vel_x,odom_vel_y)*57.2957795;
        ikart_vel_heading = atan2(ikart_vel_x,ikart_vel_y)*57.2957795;
    }

    //the integration step
    odom_x=odom_x + (odom_vel_x * period/1000.0);
    odom_y=odom_y + (odom_vel_y * period/1000.0);

    //compute traveled distance (odometer)
    traveled_distance = traveled_distance + fabs(ikart_vel_lin   * period/1000.0);
    traveled_angle    = traveled_angle    + fabs(ikart_vel_theta * period/1000.0);

    /* [ -(3^(1/2)*r)/3, (3^(1/2)*r)/3,        0]
        [            r/3,           r/3, -(2*r)/3]
        [        r/(3*L),       r/(3*L),  r/(3*L)]*/

    /*odom_x = -1.73205080*geom_r/3 * encA + 1.73205080*geom_r/3 * encB;
    odom_y = geom_r/3 * encA +  geom_r/3 * encB - (2*geom_r)/3 * encC;*/
        
    /*
    odom_x = geom_r/(3* 0.86602)*
                (
                (co3p-co3m)*encA + 
                (-cos(odom_theta)-co3p)*encB + 
                (cos(odom_theta)+co3m)*encC
                );
    odom_y = geom_r/(3* 0.86602)*
                (
                (si3m+si3p)*encA + 
                (-sin(odom_theta)-si3p)*encB + 
                (sin(odom_theta)-si3m)*encC
                );
    */

    //convert from radians back to degrees
    odom_theta       *= 57.2957795;
    ikart_vel_theta  *= 57.2957795;
    odom_vel_theta   *= 57.2957795;
    traveled_angle   *= 57.2957795;

    mutex.post();

    timeStamp.update();
    if (port_odometry.getOutputCount()>0)
    {
        port_odometry.setEnvelope(timeStamp);
        Bottle &b=port_odometry.prepare();
        b.clear();
        b.addDouble(odom_x);
        b.addDouble(odom_y);
        b.addDouble(odom_theta);
        b.addDouble(odom_vel_x);
        b.addDouble(odom_vel_y);
        b.addDouble(odom_vel_theta);
        port_odometry.write();
    }

    if (port_odometer.getOutputCount()>0)
    {
        port_odometer.setEnvelope(timeStamp);
        Bottle &t=port_odometer.prepare();
        t.clear();
        t.addDouble(traveled_distance);
        t.addDouble(traveled_angle);
        port_odometer.write();
    }

    if (port_ikart_vels.getOutputCount()>0)
    {
        port_ikart_vels.setEnvelope(timeStamp);
        Bottle &v=port_ikart_vels.prepare();
        v.clear();
        v.addDouble(ikart_vel_x);
        v.addDouble(ikart_vel_y);
        v.addDouble(ikart_vel_theta);
        port_ikart_vels.write();
    }
}