void PointCloudProcessing::getRTGeometricLinearSystem(PointCloudC::Ptr corrRef,
                                                      PointCloudC::Ptr corrNew,
                                                      Eigen::Matrix4f &transMat)
{
  // build linear system Ax = b;
  int rows = 3*corrRef->points.size();
  int cols = 6;
  Eigen::MatrixXf A(rows, cols); A.setZero();
  Eigen::MatrixXf b(rows, 1); b.setZero();
  for(int i=0; i<corrRef->points.size(); i++)
    {
      float X1 = corrRef->points.at(i).x;
      float Y1 = corrRef->points.at(i).y;
      float Z1 = corrRef->points.at(i).z;
      float X0 = corrNew->points.at(i).x;
      float Y0 = corrNew->points.at(i).y;
      float Z0 = corrNew->points.at(i).z;
      A(3*i,   0) = 0;      A(3*i,   1) = Z0+Z1;  A(3*i,   2) = -Y0-Y1; A(3*i,   3) = 1;
      A(3*i+1, 0) = -Z0-Z1; A(3*i+1, 1) = 0;      A(3*i+1, 2) = X0+X1;  A(3*i+1, 4) = 1;
      A(3*i+2, 0) = Y0+Y1;  A(3*i+1, 1) = -X0-X1; A(3*i+2, 2) = 0;      A(3*i+2, 5) = 1;

      b(3*i,   0) = X1-X0;
      b(3*i+1, 0) = Y1-Y0;
      b(3*i+2, 0) = Z1-Z0;
    }
  //    std::cout<<"A = "<<A<<std::endl;
  //    std::cout<<"b = "<<b<<std::endl;
  Eigen::MatrixXf solveX(rows, 1); solveX.setZero();
  solveX = A.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b);
  //    std::cout<<"solveX: "<<solveX<<"\n";

  // solveX = [Rx, Ry, Rz, T'x, T'y, T'z];
  Eigen::Matrix3f I_Vx; I_Vx.setOnes();
  I_Vx(0,0) = 1;          I_Vx(0,1) = solveX(2);  I_Vx(0,2) = -solveX(1);
  I_Vx(1,0) = -solveX(2); I_Vx(1,1) = 1;          I_Vx(1,2) = solveX(0);
  I_Vx(2,0) = solveX(1);  I_Vx(2,1) = -solveX(0); I_Vx(2,2) = 1;
  Eigen::Vector3f Tx; Tx.setZero();
  Tx(0) = solveX(3); Tx(1) = solveX(4); Tx(2) = solveX(5);
  Eigen::Vector3f tx; tx.setZero();
  tx = I_Vx.inverse()*Tx;
  transMat(0,3) = tx(0); transMat(1,3) = tx(1); transMat(2,3) = tx(2);

  Eigen::Matrix3f IplusVx; IplusVx.setOnes();
  IplusVx(0,0) = 1;          IplusVx(0,1) = -solveX(2);  IplusVx(0,2) = solveX(1);
  IplusVx(1,0) = solveX(2);  IplusVx(1,1) = 1;           IplusVx(1,2) = -solveX(0);
  IplusVx(2,0) = -solveX(1); IplusVx(2,1) = solveX(0);   IplusVx(2,2) = 1;
  Eigen::Matrix3f Ro; Ro.setZero();
  Ro = I_Vx.inverse()*IplusVx;
  transMat(0,0) = Ro(0,0); transMat(0,1) = Ro(0,1); transMat(0,2) = Ro(0,2); transMat(0,3) = tx(0);
  transMat(1,0) = Ro(1,0); transMat(1,1) = Ro(1,1); transMat(1,2) = Ro(1,2); transMat(1,3) = tx(1);
  transMat(2,0) = Ro(2,0); transMat(2,1) = Ro(2,1); transMat(2,2) = Ro(2,2); transMat(2,3) = tx(2);
  //    std::cout<<"transMat Geometric: "<<transMat<<"\n";
}
Example #2
0
  /** \brief Computes the gradient parameters of the patch (patch gradient components dx_ dy_, Hessian H_, Shi-Tomasi Score s_, Eigenvalues of the Hessian e0_ and e1_).
   *         The expanded patch patchWithBorder_ must be set.
   *         Sets validGradientParameters_ afterwards to true.
   */
  void computeGradientParameters() const{
    if(!validGradientParameters_){
      H_.setZero();
      const int refStep = patchSize+2;
      float* it_dx = dx_;
      float* it_dy = dy_;
      const float* it;
      Eigen::Vector3f J;
      J.setZero();
      for(int y=0; y<patchSize; ++y){
        it = patchWithBorder_ + (y+1)*refStep + 1;
        for(int x=0; x<patchSize; ++x, ++it, ++it_dx, ++it_dy){
          J[0] = 0.5 * (it[1] - it[-1]);
          J[1] = 0.5 * (it[refStep] - it[-refStep]);
          J[2] = 1;
          *it_dx = J[0];
          *it_dy = J[1];
          H_ += J*J.transpose();
        }
      }
      const float dXX = H_(0,0)/(patchSize*patchSize);
      const float dYY = H_(1,1)/(patchSize*patchSize);
      const float dXY = H_(0,1)/(patchSize*patchSize);

      e0_ = 0.5 * (dXX + dYY - sqrtf((dXX + dYY) * (dXX + dYY) - 4 * (dXX * dYY - dXY * dXY)));
      e1_ = 0.5 * (dXX + dYY + sqrtf((dXX + dYY) * (dXX + dYY) - 4 * (dXX * dYY - dXY * dXY)));
      s_ = e0_;
      validGradientParameters_ = true;
    }
  }
