Esempio n. 1
0
double QuadQuality(const Vertex & a,const Vertex &b,const Vertex &c,const Vertex &d)
{
  // calcul de 4 angles --
  R2 A((R2)a),B((R2)b),C((R2)c),D((R2)d);
  R2 AB(B-A),BC(C-B),CD(D-C),DA(A-D);
  //  Move(A),Line(B),Line(C),Line(D),Line(A);
  const Metric & Ma  = a;
  const Metric & Mb  = b;
  const Metric & Mc  = c;
  const Metric & Md  = d;
    
  double lAB=Norme2(AB);
  double lBC=Norme2(BC);
  double lCD=Norme2(CD);
  double lDA=Norme2(DA);
  AB /= lAB;  BC /= lBC;  CD /= lCD;  DA /= lDA;
  // version aniso 
  double cosDAB= Ma(DA,AB)/(Ma(DA)*Ma(AB)),sinDAB= Det(DA,AB);
  double cosABC= Mb(AB,BC)/(Mb(AB)*Mb(BC)),sinABC= Det(AB,BC);
  double cosBCD= Mc(BC,CD)/(Mc(BC)*Mc(CD)),sinBCD= Det(BC,CD);
  double cosCDA= Md(CD,DA)/(Md(CD)*Md(DA)),sinCDA= Det(CD,DA);
  double sinmin=Min(Min(sinDAB,sinABC),Min(sinBCD,sinCDA));
  // cout << A << B << C << D ;
  // cout << " sinmin " << sinmin << " " << cosDAB << " " << cosABC << " " << cosBCD << " " << cosCDA << endl;
  // rattente(1);
  if (sinmin<=0) return sinmin;
  return 1.0-Max(Max(Abs(cosDAB),Abs(cosABC)),Max(Abs(cosBCD),Abs(cosCDA)));
}
void Calib::computeProjectionMatrix()
{
    std::cout << "1111111111***********************************************************************************\n";
//    for(int i = 0;i < imagePoints.size();i++)
//    {
//        std::cout<<" imagePoints[i]= "<< imagePoints[i]<<std::endl;
//        std::cout<<" objectPoints[i]= "<< objectPoints[i]<<std::endl;
//    }

    if (objectPoints.size() != imagePoints.size())
        return;

    int n = objectPoints.size();

    Eigen::Vector2d avg2;
    Eigen::Vector3d avg3;

    for (unsigned int i = 0; i < n; i++)
    {
        avg2 += imagePoints[i];
        avg3 += objectPoints[i];
        std::cout << i << " " << objectPoints[i](0) << " " << objectPoints[i](1) << " " << objectPoints[i](2) << std::endl;
    }
    avg2 = avg2 / n;
    avg3 = avg3 / n;

    std::cout << "avg2 = " << avg2 << std::endl;
    std::cout << "avg3 = " << avg3 << std::endl;

    /* *******************************************************************************
  *  Data normalization
  *  Translates and normalises a set of 2D homogeneous points so that their centroid is at the origin and their mean distance from the origin is sqrt(2).
  */
    float meandist2 = 0;
    float meandist3 = 0;

    imagePoints_t.resize(n);
    objectPoints_t.resize(n);

    for (unsigned int i = 0; i < n; i++)
    {
        imagePoints_t[i] = imagePoints[i] - avg2;
        objectPoints_t[i] = objectPoints[i] - avg3;
//        std::cout << "1 imagePoints_t[i] = " << imagePoints_t[i] << std::endl;
//        std::cout << "1 objectPoints_t[i] = " << objectPoints_t[i] << std::endl;

        meandist2 += sqrt(imagePoints_t[i](0) * imagePoints_t[i](0) + imagePoints_t[i](1) * imagePoints_t[i](1));
        meandist3 += sqrt(objectPoints_t[i](0) * objectPoints_t[i](0) + objectPoints_t[i](1) * objectPoints_t[i](1)
                          + objectPoints_t[i](2) * objectPoints_t[i](2));
    }
    meandist2 /= n;
    meandist3 /= n;

    std::cout << "meandist2 = " << meandist2 << std::endl;
    std::cout << "meandist3 = " << meandist3 << std::endl;

    float scale2 = sqrt(2) / meandist2;
    float scale3 = sqrt(3) / meandist3;


    std::cout << "2222222222222***********************************************************************************\n";
    for (unsigned int i = 0; i < n; i++)
    {
        imagePoints_t[i] = scale2 * imagePoints_t[i];
        objectPoints_t[i] = scale3 * objectPoints_t[i];

//        std::cout << "imagePoints_t[i] = " << imagePoints_t[i] << std::endl;
//        std::cout << "objectPoints_t[i] = " << objectPoints_t[i] << std::endl;

    }

    //    std::cout<<avg3<<std::endl;
    /* *******************************************************************************
  * Similarity transformation T1 to normalize the image points,
  * and a second similarity transformation T2 to normalize the space points.
  * Page 181 in Multiple_View_Geometry_in_Computer_Vision__2nd_Edition
  */
    Eigen::Matrix3d T1;
    T1 << scale2, 0, -scale2 * avg2(0), 0, scale2, -scale2 * avg2(1), 0, 0, 1;

    Eigen::MatrixXd T2(4, 4);
    T2 << scale3, 0, 0, -scale3 * avg3(0), 0, scale3, 0, -scale3 * avg3(1), 0, 0, scale3, -scale3 * avg3(2), 0, 0, 0, 1;


    // use Eigen
    Eigen::MatrixXd A(2 * n, 12);
    A.setZero(2 * n, 12);

    for (int i = 0; i < n; i++)
    {

        A(2 * i, 0) = objectPoints_t[i](0);
        A(2 * i, 1) = objectPoints_t[i](1);
        A(2 * i, 2) = objectPoints_t[i](2);
        A(2 * i, 3) = 1;
        A(2 * i, 4) = 0;
        A(2 * i, 5) = 0;
        A(2 * i, 6) = 0;
        A(2 * i, 7) = 0;
        A(2 * i, 8) = -imagePoints_t[i](0) * objectPoints_t[i](0);
        A(2 * i, 9) = -imagePoints_t[i](0) * objectPoints_t[i](1);
        A(2 * i, 10) = -imagePoints_t[i](0) * objectPoints_t[i](2);
        A(2 * i, 11) = -imagePoints_t[i](0) * 1;

        A(2 * i + 1, 0) = 0;
        A(2 * i + 1, 1) = 0;
        A(2 * i + 1, 2) = 0;
        A(2 * i + 1, 3) = 0;
        A(2 * i + 1, 4) = 1 * objectPoints_t[i](0);
        A(2 * i + 1, 5) = 1 * objectPoints_t[i](1);
        A(2 * i + 1, 6) = 1 * objectPoints_t[i](2);
        A(2 * i + 1, 7) = 1;
        A(2 * i + 1, 8) = -imagePoints_t[i](1) * objectPoints_t[i](0);
        A(2 * i + 1, 9) = -imagePoints_t[i](1) * objectPoints_t[i](1);
        A(2 * i + 1, 10) = -imagePoints_t[i](1) * objectPoints_t[i](2);
        A(2 * i + 1, 11) = -imagePoints_t[i](1) * 1;

    }

    Eigen::JacobiSVD<Eigen::MatrixXd> svd(A, Eigen::ComputeFullU | Eigen::ComputeFullV);
    const Eigen::VectorXd & v1 = svd.matrixV().col(11);

    this->Pt << v1(0), v1(1), v1(2), v1(3), v1(4), v1(5), v1(6), v1(7), v1(8), v1(9), v1(10), v1(11);
//    std::cout<<"A= \n"<< A<<std::endl;
//    std::cout<<Pt<<std::endl;
    P = T1.inverse() * Pt * T2;


    //Decompose the projection matrix
    cv::Mat Pr(3, 4, cv::DataType<float>::type);
    cv::Mat Mt(3, 3, cv::DataType<float>::type);
    cv::Mat Rt(3, 3, cv::DataType<float>::type);
    cv::Mat Tt(4, 1, cv::DataType<float>::type);

    for (unsigned i = 0; i < 3; i++)
    {
        for (unsigned int j = 0; j < 4; j++)
        {
            Pr.at<float> (i, j) = P(i, j);
        }
    }
    cv::decomposeProjectionMatrix(Pr, Mt, Rt, Tt);

    //scale: Mt(2,2) should = 1; so update the projection matrix and decomposition again
    float k = (1 / (Mt.at<float> (2, 2)));

    /* ****************************************************************************************
      * Upate the projection matrix
      * Decomposition again to get new intrinsic matrix and rotation matrix
      */
    this->P = k * P;

    cv::Mat Pro(3, 4, cv::DataType<float>::type);
    cv::Mat Mc(3, 3, cv::DataType<float>::type); // intrinsic parameter matrix
    cv::Mat Rc(3, 3, cv::DataType<float>::type); // rotation matrix
    cv::Mat Tc(4, 1, cv::DataType<float>::type); // translation vector

    for (unsigned i = 0; i < 3; i++)
    {
        for (unsigned int j = 0; j < 4; j++)
        {
            Pro.at<float> (i, j) = P(i, j);
        }
    }
    cv::decomposeProjectionMatrix(Pro, Mc, Rc, Tc);

    // Change from OpenCV varibles to Eigen
    for (unsigned i = 0; i < 3; i++)
    {
        for (unsigned int j = 0; j < 3; j++)
        {
            M(i, j) = Mc.at<float> (i, j) ;
        }
    }


    /* ****************************************************************************************
      * Compute te rotation matrix R and translation vector T
      */
    P_temp = M.inverse() * P;
    this->R = this->P_temp.block(0,0,3,3);
    this->T = this->P_temp.block(0,3,3,1);


    std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
//    std::cout << "T1 =\n " << T2 << std::endl;
//    std::cout << "T2 =\n " << T1 << std::endl;
//    std::cout << "A =\n " << A << std::endl;
//    std::cout << "svd.matrixV() =\n " << svd.matrixV() << std::endl;
//    std::cout << "Pt =\n " << Pt << std::endl;
    std::cout << "P =\n " << P << std::endl;
    std::cout << "M =\n " << M << std::endl;
    std::cout << "R =\n " << R << std::endl;
    std::cout << "Rc =\n " << Rc << std::endl;
    std::cout << "T =\n " << T << std::endl;
    std::cout << "Mt(2,2) = " << Mt.at<float> (2, 2) << std::endl;

}