Example #1
0
void TpsRegistration::PrepareBasisKernel() {
  // TODO(bing-jian): detect singularity of the data
  vnl_matrix<double> K, U;
  ComputeTPSKernel(model_, ctrl_pts_, U, K);
  m_ = model_.rows();
  vnl_matrix<double> Pm;
  Pm.set_size(m_, d_ + 1);
  Pm.set_column(0, 1);
  Pm.update(model_, 0, 1);

  vnl_matrix<double> Pn;
  Pn.set_size(n_, d_ + 1);
  Pn.set_column(0, 1);
  Pn.update(ctrl_pts_, 0, 1);
  /* should use SVD(Pn), but vnl's SVD is an ``economy-size'' SVD  */

  /* vnl_svd<double> SVD(Pn.transpose());
  vnl_matrix<double> VV = SVD.V();
  std::cout << VV.rows() << " " << VV.cols() << std::endl;
  SaveMatrixToAsciiFile("./VV.txt", VV);
  */

  vnl_qr<double> qr(Pn);
  vnl_matrix<double> V = qr.Q();
  vnl_matrix<double> PP = V.extract(n_, n_ - d_ - 1, 0, d_ + 1);
  basis_.set_size(m_, n_);
  basis_.update(Pm);
  basis_.update(U * PP, 0, d_ + 1);
  kernel_ = PP.transpose() * K * PP;
}
Example #2
0
int ThinPlateSplineTransform(const char* f_config) {
  vnl_matrix<double> model, scene, ctrl_pts, /*source,*/ transformed_source;
  char f_model[256] = {0}, f_scene[256] = {0};
  char common_section[80] = "FILES";

  GetPrivateProfileString(common_section, "model", NULL,
      f_model, 256, f_config);
  if (LoadMatrixFromTxt(f_model, model) < 0) {
    return -1;
  }
  int d = model.cols();

  GetPrivateProfileString(common_section, "scene", NULL,
      f_scene, 256, f_config);
  if (LoadMatrixFromTxt(f_scene, scene) < 0) {
    return -1;
  }
  assert(scene.cols() == d);

  char f_ctrl_pts[256] = {0};
  GetPrivateProfileString(common_section, "ctrl_pts", NULL,
      f_ctrl_pts, 256, f_config);
  if (LoadMatrixFromTxt(f_ctrl_pts, ctrl_pts) < 0) {
    return -1;
  }
  assert(ctrl_pts.cols() == d);
  int n = ctrl_pts.rows();

  //char f_source[256] = {0};
  //GetPrivateProfileString(common_section, "source", NULL,
  //    f_source, 256, f_config);
  //if (LoadMatrixFromTxt(f_source, source) < 0) {
  //  return -1;
  //}
  //assert(source.cols() == d);
  //int m = source.rows();

  vnl_matrix<double> affine, tps;
  char f_init_affine[256] = {0}, f_init_tps[256] = {0};
  DWORD readCount = GetPrivateProfileString(common_section, "init_affine", NULL,
      f_init_affine, 256, f_config);
  if (readCount != 0)
  {
	  if (LoadMatrixFromTxt(f_init_affine, affine) < 0) {
		  return -1;
	  }
  }
  assert(affine.cols() == d);
  assert(affine.rows() == d+1);

  GetPrivateProfileString(common_section, "init_tps", NULL,
      f_init_tps, 256, f_config);
  if (LoadMatrixFromTxt(f_init_tps, tps) < 0) {
    return -1;
  }
  assert(tps.cols() == d);
  assert(tps.rows() == (n - d - 1));

  vnl_matrix<double> param_all;
  param_all.set_size(n, d);
  param_all.update(affine);
  param_all.update(tps, d + 1);

  // TODO: check if dimensions are consistent.
  bool b_normalize = GetPrivateProfileInt("GMMREG_OPT", "normalize", 1, f_config);

  double model_scale, scene_scale, ctrl_scale;
  vnl_vector<double> ctrl_centroid, model_centroid, scene_centroid;

  if (b_normalize) {
    Normalize(ctrl_pts, ctrl_centroid, ctrl_scale);
    Normalize(model, model_centroid, model_scale);
    Normalize(scene, scene_centroid, scene_scale);
    // perform normalization to source w.r.t to model space
    //Denormalize(source, -model_centroid/model_scale, 1.0/model_scale);
  }

  vnl_matrix<double> K, U;
  ComputeTPSKernel(source, ctrl_pts, U, K);
  vnl_matrix<double> Pm;
  Pm.set_size(m, d + 1);
  Pm.set_column(0, 1);
  Pm.update(source, 0, 1);

  vnl_matrix<double> Pn;
  Pn.set_size(n, d + 1);
  Pn.set_column(0, 1);
  Pn.update(ctrl_pts, 0, 1);

  vnl_qr<double> qr(Pn);
  vnl_matrix<double> V = qr.Q();
  vnl_matrix<double> PP = V.extract(n, n - d - 1, 0, d + 1);
  vnl_matrix<double> basis;
  basis.set_size(m, n);
  basis.update(Pm);
  basis.update(U * PP, 0, d + 1);

  transformed_source = basis * param_all;
  if (b_normalize) {
    Denormalize(transformed_source, scene_centroid, scene_scale);
  }
  char f_transformed_source[256] = {0};
  GetPrivateProfileString(common_section, "transformed_source", NULL,
      f_transformed_source, 256, f_config);
  std::ofstream outfile(f_transformed_source, std::ios_base::out);

  transformed_source.print(outfile);
  return 0;
}