Example #3
0
Eigen::Vector3f RobotNodeSet::getCoM()
{
	Eigen::Vector3f res;
	res.setZero();

	float m = getMass();
	if (m<=0)
		return res;

	for (size_t i=0;i<this->robotNodes.size();i++)
		res += robotNodes[i]->getCoMGlobal() * robotNodes[i]->getMass() / m;

	return res;
}
/**
 * ComputeCentroid
 */
void RigidTransformationRANSAC::ComputeCentroid(
      const std::vector<Eigen::Vector3f > &pts, 
      const std::vector<int> &indices,
      Eigen::Vector3f &centroid)
{
  // Initialize to 0
  centroid.setZero ();
  if (pts.size()==0 || indices.size()==0)
    return;

  for (unsigned i = 0; i < indices.size (); i++)
    centroid += pts[indices[i]];

  centroid /= indices.size ();
}
int PatternDetector::detectPattern(cv::Mat& image_in, Eigen::Vector3f& translation, Eigen::Quaternionf& orientation,
                                   cv::Mat& image_out)
{
  translation.setZero();
  orientation.setIdentity();

  bool found = false;

  observation_pts_t observation_points;

  switch (pattern_type)
  {
    case ASYMMETRIC_CIRCLES_GRID:
      found = cv::findCirclesGrid(image_in, grid_size, observation_points,
                                  cv::CALIB_CB_ASYMMETRIC_GRID | cv::CALIB_CB_CLUSTERING);
      break;
    case CHESSBOARD:
      found = cv::findChessboardCorners(image_in, grid_size, observation_points, cv::CALIB_CB_ADAPTIVE_THRESH);
      break;
    case CIRCLES_GRID:
      found = cv::findCirclesGrid(image_in, grid_size, observation_points, cv::CALIB_CB_SYMMETRIC_GRID);
      break;
  }

  if (found)
  {
    // Do subpixel ONLY IF THE PATTERN IS A CHESSBOARD
    if (pattern_type == CHESSBOARD)
    {
      cv::cornerSubPix(image_in, observation_points, cv::Size(5, 5), cv::Size(-1, -1),
                       cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 100, 0.01));
    }

    cv::solvePnP(cv::Mat(ideal_points), cv::Mat(observation_points), K, D, rvec, tvec, false);
    cv::Rodrigues(rvec, R); //take the 3x1 rotation representation to a 3x3 rotation matrix.

    cv::drawChessboardCorners(image_out, grid_size, cv::Mat(observation_points), found);

    convertCVtoEigen(tvec, R, translation, orientation);
  }

  return found;
}
Example #6
0
/**
 * ComputeNormal
 */
