Example #1
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
}
Example #2
0
/* Return the product x**T A x */
double matrix_double_product(int n, double *A, double *x) {
    double *tmp = malloc(sizeof(double) * n);
    double result;
    
    matrix_product(n, n, n, 1, A, x, tmp);
    matrix_product(1, n, n, 1, x, tmp, &result);

    free(tmp);

    return result;
}
void TwoFrameModel::
ComputeTransformedCovariance(bool flip, double *S, double *C) const
{
    double tmp[9];
    if (flip) {
        matrix_product(3, 3, 3, 3, S, m_C1, tmp);
        matrix_transpose_product2(3, 3, 3, 3, tmp, S, C);
    } else {
        matrix_product(3, 3, 3, 3, S, m_C0, tmp);
        matrix_transpose_product2(3, 3, 3, 3, tmp, S, C);        
    }    
}
Example #4
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;
}
Example #5
0
int main(int argc, char** argv)
{
    printf("--------verify--------\n");
    verify_matrix();
    printf("----------------------\n");

    // autorelease関数をbeginとendにはさまないで使うのはNG
    // 全てのallocされた関数は
    // (1) free
    // (2) release
    // (3) begin-endの中でautorelease
    // のいずれかを行う必要がある。
    
    // 擬似逆行列演算がこれくらい簡単に記述できる。
    
    /* 3*2行列aを確保、成分ごとの代入 */
    matrix_t* a = matrix_alloc(3, 2);
    ELEMENT(a, 0, 0) = 1; ELEMENT(a, 0, 1) = 4;
    ELEMENT(a, 1, 0) = 2; ELEMENT(a, 1, 1) = 5;
    ELEMENT(a, 2, 0) = 3; ELEMENT(a, 2, 1) = 6;

    /* 擬似逆行列の演算 */
    // auto releaseモードに入る
    matrix_begin(); 
    // 擬似逆行列を求める。一行だけ!
    matrix_t* inva = matrix_product(matrix_inverse(matrix_product(matrix_transpose(a), a)), matrix_transpose(a));
    // 擬似逆行列の表示 (invaはmatrix_endで解放されるので、begin-end内で。)
    matrix_print(inva);
    // release poolを開放する
    matrix_end();

    /* ちなみに擬似逆行列を求める関数は内部に組んだので、それを使うこともできる。 */
    // auto releaseモードに入る
    matrix_begin(); 
    // 擬似逆行列を求める関数を呼ぶ。
    matrix_t* inva_simple = matrix_pseudo_inverse(a);
    // 擬似逆行列の表示 (invaはmatrix_endで解放されるので、begin-end内で。)
    matrix_print(inva_simple);
    // release poolを開放する
    matrix_end();

    
    // これはautorelease対象でないので、しっかり自分でfree。
    // リテインカウントを実装してあるので、理解できればreleaseの方が高性能。
    //matrix_free(a);
    matrix_release(a);
 
    return 0;
}
void DistortPoint(const double x, const double y, 
		  const fisheye_params_t &p, double *R,
                  double &x_out, double &y_out)
{
    double xn = x; // - m_fCx;
    double yn = y; // - m_fCy;

    double ray[3] = { xn, yn, p.fFocal }, ray_rot[3];
    matrix_product(3, 3, 3, 1, R, ray, ray_rot);

    if (ray_rot[2] <= 0.0) {
	xn = -DBL_MAX;
	yn = -DBL_MAX;
	return;
    } else {
	xn = ray_rot[0] * p.fFocal / ray_rot[2];
	yn = ray_rot[1] * p.fFocal / ray_rot[2];
    }
    
    double r = sqrt(xn * xn + yn * yn);
    double angle = RAD2DEG(atan(r / p.fFocal));
    double rnew = p.fRad * angle / (0.5 * p.fAngle);
    
    x_out = xn * (rnew / r) + p.fCx;
    y_out = yn * (rnew / r) + p.fCy;
}
Example #7
0
double PlaneData::ProjectV(double *p, double *p_proj) 
{
    double dot;
    matrix_product(1, 3, 3, 1, p, m_vaxis, &dot);
    matrix_scale(3, 1, m_vaxis, dot, p_proj);
    return dot;
}
Example #8
0
void EKF::_predictState(double *state, double *state_new) const
{
  // copy old to new
  matrix_scale(1, 3 * _num_feats_init_structure + _num_motion_states, state, 1.0, state_new);
  double LinVel[3];
  double AngVel[3];

  LinVel[0] = state[3 * _num_feats_init_structure + 0];
  LinVel[1] = state[3 * _num_feats_init_structure + 1];
  LinVel[2] = state[3 * _num_feats_init_structure + 2];

  AngVel[0] = state[3 * _num_feats_init_structure + 3];
  AngVel[1] = state[3 * _num_feats_init_structure + 4];
  AngVel[2] = state[3 * _num_feats_init_structure + 5];

  double curr[3], new_pos[3];
  double R[3 * 3];
  matrix_scale(1, 3, LinVel, _dt, LinVel);
  matrix_scale(1, 3, AngVel, _dt, AngVel);
  RODR(AngVel, R);
  for (int i = 0; i < _num_feats_init_structure; i++)
  {
    curr[0] = state[3 * i + 0];
    curr[1] = state[3 * i + 1];
    curr[2] = state[3 * i + 2];
    matrix_product(3, 3, 3, 1, R, curr, new_pos);
    matrix_sum(3, 1, 3, 1, new_pos, LinVel, new_pos);
    //new_pos = LinVel*dt + ublas::prod(RODR(AngVel*dt),curr);
    state_new[3 * i + 0] = new_pos[0];
    state_new[3 * i + 1] = new_pos[1];
    state_new[3 * i + 2] = new_pos[2];
  }
}
Example #9
0
/* Estimate an E-matrix from a given set of point matches */
std::vector<int> EstimateEMatrix(const std::vector<Keypoint> &k1, 
                                 const std::vector<Keypoint> &k2, 
                                 std::vector<KeypointMatch> matches, 
                                 int num_trials, double threshold, 
                                 double f1, double f2, 
                                 double *E, double *F)
{
    int num_keys1 = k1.size();
    int num_keys2 = k2.size();

    std::vector<Keypoint> k1_norm, k2_norm;
    k1_norm.resize(num_keys1);
    k2_norm.resize(num_keys2);
    
    for (int i = 0; i < num_keys1; i++) {
        Keypoint k;
        k.m_x = k1[i].m_x / f1;
        k.m_y = k1[i].m_y / f1;
        k1_norm[i] = k;
    }

    for (int i = 0; i < num_keys2; i++) {
        Keypoint k;
        k.m_x = k2[i].m_x / f2;
        k.m_y = k2[i].m_y / f2;
        k2_norm[i] = k;
    }

    double scale = 0.5 * (f1 + f2);

    std::vector<int> inliers = 
        EstimateFMatrix(k1_norm, k2_norm, matches, num_trials, 
                        threshold / (scale * scale), E, true);
    
    double K1_inv[9] = { 1.0 / f1, 0.0, 0.0, 
                         0.0, 1.0 / f1, 0.0,
                         0.0, 0.0, 1.0 };
    double K2_inv[9] = { 1.0 / f2, 0.0, 0.0, 
                         0.0, 1.0 / f2, 0.0,
                         0.0, 0.0, 1.0 };
    
    double tmp[9];
    matrix_product(3, 3, 3, 3, K1_inv, E, tmp);
    matrix_product(3, 3, 3, 3, K2_inv, tmp, F);
    
    return inliers;
}
Example #10
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);
}
Example #11
0
/* Intersect a ray with the plane */
double PlaneData::IntersectRay(double *pos, double *ray, double *pt) const
{
    double pos_dot, ray_dot;

    matrix_product(1, 3, 3, 1, (double *) m_normal, pos, &pos_dot);
    matrix_product(1, 3, 3, 1, (double *) m_normal, ray, &ray_dot);

    if (ray_dot==0.0) {
        return -DBL_MAX;
    }

    double t = (-m_dist - pos_dot) / ray_dot;

    pt[0] = pos[0] + t * ray[0];
    pt[1] = pos[1] + t * ray[1];
    pt[2] = pos[2] + t * ray[2];

    return t;
}
Example #12
0
static void
homography_resids(int *m, int *n, double *x, double *fvec, int *iflag)
{
  int i;

  double resids = 0.0;

  double H[9];
  memcpy(H, x, 8 * sizeof(double));
  H[8] = 1.0;

  if (*iflag == 0 && global_num_pts > 4)
    {
      printf("[Round %d]\n", global_round);
      printf(
          "  H=(%0.5f, %0.5f, %0.5f, %0.5f, %0.5f, %0.5f, %0.5f, %0.5f, %0.1f)\n",
          H[0], H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]);
      global_round++;
    }

  for (i = 0; i < global_num_pts; i++)
    {
      double p[3], q[3];

      p[0] = Vx(global_l_pts[i]);
      p[1] = Vy(global_l_pts[i]);
      p[2] = Vz(global_l_pts[i]);

      if (*iflag == 0 && global_num_pts > 4)
        printf("    p=(%0.3f, %0.3f, %0.3f)\n", p[0], p[1], p[2]);

      matrix_product(3, 3, 3, 1, H, p, q);

      if (*iflag == 0 && global_num_pts > 4)
        printf("    q=(%0.3f, %0.3f, %0.3f)\n", q[0], q[1], q[2]);

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

      fvec[2 * i + 0] = q[0] - Vx(global_r_pts[i]);
      fvec[2 * i + 1] = q[1] - Vy(global_r_pts[i]);

      if (*iflag == 0 && global_num_pts > 4)
        printf("    (%0.3f, %0.3f) ==> (%0.3f, %0.3f)\n", q[0], q[1],
            Vx(global_r_pts[i]), Vy(global_r_pts[i]));
    }

  for (i = 0; i < 2 * global_num_pts; i++)
    {
      resids += fvec[i] * fvec[i];
    }

  if (*iflag == 0 && global_num_pts > 4)
    printf("resids = %0.3f\n", resids);
}
Example #13
0
bool PlaneData::SetCorners(double *R, double *t, double f, int w, int h, int ymin, int ymax, int xmin, int xmax)
{
	if(xmax==-1)  xmax=w;
	if(ymax==-1)  ymax=h;
	if(xmax>w || ymax>h ||xmax<-1 || ymax<-1) printf("Error in bounding box data w=%d h=%d xmin=%d xmax=%d ymin=%d ymax=%d\n",w,h,xmin,xmax,ymin,ymax);
	//printf("xmin=%d xmax=%d ymin=%d ymax=%d\n",xmin,xmax,ymin,ymax);
    double Rt[9];
    matrix_transpose(3, 3, R, Rt);

    double center[3];
    matrix_product(3, 3, 3, 1, Rt, t, center);
    matrix_scale(3, 1, center, -1.0, center);

    /* Create rays for the four corners */
	//uncomment the follwing code to use the 4 image corners
    //double ray1[3] = { -0.5 * w, -0.5 * h, -f };
    //double ray2[3] = {  0.5 * w, -0.5 * h, -f };
    //double ray3[3] = {  0.5 * w,  0.5 * h, -f };
    //double ray4[3] = { -0.5 * w,  0.5 * h, -f };

	double ray1[3] = { xmin-0.5 * w, ymin-0.5 * h, -f };
	double ray2[3] = {  xmax-0.5 * w, ymin-0.5 * h, -f };
	double ray3[3] = {  xmax -0.5 * w,  ymax-0.5 * h, -f };
	double ray4[3] = {xmin -0.5 * w,  ymax - 0.5 * h, -f };

    double ray_world[18];
    matrix_product(3, 3, 3, 1, Rt, ray1, ray_world + 0);
    matrix_product(3, 3, 3, 1, Rt, ray2, ray_world + 3);
    matrix_product(3, 3, 3, 1, Rt, ray3, ray_world + 6);
    matrix_product(3, 3, 3, 1, Rt, ray4, ray_world + 9);

    double t0 = IntersectRay(center, ray_world + 0, m_corners + 0);
    double t1 = IntersectRay(center, ray_world + 3, m_corners + 3);
    double t2 = IntersectRay(center, ray_world + 6, m_corners + 6);
    double t3 = IntersectRay(center, ray_world + 9, m_corners + 9);

    if (t0 > 0.0 && t1 > 0.0 && t2 > 0.0 && t3 > 0.0)
        return true;
    else
        return false;
}
Example #14
0
// autorelease function
matrix_t* matrix_pseudo_inverse(matrix_t* m)
{
    if (m->rows == m->cols) {
        return matrix_inverse(m);
    } else if (m->rows > m->cols) {
        matrix_begin();
        // (A^T A)^{-1} A^T
        matrix_t* ret = matrix_product(matrix_inverse(matrix_product(matrix_transpose(m), m)),matrix_transpose(m));
        matrix_retain(ret);
        matrix_end();

        return matrix_autorelease(ret);
    } else {
        matrix_begin();
        // A^T (A A^T)^{-1} 
        matrix_t* ret = matrix_product(matrix_transpose(m), matrix_inverse(matrix_product(m, matrix_transpose(m))));
        matrix_retain(ret);
        matrix_end();

        return matrix_autorelease(ret);
    }
}
Example #15
0
/* Compute the mean of a set of vectors */
void v3_svd(int n, const v3_t *v, double *U, double *S, double *VT) {
    double A[9] = { 0.0, 0.0, 0.0,
		    0.0, 0.0, 0.0,
		    0.0, 0.0, 0.0 };
    int i;

    for (i = 0; i < n; i++) {
	double tensor[9];
	matrix_product(3, 1, 1, 3, v[i].p, v[i].p, tensor);
	matrix_sum(3, 3, 3, 3, A, tensor, A);
    }
    
    dgesvd_driver(3, 3, A, U, S, VT);
}
Example #16
0
/* Compute the covariance of a set of (zero-mean) vectors */
void v3_covariance_zm(int n, const v3_t *v, double *cov) {
    int i;
    
    for (i = 0; i < 9; i++)
        cov[i] = 0.0;

    for (i = 0; i < n; i++) {
        double tmp[9];
        matrix_product(3, 1, 1, 3, v[i].p, v[i].p, tmp);
        matrix_sum(3, 3, 3, 3, cov, tmp, cov);
    }

    matrix_scale(3, 3, cov, 1.0 / n, cov);
}
Example #17
0
/* Decompose a square matrix into an orthogonal matrix and a symmetric
 * positive semidefinite matrix */
