コード例 #1
0
void sumAndNormalize( Eigen::MatrixXf & out, const Eigen::MatrixXf & in, const Eigen::MatrixXf & Q ) {
	out.resize( in.rows(), in.cols() );
	for( int i=0; i<in.cols(); i++ ){
		Eigen::VectorXf b = in.col(i);
		Eigen::VectorXf q = Q.col(i);
		out.col(i) = b.array().sum()*q - b;
	}
}
コード例 #2
0
///////////////////////
/////  Inference  /////
///////////////////////
void expAndNormalize ( Eigen::MatrixXf & out, const Eigen::MatrixXf & in ) {
	out.resize( in.rows(), in.cols() );
	for( int i=0; i<out.cols(); i++ ){
		Eigen::VectorXf b = in.col(i);
		b.array() -= b.maxCoeff();
		b = b.array().exp();
		out.col(i) = b / b.array().sum();
	}
}
コード例 #3
0
std::vector<int> fillSubset(const Eigen::MatrixXf &data, Eigen::MatrixXf &subset, int num_columns)
{
    std::vector<int> column_indices;
    for(int i = 0; i < num_columns; i++)
    {
        int column_number = rand() % data.cols();
        column_indices.push_back(column_number);
        subset.col(i) = data.col(column_number);        
        //subset.col(i) = data.col(100 + i);        
    }
    return column_indices;
}
コード例 #4
0
ファイル: HW2p2.cpp プロジェクト: aaronmyers/ML
double RMSEcalc(std::vector< std::vector<int> > traindata, Eigen::MatrixXf U, Eigen::MatrixXf M) {
	Eigen::VectorXf sqvals(traindata[1].size());
#pragma omp parallel for
	for(int p=0;p<traindata[1].size();p++) {
		sqvals(p)=(U.col(traindata[0][p]-1).transpose()*M.col(traindata[1][p]-1) - traindata[2][p])*(U.col(traindata[0][p]-1).transpose()*M.col(traindata[1][p]-1) - traindata[2][p]);	
	}	
	double total;
       	total = sqvals.sum();
	return total;


}
コード例 #5
0
	void calcMeanAndCovarWeighedVectorized(const Eigen::MatrixXf &input, const Eigen::VectorXd &inputWeights, Eigen::MatrixXf &out_covMat, Eigen::VectorXf &out_mean,Eigen::MatrixXf &temp)
	{
		out_mean=input.col(0); //to resize
		out_mean.setZero();
		double wSumInv=1.0/inputWeights.sum();
		for (int k=0;k<inputWeights.size();k++){
			double w=inputWeights[k];
			out_mean+=input.col(k)*(float)(w*wSumInv);
		}
		out_mean = input.rowwise().mean();
		temp = (input.colwise() - out_mean);
		for (int k=0;k<inputWeights.size();k++){
			temp.col(k) *= (float)(sqrt(inputWeights(k)*wSumInv));	//using square roots, as we only want the normalized weights to be included once for each result element in the multiplication below
		}
		out_covMat = temp*temp.transpose();
	}
コード例 #6
0
ファイル: main2.cpp プロジェクト: Daiver/jff
void coordinateDescentLasso(
        const Eigen::MatrixXf &data,
        const Eigen::VectorXf &output,
        Eigen::VectorXf &weights, 
        const float lambda,
        const int nIters,
        const bool verbose)
{
    const int nExamples = data.rows();
    const int nFeatures = data.cols();
    for(int iter = 0; iter < nIters; ++iter){
        const int featureInd = iter % nFeatures;
        float rho = 0;
        for(int i = 0; i < nExamples; ++i)
            rho += residualWithoutKWeight(
                    weights,
                    data.row(i).transpose(),
                    output[i],
                    featureInd) * data(i, featureInd);
        auto column = data.col(featureInd);
        float sumOfColumn = (column.transpose() * column).sum();
        weights[featureInd] = coordinateDescentStepLasso(weights[featureInd], sumOfColumn, rho, lambda);
        if(verbose){
            const float err = rss(weights, data, output);
            std::cout << "iter " << iter << " err " << err << std::endl;
            std::cout << weights << std::endl;
        }
    }
}
コード例 #7
0
VectorXs DenseCRF::currentMap( const Eigen::MatrixXf & Q ) const{
	VectorXs r(Q.cols());
	// Find the map
	for( int i=0; i<N_; i++ ){
		int m;
		Q.col(i).maxCoeff( &m );
		r[i] = m;
	}
	return r;
}
コード例 #8
0
ファイル: miscellaneous.hpp プロジェクト: Cerarus/v4r
float
computeHistogramIntersection (const Eigen::VectorXf &histA, const Eigen::VectorXf &histB)
{
    Eigen::MatrixXf histAB (histA.rows(), 2);
    histAB.col(0) = histA;
    histAB.col(1) = histB;

    Eigen::VectorXf minv = histAB.rowwise().minCoeff();
    return minv.sum();
}
コード例 #9
0
ファイル: main_blending.cpp プロジェクト: danielepanozzo/cg
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    // Update the position of the first vertex if the keys 1,2, or 3 are pressed
    switch (key)
    {
        case  GLFW_KEY_1:
            V.col(0) << -0.5,  0.5;
            break;
        case GLFW_KEY_2:
            V.col(0) << 0,  0.5;
            break;
        case  GLFW_KEY_3:
            V.col(0) << 0.5,  0.5;
            break;
        default:
            break;
    }

    // Upload the change to the GPU
    VBO.update(V);
}
コード例 #10
0
Eigen::Vector4f PhotoCamera::center(const Eigen::MatrixXf &camera)
{
    Eigen::Matrix3f C1, C2, C3, C4;
    C1 << camera.col(1), camera.col(2), camera.col(3);
    C2 << camera.col(0), camera.col(2), camera.col(3);
    C3 << camera.col(0), camera.col(1), camera.col(3);
    C4 << camera.col(0), camera.col(1), camera.col(2);

    Eigen::Vector4f C;
    C << C1.determinant(), -C2.determinant(), C3.determinant(), -C4.determinant();
    return C;
}
コード例 #11
0
void HierarchicalWalkingIK::computeWalkingTrajectory(const Eigen::Matrix3Xf& comTrajectory,
                                                     const Eigen::Matrix6Xf& rightFootTrajectory,
                                                     const Eigen::Matrix6Xf& leftFootTrajectory,
                                                     std::vector<Eigen::Matrix3f>& rootOrientation,
                                                     Eigen::MatrixXf& trajectory)
{
    int rows = outputNodeSet->getSize();

    trajectory.resize(rows, rightFootTrajectory.cols());
    rootOrientation.resize(rightFootTrajectory.cols());

    Eigen::Vector3f com = colModelNodeSet->getCoM();

    Eigen::VectorXf configuration;
    int N = trajectory.cols();

    Eigen::Matrix4f leftFootPose  = Eigen::Matrix4f::Identity();
    Eigen::Matrix4f rightFootPose = Eigen::Matrix4f::Identity();
    Eigen::Matrix4f chestPose     = chest->getGlobalPose();
    Eigen::Matrix4f pelvisPose    = pelvis->getGlobalPose();

    for (int i = 0; i < N; i++)
    {
        VirtualRobot::MathTools::posrpy2eigen4f(1000 * leftFootTrajectory.block(0, i, 3, 1),  leftFootTrajectory.block(3, i, 3, 1),  leftFootPose);
        VirtualRobot::MathTools::posrpy2eigen4f(1000 * rightFootTrajectory.block(0, i, 3, 1), rightFootTrajectory.block(3, i, 3, 1), rightFootPose);

        // FIXME the orientation of the chest and chest is specific to armar 4
        // since the x-Axsis points in walking direction
        Eigen::Vector3f xAxisChest = (leftFootPose.block(0, 1, 3, 1) + rightFootPose.block(0, 1, 3, 1))/2;
        xAxisChest.normalize();
        chestPose.block(0, 0, 3, 3) = Bipedal::poseFromXAxis(xAxisChest);
        pelvisPose.block(0, 0, 3, 3) = Bipedal::poseFromYAxis(-xAxisChest);

        std::cout << "Frame #" << i << ", ";
        robot->setGlobalPose(leftFootPose);
        computeStepConfiguration(1000 * comTrajectory.col(i),
                                 rightFootPose,
                                 chestPose,
                                 pelvisPose,
                                 configuration);

        trajectory.col(i) = configuration;
        rootOrientation[i] = leftFootPose.block(0, 0, 3, 3);
    }
}
コード例 #12
0
	Eigen::VectorXf ZMeshFilterManifold::computeMaxEigenVector(const Eigen::MatrixXf& inputMat, const std::vector<bool>& clusterK)
	{
		//Eigen::VectorXf ret(rangeDim_);
		Eigen::VectorXf ret(3);
		ret.fill(0);
		int count = 0;
		for (int i=0; i<clusterK.size(); i++) if (clusterK[i]) count++;
		Eigen::MatrixXf realInput(count, rangeDim_);
		//Eigen::MatrixXf realInput(count, 3);
		count = 0;
		for (int i=0; i<clusterK.size(); i++)
		{
			if (clusterK[i])
			{
				realInput.row(count) = inputMat.row(i);
				//realInput.row(count) = MATH::spherical2Cartesian(inputMat.row(i));
				count++;
			}
		}
		Eigen::MatrixXf mat = realInput.transpose()*realInput;
		Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> eigenSolver(mat);
		if (eigenSolver.info()!=Eigen::Success) {
			std::cerr << "Error in SVD decomposition!\n";
			return ret;
		}
		Eigen::VectorXf eigenValues = eigenSolver.eigenvalues();
		Eigen::MatrixXf eigenVectors = eigenSolver.eigenvectors();
		int maxIdx = 0;
		float maxValue = eigenValues(maxIdx);
		for (int i=1; i<eigenValues.size(); i++)
		{
			if (eigenValues(i)>maxValue)
			{
				maxIdx = i;
				maxValue = eigenValues(maxIdx);
			}
		}
		ret = eigenVectors.col(maxIdx);
		return ret;
// 		Eigen::VectorXf retSph = MATH::cartesian2Spherical(ret, 1);
// 		return retSph.head(rangeDim_);
	}