float ZAdaptiveNormals::computeNormal(const v4r::DataMatrix2D<Eigen::Vector3f> &cloud, std::vector<int> &indices, Eigen::Matrix3f &eigen_vectors)
{
  if (indices.size()<4)
    return NaN;

  Eigen::Vector3f mean;
  mean.setZero();
  for (unsigned j=0; j<indices.size(); j++)
    mean += cloud.data[indices[j]];
  mean /= (float)indices.size();

  Eigen::Matrix3f cov;
  computeCovarianceMatrix (cloud, indices, mean, cov);

  Eigen::Vector3f eigen_values;
  v4r::eigen33 (cov, eigen_vectors, eigen_values);
  float eigsum = eigen_values.sum();
  if (eigsum != 0)
    return fabs (eigen_values[0] / eigsum );
  
  return NaN;
}
Example #7
0
File: board.hpp Project: 2php/pcl
template<typename PointInT, typename PointNT, typename PointOutT> void
pcl::BOARDLocalReferenceFrameEstimation<PointInT, PointNT, PointOutT>::planeFitting (
                                                                                     Eigen::Matrix<float,
                                                                                         Eigen::Dynamic, 3> const &points,
                                                                                     Eigen::Vector3f &center,
                                                                                     Eigen::Vector3f &norm)
{
  // -----------------------------------------------------
  // Plane Fitting using Singular Value Decomposition (SVD)
  // -----------------------------------------------------

  int n_points = static_cast<int> (points.rows ());
  if (n_points == 0)
  {
    return;
  }

  //find the center by averaging the points positions
  center.setZero ();

  for (int i = 0; i < n_points; ++i)
  {
    center += points.row (i);
  }

  center /= static_cast<float> (n_points);

  //copy points - average (center)
  Eigen::Matrix<float, Eigen::Dynamic, 3> A (n_points, 3); //PointData
  for (int i = 0; i < n_points; ++i)
  {
    A (i, 0) = points (i, 0) - center.x ();
    A (i, 1) = points (i, 1) - center.y ();
    A (i, 2) = points (i, 2) - center.z ();
  }

  Eigen::JacobiSVD<Eigen::MatrixXf> svd (A, Eigen::ComputeFullV);
  norm = svd.matrixV ().col (2);
}
Example #8
0
/**
 * estimatePlaneLS
 * least squares estimation of a plan using points defined by indices
 */
