Ejemplo n.º 1
0
void TwoFrameModel::WriteSparse(FILE *f)
{
    // WriteCameraPose(f, m_camera0);
    // WriteCameraPose(f, m_camera1);

    /* Compute the camera pose of camera1 relative to camera0 */
    double pos0[3], pos1[3];
    
    // matrix_transpose_product(3, 3, 3, 1, m_camera0.R, m_camera0.t, pos0);
    // matrix_transpose_product(3, 3, 3, 1, m_camera1.R, m_camera1.t, pos1);
    memcpy(pos0, m_camera0.t, 3 * sizeof(double));
    memcpy(pos1, m_camera1.t, 3 * sizeof(double));

    // matrix_scale(3, 1, pos0, -1.0, pos0);
    // matrix_scale(3, 1, pos1, -1.0, pos1);
    
    double diff[3];
    matrix_diff(3, 1, 3, 1, pos1, pos0, diff);
    
    double R1[9], tr[3];
    matrix_transpose_product2(3, 3, 3, 3, m_camera0.R, m_camera1.R, R1);
    // matrix_transpose_product(3, 3, 3, 3, m_camera1.R, m_camera0.R, R1);
    matrix_product(3, 3, 3, 1, m_camera0.R, diff, tr);

    double norm = matrix_norm(3, 1, tr);
    matrix_scale(3, 1, tr, 1.0 / norm, tr);

    double viewdir[3] = { -R1[2], -R1[5], -R1[8] };
    double twist_angle = GetTwist(R1);
    
    /* Compute the distance to the scene */
    double z_avg = 0.0;
    
    for (int p = 0; p < m_num_points; p++) {
        v3_t &pt = m_points[p];

        double diff1[3], diff2[3];
        matrix_diff(3, 1, 3, 1, pt.p, pos0, diff1);
        matrix_diff(3, 1, 3, 1, pt.p, pos1, diff2);

        double dist1 = matrix_norm(3, 1, diff1);
        double dist2 = matrix_norm(3, 1, diff2);

        z_avg += 0.5 * (dist1 + dist2) / norm;
    }

    z_avg /= m_num_points;
    
    WriteVector(f, 9, R1);
    /* Write the viewing direction */
    // WriteVector(f, 3, viewdir);
    /* Write the twist angle */
    // fprintf(f, "%0.8f\n", twist_angle);
    /* Write the translation */
    WriteVector(f, 3, tr);

    fprintf(f, "%0.6f\n", z_avg);
}
Ejemplo n.º 2
0
/* Returns true (and stores the endpoints in t and u) if the
 * epipolar swath e1, e2 intersects this segment */