void matrix_polar_decomposition(int n, double *A, double *Q, double *S) 
{
    double *U, *diag, *VT;
    double *diag_full, *tmp;
    int i;

    U = (double *) malloc(sizeof(double) * n * n);
    diag = (double *) malloc(sizeof(double) * n);
    VT = (double *) malloc(sizeof(double) * n * n);

    /* Compute SVD */
    dgesvd_driver(n, n, A, U, diag, VT);
 
    /* Compute Q */
    matrix_product(n, n, n, n, U, VT, Q);
    
    /* Compute S */
    diag_full = (double *) malloc(sizeof(double) * n * n);

    for (i = 0; i < n * n; i++) {
	diag_full[i] = 0.0;
    }
    
    for (i = 0; i < n; i++) {
	diag_full[i * n + i] = diag[i];
    }

    tmp = (double *) malloc(sizeof(double) * n * n);
    matrix_transpose_product(n, n, n, n, VT, diag_full, tmp);
    matrix_product(n, n, n, n, tmp, VT, S);

    free(U);
    free(diag);
    free(VT);
    free(diag_full);
    free(tmp);
}
Example #18
0
void slerp(double *v1, double *v2, double t, double *v3)
{
    double dot, angle, sin1t, sint, sina;
    matrix_product(1, 3, 3, 1, v1, v2, &dot);

    angle = acos(CLAMP(dot, -1.0 + 1.0e-8, 1.0 - 1.0e-8));

    sin1t = sin((1.0-t) * angle);
    sint = sin(t * angle);
    sina = sin(angle);
    
    v3[0] = (sin1t / sina) * v1[0] + (sint / sina) * v2[0];
    v3[1] = (sin1t / sina) * v1[1] + (sint / sina) * v2[1];
    v3[2] = (sin1t / sina) * v1[2] + (sint / sina) * v2[2];
}
Example #19
0
v3_t BundlerApp::GeneratePointAtInfinity(const ImageKeyVector &views, 
                                         int *added_order, 
                                         camera_params_t *cameras,
                                         double &error, 
                                         bool explicit_camera_centers)
{
    camera_params_t *cam = NULL;

    int camera_idx = views[0].first;
    int image_idx = added_order[camera_idx];
    int key_idx = views[0].second;
    Keypoint &key = GetKey(image_idx, key_idx);

    cam = cameras + camera_idx;

    double p3[3] = { key.m_x, key.m_y, 1.0 };

    if (m_optimize_for_fisheye) {
        /* Undistort the point */
        double x = p3[0], y = p3[1];
        m_image_data[image_idx].UndistortPoint(x, y, p3[0], p3[1]);
    }

    double K[9], Kinv[9];
    GetIntrinsics(cameras[camera_idx], K);
    matrix_invert(3, K, Kinv);

    double ray[3];
    matrix_product(3, 3, 3, 1, Kinv, p3, ray);

    /* We now have a ray, put it at infinity */
    double ray_world[3];
    matrix_transpose_product(3, 3, 3, 1, cam->R, ray, ray_world);

    double pos[3] = { 0.0, 0.0, 0.0 };
    double pt_inf[3] = { 0.0, 0.0, 0.0 };

    if (!explicit_camera_centers) {
        
    } else {
        memcpy(pos, cam->t, 3 * sizeof(double));
        double ray_extend[3];
        matrix_scale(3, 1, ray, 100.0, ray_extend);
        matrix_sum(3, 1, 3, 1, pos, ray, pt_inf);
    }

    return v3_new(pt_inf[0], pt_inf[1], pt_inf[2]);
}
Example #20
0
File: 0011.c Project: jcast/euler
int highest_product(int len, int matrix[MY][MX]) {
  int highest = 0;
  int product;

  int y; for(y = 0; y < MY; y++) {
    int x; for(x = 0; x < MX; x++) {
      int dir; for(dir = 0; dir < 4; dir++) {

        product = matrix_product(x, y, len, dir, matrix);
        if(product > highest) highest = product;
      }
    }
  }

  return highest;
}
Example #21
0
/* Compute the power of a matrix */
void matrix_power(int n, double *A, int pow, double *R)
{
    int i;
    
    /* Slow way */
    double *curr = (double *) malloc(sizeof(double) * n * n);
    double *tmp = (double *) malloc(sizeof(double) * n * n);

    matrix_ident(n, curr);
    for (i = 0; i < pow; i++) {
	matrix_product(n, n, n, n, curr, A, tmp);
	memcpy(curr, tmp, sizeof(double) * n * n);
    }

    memcpy(R, curr, sizeof(double) * n * n);

    free(curr);
    free(tmp);
}
Example #22
0
/* Create a planar patch for this point */
void PointData::CreatePlanarPatch(double size, PlaneData &plane)
{
    memcpy(plane.m_normal, m_norm, 3 * sizeof(double));

    double dist;
    matrix_product(1, 3, 3, 1, m_norm, m_pos, &dist);
    plane.m_dist = -dist;

    memcpy(plane.m_origin, m_pos, 3 * sizeof(double));

    // u-axis should be perp to the y-axis and to normal
    double y[3] = { 0.0, 1.0, 0.0 };
    matrix_cross(m_norm, y, plane.m_uaxis);

    // v-axis should be perp to normal and uaxis
    matrix_cross(m_norm, plane.m_uaxis, plane.m_vaxis);

    plane.m_u_extent = plane.m_v_extent = size;
}
Example #23
0
/* Project a point onto the plane */
void PlaneData::Project(double *p, double *p_proj) 
{
    /* Subtract the distance vector */
    double vec[3];    
    matrix_scale(3, 1, m_normal, m_dist, vec);
    
    double p_norm[3];
    matrix_diff(3, 1, 3, 1, p, vec, p_norm);

    double dot;
    matrix_product(1, 3, 3, 1, m_normal, p_norm, &dot);
    
    double p_par[3];
    matrix_scale(3, 1, m_normal, dot, p_par);

    double p_perp[3];
    matrix_diff(3, 1, 3, 1, p_norm, p_par, p_perp);
    
    matrix_sum(3, 1, 3, 1, p_perp, vec, p_proj);
}
Example #24
0
static int CountInliers(const std::vector<Keypoint> &k1, 
			const std::vector<Keypoint> &k2, 
			std::vector<KeypointMatch> matches,
			double *M, double thresh, std::vector<int> &inliers)
{
    inliers.clear();
    int count = 0;

    for (unsigned int i = 0; i < matches.size(); i++) {
	/* Determine if the ith feature in f1, when transformed by M,
	 * is within RANSACthresh of its match in f2 (if one exists)
	 *
	 * if so, increment count and append i to inliers */

	double p[3];

	p[0] = k1[matches[i].m_idx1].m_x;
	p[1] = k1[matches[i].m_idx1].m_y;
	p[2] = 1.0;

	double q[3];
	matrix_product(3, 3, 3, 1, M, p, q);

	double qx = q[0] / q[2];
	double qy = q[1] / q[2];

	double dx = qx - k2[matches[i].m_idx2].m_x;
	double dy = qy - k2[matches[i].m_idx2].m_y;
	
	double dist = sqrt(dx * dx + dy * dy);
	
	if (dist <= thresh) {
	    count++;
	    inliers.push_back(i);
	}
    }

    return count;
}
Example #25
0
void EKF::_getA(double *state, double *A) const
{
  double LinVel[3];
  double AngVel[3];
  matrix_zeroes(3 * _num_feats_init_structure + _num_motion_states, 3 * _num_feats_init_structure + _num_motion_states,
                A);

  LinVel[0] = state[3 * _num_feats_init_structure + 0];
  LinVel[1] = state[3 * _num_feats_init_structure + 1];
  LinVel[2] = state[3 * _num_feats_init_structure + 2];

  AngVel[0] = state[3 * _num_feats_init_structure + 3];
  AngVel[1] = state[3 * _num_feats_init_structure + 4];
  AngVel[2] = state[3 * _num_feats_init_structure + 5];

  matrix_scale(1, 3, LinVel, _dt, LinVel);
  matrix_scale(1, 3, AngVel, _dt, AngVel);

  double DR[9 * 3];
  double DRx[3 * 3], DRy[3 * 3], DRz[3 * 3];
  double I3[3 * 3];
  matrix_ident(3, I3);
  RODR_derivative(AngVel, DR);

  DRx[0 * 3 + 0] = DR[0 * 3 + 0];
  DRx[0 * 3 + 1] = DR[0 * 3 + 1];
  DRx[0 * 3 + 2] = DR[0 * 3 + 2];
  DRx[1 * 3 + 0] = DR[1 * 3 + 0];
  DRx[1 * 3 + 1] = DR[1 * 3 + 1];
  DRx[1 * 3 + 2] = DR[1 * 3 + 2];
  DRx[2 * 3 + 0] = DR[2 * 3 + 0];
  DRx[2 * 3 + 1] = DR[2 * 3 + 1];
  DRx[2 * 3 + 2] = DR[2 * 3 + 2];

  DRy[0 * 3 + 0] = DR[3 * 3 + 0];
  DRy[0 * 3 + 1] = DR[3 * 3 + 1];
  DRy[0 * 3 + 2] = DR[3 * 3 + 2];
  DRy[1 * 3 + 0] = DR[4 * 3 + 0];
  DRy[1 * 3 + 1] = DR[4 * 3 + 1];
  DRy[1 * 3 + 2] = DR[4 * 3 + 2];
  DRy[2 * 3 + 0] = DR[5 * 3 + 0];
  DRy[2 * 3 + 1] = DR[5 * 3 + 1];
  DRy[2 * 3 + 2] = DR[5 * 3 + 2];

  DRz[0 * 3 + 0] = DR[6 * 3 + 0];
  DRz[0 * 3 + 1] = DR[6 * 3 + 1];
  DRz[0 * 3 + 2] = DR[6 * 3 + 2];
  DRz[1 * 3 + 0] = DR[7 * 3 + 0];
  DRz[1 * 3 + 1] = DR[7 * 3 + 1];
  DRz[1 * 3 + 2] = DR[7 * 3 + 2];
  DRz[2 * 3 + 0] = DR[8 * 3 + 0];
  DRz[2 * 3 + 1] = DR[8 * 3 + 1];
  DRz[2 * 3 + 2] = DR[8 * 3 + 2];

  double R[3 * 3];
  RODR(AngVel, R);

  double P[3];
  double dfdxyz[3 * 3];
  double dfdAVx[3];
  double dfdAVy[3];
  double dfdAVz[3];
  //feature with respect to itself
  //ublas::matrix<double> dfdxyz = ublas::prod(RODR(AngVel*dt),ublas::identity_matrix<double>(3));
  matrix_product(3, 3, 3, 3, R, I3, dfdxyz);
  //diff features wrt. features
  for (int i = 0; i < _num_feats_init_structure; i++)
  {
    P[0] = state[3 * i + 0];
    P[1] = state[3 * i + 1];
    P[2] = state[3 * i + 2];

    A[(3 * i + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * i + 0] = dfdxyz[0 * 3 + 0];
    A[(3 * i + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * i + 1] = dfdxyz[0 * 3 + 1];
    A[(3 * i + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * i + 2] = dfdxyz[0 * 3 + 2];
    A[(3 * i + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * i + 0] = dfdxyz[1 * 3 + 0];
    A[(3 * i + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * i + 1] = dfdxyz[1 * 3 + 1];
    A[(3 * i + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * i + 2] = dfdxyz[1 * 3 + 2];
    A[(3 * i + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * i + 0] = dfdxyz[2 * 3 + 0];
    A[(3 * i + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * i + 1] = dfdxyz[2 * 3 + 1];
    A[(3 * i + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * i + 2] = dfdxyz[2 * 3 + 2];

    //feature with respect to the 9 last variables (linear/angular velocities and translation of center of rotation)
    //feature with respect to linear velocities
    A[(3 * i + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure] = _dt;
    A[(3 * i + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 1] = 0;
    A[(3 * i + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 2] = 0;
    A[(3 * i + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure] = 0;
    A[(3 * i + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 1] = _dt;
    A[(3 * i + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 2] = 0;
    A[(3 * i + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure] = 0;
    A[(3 * i + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 1] = 0;
    A[(3 * i + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 2] = _dt;
    //feature with respect to angular velocities

    //ublas::vector<double> dfdAVx = ublas::prod(ublas::prod(DRx, ublas::identity_matrix<double>(3)),ublas::trans(P));
    matrix_product(3, 3, 3, 1, DRx, P, dfdAVx);
    //ublas::vector<double> dfdAVy = ublas::prod(ublas::prod(DRy, ublas::identity_matrix<double>(3)),ublas::trans(P));
    matrix_product(3, 3, 3, 1, DRy, P, dfdAVy);
    //ublas::vector<double> dfdAVz = ublas::prod(ublas::prod(DRz, ublas::identity_matrix<double>(3)),ublas::trans(P));
    matrix_product(3, 3, 3, 1, DRz, P, dfdAVz);

    A[(3 * i + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 3]
        = dfdAVx[0];
    A[(3 * i + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 4]
        = dfdAVy[0];
    A[(3 * i + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 5]
        = dfdAVz[0];
    A[(3 * i + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 3]
        = dfdAVx[1];
    A[(3 * i + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 4]
        = dfdAVy[1];
    A[(3 * i + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 5]
        = dfdAVz[1];
    A[(3 * i + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 3]
        = dfdAVx[2];
    A[(3 * i + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 4]
        = dfdAVy[2];
    A[(3 * i + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3 * _num_feats_init_structure + 5]
        = dfdAVz[2];
  }
  //the last 9 variables with respect to themselves
  //dLinVel/dLinVel
  A[(3 * _num_feats_init_structure + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 0] = 1;
  A[(3 * _num_feats_init_structure + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 1] = 0;
  A[(3 * _num_feats_init_structure + 0) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 2] = 0;
  A[(3 * _num_feats_init_structure + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 0] = 0;
  A[(3 * _num_feats_init_structure + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 1] = 1;
  A[(3 * _num_feats_init_structure + 1) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 2] = 0;
  A[(3 * _num_feats_init_structure + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 0] = 0;
  A[(3 * _num_feats_init_structure + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 1] = 0;
  A[(3 * _num_feats_init_structure + 2) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 2] = 1;
  //dAngVel/dAngVel
  A[(3 * _num_feats_init_structure + 3) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 3] = 1;
  A[(3 * _num_feats_init_structure + 3) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 4] = 0;
  A[(3 * _num_feats_init_structure + 3) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 5] = 0;
  A[(3 * _num_feats_init_structure + 4) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 3] = 0;
  A[(3 * _num_feats_init_structure + 4) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 4] = 1;
  A[(3 * _num_feats_init_structure + 4) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 5] = 0;
  A[(3 * _num_feats_init_structure + 5) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 3] = 0;
  A[(3 * _num_feats_init_structure + 5) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 4] = 0;
  A[(3 * _num_feats_init_structure + 5) * (3 * _num_feats_init_structure + _num_motion_states) + 3
      * _num_feats_init_structure + 5] = 1;
}
Example #26
0
double EKF::_step(const std::vector<vision::FeaturePtr> &y)
{
  double mean_innovation;
  if (y.size() != _num_feats_init_structure)
  {
    ROS_ERROR(
        "[EKF::_step] The size of the measurement y differs from the expected number of tracked and matched Features.\nSize of y: %d Expected size (number of matched Features): %d",
        y.size(), _num_feats_init_structure);
    throw std::string(
                      "FATAL ERROR [EKF::_step]: The size of the measurement y differs from the expected number of tracked and matched Features.");
  }

  // Prediction step
  _getA(_updated_state, _A_ekf);
  _predictState(_updated_state, _predicted_state);
  //        predCovar=A*upCovar*A'+WQW;
  matrix_product(3 * _num_feats_init_structure + _num_motion_states,
                 3 * _num_feats_init_structure + _num_motion_states,
                 3 * _num_feats_init_structure + _num_motion_states,
                 3 * _num_feats_init_structure + _num_motion_states, _A_ekf, _updated_covar, _A_ekf_covar);
  matrix_transpose_product2(3 * _num_feats_init_structure + _num_motion_states,
                            3 * _num_feats_init_structure + _num_motion_states,
                            3 * _num_feats_init_structure + _num_motion_states,
                            3 * _num_feats_init_structure + _num_motion_states, _A_ekf_covar, _A_ekf, _predicted_covar);
  matrix_sum(3 * _num_feats_init_structure + _num_motion_states, 3 * _num_feats_init_structure + _num_motion_states,
             3 * _num_feats_init_structure + _num_motion_states, 3 * _num_feats_init_structure + _num_motion_states,
             _predicted_covar, _W_Q_W_ekf_trans, _predicted_covar);
  //update step
  _computeH(_predicted_state, _H_ekf);
  // K=predCovar*H'/(H*predCovar*H'+R);
  // H'
  matrix_transpose(_num_feats_init_structure * 2, 3 * _num_feats_init_structure + _num_motion_states, _H_ekf,
                   _H_ekf_trans);
  // predCovar*H'
  matrix_product(3 * _num_feats_init_structure + _num_motion_states,
                 3 * _num_feats_init_structure + _num_motion_states,
                 3 * _num_feats_init_structure + _num_motion_states, _num_feats_init_structure * 2, _predicted_covar,
                 _H_ekf_trans, _covar_H_ekf);
  // H*predCovar
  matrix_product(_num_feats_init_structure * 2, 3 * _num_feats_init_structure + _num_motion_states,
                 3 * _num_feats_init_structure + _num_motion_states,
                 3 * _num_feats_init_structure + _num_motion_states, _H_ekf, _predicted_covar, _H_ekf_covar);
  // H*predCovar*H'
  matrix_product(_num_feats_init_structure * 2, 3 * _num_feats_init_structure + _num_motion_states,
                 3 * _num_feats_init_structure + _num_motion_states, _num_feats_init_structure * 2, _H_ekf_covar,
                 _H_ekf_trans, _H_covar_H_ekf);
  // (H*predCovar*H'+R)
  matrix_sum(_num_feats_init_structure * 2, _num_feats_init_structure * 2, _num_feats_init_structure * 2,
             _num_feats_init_structure * 2, _H_covar_H_ekf, _R_ekf, _H_covar_H_ekf);
  // inv(H*predCovar*H'+R)
  matrix_invert(_num_feats_init_structure * 2, _H_covar_H_ekf, _H_Q_H_ekf);
  //K=predCovar*H'*inv(H*predCovar*H'+R);
  matrix_product(3 * _num_feats_init_structure + _num_motion_states, _num_feats_init_structure * 2,
                 _num_feats_init_structure * 2, _num_feats_init_structure * 2, _covar_H_ekf, _H_Q_H_ekf, _K_ekf);
  // predict
  _predictObservation(_predicted_state, _estimated_z);
  // measurement
  for (int i = 0; i < _num_feats_init_structure; i++)
  {
    _z[i * 2 + 0] = y[i]->getX();
    _z[i * 2 + 1] = y[i]->getY();
  }
  //innovation = z-z_estimate;
  matrix_diff(1, _num_feats_init_structure * 2, 1, _num_feats_init_structure * 2, _z, _estimated_z, _innovation);

  //		upState=predState+K*(innovation);
  matrix_product(3 * _num_feats_init_structure + _num_motion_states, _num_feats_init_structure * 2,
                 _num_feats_init_structure * 2, 1, _K_ekf, _innovation, _updated_state);
  matrix_sum(1, 3 * _num_feats_init_structure + _num_motion_states, 1,
             3 * _num_feats_init_structure + _num_motion_states, _updated_state, _predicted_state, _updated_state);

  //        upCovar=(eye(3*numFeatures+6)-K*H)*predCovar;
  matrix_product(3 * _num_feats_init_structure + _num_motion_states, _num_feats_init_structure * 2,
                 _num_feats_init_structure * 2, 3 * _num_feats_init_structure + _num_motion_states, _K_ekf, _H_ekf,
                 _K_H_ekf);
  //I_KH = (I - KH);
  matrix_diff(_num_feats_init_structure * 3 + _num_motion_states, _num_feats_init_structure * 3 + _num_motion_states,
              _num_feats_init_structure * 3 + _num_motion_states, _num_feats_init_structure * 3 + _num_motion_states,
              _I_ekf, _K_H_ekf, _I_K_H_ekf);
  matrix_product(_num_feats_init_structure * 3 + _num_motion_states,
                 _num_feats_init_structure * 3 + _num_motion_states,
                 _num_feats_init_structure * 3 + _num_motion_states,
                 _num_feats_init_structure * 3 + _num_motion_states, _I_K_H_ekf, _predicted_covar, _updated_covar);

  // calculate error after correction
  _predictObservation(_updated_state, _estimated_z);
  //innovation = z-z_estimate;
  matrix_diff(1, _num_feats_init_structure * 2, 1, _num_feats_init_structure * 2, _z, _estimated_z, _innovation);
  double dist = 0;
  for (int i = 0; i < _num_feats_init_structure; i++)
  {
    dist += sqrt(pow(_innovation[i * 2 + 0], 2) + pow(_innovation[i * 2 + 1], 2));
  }
  mean_innovation = dist / ((double)_num_feats_init_structure);
  return mean_innovation;
}
Example #27
0
void EKF::_initVariables()
{
  _updated_covar = new double[(_num_feats_init_structure * 3 + _num_motion_states) * (_num_feats_init_structure * 3
      + _num_motion_states)];
  matrix_ident(_num_feats_init_structure * 3 + _num_motion_states, _updated_covar);
  matrix_scale(_num_feats_init_structure * 3 + _num_motion_states, _num_feats_init_structure * 3 + _num_motion_states,
               _updated_covar, 0.00001, _updated_covar);

  double Qrot = 1;
  double Qtrans = 1;
  _updated_covar[(_num_feats_init_structure * 3 + _num_motion_states) * (3 * _num_feats_init_structure + 0) + 3
      * _num_feats_init_structure + 0] = Qtrans;
  _updated_covar[(_num_feats_init_structure * 3 + _num_motion_states) * (3 * _num_feats_init_structure + 1) + 3
      * _num_feats_init_structure + 1] = Qtrans;
  _updated_covar[(_num_feats_init_structure * 3 + _num_motion_states) * (3 * _num_feats_init_structure + 2) + 3
      * _num_feats_init_structure + 2] = Qtrans;

  _updated_covar[(_num_feats_init_structure * 3 + _num_motion_states) * (3 * _num_feats_init_structure + 3) + 3
      * _num_feats_init_structure + 3] = Qrot;
  _updated_covar[(_num_feats_init_structure * 3 + _num_motion_states) * (3 * _num_feats_init_structure + 4) + 3
      * _num_feats_init_structure + 4] = Qrot;
  _updated_covar[(_num_feats_init_structure * 3 + _num_motion_states) * (3 * _num_feats_init_structure + 5) + 3
      * _num_feats_init_structure + 5] = Qrot;

  _R_ekf = new double[(_num_feats_init_structure * 2) * (_num_feats_init_structure * 2)];
  matrix_ident(_num_feats_init_structure * 2, _R_ekf);
  matrix_scale(_num_feats_init_structure * 2, _num_feats_init_structure * 2, _R_ekf, 0.01, _R_ekf);

  _Q_ekf = new double[_num_motion_states * _num_motion_states];
  matrix_ident(_num_motion_states, _Q_ekf);
  _Q_ekf[_num_motion_states * 0 + 0] = 1;
  _Q_ekf[_num_motion_states * 1 + 1] = 1;
  _Q_ekf[_num_motion_states * 2 + 2] = 1; // linear
  _Q_ekf[_num_motion_states * 3 + 3] = 3;
  _Q_ekf[_num_motion_states * 4 + 4] = 3;
  _Q_ekf[_num_motion_states * 5 + 5] = 3; // rotation
  matrix_scale(_num_motion_states, _num_motion_states, _Q_ekf, 0.01, _Q_ekf);

  _A_ekf = new double[(3 * _num_feats_init_structure + _num_motion_states) * (3 * _num_feats_init_structure
      + _num_motion_states)];
  matrix_zeroes(3 * _num_feats_init_structure + _num_motion_states, 3 * _num_feats_init_structure + _num_motion_states,
                _A_ekf);

  // _W_ekf doesn't depend on values of the state only the size matters
  _W_ekf = new double[(3 * _num_feats_init_structure + _num_motion_states) * _num_motion_states];
  _getW(_updated_state, _W_ekf);
  _W_ekf_trans = new double[(3 * _num_feats_init_structure + _num_motion_states) * _num_motion_states];
  matrix_transpose(3 * _num_feats_init_structure + _num_motion_states, _num_motion_states, _W_ekf, _W_ekf_trans);

  _W_Q_ekf = new double[(3 * _num_feats_init_structure + _num_motion_states) * _num_motion_states];
  matrix_product(3 * _num_feats_init_structure + _num_motion_states, _num_motion_states, _num_motion_states,
                 _num_motion_states, _W_ekf, _Q_ekf, _W_Q_ekf);
  //_W_Q_W_ekf_trans = ublas::prod(W_Q, W_trans);
  _W_Q_W_ekf_trans = new double[(3 * _num_feats_init_structure + _num_motion_states) * (3 * _num_feats_init_structure
      + _num_motion_states)];
  matrix_product((3 * _num_feats_init_structure + _num_motion_states), _num_motion_states, _num_motion_states,
                 (3 * _num_feats_init_structure + _num_motion_states), _W_Q_ekf, _W_ekf_trans, _W_Q_W_ekf_trans);

  _predicted_state = new double[_num_feats_init_structure * 3 + _num_motion_states];
  matrix_zeroes(1, _num_feats_init_structure * 3 + _num_motion_states, _predicted_state);

  _A_ekf_covar = new double[(3 * _num_feats_init_structure + _num_motion_states) * (3 * _num_feats_init_structure
      + _num_motion_states)];

  _predicted_covar = new double[(3 * _num_feats_init_structure + _num_motion_states) * (3 * _num_feats_init_structure
      + _num_motion_states)];
  // z is the observation vector
  _z = new double[_num_feats_init_structure * 2];
  _H_ekf = new double[(_num_feats_init_structure * 2) * (3 * _num_feats_init_structure + _num_motion_states)];
  matrix_zeroes((_num_feats_init_structure * 2), (3 * _num_feats_init_structure + _num_motion_states), _H_ekf);
  _H_ekf_trans = new double[(3 * _num_feats_init_structure + _num_motion_states) * (_num_feats_init_structure * 2)];

  //H_covar = ublas::prod(H,predCovar);
  _H_ekf_covar = new double[(_num_feats_init_structure * 2) * (3 * _num_feats_init_structure + _num_motion_states)];

  //covarH = ublas::prod(predCovar, H_trans);
  _covar_H_ekf = new double[(3 * _num_feats_init_structure + _num_motion_states) * (_num_feats_init_structure * 2)];
  //HcovarH = ublas::prod(H_covar, H_trans) + R;
  _H_covar_H_ekf = new double[(_num_feats_init_structure * 2) * (_num_feats_init_structure * 2)];

  _K_ekf = new double[(3 * _num_feats_init_structure + _num_motion_states) * (_num_feats_init_structure * 2)];

  _estimated_z = new double[_num_feats_init_structure * 2];
  _innovation = new double[_num_feats_init_structure * 2];

  _I_ekf = new double[(_num_feats_init_structure * 3 + _num_motion_states) * (_num_feats_init_structure * 3
      + _num_motion_states)];
  matrix_ident(_num_feats_init_structure * 3 + _num_motion_states, _I_ekf);
  //KH = ublas::prod(K,H);
  _K_H_ekf = new double[(_num_feats_init_structure * 3 + _num_motion_states) * (_num_feats_init_structure * 3
      + _num_motion_states)];
  //I_KH = (I - KH);
  _I_K_H_ekf = new double[(_num_feats_init_structure * 3 + _num_motion_states) * (_num_feats_init_structure * 3
      + _num_motion_states)];
  //HQH = ublas::matrix<double>(2*numFeatures, 2*numFeatures);
  _H_Q_H_ekf = new double[(2 * _num_feats_init_structure) * (2 * _num_feats_init_structure)];
}
Example #28
0
/* Estimate an F-matrix from a given set of point matches */
std::vector<int> EstimateFMatrix(const std::vector<Keypoint> &k1, 
				 const std::vector<Keypoint> &k2, 
				 std::vector<KeypointMatch> matches, 
				 int num_trials, double threshold, 
				 double *F, bool essential)
{
    int num_pts = (int) matches.size();

    /* num_pts should be greater than a threshold */
    if (num_pts < 20) {
        std::vector<int> inliers;
        return inliers;
    }

    v3_t *k1_pts = new v3_t[num_pts];
    v3_t *k2_pts = new v3_t[num_pts];

    v3_t *k1_pts_in = new v3_t[num_pts];
    v3_t *k2_pts_in = new v3_t[num_pts];

    for (int i = 0; i < num_pts; i++) {
        int idx1 = matches[i].m_idx1;
        int idx2 = matches[i].m_idx2;

		if(idx1 >= k1.size()) {
			fprintf(stderr, "Error: %d >= %d\n", idx1, k1.size());
			fprintf(stderr, "idx1/idx2: %d %d\n", idx1, idx2);
			fprintf(stderr, "Fix me 1\n");
			continue;
		}

		if(idx2 >= k2.size()) {
			fprintf(stderr, "Error: %d >= %d\n", idx2, k2.size());
			fprintf(stderr, "idx1/idx2: %d %d\n", idx1, idx2);
			fprintf(stderr, "Fix me 2\n");
			continue;
		}

        assert(idx1 < (int) k1.size());
        assert(idx2 < (int) k2.size());

        k1_pts[i] = v3_new(k1[idx1].m_x, k1[idx1].m_y, 1.0);
        k2_pts[i] = v3_new(k2[idx2].m_x, k2[idx2].m_y, 1.0);
    }

    estimate_fmatrix_ransac_matches(num_pts, k2_pts, k1_pts, 
        num_trials, threshold, 0.99,
        (essential ? 1 : 0), F);

    /* Find the inliers */
    std::vector<int> inliers;

    for (int i = 0; i < num_pts; i++) {
        double dist = fmatrix_compute_residual(F, k2_pts[i], k1_pts[i]);
        if (dist < threshold) {
            inliers.push_back(i);
        }
    }

    /* Re-estimate using inliers */
    int num_inliers = (int) inliers.size();

    for (int i = 0; i < num_inliers; i++) {
        k1_pts_in[i] = k1_pts[inliers[i]]; // v3_new(k1[idx1]->m_x, k1[idx1]->m_y, 1.0);
        k2_pts_in[i] = k2_pts[inliers[i]]; // v3_new(k2[idx2]->m_x, k2[idx2]->m_y, 1.0);
    }

    // printf("[1] num_inliers = %d\n", num_inliers);

#if 0
    double F0[9];
    double e1[3], e2[3];
    estimate_fmatrix_linear(num_inliers, k2_pts_in, k1_pts_in, F0, e1, e2);

    inliers.clear();
    for (int i = 0; i < num_pts; i++) {
        double dist = fmatrix_compute_residual(F0, k2_pts[i], k1_pts[i]);
        if (dist < threshold) {
            inliers.push_back(i);
        }
    }
    num_inliers = inliers.size();
    // printf("[2] num_inliers = %d\n", num_inliers);

    // matrix_print(3, 3, F0);
#else
    double F0[9];
    memcpy(F0, F, sizeof(double) * 9);
#endif

    if (!essential) {
        /* Refine using NLLS */
        for (int i = 0; i < num_inliers; i++) {
            k1_pts_in[i] = k1_pts[inliers[i]];
            k2_pts_in[i] = k2_pts[inliers[i]];
        }

        refine_fmatrix_nonlinear_matches(num_inliers, k2_pts_in, k1_pts_in, 
            F0, F);
    } else {
        memcpy(F, F0, sizeof(double) * 9);
    }

#if 0
    if (essential) {
        /* Compute the SVD of F */
        double U[9], S[3], VT[9];
        dgesvd_driver(3, 3, F, U, S, VT);
        double E0[9] = { 1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 0.0 };

        double tmp[9];
        matrix_product(3, 3, 3, 3, U, E0, tmp);
        matrix_product(3, 3, 3, 3, tmp, VT, F);
    }
#endif

    inliers.clear();
    for (int i = 0; i < num_pts; i++) {
        double dist = fmatrix_compute_residual(F, k2_pts[i], k1_pts[i]);
        if (dist < threshold) {
            inliers.push_back(i);
        }
    }
    num_inliers = (int) inliers.size();

    delete [] k1_pts;
    delete [] k2_pts;
    delete [] k1_pts_in;
    delete [] k2_pts_in;

    return inliers;
}
Example #29
0
/* Triangulate a subtrack */
v3_t BundlerApp::TriangulateNViews(const ImageKeyVector &views, 
                                   int *added_order, 
                                   camera_params_t *cameras,
                                   double &error, 
                                   bool explicit_camera_centers)
{
    int num_views = (int) views.size();

    v2_t *pv = new v2_t[num_views];
    double *Rs = new double[9 * num_views];
    double *ts = new double[3 * num_views];
	
    for (int i = 0; i < num_views; i++) {
	camera_params_t *cam = NULL;

	int camera_idx = views[i].first;
	int image_idx = added_order[camera_idx];
	int key_idx = views[i].second;
	Keypoint &key = GetKey(image_idx, key_idx);

	double p3[3] = { key.m_x, key.m_y, 1.0 };

        if (m_optimize_for_fisheye) {
            /* Undistort the point */
            double x = p3[0], y = p3[1];
            m_image_data[image_idx].UndistortPoint(x, y, p3[0], p3[1]);
        }

	double K[9], Kinv[9];
	GetIntrinsics(cameras[camera_idx], K);
	matrix_invert(3, K, Kinv);

	double p_n[3];
	matrix_product(3, 3, 3, 1, Kinv, p3, p_n);

        // EDIT!!!
	pv[i] = v2_new(-p_n[0], -p_n[1]);
        pv[i] = UndistortNormalizedPoint(pv[i], cameras[camera_idx]);

	cam = cameras + camera_idx;

	memcpy(Rs + 9 * i, cam->R, 9 * sizeof(double));
	if (!explicit_camera_centers) {
	    memcpy(ts + 3 * i, cam->t, 3 * sizeof(double));
	} else {
	    matrix_product(3, 3, 3, 1, cam->R, cam->t, ts + 3 * i);
	    matrix_scale(3, 1, ts + 3 * i, -1.0, ts + 3 * i);
	}
    }
    
    v3_t pt = triangulate_n(num_views, pv, Rs, ts, &error);

    error = 0.0;
    for (int i = 0; i < num_views; i++) {
	int camera_idx = views[i].first;
	int image_idx = added_order[camera_idx];
	int key_idx = views[i].second;
	Keypoint &key = GetKey(image_idx, key_idx);

	v2_t pr = sfm_project_final(cameras + camera_idx, pt, 
				    explicit_camera_centers ? 1 : 0,
                                    m_estimate_distortion ? 1 : 0);
        
        if (m_optimize_for_fisheye) {
            double x = Vx(pr), y = Vy(pr);
            m_image_data[image_idx].DistortPoint(x, y, Vx(pr), Vy(pr));
        }        

	double dx = Vx(pr) - key.m_x;
	double dy = Vy(pr) - key.m_y;

	error += dx * dx + dy * dy;
    }

    error = sqrt(error / num_views);

    delete [] pv;
    delete [] Rs;
    delete [] ts;

    return pt;
}
Example #30
0
/* Triangulate two points */
v3_t Triangulate(v2_t p, v2_t q, 
                 camera_params_t c1, camera_params_t c2, 
                 double &proj_error, bool &in_front, double &angle,
                 bool explicit_camera_centers)
{
    double K1[9], K2[9];
    double K1inv[9], K2inv[9];

    GetIntrinsics(c1, K1);
    GetIntrinsics(c2, K2);
    
    matrix_invert(3, K1, K1inv);
    matrix_invert(3, K2, K2inv);

    /* Set up the 3D point */
    // EDIT!!!
    double proj1[3] = { Vx(p), Vy(p), -1.0 };
    double proj2[3] = { Vx(q), Vy(q), -1.0 };

    double proj1_norm[3], proj2_norm[3];

    matrix_product(3, 3, 3, 1, K1inv, proj1, proj1_norm);
    matrix_product(3, 3, 3, 1, K2inv, proj2, proj2_norm);

    v2_t p_norm = v2_new(proj1_norm[0] / proj1_norm[2],
			 proj1_norm[1] / proj1_norm[2]);
    
    v2_t q_norm = v2_new(proj2_norm[0] / proj2_norm[2],
			 proj2_norm[1] / proj2_norm[2]);

    /* Undo radial distortion */
    p_norm = UndistortNormalizedPoint(p_norm, c1);
    q_norm = UndistortNormalizedPoint(q_norm, c2);

    /* Compute the angle between the rays */
    angle = ComputeRayAngle(p, q, c1, c2);

    /* Triangulate the point */
    v3_t pt;
    if (!explicit_camera_centers) {
	pt = triangulate(p_norm, q_norm, c1.R, c1.t, c2.R, c2.t, &proj_error);
    } else {
	double t1[3];
	double t2[3];
			
	/* Put the translation in standard form */
	matrix_product(3, 3, 3, 1, c1.R, c1.t, t1);
	matrix_scale(3, 1, t1, -1.0, t1);
	matrix_product(3, 3, 3, 1, c2.R, c2.t, t2);
	matrix_scale(3, 1, t2, -1.0, t2);
			
	pt = triangulate(p_norm, q_norm, c1.R, t1, c2.R, t2, &proj_error);
    }

    proj_error = (c1.f + c2.f) * 0.5 * sqrt(proj_error * 0.5);

    /* Check cheirality */
    bool cc1 = CheckCheirality(pt, c1);
    bool cc2 = CheckCheirality(pt, c2);

    in_front = (cc1 && cc2);

    return pt;
}