void PlaneEstimationRANSAC::estimatePlaneLS(const std::vector<Eigen::Vector3f> &pts, const std::vector<int> &indices, Eigen::Vector3f &pt, Eigen::Vector3f &n)
{
  Eigen::Vector3f mean;
  EIGEN_ALIGN16 Eigen::Matrix3f cov;
  

  mean.setZero();

  for (unsigned j=0; j<indices.size(); j++)
    mean += pts[indices[j]];

  mean /= (float)indices.size();

  computeCovarianceMatrix(pts, indices, mean, cov);

  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> sv(cov);
  Eigen::Matrix3f eigen_vectors = sv.eigenvectors();

  n[0] = eigen_vectors(0,0);
  n[1] = eigen_vectors(1,0);
  n[2] = eigen_vectors(2,0);
}
Example #9
0
Eigen::Vector3f& MyPointCloud::getCentroid() {
	
	DeviceArray2D<pcl::PointXYZ> cloudDevice;
	pcl::PointCloud<PointXYZ>::Ptr hostFrameCloud;

	this->getLastFrameCloud(cloudDevice);

	int c;
	hostFrameCloud = PointCloud<PointXYZ>::Ptr (new PointCloud<PointXYZ>);
	cloudDevice.download (hostFrameCloud->points, c);
	hostFrameCloud->width = cloudDevice.cols ();
	hostFrameCloud->height = cloudDevice.rows ();
	
	Eigen::Vector3f centroid;
	centroid.setZero();

	int count = 0;
	for(int point = 0; point < hostFrameCloud->points.size(); point++) {

		if(hostFrameCloud->points[point].z == hostFrameCloud->points[point].z) {
			
			if(hostFrameCloud->points[point].z != 0) {

				centroid(0) += hostFrameCloud->points[point].x;
				centroid(1) += hostFrameCloud->points[point].y;
				centroid(2) += hostFrameCloud->points[point].z;
				count++;
			
			}

		}

	}

	centroid /= count;
	return centroid;

}
void PointWithNormalStatistcsGenerator::computeNormalsAndSVD(PointWithNormalVector& points, PointWithNormalSVDVector& svds, const Eigen::MatrixXi& indices, 
							     const Eigen::Matrix3f& cameraMatrix, const Eigen::Isometry3f& transform){
  _integralImage.compute(indices,points);
  int q=0;
  int outerStep = _numThreads * _step;
  PixelMapper pixelMapper;
  pixelMapper.setCameraMatrix(cameraMatrix);
  pixelMapper.setTransform(transform);
  Eigen::Isometry3f inverseTransform = transform.inverse();
  #pragma omp parallel
  {
#ifdef _PWN_USE_OPENMP_
    int threadNum = omp_get_thread_num();
#else // _PWN_USE_OPENMP_
    int threadNum = 0; 
    Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigenSolver;
#endif // _PWN_USE_OPENMP_

    for (int c=threadNum; c<indices.cols(); c+=outerStep) {
#ifdef _PWN_USE_OPENMP_
      Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigenSolver;
#endif // _PWN_USE_OPENMP_
      for (int r=0; r<indices.rows(); r+=_step, q++){
	int index  = indices(r,c);
	//cerr << "index("  << r <<"," << c << ")=" << index <<  endl;
	if (index<0)
	  continue;
	// determine the region
	PointWithNormal& point = points[index];
	PointWithNormalSVD& originalSVD = svds[index];
	PointWithNormalSVD svd;
	Eigen::Vector3f normal = point.normal();
	Eigen::Vector3f coord = pixelMapper.projectPoint(point.point()+Eigen::Vector3f(_worldRadius, _worldRadius, 0));
	svd._z=point(2);

	coord.head<2>()*=(1./coord(2));
	int dx = abs(c - coord[0]);
	int dy = abs(r - coord[1]);
	if (dx>_imageRadius)
	  dx = _imageRadius;
	if (dy>_imageRadius)
	  dy = _imageRadius;
	PointAccumulator acc = _integralImage.getRegion(c-dx, c+dx, r-dy, r+dy);
	svd._mean=point.point();
	if (acc.n()>_minPoints){
	  Eigen::Vector3f mean = acc.mean();
	  svd._mean = mean;
	  svd._n = acc.n();
	  Eigen::Matrix3f cov  = acc.covariance();
	  eigenSolver.compute(cov);
	  svd._U=eigenSolver.eigenvectors();
	  svd._singularValues=eigenSolver.eigenvalues();
	  if (svd._singularValues(0) <0)
	    svd._singularValues(0) = 0;
	  /*
	    cerr << "\t svd.singularValues():" << svd.singularValues() << endl;
	    cerr << "\t svd.U():" << endl << svd.U() << endl;
	    //cerr << "\t svd.curvature():" << svd.curvature() << endl;
	
	    */
	

	  normal = eigenSolver.eigenvectors().col(0).normalized();
	  if (normal.dot(inverseTransform * mean) > 0.0f)
	    normal =-normal;
	  svd.updateCurvature();
	  //cerr << "n(" << index << ") c:"  << svd.curvature() << endl << point.tail<3>() << endl;
	  if (svd.curvature()>_maxCurvature){
	    //cerr << "region: " << c-dx << " " <<  c+dx << " " <<  r-dx << " " << r+dx << " points: " << acc.n() << endl;
	    normal.setZero();
	  } 
	} else {
	  normal.setZero();
	  svd = PointWithNormalSVD();
	}
	if (svd.n() > originalSVD.n()){
	  originalSVD = svd;
	  point.setNormal(normal);
	}
      } 
    }
  }
}
Example #11
0
template <typename PointInT, typename PointNT, typename PointOutT, typename IntensitySelectorT> void
pcl::IntensityGradientEstimation<PointInT, PointNT, PointOutT, IntensitySelectorT>::computeFeature (PointCloudOut &output)
{
  // Allocate enough space to hold the results
  // \note This resize is irrelevant for a radiusSearch ().
  std::vector<int> nn_indices (k_);
  std::vector<float> nn_dists (k_);
  output.is_dense = true;

  // If the data is dense, we don't need to check for NaN
  if (surface_->is_dense)
  {
#ifdef _OPENMP
#pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(threads_)
#endif
    // Iterating over the entire index vector
    for (int idx = 0; idx < static_cast<int> (indices_->size ()); ++idx)
    {
      PointOutT &p_out = output.points[idx];

      if (!this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists))
      {
        p_out.gradient[0] = p_out.gradient[1] = p_out.gradient[2] = std::numeric_limits<float>::quiet_NaN ();
        output.is_dense = false;
        continue;
      }

      Eigen::Vector3f centroid;
      float mean_intensity = 0;
      // Initialize to 0
      centroid.setZero ();
      for (size_t i = 0; i < nn_indices.size (); ++i)
      {
        centroid += surface_->points[nn_indices[i]].getVector3fMap ();
        mean_intensity += intensity_ (surface_->points[nn_indices[i]]);
      }
      centroid /= static_cast<float> (nn_indices.size ());
      mean_intensity /= static_cast<float> (nn_indices.size ());

      Eigen::Vector3f normal = Eigen::Vector3f::Map (normals_->points[(*indices_) [idx]].normal);
      Eigen::Vector3f gradient;
      computePointIntensityGradient (*surface_, nn_indices, centroid, mean_intensity, normal, gradient);

      p_out.gradient[0] = gradient[0];
      p_out.gradient[1] = gradient[1];
      p_out.gradient[2] = gradient[2];
    }
  }
  else
  {
#ifdef _OPENMP
#pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(threads_)
#endif
    // Iterating over the entire index vector
    for (int idx = 0; idx < static_cast<int> (indices_->size ()); ++idx)
    {
      PointOutT &p_out = output.points[idx];
      if (!isFinite ((*surface_) [(*indices_)[idx]]) ||
          !this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists))
      {
        p_out.gradient[0] = p_out.gradient[1] = p_out.gradient[2] = std::numeric_limits<float>::quiet_NaN ();
        output.is_dense = false;
        continue;
      }
      Eigen::Vector3f centroid;
      float mean_intensity = 0;
      // Initialize to 0
      centroid.setZero ();
      unsigned cp = 0;
      for (size_t i = 0; i < nn_indices.size (); ++i)
      {
        // Check if the point is invalid
        if (!isFinite ((*surface_) [nn_indices[i]]))
          continue;

        centroid += surface_->points [nn_indices[i]].getVector3fMap ();
        mean_intensity += intensity_ (surface_->points [nn_indices[i]]);
        ++cp;
      }
      centroid /= static_cast<float> (cp);
      mean_intensity /= static_cast<float> (cp);
      Eigen::Vector3f normal = Eigen::Vector3f::Map (normals_->points[(*indices_) [idx]].normal);
      Eigen::Vector3f gradient;
      computePointIntensityGradient (*surface_, nn_indices, centroid, mean_intensity, normal, gradient);

      p_out.gradient[0] = gradient[0];
      p_out.gradient[1] = gradient[1];
      p_out.gradient[2] = gradient[2];
    }
  }
}
bool  PositionBasedElasticRod::ProjectEdgeConstraints(
	const Eigen::Vector3f& pA, const float wA, 
	const Eigen::Vector3f& pB, const float wB, 
	const Eigen::Vector3f& pG, const float wG,
	const float edgeKs, const float edgeRestLength, const float ghostEdgeRestLength,
	Eigen::Vector3f& corrA, Eigen::Vector3f&  corrB, Eigen::Vector3f&  corrC)
{
	corrA.setZero(); corrB.setZero(); corrC.setZero();

	//Edge distance constraint
	Eigen::Vector3f dir = pA - pB;
	float len = dir.norm();

	float wSum = wA + wB;
	if (len > EPSILON && wSum > EPSILON)
	{
		Eigen::Vector3f dP = (1.0f / wSum) * (len - edgeRestLength) * (dir / len) * edgeKs;

		corrA -= dP * wA;
		corrB += dP * wB;
		corrC = Eigen::Vector3f(0, 0, 0);
	}

	//Bisector constraint
	Eigen::Vector3f pm = 0.5f * (pA + pB);
	Eigen::Vector3f p0p2 = pA - pG;
	Eigen::Vector3f p2p1 = pG - pB;
	Eigen::Vector3f p1p0 = pB - pA;
	Eigen::Vector3f p2pm = pG - pm;
	float lambda;

	wSum = wA * p0p2.squaredNorm() + wB * p2p1.squaredNorm() + wG * p1p0.squaredNorm();
	if (wSum > EPSILON)
	{
		lambda = p2pm.dot(p1p0) / wSum * edgeKs;

		corrA -= p0p2 * lambda * wA;
		corrB -= p2p1 * lambda * wB;
		corrC -= p1p0 * lambda * wG;
	}

	////Ghost-Edge constraint
	wSum = 0.25f * wA + 0.25f * wB + 1.0f * wG;

	if (wSum > EPSILON)
	{
		//need to use updated positions
		pm = 0.5f * (pA + corrA + pB + corrB);
		p2pm = pG + corrC - pm;

		float p2pm_mag = p2pm.norm();
		p2pm *= 1.0f / p2pm_mag;

		lambda = (p2pm_mag - ghostEdgeRestLength) / wSum * edgeKs;

		corrA += 0.5f * wA * lambda * p2pm;
		corrB += 0.5f * wB * lambda * p2pm;
		corrC -= 1.0f * wG * lambda * p2pm;
	}


	return true;
}