コード例 #13
0
ファイル: main_blending.cpp プロジェクト: danielepanozzo/cg
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
    // Get the position of the mouse in the window
    double xpos, ypos;
    glfwGetCursorPos(window, &xpos, &ypos);

    // Get the size of the window
    int width, height;
    glfwGetWindowSize(window, &width, &height);

    // Convert screen position to world coordinates
    double xworld = ((xpos/double(width))*2)-1;
    double yworld = (((height-1-ypos)/double(height))*2)-1; // NOTE: y axis is flipped in glfw

    // Update the position of the first vertex if the left button is pressed
    if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
        V.col(0) << xworld, yworld;

    // Upload the change to the GPU
    VBO.update(V);
}
コード例 #14
0
ファイル: Kinematics.cpp プロジェクト: TheMarex/libbipedal
void extractControlFrames(VirtualRobot::RobotPtr robot,
                          const Eigen::Matrix6Xf& leftFootTrajectory,
                          const Eigen::MatrixXf&  bodyTrajectory,
                          VirtualRobot::RobotNodeSetPtr bodyJoints,
                          VirtualRobot::RobotNodePtr node,
                          std::vector<Eigen::Matrix4f>& controlFrames)
{
    int N = leftFootTrajectory.cols();

    for (int i = 0; i < N; i++)
    {
        // Move basis along with the left foot
        Eigen::Matrix4f leftFootPose = Eigen::Matrix4f::Identity();
        VirtualRobot::MathTools::posrpy2eigen4f(1000 * leftFootTrajectory.block(0, i, 3, 1),
                                                leftFootTrajectory.block(3, i, 3, 1),  leftFootPose);
        robot->setGlobalPose(leftFootPose);
        bodyJoints->setJointValues(bodyTrajectory.col(i));

        controlFrames.push_back(node->getGlobalPose());
    }
}
コード例 #15
0
ファイル: CurveFitting.cpp プロジェクト: Erickmok/Examples
  int df(const Eigen::VectorXf &x, Eigen::MatrixXf &fjac) const
  {
    // This problem is R^2 -> R^(fvec.rows()), so the dimension of the Jacobian is fvec.rows() x 2
    
    float epsilon = 1e-5;
    Eigen::VectorXf epsilonVector(2);

    Eigen::VectorXf f(this->Points.size());
    operator()(epsilonVector, f);
    
    for(unsigned int parameter = 0; parameter < 2; parameter++)
      {
      epsilonVector = x;
      epsilonVector(parameter) += epsilon;

      Eigen::VectorXf fForward(2);
      operator()(epsilonVector, fForward);

      fjac.col(parameter) = (fForward - f)/epsilon;
      }

    return 0;
  }
