test_common.cpp 2.71 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
#include "test_precomp.hpp"

#include <fstream>
#include <cstdlib>

using namespace cv;
using namespace cv::sfm;
using namespace std;

namespace cvtest
{

void generateTwoViewRandomScene( cvtest::TwoViewDataSet &data )
{
    vector<Mat_<double> > points2d;
    vector<cv::Matx33d> Rs;
    vector<cv::Vec3d> ts;
    vector<cv::Matx34d> Ps;
    Matx33d K;
    Mat_<double> points3d;

    int nviews = 2;
    int npoints = 30;
    bool is_projective = true;

    generateScene(nviews, npoints, is_projective, K, Rs, ts, Ps, points3d, points2d);

    // Internal parameters (same K)
    data.K1 = K;
    data.K2 = K;

    // Rotation
    data.R1 = Rs[0];
    data.R2 = Rs[1];

    // Translation
    data.t1 = ts[0];
    data.t2 = ts[1];

    // Projection matrix, P = K(R|t)
    data.P1 = Ps[0];
    data.P2 = Ps[1];

    // Fundamental matrix
    fundamentalFromProjections( data.P1, data.P2, data.F );

    // 3D points
    data.X = points3d;

    // Projected points
    data.x1 = points2d[0];
    data.x2 = points2d[1];
}

/** Check the properties of a fundamental matrix:
*
*   1. The determinant is 0 (rank deficient)
*   2. The condition x'T*F*x = 0 is satisfied to precision.
*/
void
expectFundamentalProperties( const cv::Matx33d &F,
                             const cv::Mat_<double> &ptsA,
                             const cv::Mat_<double> &ptsB,
                             double precision )
{
  EXPECT_NEAR( 0, determinant(F), precision );

  int n = ptsA.cols;
  EXPECT_EQ( n, ptsB.cols );

  cv::Mat_<double> x1, x2;
  euclideanToHomogeneous( ptsA, x1 );
  euclideanToHomogeneous( ptsB, x2 );

  for( int i = 0; i < n; ++i )
  {
    double residual = Vec3d(x2(0,i),x2(1,i),x2(2,i)).ddot( F * Vec3d(x1(0,i),x1(1,i),x1(2,i)) );
    EXPECT_NEAR( 0.0, residual, precision );
  }
}


void
parser_2D_tracks(const string &_filename, std::vector<Mat> &points2d )
{
  ifstream myfile(_filename.c_str());

  if (!myfile.is_open())
  {
    cout << "Unable to read file: " << _filename << endl;
    exit(0);

  } else {

    double x, y;
    string line_str;
    Mat nan_mat = Mat(2, 1 , CV_64F, -1);
    int n_frames = 0, n_tracks = 0, track = 0;

    while ( getline(myfile, line_str) )
    {
      istringstream line(line_str);

      if ( track > n_tracks )
      {
        n_tracks = track;

        for (int i = 0; i < n_frames; ++i)
          cv::hconcat(points2d[i], nan_mat, points2d[i]);
      }

      for (int frame = 1; line >> x >> y; ++frame)
      {
        if ( frame > n_frames )
        {
          n_frames = frame;
          points2d.push_back(nan_mat);
        }

        points2d[frame-1].at<double>(0,track) = x;
        points2d[frame-1].at<double>(1,track) = y;
      }

      ++track;
    }

    myfile.close();
  }

}

} // namespace cvtest