bool LineSegment2D::IntersectsEpipolarSwath(double e1[3], double e2[3], 
					    double &t, double &u)
{
    /* Find the line between the two endpoints */
    double p[3] = { m_p1[0], m_p1[1], 1.0 };
    double q[3] = { m_p2[0], m_p2[1], 1.0 };

    double l[3];
    matrix_cross(p, q, l);

    /* Intersect the line with the two epipolar lines */
    double i1[3], i2[3];

    matrix_cross(l, e1, i1);
    matrix_cross(l, e2, i2);

    double inv_i12 = 1.0 / i1[2];
    i1[0] *= inv_i12;
    i1[1] *= inv_i12;

    double inv_i22 = 1.0 / i2[2];
    i2[0] *= inv_i22;
    i2[1] *= inv_i22;

    double qp[3], i1p[3], i2p[3];
    matrix_diff(2, 1, 2, 1, q, p, qp);

    matrix_diff(2, 1, 2, 1, i1, p, i1p);
    matrix_diff(2, 1, 2, 1, i2, p, i2p);

    double dot1, dot2;
    matrix_product(1, 2, 2, 1, i1p, qp, &dot1);
    matrix_product(1, 2, 2, 1, i2p, qp, &dot2);

    int sign1 = SGN(dot1);
    int sign2 = SGN(dot2);

    double inv_norm = 1.0 / matrix_norm(2, 1, qp);
    double mag1 = matrix_norm(2, 1, i1p) * inv_norm; // matrix_norm(2, 1, qp);
    double mag2 = matrix_norm(2, 1, i2p) * inv_norm; // matrix_norm(2, 1, qp);

    t = sign1 * mag1;
    u = sign2 * mag2;

    /* Intersection check */
    if ((t < 0.0 && u < 0.0) || (t > 1.0 && u > 1.0))
	return false;
    else
	return true;
}
Ejemplo n.º 3
0
void PlaneData::Transform(const double *M)
{
    double p[4] = { m_normal[0], m_normal[1], m_normal[2], m_dist };

    double Minv[16];
    matrix_invert(4, (double *)M, Minv);
    
    double pNew[4];
    matrix_transpose_product(4, 4, 4, 1, Minv, p, pNew);

    double len = matrix_norm(3, 1, pNew);
    
    m_normal[0] = pNew[0] / len;
    m_normal[1] = pNew[1] / len;
    m_normal[2] = pNew[2] / len;
    m_dist = pNew[3] / len;

#if 0
    double origin[4] = { m_origin[0], m_origin[1], m_origin[2], 1.0 };
    double Morigin[4];
    matrix_product(4, 4, 4, 1, (double *) M, origin, Morigin);

    double dot0, dot1;
    matrix_product(1, 4, 4, 1, p, origin, &dot0);
    matrix_product(1, 4, 4, 1, pNew, Morigin, &dot1);

    printf("dot0 = %0.3f\n", dot0);
    printf("dot1 = %0.3f\n", dot1);
#endif
}
Ejemplo n.º 4
0
double TwoFrameModel::AverageDistanceToPoints() const {
    double dist_sum = 0.0;
    const double *pos1 = m_camera0.t;
    const double *pos2 = m_camera1.t;
    
    for (int i = 0; i < m_num_points; i++) {
        double diff1[3], diff2[3];
        matrix_diff(3, 1, 3, 1, m_points[i].p, (double *) pos1, diff1);
        matrix_diff(3, 1, 3, 1, m_points[i].p, (double *) pos2, diff2);
        
        double norm1 = matrix_norm(3, 1, diff1);
        double norm2 = matrix_norm(3, 1, diff2);

        dist_sum += (norm1 + norm2);
    }

    return dist_sum / (2 * m_num_points);
}
Ejemplo n.º 5
0
/* Return the homogeneous form of the line */
void LineSegment2D::Homogeneous(double *l)
{
    double p1[3] = { m_p1[0], m_p1[1], 1.0 };
    double p2[3] = { m_p2[0], m_p2[1], 1.0 };    

    matrix_cross(p1, p2, l);
    
    double norm = matrix_norm(3, 1, l);
    matrix_scale(3, 1, l, 1.0 / norm, l);
}
Ejemplo n.º 6
0
int values(double *A, int n, double *Q1, double *Q2, double *v, double eps){
	double norm = matrix_norm(n,A);
	double qe = fabs(eps*norm);
//	printf("need %e\n", qe);
	if (n > 2){
		TDiag(A,n);
	}
	double* A1;
	double sk;
	double t = fabs(A[(n-1)*n + (n-2)]);
	int r = n;
	int c = 0;
	while (r > 2)
	{
		sk = A[(r-1)*n + (r-1)];
		for (int i = 0; i < r; i++){
			A[i*n + i] -= sk;
		}
		A1 = new double [r*r];
		for (int i = 0; i < r; i++){
			for (int j = 0; j < r; j++){
				A1[i*r+j] = A[i*n + j];
			}
		}
		if (QR(A1,r,Q1,Q2)==-1){
			delete [] A1;
			return -1;
		}
		for (int i = 0; i < r; i++){
			for (int j = 0; j < r; j++){
				A[i*n+j] = A1[i*r+j];
			}
		}
		delete [] A1;
		for (int i = 0; i < r; i++){
			A[i*n + i] += sk;
		}
		if ((fabs(A[(r-1)*n + (r-2)])-t)<EPS){
			c++;
		}
		t = fabs(A[(r-1)*n + (r-2)]);
		if (t < qe){
			v[r-1] = A[(r-1)*n + (r-1)];
			r--;
		}
		if (c > 10){
		   return 3;
		}
	}
	double D = (A[0]+A[n+1])*(A[0]+A[n+1]) - 4.*(A[0]*A[n+1] - A[1]*A[n]);
	v[1] = (A[0]+A[n+1] - sqrt(D))/2.;
	v[0] = (A[0]+A[n+1] + sqrt(D))/2.;
	return 1;
}
Ejemplo n.º 7
0
void infomax(gsl_matrix *x_white, gsl_matrix *weights, gsl_matrix *S, int  verbose){
  /*Computes ICA infomax in whitened data
    Decomposes x_white as x_white=AS
    *Input
    x_white: whitened data (Use PCAwhiten)
    *Output
    A : mixing matrix
    S : source matrix
  */
  // int verbose = 1; //true
  size_t NCOMP = x_white->size1;
  size_t NVOX = x_white->size2;

  //getting permutation vector
  const gsl_rng_type * T;
  gsl_rng * r;
  gsl_permutation * p = gsl_permutation_alloc (NVOX);
  // gsl_rng_env_setup();
  T = gsl_rng_default;
  r = gsl_rng_alloc (T);
  gsl_permutation_init (p);

  gsl_matrix *old_weights    = gsl_matrix_alloc(NCOMP,NCOMP);
  gsl_matrix *bias           = gsl_matrix_calloc(NCOMP, 1);
  gsl_matrix *d_weights      = gsl_matrix_calloc(NCOMP,NCOMP);
  gsl_matrix *temp_change    = gsl_matrix_alloc(NCOMP,NCOMP);
  gsl_matrix *old_d_weights  = gsl_matrix_calloc(NCOMP,NCOMP);
  gsl_matrix *shuffled_x_white  = gsl_matrix_calloc(NCOMP,x_white->size2);
  gsl_matrix_memcpy(shuffled_x_white, x_white);
  gsl_matrix_set_identity(weights);
  gsl_matrix_set_identity(old_weights);
  double lrate = 0.005/log((double)NCOMP);
  double change=1;
  double angle_delta =0;
  size_t step = 1;
  int error = 0;
  while( (step < MAX_STEP) && (change > W_STOP)){
    error = w_update(weights, x_white, bias,
      shuffled_x_white, p, r, lrate);
    if (error==1 || error==2){
      // It blowed up! RESTART!
      step = 1;
      // change = 1;
      error = 0;
      lrate *= ANNEAL;
      gsl_matrix_set_identity(weights);
      gsl_matrix_set_identity(old_weights);
      gsl_matrix_set_zero(d_weights);
      gsl_matrix_set_zero(old_d_weights);
      gsl_matrix_set_zero(bias);

      if (lrate > MIN_LRATE){
        printf("\nLowering learning rate to %g and starting again.\n",lrate);
      }
      else{
        printf("\nMatrix may not be invertible");
      }
    }
    else if (error==0){
      gsl_matrix_memcpy(d_weights, weights);
      gsl_matrix_sub(d_weights, old_weights);
      change = matrix_norm(d_weights);

      if (step > 2){
        // Compute angle delta
        gsl_matrix_memcpy(temp_change, d_weights);
        gsl_matrix_mul_elements(temp_change, old_d_weights);
        angle_delta = acos(matrix_sum(temp_change) / sqrt(matrix_norm(d_weights)*(matrix_norm(old_d_weights))));
        angle_delta *= (180.0 / M_PI);
      }

      gsl_matrix_memcpy(old_weights, weights);

      if (angle_delta > 60){
        lrate *= ANNEAL;
        gsl_matrix_memcpy(old_d_weights, d_weights);
      } else if (step==1) {
        gsl_matrix_memcpy(old_d_weights, d_weights);
      }

      if ((verbose && (step % 10)== 0) || change < W_STOP){
        printf("\nStep %zu: Lrate %.1e, Wchange %.1e, Angle %.2f",
          step, lrate, change, angle_delta);
      }

      step ++;
    }
  }

  matrix_mmul(weights, x_white, S);
  gsl_matrix_free(old_d_weights);
  gsl_matrix_free(old_weights);
  gsl_matrix_free(bias);
  gsl_matrix_free(d_weights);
  gsl_matrix_free(shuffled_x_white);
  gsl_rng_free (r);
  gsl_permutation_free (p);
}
Ejemplo n.º 8
0
void LineSegment3D::Render(const CameraInfo &camera, double max_width,
			   int stroke_texture, ParameterBound stroke_bounds)
{
#ifndef __BUNDLER__
#ifndef __DEMO__
#if 1
    /* Project the line into the camera */
    double p1[4] = { m_p1[0], m_p1[1], m_p1[2], 1.0 };
    double p2[4] = { m_p2[0], m_p2[1], m_p2[2], 1.0 };    
    double proj1[3], proj2[3];

    matrix_product(3, 4, 4, 1, (double *) camera.m_Pmatrix, p1, proj1);
    matrix_product(3, 4, 4, 1, (double *) camera.m_Pmatrix, p2, proj2);

    if (proj1[2] >= 0.0 || proj2[2] >= 0.0)
	return;

    double width = CLAMP(5.0 / (-proj1[2] - proj2[2]), 0.5, max_width);

    proj1[0] /= -proj1[2];
    proj1[1] /= -proj1[2];

    proj2[0] /= -proj2[2];
    proj2[1] /= -proj2[2];
#endif

#if 0
    bool in_front1 = camera.Project(m_p1, proj1);
    bool in_front2 = camera.Project(m_p2, proj2);

    if (!in_front1 || !in_front2)
	return;
#endif    

    /* Draw a line segment whose width is proportional to the distance
     * from the camera */

#if 0
    double pos[3];
    camera.GetPosition(pos);

    double disp[3];
    matrix_diff(3, 1, 3, 1, pos, m_p1, disp);
    
    double dist = matrix_norm(3, 1, disp);
#endif

    if (stroke_texture != -1) {
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, stroke_texture);
    }