コード例 #16
0
ファイル: Kinematics.cpp プロジェクト: TheMarex/libbipedal
void transformOrientationToGroundFrame(const VirtualRobot::RobotPtr& robot,
                                       const Eigen::Matrix6Xf& leftFootTrajectory,
                                       const VirtualRobot::RobotNodePtr& leftFoot,
                                       const VirtualRobot::RobotNodePtr& rightFoot,
                                       const VirtualRobot::RobotNodeSetPtr& bodyJoints,
                                       const Eigen::MatrixXf& bodyTrajectory,
                                       const Eigen::Matrix3Xf& trajectory,
                                       const std::vector<SupportInterval>& intervals,
                                       Eigen::Matrix3Xf& relativeTrajectory)
{
    Eigen::Matrix4f leftInitialPose = bodyJoints->getKinematicRoot()->getGlobalPose();
    int N = trajectory.cols();
    int M = trajectory.rows();
    relativeTrajectory.resize(M, N);

    BOOST_ASSERT(M > 0 && M <= 3);

    auto intervalIter = intervals.begin();
    for (int i = 0; i < N; i++)
    {
        while (i >= intervalIter->endIdx)
        {
            intervalIter = std::next(intervalIter);
        }
        // Move basis along with the left foot
        Eigen::Matrix4f leftFootPose = Eigen::Matrix4f::Identity();
        VirtualRobot::MathTools::posrpy2eigen4f(1000 * leftFootTrajectory.block(0, i, 3, 1),
                                                leftFootTrajectory.block(3, i, 3, 1),  leftFootPose);
        robot->setGlobalPose(leftFootPose);
        bodyJoints->setJointValues(bodyTrajectory.col(i));
        Eigen::Matrix3f worldToRef = computeGroundFrame(leftFoot->getGlobalPose(),
                                                        rightFoot->getGlobalPose(),
                                                        intervalIter->phase).block(0, 0, 3, 3);
        relativeTrajectory.block(0, i, M, 1) = worldToRef.colPivHouseholderQr().solve(trajectory.col(i)).block(0, 0, M, 1);
    }
}
コード例 #17
0
ファイル: pca.hpp プロジェクト: hitsjt/StanfordPCL
template<typename PointT> inline void
pcl::PCA<PointT>::update (const PointT& input_point, FLAG flag)
{
    if (!compute_done_)
        initCompute ();
    if (!compute_done_)
        PCL_THROW_EXCEPTION (InitFailedException, "[pcl::PCA::update] PCA initCompute failed");

    Eigen::Vector3f input (input_point.x, input_point.y, input_point.z);
    const size_t n = eigenvectors_.cols ();// number of eigen vectors
    Eigen::VectorXf meanp = (float(n) * (mean_.head<3>() + input)) / float(n + 1);
    Eigen::VectorXf a = eigenvectors_.transpose() * (input - mean_.head<3>());
    Eigen::VectorXf y = (eigenvectors_ * a) + mean_.head<3>();
    Eigen::VectorXf h = y - input;
    if (h.norm() > 0)
        h.normalize ();
    else
        h.setZero ();
    float gamma = h.dot(input - mean_.head<3>());
    Eigen::MatrixXf D = Eigen::MatrixXf::Zero (a.size() + 1, a.size() + 1);
    D.block(0,0,n,n) = a * a.transpose();
    D /=  float(n)/float((n+1) * (n+1));
    for(std::size_t i=0; i < a.size(); i++) {
        D(i,i)+= float(n)/float(n+1)*eigenvalues_(i);
        D(D.rows()-1,i) = float(n) / float((n+1) * (n+1)) * gamma * a(i);
        D(i,D.cols()-1) = D(D.rows()-1,i);
        D(D.rows()-1,D.cols()-1) = float(n)/float((n+1) * (n+1)) * gamma * gamma;
    }

    Eigen::MatrixXf R(D.rows(), D.cols());
    Eigen::EigenSolver<Eigen::MatrixXf> D_evd (D, false);
    Eigen::VectorXf alphap = D_evd.eigenvalues().real();
    eigenvalues_.resize(eigenvalues_.size() +1);
    for(std::size_t i=0; i<eigenvalues_.size(); i++) {
        eigenvalues_(i) = alphap(eigenvalues_.size()-i-1);
        R.col(i) = D.col(D.cols()-i-1);
    }
    Eigen::MatrixXf Up = Eigen::MatrixXf::Zero(eigenvectors_.rows(), eigenvectors_.cols()+1);
    Up.topLeftCorner(eigenvectors_.rows(),eigenvectors_.cols()) = eigenvectors_;
    Up.rightCols<1>() = h;
    eigenvectors_ = Up*R;
    if (!basis_only_) {
        Eigen::Vector3f etha = Up.transpose() * (mean_.head<3>() - meanp);
        coefficients_.resize(coefficients_.rows()+1,coefficients_.cols()+1);
        for(std::size_t i=0; i < (coefficients_.cols() - 1); i++) {
            coefficients_(coefficients_.rows()-1,i) = 0;
            coefficients_.col(i) = (R.transpose() * coefficients_.col(i)) + etha;
        }
        a.resize(a.size()+1);
        a(a.size()-1) = 0;
        coefficients_.col(coefficients_.cols()-1) = (R.transpose() * a) + etha;
    }
    mean_.head<3>() = meanp;
    switch (flag)
    {
    case increase:
        if (eigenvectors_.rows() >= eigenvectors_.cols())
            break;
    case preserve:
        if (!basis_only_)
            coefficients_ = coefficients_.topRows(coefficients_.rows() - 1);
        eigenvectors_ = eigenvectors_.leftCols(eigenvectors_.cols() - 1);
        eigenvalues_.resize(eigenvalues_.size()-1);
        break;
    default:
        PCL_ERROR("[pcl::PCA] unknown flag\n");
    }
}
コード例 #18
0
ファイル: TraceStoreCol.cpp プロジェクト: Lingrui/TS
bool TraceStoreCol::PcaLossyCompressChunk(int row_start, int row_end,
                                          int col_start, int col_end,
                                          int num_rows, int num_cols, int num_frames,
                                          int frame_stride,
                                          int flow_ix, int flow_frame_stride,
                                          short *data, bool replace,
                                          float *ssq, char *filters,
                                          int row_step, int col_step,
                                          int num_pca) {

  Eigen::MatrixXf Ysub, Y, S, Basis;

  int loc_num_wells = (col_end - col_start) * (row_end - row_start);
  int loc_num_cols = col_end - col_start;

  // Take a sample of the data at rate step, avoiding flagged wells
  // Count the good rows
  int sample_wells = 0;
  for (int row_ix = row_start; row_ix < row_end; row_ix+= row_step) {
    char *filt_start = filters + row_ix * num_cols + col_start;
    char *filt_end = filt_start + loc_num_cols;
    while (filt_start < filt_end) {
      if (*filt_start == 0) {
        sample_wells++;
      }
      filt_start += col_step;
    }
  }
  // try backing off to every well rather than just sampled if we didn't get enough
  if (sample_wells < MIN_SAMPLE_WELL) {
    row_step = 1;
    col_step = 1;
    int sample_wells = 0;
    for (int row_ix = row_start; row_ix < row_end; row_ix+= row_step) {
      char *filt_start = filters + row_ix * num_cols + col_start;
      char *filt_end = filt_start + loc_num_cols;
      while (filt_start < filt_end) {
        if (*filt_start == 0) {
          sample_wells++;
        }
        filt_start += col_step;
      }
    }
  }

  if (sample_wells < MIN_SAMPLE_WELL) {
    return false; // just give up
  }

  // Got enough data to work with, zero out the ssq array for accumulation
  for (int row_ix = row_start; row_ix < row_end; row_ix++) {
    float *ssq_start = ssq + row_ix * num_cols + col_start;
    float *ssq_end = ssq_start + loc_num_cols;
    while (ssq_start != ssq_end) {
      *ssq_start++ = 0;
    }
  }
  // Copy the sampled data in Matrix, frame major
  Ysub.resize(sample_wells, num_frames);
  for (int frame_ix = 0; frame_ix < (int)num_frames; frame_ix++) {
    int sample_offset = 0;
    for (int row_ix = row_start; row_ix < row_end; row_ix+=row_step) {
      size_t store_offset = row_ix * num_cols + col_start;
      char *filt_start = filters + store_offset;
      char *filt_end = filt_start + loc_num_cols;
      int16_t *trace_start = data + (flow_frame_stride * frame_ix) + (flow_ix * frame_stride) + store_offset;
      float *ysub_start = Ysub.data() + sample_wells * frame_ix + sample_offset;
      while (filt_start < filt_end) {
        if (*filt_start == 0) {
          *ysub_start = *trace_start;
          ysub_start++;
          sample_offset++;
        }
        trace_start += col_step;
        filt_start += col_step;
      }
    }
  }

  // Copy in all the data into working matrix
  Y.resize(loc_num_wells, (int)num_frames);
  for (int frame_ix = 0; frame_ix < (int)num_frames; frame_ix++) {
    for (int row_ix = row_start; row_ix < row_end; row_ix++) {
      size_t store_offset = row_ix * num_cols + col_start;
      int16_t *trace_start = data + (flow_frame_stride * frame_ix) + (flow_ix * frame_stride) + store_offset;
      int16_t *trace_end = trace_start + loc_num_cols;
      float * y_start = Y.data() + loc_num_wells * frame_ix + (row_ix - row_start) * loc_num_cols;
      while( trace_start != trace_end ) {
        *y_start++ = *trace_start++;
      }
    }
  }
  Eigen::VectorXf col_mean = Y.colwise().sum();
  col_mean /= Y.rows();

  for (int i = 0; i < Y.cols(); i++) {
    Y.col(i).array() -= col_mean.coeff(i);
  }
  // Create scatter matrix
  S = Ysub.transpose() * Ysub;
  // Compute the eigenvectors
  Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> es;
  es.compute(S);
  Eigen::MatrixXf Pca_Basis = es.eigenvectors();
  Eigen::VectorXf Pca_Values = es.eigenvalues();
  // Copy top eigen vectors into basis for projection
  Basis.resize(num_frames, num_pca);
  for (int i = 0; i < Basis.cols(); i++) {
    //    Basis.col(i) = es.eigenvectors().col(es.eigenvectors().cols() - i -1);
    Basis.col(i) = Pca_Basis.col(Pca_Basis.cols() - i - 1);
  }
  // Create solver matrix, often not a good way of solving things but eigen vectors should be stable and fast
  Eigen::MatrixXf SX = (Basis.transpose() * Basis).inverse() * Basis.transpose();
  // Get coefficients to solve
  Eigen::MatrixXf B = Y * SX.transpose();
  // Uncompress data into yhat matrix
  Eigen::MatrixXf Yhat = B * Basis.transpose();

  for (int i = 0; i < Yhat.cols(); i++) {
    Yhat.col(i).array() += col_mean.coeff(i);
    Y.col(i).array() += col_mean.coeff(i);
  }
  
  // H5File h5("pca_lossy.h5");
  // h5.Open();
  // char buff[256];
  // snprintf(buff, sizeof(buff), "/Y_%d_%d_%d", flow_ix, row_start, col_start);
  // H5Eigen::WriteMatrix(h5, buff, Y);
  // snprintf(buff, sizeof(buff), "/Yhat_%d_%d_%d", flow_ix, row_start, col_start);
  // H5Eigen::WriteMatrix(h5, buff, Yhat);
  // snprintf(buff, sizeof(buff), "/Basis_%d_%d_%d", flow_ix, row_start, col_start);
  // H5Eigen::WriteMatrix(h5, buff, Basis);
  // h5.Close();
  // Copy data out of yhat matrix into original data structure, keeping track of residuals
  for (int frame_ix = 0; frame_ix < (int)num_frames; frame_ix++) {
    for (int row_ix = row_start; row_ix < row_end; row_ix++) {
      size_t store_offset = row_ix * num_cols + col_start;
      int16_t *trace_start = data + flow_frame_stride * frame_ix + flow_ix * frame_stride + store_offset;
      int16_t *trace_end = trace_start + loc_num_cols;
      float * ssq_start = ssq + store_offset;
      size_t loc_offset = (row_ix - row_start) * loc_num_cols;
      float * y_start = Y.data() + loc_num_wells * frame_ix + loc_offset;
      float * yhat_start = Yhat.data() + loc_num_wells * frame_ix + loc_offset;
      while( trace_start != trace_end ) {
        if (replace) {
          *trace_start = (int16_t)(*yhat_start + .5);
        }
        float val = *y_start - *yhat_start;
        *ssq_start += val * val;
        y_start++;
        yhat_start++;
        trace_start++;
        ssq_start++;
      }
    }
  }

  // divide ssq data out for per frame avg
  for (int row_ix = row_start; row_ix < row_end; row_ix++) {
    size_t store_offset = row_ix * num_cols + col_start;
    float * ssq_start = ssq + store_offset;
    float * ssq_end = ssq_start + loc_num_cols;
    while (ssq_start != ssq_end) {
      *ssq_start /= num_frames;
      ssq_start++;
    }
  }
  return true;
}
コード例 #19
0
/**
 * @function calculateTrifocalTensor
 */