#if 0
    #define LINE_WIDTH_SIGMA 1.0
    double width =
	max_width * exp(-dist * dist / (LINE_WIDTH_SIGMA * LINE_WIDTH_SIGMA));
#endif

    /* Create a stroke */
    Stroke s;
    s.radius() = 0.5 * width;
    s.cap() = false;
    s.depth() = 1.0;

    if (stroke_texture == -1) {
	s.useTexture() = false;
	s.color() = makeColor(0, 0, 0, 0.9f);
    } else {
	GLubyte b = 0x0;
	s.useTexture() = true;
	s.color() = makeColor(b, b, b, 0.9f);
    }

    s.addControlPoint(proj1[0], proj1[1]);
    s.addControlPoint(proj2[0], proj2[1]);

    s.render();

    if (stroke_texture != -1) {
		glDisable(GL_TEXTURE_2D);
    }
#endif /* __DEMO__ */
#endif /* __BUNDLER__ */
}
Ejemplo n.º 9
0
/* Align two sets of points with a 3D similarity transform */
int align_horn_3D_ransac(int n, v3_t *r_pts, v3_t *l_pts, 
                         int num_ransac_rounds, double ransac_thresh,
                         double *Tret)
{
    int round;    
#define MIN_SUPPORT 3
    v3_t *l_inliers, *r_inliers;
    double *Vp, *TVp;
    int num_inliers, max_inliers = 0;
    double Tbest[16], TbestT[16];
    int i;
    double *ptr;

    double ransac_threshsq = ransac_thresh * ransac_thresh;

    if (n < MIN_SUPPORT) {
	printf("[align_horn_3D_ransac] Error: need at least %d points!\n",
               MIN_SUPPORT);
	return 0;
    }

    l_inliers = (v3_t *) malloc(sizeof(v3_t) * n);
    r_inliers = (v3_t *) malloc(sizeof(v3_t) * n);

    Vp = (double *) malloc(sizeof(double) * 4 * n);
    TVp = (double *) malloc(sizeof(double) * 4 * n);

    for (i = 0; i < n; i++) {
        memcpy(Vp + 4 * i, l_pts[i].p, 3 * sizeof(double));
        Vp[4 * i + 3] = 1.0;
    }

    for (round = 0; round < num_ransac_rounds; round++) {
	int support[MIN_SUPPORT];
	int i, j;
	v3_t r_pts_small[MIN_SUPPORT], l_pts_small[MIN_SUPPORT];
	double Tout[16], ToutT[16];
        int nan = 0;
	
	for (i = 0; i < MIN_SUPPORT; i++) {
	    /* Select an index from 0 to n-1 */
	    int idx, reselect;
	    do {
		reselect = 0;
		idx = rand() % n;
		for (j = 0; j < i; j++) {
		    if (support[j] == idx) {
			reselect = 1;
			break;
		    }
		}
	    } while (reselect);

	    support[i] = idx;
	    r_pts_small[i] = r_pts[idx];
	    l_pts_small[i] = l_pts[idx];
	}

        align_horn_3D_2(MIN_SUPPORT, r_pts_small, l_pts_small, 1, Tout);

#if 1
        for (i = 0; i < 16; i++) {
            if (isnan(Tout[i]) || Tout[i] != Tout[i]) {
                nan = 1;
                break;
            }
        }
        
        if (nan == 1)
            continue;
#endif

	/* Count inliers */
	num_inliers = 0;

#if 0
	for (i = 0; i < n; i++) {
	    double Tp[4];
	    double diff[3];
	    double dist;

            double p[4] = { l_pts[i].p[0], l_pts[i].p[1], l_pts[i].p[2], 1.0 };

	    matrix_product(4, 4, 4, 1, Tout, p, Tp);
	    matrix_diff(3, 1, 3, 1, Tp, r_pts[i].p, diff);
	    dist = matrix_norm(3, 1, diff);
	    
	    if (dist < ransac_thresh) {
		num_inliers++;
	    }
	}
#else
        matrix_transpose(4, 4, Tout, ToutT);
        matrix_product_old(n, 4, 4, 4, Vp, ToutT, TVp);

        ptr = TVp;

        for (i = 0; i < n; i++) {
            // double diff[3], dist;
            double dx, dy, dz, dist;
            // matrix_diff(3, 1, 3, 1, TVp + 4 * i, r_pts[i].p, diff);
            dx = ptr[0] - r_pts[i].p[0];
            dy = ptr[1] - r_pts[i].p[1];
            dz = ptr[2] - r_pts[i].p[2];

	    dist = dx * dx + dy * dy + dz * dz; // matrix_normsq(3, 1, diff);
	    
	    if (dist < ransac_threshsq)
		num_inliers++;

            ptr += 4;
        }
#endif

        if (num_inliers > max_inliers) {
            max_inliers = num_inliers;
            memcpy(Tbest, Tout, sizeof(double) * 16);
        }
    }

    /* Reestimate using all inliers */
#if 0
    matrix_transpose(4, 4, Tbest, TbestT);
    matrix_product(n, 4, 4, 4, Vp, TbestT, TVp);

    num_inliers = 0;
    for (i = 0; i < n; i++) {
	// double Tp[4];
	double diff[3];
	double dist;

        matrix_diff(3, 1, 3, 1, TVp + 4 * i, r_pts[i].p, diff);

        // double p[4] = { l_pts[i].p[0], l_pts[i].p[1], l_pts[i].p[2], 1.0 };

	// matrix_product(4, 4, 4, 1, Tbest, p, Tp);
	// matrix_diff(3, 1, 3, 1, Tp, r_pts[i].p, diff);
	dist = matrix_normsq(3, 1, diff);
	    
	if (dist < ransac_threshsq) {
	    r_inliers[num_inliers] = r_pts[i];
	    l_inliers[num_inliers] = l_pts[i];
	    num_inliers++;
	}
    }

    align_horn_3D_2(num_inliers, r_inliers, l_inliers, 1, Tret);

    // memcpy(Tret, Tbest, 16 * sizeof(double));

    if (isnan(Tret[0]) || Tret[0] != Tret[0]) {
        printf("[align_horn_3D_ransac] nan at end [num_inliers: %d], "
               "restoring old matrix\n", num_inliers);
        memcpy(Tret, Tbest, sizeof(double) * 16);
    }
#else
    memcpy(Tret, Tbest, sizeof(double) * 16);
#endif

    free(r_inliers);
    free(l_inliers);
    free(Vp);
    free(TVp);

    return max_inliers;
#undef MIN_SUPPORT
}
Ejemplo n.º 10
0
/* Align two sets of points with a 2D similarity transform */
int align_horn_ransac(int n, v3_t *r_pts, v3_t *l_pts, 
                      int num_ransac_rounds, double ransac_thresh,
                      double *Tret)
{
    int round;    
#define MIN_SUPPORT 3
    v3_t *l_inliers, *r_inliers;
    int num_inliers, max_inliers = 0;
    double Tbest[9], R[9], T[9], scale;
    int i;

    if (n < 3) {
	printf("[align_horn_ransac] Error: need at least 3 points!\n");
	return 0;
    }

    l_inliers = (v3_t *) malloc(sizeof(v3_t) * n);
    r_inliers = (v3_t *) malloc(sizeof(v3_t) * n);

    for (round = 0; round < num_ransac_rounds; round++) {
	int support[MIN_SUPPORT];
	int i, j;
	v3_t r_pts_small[MIN_SUPPORT], l_pts_small[MIN_SUPPORT];
	double Rtmp[9], Ttmp[9], Tout[9], scale_tmp;
	
	for (i = 0; i < MIN_SUPPORT; i++) {
	    /* Select an index from 0 to n-1 */
	    int idx, reselect;
	    do {
		reselect = 0;
		idx = rand() % n;
		for (j = 0; j < i; j++) {
		    if (support[j] == idx) {
			reselect = 1;
			break;
		    }
		}
	    } while (reselect);

	    support[i] = idx;
	    r_pts_small[i] = r_pts[idx];
	    l_pts_small[i] = l_pts[idx];
	}

        align_horn(MIN_SUPPORT, r_pts_small, l_pts_small, Rtmp, Ttmp, 
                   Tout, &scale_tmp, NULL);

	/* Count inliers */
	num_inliers = 0;
	for (i = 0; i < n; i++) {
	    double Tp[3];
	    double diff[3];
	    double dist;
	    matrix_product(3, 3, 3, 1, Tout, l_pts[i].p, Tp);
	    matrix_diff(3, 1, 3, 1, Tp, r_pts[i].p, diff);
	    dist = matrix_norm(3, 1, diff);
	    
	    if (dist < ransac_thresh) {
		num_inliers++;
	    }

	    if (num_inliers > max_inliers) {
		max_inliers = num_inliers;
		memcpy(Tbest, Tout, sizeof(double) * 9);
                // printf(" inliers_new: %d\n", num_inliers);
	    }
	}
    }

#if 0
    /* Reestimate using all inliers */
    num_inliers = 0;
    for (i = 0; i < n; i++) {
	double Tp[3];
	double diff[3];
	double dist;
	matrix_product(3, 3, 3, 1, Tbest, l_pts[i].p, Tp);
	matrix_diff(3, 1, 3, 1, Tp, r_pts[i].p, diff);
	dist = matrix_norm(3, 1, diff);
	    
	if (dist < ransac_thresh) {
	    r_inliers[num_inliers] = r_pts[i];
	    l_inliers[num_inliers] = l_pts[i];
	    num_inliers++;
	}
    }

    // printf(" inliers: %d\n", num_inliers);

    align_horn(num_inliers, r_inliers, l_inliers, R, T, Tret, &scale, NULL);
#else
    memcpy(Tret, Tbest, 9 * sizeof(double));
#endif

    free(r_inliers);
    free(l_inliers);

    return num_inliers;
#undef MIN_SUPPORT
}
Ejemplo n.º 11
0
/* Align two sets of points with a 2D similarity transform */
int align_2D_ransac(int n, v3_t *r_pts, v3_t *l_pts, 
                    int num_ransac_rounds, double ransac_thresh,
                    double *Tret)
{
    int round;    
#define MIN_SUPPORT 2
    v3_t *l_inliers, *r_inliers;
    int num_inliers, max_inliers = 0;
    double Tbest[9], R[9], T[9], scale;
    int i;

    if (n < 3) {
	printf("[align_2D_ransac] Error: need at least 3 points!\n");
	return 0;
    }

    l_inliers = (v3_t *) malloc(sizeof(v3_t) * n);
    r_inliers = (v3_t *) malloc(sizeof(v3_t) * n);

    for (round = 0; round < num_ransac_rounds; round++) {
	int support[MIN_SUPPORT];
	int i, j;
    v3_t r_mean, l_mean, r0, l0;
	v3_t r_pts_small[MIN_SUPPORT], l_pts_small[MIN_SUPPORT];
	double Rtmp[9], T1tmp[9], T2tmp[9], tmp[9], Tout[9];
    double a, b;

    for (i = 0; i < MIN_SUPPORT; i++) {
        /* Select an index from 0 to n-1 */
        int idx, reselect;

        do {
            reselect = 0;
            idx = rand() % n;
            for (j = 0; j < i; j++) {
                if (support[j] == idx) {
                    reselect = 1;
                    break;
                }
            }
        } while (reselect);

        support[i] = idx;
        r_pts_small[i] = r_pts[idx];
        l_pts_small[i] = l_pts[idx];
    }

    r_mean = v3_scale(0.5, v3_add(r_pts_small[0], r_pts_small[1]));
    l_mean = v3_scale(0.5, v3_add(l_pts_small[0], l_pts_small[1]));

    r0 = v3_sub(r_pts_small[0], r_mean);
    // v3_t r1 = v3_sub(r_pts_small[1], mean);
    l0 = v3_sub(l_pts_small[0], l_mean);
    // v3_t l1 = v3_sub(l_pts_small[1], mean);

    a = (Vy(r0) + Vx(r0) * Vx(l0) / Vy(l0)) / 
        (Vy(l0) + Vx(l0) * Vx(l0) / Vy(l0));
    b = (Vx(r0) - a * Vx(l0)) / Vy(l0);

    Rtmp[0] = a;  Rtmp[1] = b;  Rtmp[2] = 0.0;
    Rtmp[3] = -b; Rtmp[4] = a;  Rtmp[5] = 0.0;
    Rtmp[6] = 0;  Rtmp[7] = 0;  Rtmp[8] = 1.0;

    matrix_ident(3, T1tmp);
    T1tmp[2] = -Vx(l_mean);
    T1tmp[5] = -Vy(l_mean);

    matrix_ident(3, T2tmp);
    T2tmp[2] = Vx(r_mean);
    T2tmp[5] = Vy(r_mean);        

    matrix_product(3, 3, 3, 3, Rtmp, T1tmp, tmp);
    matrix_product(3, 3, 3, 3, T2tmp, tmp, Tout);

	/* Count inliers */
	num_inliers = 0;
	for (i = 0; i < n; i++) {
	    double Tp[3];
	    double diff[3];
	    double dist;
	    matrix_product(3, 3, 3, 1, Tout, l_pts[i].p, Tp);
	    matrix_diff(3, 1, 3, 1, Tp, r_pts[i].p, diff);
	    dist = matrix_norm(3, 1, diff);
	    
	    if (dist < ransac_thresh) {
		num_inliers++;
	    }

	    if (num_inliers > max_inliers) {
		max_inliers = num_inliers;
		memcpy(Tbest, Tout, sizeof(double) * 9);
                // printf(" inliers_new: %d\n", num_inliers);
	    }
	}
    }

#if 0
    /* Reestimate using all inliers */
    num_inliers = 0;
    for (i = 0; i < n; i++) {
	double Tp[3];
	double diff[3];
	double dist;
	matrix_product(3, 3, 3, 1, Tbest, l_pts[i].p, Tp);
	matrix_diff(3, 1, 3, 1, Tp, r_pts[i].p, diff);
	dist = matrix_norm(3, 1, diff);
	    
	if (dist < ransac_thresh) {
	    r_inliers[num_inliers] = r_pts[i];
	    l_inliers[num_inliers] = l_pts[i];
	    num_inliers++;
	}
    }

    // align_horn(num_inliers, r_inliers, l_inliers, R, T, Tret, &scale, NULL);
    align_2D(num_inliers, r_inliers, l_inliers, R, T, Tret, &scale, NULL);
#else
    memcpy(Tret, Tbest, 9 * sizeof(double));
#endif

    free(r_inliers);
    free(l_inliers);

    return num_inliers;
#undef MIN_SUPPORT
}
Ejemplo n.º 12
0
/* Align two sets of points with a 3D rotation */
double align_3D_rotation(int n, v3_t *r_pts, v3_t *l_pts, double *R)
{
    double A[9];
    double U[9], S[3], V[9], VT[9], RT[9];
    int i;
    double error;

#if 0
    if (n > 3) {
        printf("A:\n");
        for (i = 0; i < n; i++) {
            printf("%0.6f %0.6f %0.6f\n", 
                   Vx(r_pts[i]), Vy(r_pts[i]), Vz(r_pts[i]));
        }
        printf("B:\n");
        for (i = 0; i < n; i++) {
            printf("%0.6f %0.6f %0.6f\n", 
                   Vx(l_pts[i]), Vy(l_pts[i]), Vz(l_pts[i]));                
        }        
    }
#endif

    for (i = 0; i < 9; i++)
	A[i] = 0.0;

    for (i = 0; i < n; i++) {
        double *a = l_pts[i].p, *b = r_pts[i].p;
	// matrix_product(3, 1, 1, 3, l_pts[i].p, r_pts[i].p, tensor);
        A[0] += a[0] * b[0];
        A[1] += a[0] * b[1];
        A[2] += a[0] * b[2];

        A[3] += a[1] * b[0];
        A[4] += a[1] * b[1];
        A[5] += a[1] * b[2];

        A[6] += a[2] * b[0];
        A[7] += a[2] * b[1];
        A[8] += a[2] * b[2];
    }

    // dgesvd_driver(3, 3, A, U, S, VT);
    // printf("svd:\n");
    // matrix_print(3, 3, A);
    svd(3, 3, 1, 1, 1.0e-12, 1.0e-12, A, S, U, V, VT);
    
    // printf("U:\n");
    // matrix_print(3, 3, U);
    // printf("VT:\n");
    // matrix_print(3, 3, VT);
    // printf("S:\n");
    // matrix_print(3, 3, S);

    matrix_product33(U, VT, RT);
    matrix_transpose(3, 3, RT, R);

    // printf("R:\n");
    // matrix_print(3, 3, R);

    if (matrix_determinant3(R) < 0.0) {
        /* We're dealing with a reflection */
        double tmp[9];
        double reflectZ[9] = { 1.0, 0.0,  0.0,
                               0.0, 1.0,  0.0, 
                               0.0, 0.0, -1.0 };

        matrix_product33(U, reflectZ, tmp);
        matrix_product33(tmp, VT, RT);
        matrix_transpose(3, 3, RT, R);
    }

    /* Compute error */
    error = 0.0;
    for (i = 0; i < n; i++) {
	double rot[3];
	double diff[3];
	double dist;
	matrix_product331(R, l_pts[i].p, rot);
	matrix_diff(3, 1, 3, 1, rot, r_pts[i].p, diff);
	dist = matrix_norm(3, 1, diff);

        // printf("d[%d] = %0.6f\n", i, dist);
	error += dist;
    }

    return error / n;
}
Ejemplo n.º 13
0
/* Align two sets of points with a 3D rotation */
int align_3D_rotation_ransac(int n, v3_t *r_pts, v3_t *l_pts, 
			     int num_ransac_rounds, double ransac_thresh,
			     double *R)
{
    int round;    
    double error = 0.0;
#define MIN_SUPPORT 3
    // const int min_support = 3;
    v3_t *l_inliers, *r_inliers;
    int num_inliers, max_inliers = 0;
    double Rbest[9];
    int i;

    if (n < 3) {
	printf("[align_3D_rotation_ransac] Error: need at least 3 points!\n");
	return 0;
    }

    l_inliers = (v3_t *) malloc(sizeof(v3_t) * n);
    r_inliers = (v3_t *) malloc(sizeof(v3_t) * n);

    for (round = 0; round < num_ransac_rounds; round++) {
	int support[MIN_SUPPORT];
	int i, j;
	v3_t r_pts_small[MIN_SUPPORT], l_pts_small[MIN_SUPPORT];
	double Rtmp[9];
	
	for (i = 0; i < MIN_SUPPORT; i++) {
	    /* Select an index from 0 to n-1 */
	    int idx, reselect;
	    do {
		reselect = 0;
		idx = rand() % n;
		for (j = 0; j < i; j++) {
		    if (support[j] == idx) {
			reselect = 1;
			break;
		    }
		}
	    } while (reselect);

	    support[i] = idx;
	    r_pts_small[i] = r_pts[idx];
	    l_pts_small[i] = l_pts[idx];
	}

	align_3D_rotation(MIN_SUPPORT, r_pts_small, l_pts_small, Rtmp);

	/* Count inliers */
	num_inliers = 0;

	for (i = 0; i < n; i++) {
	    double rot[3];
	    double diff[3];
	    double dist;
	    matrix_product(3, 3, 3, 1, Rtmp, l_pts[i].p, rot);
	    matrix_diff(3, 1, 3, 1, rot, r_pts[i].p, diff);
	    dist = matrix_norm(3, 1, diff);
	    
	    if (dist < ransac_thresh) {
		num_inliers++;
	    }

	    if (num_inliers > max_inliers) {
		max_inliers = num_inliers;
		memcpy(Rbest, Rtmp, sizeof(double) * 9);
	    }
	}
    }

#if 0
    /* Reestimate using all inliers */
    num_inliers = 0;
    for (i = 0; i < n; i++) {
	double rot[3];
	double diff[3];
	double dist;
	matrix_product(3, 3, 3, 1, Rbest, l_pts[i].p, rot);
	matrix_diff(3, 1, 3, 1, rot, r_pts[i].p, diff);
	dist = matrix_norm(3, 1, diff);
	    
	if (dist < ransac_thresh) {
	    r_inliers[num_inliers] = r_pts[i];
	    l_inliers[num_inliers] = l_pts[i];
	    num_inliers++;
	}
    }

    error = align_3D_rotation(num_inliers, r_inliers, l_inliers, R);    

    printf("[align_3D_rotation] Error: %0.3f\n", error);

    free(r_inliers);
    free(l_inliers);

    return num_inliers;
#else
    memcpy(R, Rbest, 9 * sizeof(double));

    free(r_inliers);
    free(l_inliers);

    return max_inliers;
#endif

#undef MIN_SUPPORT
}