void trifocalTensor::calculateTrifocalTensor() {

  Eigen::JacobiSVD<Eigen::MatrixXf> svd( mEq, Eigen::ComputeThinU | Eigen::ComputeThinV );
  Eigen::MatrixXf V = svd.matrixV();
  printf("* V has %d rows and %d cols \n", V.rows(), V.cols() );


  Eigen::FullPivLU<Eigen::MatrixXf> lu(mEq);
  printf("* Rank of mEq is: %d \n", lu.rank() );
  //std::cout << "Columns are nullspace : " << std::endl;
  //std::cout<< lu.kernel() << std::endl;
  //Eigen::MatrixXf kernel = lu.kernel();
  //mmEq(mPointer, ToIndex1(3,1,2)=;3 = kernel.col( kernel.cols() - 1 );
  
  // Eigen::MatrixXf Vt = V.transpose(); mmEq(mPointer, ToIndex1(3,1,2)=;3 = Vt.col( Vt.cols() - 1 );
  mT123 = V.col( V.cols() - 1 );
  printf("mT123: Rows: %d  cols: %d \n", mT123.rows(), mT123.cols() );

  // Saving them properly
  mT.resize(0);
  Eigen::MatrixXf T1(3,3);
  T1(0,0) = mT123(0,0); T1(0,1) = mT123(1,0); T1(0,2) = mT123(2,0);
  T1(1,0) = mT123(3,0); T1(1,1) = mT123(4,0); T1(1,2) = mT123(5,0);
  T1(2,0) = mT123(6,0); T1(2,1) = mT123(7,0); T1(2,2) = mT123(8,0);

  mT.push_back(T1);
  printf("Saved T1 \n");

  Eigen::MatrixXf T2(3,3);
  T2(0,0) = mT123(9,0); T2(0,1) = mT123(10,0); T2(0,2) = mT123(11,0);
  T2(1,0) = mT123(12,0); T2(1,1) = mT123(13,0); T2(1,2) = mT123(14,0);
  T2(2,0) = mT123(15,0); T2(2,1) = mT123(16,0); T2(2,2) = mT123(17,0);

  mT.push_back(T2);
  printf("Saved T2 \n");

  Eigen::MatrixXf T3(3,3);
  T3(0,0) = mT123(18,0); T3(0,1) = mT123(19,0); T3(0,2) = mT123(20,0);
  T3(1,0) = mT123(21,0); T3(1,1) = mT123(22,0); T3(1,2) = mT123(23,0);
  T3(2,0) = mT123(24,0); T3(2,1) = mT123(25,0); T3(2,2) = mT123(26,0);

  mT.push_back(T3);
  printf("Saved T3 \n");

  // Checking
  Eigen::MatrixXf res = mEq*mT123;
  std::cout << "Checking mEq*T: \n"<< res.transpose() << std::endl;

  // Making it with last guy = 1
  // Normalizing
  
  for( int i = 0; i < mT.size(); ++i ) {

    float temp = mT[i](2,2);

    for( int j = 0; j < 3; ++j ) {
      for( int k = 0; k < 3; ++k ) {

	float orig = mT[i](j,k);
	mT[i](j,k) = orig / temp;

      }
    }
  }
  
  // Visualize
  for( int i = 0; i < mT.size(); ++i ) {
    std::cout << "T("<<i<<"): \n" << mT[i] << std::endl;
  }

  // Test lines
  for( int i = 0; i < mLLL.size(); ++i ) {
    Eigen::VectorXf A(3);
    Eigen::VectorXf B(3);
    Eigen::VectorXf C(3);
    Eigen::VectorXf Ap(3);

    A(0) = mLLL[i][0].x; 
    A(1) = mLLL[i][0].y; 
    A(2) = mLLL[i][0].z;

    B(0) = mLLL[i][1].x; 
    B(1) = mLLL[i][1].y; 
    B(2) = mLLL[i][1].z;
 
    C(0) = mLLL[i][2].x; 
    C(1) = mLLL[i][2].y; 
    C(2) = mLLL[i][2].z;


    Eigen::MatrixXf r0, r1, r2;
    Eigen::MatrixXf Tt;
    Tt = mT[0];
    r0 = ( B.transpose() )*Tt*C; 
    Ap(0) = r0(0,0);
    Tt = mT[1];
    r1 = ( B.transpose() )*Tt*C; 
    Ap(1) = r1(0,0);
    Tt = mT[2];
    r2 = ( B.transpose() )*Tt*C; 
    Ap(2) = r2(0,0);

    // Normalize Ap
    float temp = A(2) / Ap(2);
    float num;
    num = Ap(0)*temp; Ap(0) = num;
    num = Ap(1)*temp; Ap(1) = num;
    num = Ap(2)*temp; Ap(2) = num;

    std::cout <<" ("<<i<<") " <<" A:  " << A.transpose()  << std::endl;
    std::cout <<" ("<<i<<") " <<" Ap: " << Ap.transpose()  << std::endl;
  }
}
コード例 #20
0
ファイル: structure_from_motion.hpp プロジェクト: matt-42/vpp
void pose_estimation_from_line_correspondence(Eigen::MatrixXf start_points,
                                              Eigen::MatrixXf end_points,
                                              Eigen::MatrixXf directions,
                                              Eigen::MatrixXf points,
                                              Eigen::MatrixXf &rot_cw,
                                              Eigen::VectorXf &pos_cw)
{


    int n = start_points.cols();
    if(n != directions.cols())
    {
        return;
    }

    if(n<4)
    {
        return;
    }


    float condition_err_threshold = 1e-3;
    Eigen::VectorXf cosAngleThreshold(3);
    cosAngleThreshold << 1.1, 0.9659, 0.8660;
    Eigen::MatrixXf optimumrot_cw(3,3);
    Eigen::VectorXf optimumpos_cw(3);
    std::vector<float> lineLenVec(n,1);

    vfloat3 l1;
    vfloat3 l2;
    vfloat3 nc1;
    vfloat3 Vw1;
    vfloat3 Xm;
    vfloat3 Ym;
    vfloat3 Zm;
    Eigen::MatrixXf Rot(3,3);
    std::vector<vfloat3> nc_bar(n,vfloat3(0,0,0));
    std::vector<vfloat3> Vw_bar(n,vfloat3(0,0,0));
    std::vector<vfloat3> n_c(n,vfloat3(0,0,0));
    Eigen::MatrixXf Rx(3,3);
    int line_id;

    for(int HowToChooseFixedTwoLines = 1 ; HowToChooseFixedTwoLines <=3 ; HowToChooseFixedTwoLines++)
    {

        if(HowToChooseFixedTwoLines==1)
        {
#pragma omp parallel for
            for(int i = 0; i < n ; i++ )
            {
                // to correct
                float lineLen = 10;
                lineLenVec[i] = lineLen;
            }
            std::vector<float>::iterator result;
            result = std::max_element(lineLenVec.begin(), lineLenVec.end());
            line_id = std::distance(lineLenVec.begin(), result);
            vfloat3 temp;
            temp = start_points.col(0);
            start_points.col(0) = start_points.col(line_id);
            start_points.col(line_id) = temp;

            temp = end_points.col(0);
            end_points.col(0) = end_points.col(line_id);
            end_points.col(line_id) = temp;

            temp = directions.col(line_id);
            directions.col(0) = directions.col(line_id);
            directions.col(line_id) = temp;

            temp = points.col(0);
            points.col(0) = points.col(line_id);
            points.col(line_id) = temp;

            lineLenVec[line_id] = lineLenVec[1];
            lineLenVec[1] = 0;
            l1 = start_points.col(0) - end_points.col(0);
            l1 = l1/l1.norm();
        }


        for(int i = 1; i < n; i++)
        {
            std::vector<float>::iterator result;
            result = std::max_element(lineLenVec.begin(), lineLenVec.end());
            line_id = std::distance(lineLenVec.begin(), result);
            l2 = start_points.col(line_id) - end_points.col(line_id);
            l2 = l2/l2.norm();
            lineLenVec[line_id] = 0;
            MatrixXf cosAngle(3,3);
            cosAngle = (l1.transpose()*l2).cwiseAbs();
            if(cosAngle.maxCoeff() < cosAngleThreshold[HowToChooseFixedTwoLines])
            {
                break;
            }
        }



        vfloat3 temp;
        temp = start_points.col(1);
        start_points.col(1) = start_points.col(line_id);
        start_points.col(line_id) = temp;

        temp = end_points.col(1);
        end_points.col(1) = end_points.col(line_id);
        end_points.col(line_id) = temp;

        temp = directions.col(1);
        directions.col(1) = directions.col(line_id);
        directions.col(line_id) = temp;

        temp = points.col(1);
        points.col(1) = points.col(line_id);
        points.col(line_id) = temp;

        lineLenVec[line_id] = lineLenVec[1];
        lineLenVec[1] = 0;

        // The rotation matrix R_wc is decomposed in way which is slightly different from the description in the paper,
        // but the framework is the same.
        // R_wc = (Rot') * R * Rot =  (Rot') * (Ry(theta) * Rz(phi) * Rx(psi)) * Rot
        nc1 = x_cross(start_points.col(1),end_points.col(1));
        nc1 = nc1/nc1.norm();

        Vw1 = directions.col(1);
        Vw1 = Vw1/Vw1.norm();

        //the X axis of Model frame
        Xm = x_cross(nc1,Vw1);
        Xm = Xm/Xm.norm();

        //the Y axis of Model frame
        Ym = nc1;

        //the Z axis of Model frame
        Zm = x_cross(Xm,Zm);
        Zm = Zm/Zm.norm();

        //Rot * [Xm, Ym, Zm] = I.
        Rot.col(0) = Xm;
        Rot.col(1) = Ym;
        Rot.col(2) = Zm;

        Rot = Rot.transpose();


        //rotate all the vector by Rot.
        //nc_bar(:,i) = Rot * nc(:,i)
        //Vw_bar(:,i) = Rot * Vw(:,i)
#pragma omp parallel for
        for(int i = 0 ; i < n ; i++)
        {
            vfloat3 nc = x_cross(start_points.col(1),end_points.col(1));
            nc = nc/nc.norm();
            n_c[i] = nc;
            nc_bar[i] = Rot * nc;
            Vw_bar[i] = Rot * directions.col(i);
        }

        //Determine the angle psi, it is the angle between z axis and Vw_bar(:,1).
        //The rotation matrix Rx(psi) rotates Vw_bar(:,1) to z axis
        float cospsi = (Vw_bar[1])[2];//the angle between z axis and Vw_bar(:,1); cospsi=[0,0,1] * Vw_bar(:,1);.
        float sinpsi= sqrt(1 - cospsi*cospsi);
        Rx.row(0) = vfloat3(1,0,0);
        Rx.row(1) = vfloat3(0,cospsi,-sinpsi);
        Rx.row(2) = vfloat3(0,sinpsi,cospsi);
        vfloat3 Zaxis = Rx * Vw_bar[1];
        if(1-fabs(Zaxis[3]) > 1e-5)
        {
            Rx = Rx.transpose();
        }

        //estimate the rotation angle phi by least square residual.
        //i.e the rotation matrix Rz(phi)
        vfloat3 Vm2 = Rx * Vw_bar[1];
        float A2 = Vm2[0];
        float B2 = Vm2[1];
        float C2 = Vm2[2];
        float x2 = (nc_bar[1])[0];
        float y2 = (nc_bar[1])[1];
        float z2 = (nc_bar[1])[2];
        Eigen::PolynomialSolver<double, Eigen::Dynamic> solver;
        Eigen::VectorXf coeff(9);

        std::vector<float> coef(9,0); //coefficients of equation (7)
        Eigen::VectorXf polyDF = VectorXf::Zero(16); //%dF = ployDF(1) * t^15 + ployDF(2) * t^14 + ... + ployDF(15) * t + ployDF(16);

        //construct the  polynomial F'
#pragma omp parallel for
        for(int i = 3 ; i < n ; i++)
        {
            vfloat3 Vm3 = Rx*Vw_bar[i];
            float A3 = Vm3[0];
            float B3 = Vm3[1];
            float C3 = Vm3[2];
            float x3 = (nc_bar[i])[0];
            float y3 = (nc_bar[i])[1];
            float z3 = (nc_bar[i])[2];
            float u11 = -z2*A2*y3*B3 + y2*B2*z3*A3;
            float u12 = -y2*A2*z3*B3 + z2*B2*y3*A3;
            float u13 = -y2*B2*z3*B3 + z2*B2*y3*B3 + y2*A2*z3*A3 - z2*A2*y3*A3;
            float u14 = -y2*B2*x3*C3 + x2*C2*y3*B3;
            float u15 =  x2*C2*y3*A3 - y2*A2*x3*C3;
            float u21 = -x2*A2*y3*B3 + y2*B2*x3*A3;
            float u22 = -y2*A2*x3*B3 + x2*B2*y3*A3;
            float u23 =  x2*B2*y3*B3 - y2*B2*x3*B3 - x2*A2*y3*A3 + y2*A2*x3*A3;
            float u24 =  y2*B2*z3*C3 - z2*C2*y3*B3;
            float u25 =  y2*A2*z3*C3 - z2*C2*y3*A3;
            float u31 = -x2*A2*z3*A3 + z2*A2*x3*A3;
            float u32 = -x2*B2*z3*B3 + z2*B2*x3*B3;
            float u33 =  x2*A2*z3*B3 - z2*A2*x3*B3 + x2*B2*z3*A3 - z2*B2*x3*A3;
            float u34 =  z2*A2*z3*C3 + x2*A2*x3*C3 - z2*C2*z3*A3 - x2*C2*x3*A3;
            float u35 = -z2*B2*z3*C3 - x2*B2*x3*C3 + z2*C2*z3*B3 + x2*C2*x3*B3;
            float u36 = -x2*C2*z3*C3 + z2*C2*x3*C3;
            float a4 =   u11*u11 + u12*u12 - u13*u13 - 2*u11*u12 +   u21*u21 + u22*u22 - u23*u23
                    -2*u21*u22 - u31*u31 - u32*u32 +   u33*u33 + 2*u31*u32;
            float a3 =2*(u11*u14 - u13*u15 - u12*u14 +   u21*u24 -   u23*u25
                         - u22*u24 - u31*u34 + u33*u35 +   u32*u34);
            float a2 =-2*u12*u12 + u13*u13 + u14*u14 -   u15*u15 + 2*u11*u12 - 2*u22*u22 + u23*u23
                    + u24*u24 - u25*u25 +2*u21*u22+ 2*u32*u32 -   u33*u33
                    - u34*u34 + u35*u35 -2*u31*u32- 2*u31*u36 + 2*u32*u36;
            float a1 =2*(u12*u14 + u13*u15 +  u22*u24 +  u23*u25 -   u32*u34 - u33*u35 - u34*u36);
            float a0 =   u12*u12 + u15*u15+   u22*u22 +  u25*u25 -   u32*u32 - u35*u35 - u36*u36 - 2*u32*u36;
            float b3 =2*(u11*u13 - u12*u13 +  u21*u23 -  u22*u23 -   u31*u33 + u32*u33);
            float b2 =2*(u11*u15 - u12*u15 +  u13*u14 +  u21*u25 -   u22*u25 + u23*u24 - u31*u35 + u32*u35 - u33*u34);
            float b1 =2*(u12*u13 + u14*u15 +  u22*u23 +  u24*u25 -   u32*u33 - u34*u35 - u33*u36);
            float b0 =2*(u12*u15 + u22*u25 -  u32*u35 -  u35*u36);

            float d0 =    a0*a0 -   b0*b0;
            float d1 = 2*(a0*a1 -   b0*b1);
            float d2 =    a1*a1 + 2*a0*a2 +   b0*b0 - b1*b1 - 2*b0*b2;
            float d3 = 2*(a0*a3 +   a1*a2 +   b0*b1 - b1*b2 -   b0*b3);
            float d4 =    a2*a2 + 2*a0*a4 + 2*a1*a3 + b1*b1 + 2*b0*b2 - b2*b2 - 2*b1*b3;
            float d5 = 2*(a1*a4 +   a2*a3 +   b1*b2 + b0*b3 -   b2*b3);
            float d6 =    a3*a3 + 2*a2*a4 +   b2*b2 - b3*b3 + 2*b1*b3;
            float d7 = 2*(a3*a4 +   b2*b3);
            float d8 =    a4*a4 +   b3*b3;
            std::vector<float> v { a4, a3, a2, a1, a0, b3, b2, b1, b0 };
            Eigen::VectorXf vp;
            vp <<  a4, a3, a2, a1, a0, b3, b2, b1, b0 ;
            //coef = coef + v;
            coeff = coeff + vp;

            polyDF[0] = polyDF[0] + 8*d8*d8;
            polyDF[1] = polyDF[1] + 15* d7*d8;
            polyDF[2] = polyDF[2] + 14* d6*d8 + 7*d7*d7;
            polyDF[3] = polyDF[3] + 13*(d5*d8 +  d6*d7);
            polyDF[4] = polyDF[4] + 12*(d4*d8 +  d5*d7) +  6*d6*d6;
            polyDF[5] = polyDF[5] + 11*(d3*d8 +  d4*d7 +  d5*d6);
            polyDF[6] = polyDF[6] + 10*(d2*d8 +  d3*d7 +  d4*d6) + 5*d5*d5;
            polyDF[7] = polyDF[7] + 9 *(d1*d8 +  d2*d7 +  d3*d6  + d4*d5);
            polyDF[8] = polyDF[8] + 8 *(d1*d7 +  d2*d6 +  d3*d5) + 4*d4*d4 + 8*d0*d8;
            polyDF[9] = polyDF[9] + 7 *(d1*d6 +  d2*d5 +  d3*d4) + 7*d0*d7;
            polyDF[10] = polyDF[10] + 6 *(d1*d5 +  d2*d4) + 3*d3*d3 + 6*d0*d6;
            polyDF[11] = polyDF[11] + 5 *(d1*d4 +  d2*d3)+ 5*d0*d5;
            polyDF[12] = polyDF[12] + 4 * d1*d3 +  2*d2*d2 + 4*d0*d4;
            polyDF[13] = polyDF[13] + 3 * d1*d2 +  3*d0*d3;
            polyDF[14] = polyDF[14] + d1*d1 + 2*d0*d2;
            polyDF[15] = polyDF[15] + d0*d1;
        }


        Eigen::VectorXd coefficientPoly = VectorXd::Zero(16);

        for(int j =0; j < 16 ; j++)
        {
            coefficientPoly[j] = polyDF[15-j];
        }


        //solve polyDF
        solver.compute(coefficientPoly);
        const Eigen::PolynomialSolver<double, Eigen::Dynamic>::RootsType & r = solver.roots();
        Eigen::VectorXd rs(r.rows());
        Eigen::VectorXd is(r.rows());
        std::vector<float> min_roots;
        for(int j =0;j<r.rows();j++)
        {
            rs[j] = fabs(r[j].real());
            is[j] = fabs(r[j].imag());
        }


        float maxreal = rs.maxCoeff();

        for(int j = 0 ; j < rs.rows() ; j++ )
        {
            if(is[j]/maxreal <= 0.001)
            {
                min_roots.push_back(rs[j]);
            }
        }

        std::vector<float> temp_v(15);
        std::vector<float> poly(15);
        for(int j = 0 ; j < 15 ; j++)
        {
            temp_v[j] = j+1;
        }

        for(int j = 0 ; j < 15 ; j++)
        {
            poly[j] = polyDF[j]*temp_v[j];
        }

        Eigen::Matrix<double,16,1> polynomial;

        Eigen::VectorXd evaluation(min_roots.size());

        for( int j = 0; j < min_roots.size(); j++ )
        {
            evaluation[j] = poly_eval( polynomial, min_roots[j] );
        }


        std::vector<float> minRoots;


        for( int j = 0; j < min_roots.size(); j++ )
        {
            if(!evaluation[j]<=0)
            {
                minRoots.push_back(min_roots[j]);
            }
        }


        if(minRoots.size()==0)
        {
            cout << "No solution" << endl;
            return;
        }

        int numOfRoots = minRoots.size();
        //for each minimum, we try to find a solution of the camera pose, then
        //choose the one with the least reprojection residual as the optimum of the solution.
        float minimalReprojectionError = 100;
        // In general, there are two solutions which yields small re-projection error
        // or condition error:"n_c * R_wc * V_w=0". One of the solution transforms the
        // world scene behind the camera center, the other solution transforms the world
        // scene in front of camera center. While only the latter one is correct.
        // This can easily be checked by verifying their Z coordinates in the camera frame.
        // P_c(Z) must be larger than 0 if it's in front of the camera.



        for(int rootId = 0 ; rootId < numOfRoots ; rootId++)
        {

            float cosphi = minRoots[rootId];
            float sign1 = sign_of_number(coeff[0] * pow(cosphi,4)
                    + coeff[1] * pow(cosphi,3) + coeff[2] * pow(cosphi,2)
                    + coeff[3] * cosphi + coeff[4]);
            float  sign2 = sign_of_number(coeff[5] * pow(cosphi,3)
                    + coeff[6] * pow(cosphi,2) + coeff[7] * cosphi   + coeff[8]);
            float sinphi= -sign1*sign2*sqrt(abs(1-cosphi*cosphi));
            Eigen::MatrixXf Rz(3,3);
            Rz.row(0) = vfloat3(cosphi,-sinphi,0);
            Rz.row(1) = vfloat3(sinphi,cosphi,0);
            Rz.row(2) = vfloat3(0,0,1);
            //now, according to Sec4.3, we estimate the rotation angle theta
            //and the translation vector at a time.
            Eigen::MatrixXf RzRxRot(3,3);
            RzRxRot = Rz*Rx*Rot;


            //According to the fact that n_i^C should be orthogonal to Pi^c and Vi^c, we
            //have: scalarproduct(Vi^c, ni^c) = 0  and scalarproduct(Pi^c, ni^c) = 0.
            //where Vi^c = Rwc * Vi^w,  Pi^c = Rwc *(Pi^w - pos_cw) = Rwc * Pi^w - pos;
            //Using the above two constraints to construct linear equation system Mat about
            //[costheta, sintheta, tx, ty, tz, 1].
            Eigen::MatrixXf Matrice(2*n-1,6);
#pragma omp parallel for
            for(int i = 0 ; i < n ; i++)
            {
                float nxi = (nc_bar[i])[0];
                float nyi = (nc_bar[i])[1];
                float nzi = (nc_bar[i])[2];
                Eigen::VectorXf Vm(3);
                Vm = RzRxRot * directions.col(i);
                float Vxi = Vm[0];
                float Vyi = Vm[1];
                float Vzi = Vm[2];
                Eigen::VectorXf Pm(3);
                Pm = RzRxRot * points.col(i);
                float Pxi = Pm(1);
                float Pyi = Pm(2);
                float Pzi = Pm(3);
                //apply the constraint scalarproduct(Vi^c, ni^c) = 0
                //if i=1, then scalarproduct(Vi^c, ni^c) always be 0
                if(i>1)
                {
                    Matrice(2*i-3, 0) = nxi * Vxi + nzi * Vzi;
                    Matrice(2*i-3, 1) = nxi * Vzi - nzi * Vxi;
                    Matrice(2*i-3, 5) = nyi * Vyi;
                }
                //apply the constraint scalarproduct(Pi^c, ni^c) = 0
                Matrice(2*i-2, 0) = nxi * Pxi + nzi * Pzi;
                Matrice(2*i-2, 1) = nxi * Pzi - nzi * Pxi;
                Matrice(2*i-2, 2) = -nxi;
                Matrice(2*i-2, 3) = -nyi;
                Matrice(2*i-2, 4) = -nzi;
                Matrice(2*i-2, 5) = nyi * Pyi;
            }

            //solve the linear system Mat * [costheta, sintheta, tx, ty, tz, 1]' = 0  using SVD,
            JacobiSVD<MatrixXf> svd(Matrice, ComputeThinU | ComputeThinV);
            Eigen::MatrixXf VMat = svd.matrixV();
            Eigen::VectorXf vec(2*n-1);
            //the last column of Vmat;
            vec = VMat.col(5);
            //the condition that the last element of vec should be 1.
            vec = vec/vec[5];
            //the condition costheta^2+sintheta^2 = 1;
            float normalizeTheta = 1/sqrt(vec[0]*vec[1]+vec[1]*vec[1]);
            float costheta = vec[0]*normalizeTheta;
            float sintheta = vec[1]*normalizeTheta;
            Eigen::MatrixXf Ry(3,3);
            Ry << costheta, 0, sintheta , 0, 1, 0 , -sintheta, 0, costheta;

            //now, we get the rotation matrix rot_wc and translation pos_wc
            Eigen::MatrixXf rot_wc(3,3);
            rot_wc = (Rot.transpose()) * (Ry * Rz * Rx) * Rot;
            Eigen::VectorXf pos_wc(3);
            pos_wc = - Rot.transpose() * vec.segment(2,4);

            //now normalize the camera pose by 3D alignment. We first translate the points
            //on line in the world frame Pw to points in the camera frame Pc. Then we project
            //Pc onto the line interpretation plane as Pc_new. So we could call the point
            //alignment algorithm to normalize the camera by aligning Pc_new and Pw.
            //In order to improve the accuracy of the aligment step, we choose two points for each
            //lines. The first point is Pwi, the second point is  the closest point on line i to camera center.
            //(Pw2i = Pwi - (Pwi'*Vwi)*Vwi.)
            Eigen::MatrixXf Pw2(3,n);
            Pw2.setZero();
            Eigen::MatrixXf Pc_new(3,n);
            Pc_new.setZero();
            Eigen::MatrixXf Pc2_new(3,n);
            Pc2_new.setZero();

            for(int i = 0 ; i < n ; i++)
            {
                vfloat3 nci = n_c[i];
                vfloat3 Pwi = points.col(i);
                vfloat3 Vwi = directions.col(i);
                //first point on line i
                vfloat3 Pci;
                Pci = rot_wc * Pwi + pos_wc;
                Pc_new.col(i) = Pci - (Pci.transpose() * nci) * nci;
                //second point is the closest point on line i to camera center.
                vfloat3 Pw2i;
                Pw2i = Pwi - (Pwi.transpose() * Vwi) * Vwi;
                Pw2.col(i) = Pw2i;
                vfloat3 Pc2i;
                Pc2i = rot_wc * Pw2i + pos_wc;
                Pc2_new.col(i) = Pc2i - ( Pc2i.transpose() * nci ) * nci;
            }

            MatrixXf XXc(Pc_new.rows(), Pc_new.cols()+Pc2_new.cols());
            XXc << Pc_new, Pc2_new;
            MatrixXf XXw(points.rows(), points.cols()+Pw2.cols());
            XXw << points, Pw2;
            int nm = points.cols()+Pw2.cols();
            cal_campose(XXc,XXw,nm,rot_wc,pos_wc);
            pos_cw = -rot_wc.transpose() * pos_wc;

            //check the condition n_c^T * rot_wc * V_w = 0;
            float conditionErr = 0;
            for(int i =0 ; i < n ; i++)
            {
                float val = ( (n_c[i]).transpose() * rot_wc * directions.col(i) );
                conditionErr = conditionErr + val*val;
            }

            if(conditionErr/n < condition_err_threshold || HowToChooseFixedTwoLines ==3)
            {
                //check whether the world scene is in front of the camera.
                int numLineInFrontofCamera = 0;
                if(HowToChooseFixedTwoLines<3)
                {
                    for(int i = 0 ; i < n ; i++)
                    {
                        vfloat3 P_c = rot_wc * (points.col(i) - pos_cw);
                        if(P_c[2]>0)
                        {
                            numLineInFrontofCamera++;
                        }
                    }
                }
                else
                {
                    numLineInFrontofCamera = n;
                }

                if(numLineInFrontofCamera > 0.5*n)
                {
                    //most of the lines are in front of camera, then check the reprojection error.
                    int reprojectionError = 0;
                    for(int i =0; i < n ; i++)
                    {
                        //line projection function
                        vfloat3 nc = rot_wc * x_cross(points.col(i) - pos_cw , directions.col(i));
                        float h1 = nc.transpose() * start_points.col(i);
                        float h2 = nc.transpose() * end_points.col(i);
                        float lineLen = (start_points.col(i) - end_points.col(i)).norm()/3;
                        reprojectionError += lineLen * (h1*h1 + h1*h2 + h2*h2) / (nc[0]*nc[0]+nc[1]*nc[1]);
                    }
                    if(reprojectionError < minimalReprojectionError)
                    {
                        optimumrot_cw = rot_wc.transpose();
                        optimumpos_cw = pos_cw;
                        minimalReprojectionError = reprojectionError;
                    }
                }
            }
        }
        if(optimumrot_cw.rows()>0)
        {
            break;
        }
    }
    pos_cw = optimumpos_cw;
    rot_cw = optimumrot_cw;
}
コード例 #21
0
ファイル: structure_from_motion.hpp プロジェクト: matt-42/vpp
inline
void cal_campose(Eigen::MatrixXf XXc,Eigen::MatrixXf XXw,
                int n,Eigen::MatrixXf &R2,Eigen::VectorXf &t2)
{
    //A
    Eigen::MatrixXf X = XXw;
    //B
    Eigen::MatrixXf Y = XXc;
    Eigen::MatrixXf eyen(n,n);
    eyen = Eigen::MatrixXf::Identity(n,n);
    Eigen::MatrixXf ones(n,n);
    ones.setOnes();
    Eigen::MatrixXf K(n,n);
    K = eyen - ones/n;


    vfloat3 ux;
    for(int i =0; i < n; i++)
    {
        ux = ux + X.col(i);
    }
    ux = ux/n;
    vfloat3 uy;
    for(int i =0; i < n; i++)
    {
        uy = uy + Y.col(i);
    }
    uy = uy/n;
    Eigen::MatrixXf XK(3,n);
    XK = X*K;
    Eigen::MatrixXf XKarre(3,n);
    for(int i = 0 ; i < n ; i++)
    {
        XKarre(0,i) = XK(0,i)*XK(0,i);
        XKarre(1,i) = XK(1,i)*XK(1,i);
        XKarre(2,i) = XK(2,i)*XK(2,i);
    }
    Eigen::VectorXf sumXKarre(n);
    float sigmx2 = 0;
    for(int i = 0 ; i < n ; i++)
    {
        sumXKarre[i] = XKarre(0,i) + XKarre(1,i) + XKarre(2,i);
        sigmx2 += sumXKarre[i];
    }
    sigmx2 /=n;
    Eigen::MatrixXf SXY(3,3);
    SXY = Y*K*(X.transpose())/n;
    JacobiSVD<MatrixXf> svd(SXY, ComputeThinU | ComputeThinV);
    Eigen::MatrixXf S(3,3);
    S = Eigen::MatrixXf::Identity(3,3);

    if(SXY.determinant() < 0)
    {
        S(3,3) = -1;
    }

    R2 = svd.matrixU() * S * (svd.matrixV()).transpose();

    Eigen::MatrixXf D(3,3);
    D.setZero();

    for(int i = 0 ; i < svd.singularValues().size() ; i++)
    {
        D(i,i) = (svd.singularValues())[i];
    }

    float c2 = (D*S).trace()/sigmx2;
    t2 = uy - c2*R2*ux;

    vfloat3 Xx = R2.col(0);
    vfloat3 Yy = R2.col(1);
    vfloat3 Zz = R2.col(2);

    if((x_cross(Xx,Yy)-Zz).norm()>2e-2)
    {
        R2.col(2) = -Zz;
    }
}
コード例 #22
0
ファイル: rt_dlt.cpp プロジェクト: chrisluu/PoseEstimation
Eigen::Matrix<double,6,1> rt_dlt(const Eigen::MatrixX3f & obj_pts,const Eigen::MatrixX3f & proj_pts)
{
  //Check the number of points that we have available as inputs
  //Demand that there be atleast 6 points input.
    if(obj_pts.rows()<6)
    {
        std::cout << "Need a minimum of 6 points\n";
    }
    if(obj_pts.rows()!=proj_pts.rows())
    {
        std::cout << "Need and equal nummber of Object Points and Normalized Projection Points\n";
    }

    //To ensure numerical stability, we expect the model coordinates to be well behaved as well
    //(Small values, close to 1)

    //Create a vector of size 12, that would hold the rotation and translation elements, estimate
    //it using DLT (SVD and other magic)
    Eigen::VectorXf v(12);
    Eigen::MatrixXf M(2*obj_pts.rows(),12);
    //
    //See http://www.maths.lth.se/matematiklth/personal/calle/datorseende13/notes/forelas3.pdf for
    //details
    //Populate M
    for(int i=0; i< obj_pts.rows(); i++)
    {
        //Eigen::RowVectorXf & Xrow(12);
        //Xrow = M.row(2*i);
        //Eigen::RowVectorXf & Yrow(12);
        //Yrow= M.row(2*i+1);
        Eigen::Vector3f ob_pt = obj_pts.row(i);
        Eigen::Vector3f pr_pt = proj_pts.row(i);

        M(2*i,0) = ob_pt(0);            //-X
        M(2*i,1) = ob_pt(1);            //-Y
        M(2*i,2) = ob_pt(2);            //-Z
        M(2*i,3) = 0;
        M(2*i,4) = 0;
        M(2*i,5) = 0;
        M(2*i,6) = -ob_pt(0)*pr_pt(0);    //Xx
        M(2*i,7) = -ob_pt(1)*pr_pt(0);    //Yx
        M(2*i,8) = -ob_pt(2)*pr_pt(0);    //Zx
        M(2*i,9) = 1;
        M(2*i,10) = 0;
        M(2*i,11) = -pr_pt(0);            //x

        M(2*i+1,3) = ob_pt(0);            //-X
        M(2*i+1,4) = ob_pt(1);            //-Y
        M(2*i+1,5) = ob_pt(2);            //-Z
        M(2*i+1,0) = 0;
        M(2*i+1,1) = 0;
        M(2*i+1,2) = 0;
        M(2*i+1,6) = -ob_pt(0)*pr_pt(1);    //Xy
        M(2*i+1,7) = -ob_pt(1)*pr_pt(1);    //Yy
        M(2*i+1,8) = -ob_pt(2)*pr_pt(1);    //Zy
        M(2*i+1,9) = 0;
        M(2*i+1,10) = 1;
        M(2*i+1,11) = -pr_pt(1);            //y

    }

    //Compute M'M
    Eigen::MatrixXf MTM;
    MTM = M.transpose()*M;

    //Do SVD of MTM
    Eigen::JacobiSVD<Eigen::MatrixXf> svd(MTM, Eigen::ComputeThinU);
    //Get the eigenvector corresponding to the smallest eigenvalue
    Eigen::MatrixXf MatU = svd.matrixU();
    int nz_num = svd.nonzeroSingularValues();
    v = MatU.col(nz_num - 1);
    float scale = v(0)*v(0)+v(1)*v(1)+v(2)*v(2)+v(3)*v(3)+v(4)*v(4)+v(5)*v(5)+v(6)*v(6)+v(7)*v(7)+v(8)*v(8);
    scale/=3;
    scale = pow(scale,0.5);
    //Take care of scaling
    v = v /scale;
    //std::cout<<"Size of U"<<MatU.rows()<<" "<<MatU.cols()<<"\n";
    std::cout<<"V: "<<v.transpose()<<"\n";
    Eigen::Matrix3f rot_mat;
    rot_mat<< v(0),v(1),v(2),v(3),v(4),v(5),v(6),v(7),v(8);
    Eigen::Vector3f euler = rot_mat.eulerAngles(2,1,0);
     //The vector to be returned carries 3 euler angles and 3 translation elements
    Eigen::VectorXd x(6);
    x<< v(9),v(10),v(11),euler(0),euler(1),euler(2);
    return(x);

}