Esempio n. 1
0
File: fpfh.hpp Progetto: Bardo91/pcl
template <typename PointInT, typename PointNT, typename PointOutT> void
pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computeSPFHSignatures (std::vector<int> &spfh_hist_lookup,
    Eigen::MatrixXf &hist_f1, Eigen::MatrixXf &hist_f2, Eigen::MatrixXf &hist_f3)
{
  // Allocate enough space to hold the NN search results
  // \note This resize is irrelevant for a radiusSearch ().
  std::vector<int> nn_indices (k_);
  std::vector<float> nn_dists (k_);

  std::set<int> spfh_indices;
  spfh_hist_lookup.resize (surface_->points.size ());

  // Build a list of (unique) indices for which we will need to compute SPFH signatures
  // (We need an SPFH signature for every point that is a neighbor of any point in input_[indices_])
  if (surface_ != input_ ||
      indices_->size () != surface_->points.size ())
  { 
    for (size_t idx = 0; idx < indices_->size (); ++idx)
    {
      int p_idx = (*indices_)[idx];
      if (this->searchForNeighbors (p_idx, search_parameter_, nn_indices, nn_dists) == 0)
        continue;

      spfh_indices.insert (nn_indices.begin (), nn_indices.end ());
    }
  }
  else
  {
    // Special case: When a feature must be computed at every point, there is no need for a neighborhood search
    for (size_t idx = 0; idx < indices_->size (); ++idx)
      spfh_indices.insert (static_cast<int> (idx));
  }

  // Initialize the arrays that will store the SPFH signatures
  size_t data_size = spfh_indices.size ();
  hist_f1.setZero (data_size, nr_bins_f1_);
  hist_f2.setZero (data_size, nr_bins_f2_);
  hist_f3.setZero (data_size, nr_bins_f3_);

  // Compute SPFH signatures for every point that needs them
  std::set<int>::iterator spfh_indices_itr = spfh_indices.begin ();
  for (int i = 0; i < static_cast<int> (spfh_indices.size ()); ++i)
  {
    // Get the next point index
    int p_idx = *spfh_indices_itr;
    ++spfh_indices_itr;

    // Find the neighborhood around p_idx
    if (this->searchForNeighbors (*surface_, p_idx, search_parameter_, nn_indices, nn_dists) == 0)
      continue;

    // Estimate the SPFH signature around p_idx
    computePointSPFHSignature (*surface_, *normals_, p_idx, i, nn_indices, hist_f1, hist_f2, hist_f3);

    // Populate a lookup table for converting a point index to its corresponding row in the spfh_hist_* matrices
    spfh_hist_lookup[p_idx] = i;
  }
}
	void addEigenMatrixRow( Eigen::MatrixXf &m )
	{
		Eigen::MatrixXf temp=m;
		m.resize(m.rows()+1,m.cols());
		m.setZero();
		m.block(0,0,temp.rows(),temp.cols())=temp;
	}
	void calcCovarWeighed(const float *input, const double *inputWeights, int vectorLength, int nVectors, Eigen::MatrixXf &out_covMat, const Eigen::VectorXf &mean)
	{
		//compute covariance matrix
		out_covMat.setZero();

		//Eigen::MatrixXf inMat = Eigen::MatrixXf::Zero(vectorLength,nVectors);
		//for (int i=0;i<vectorLength;i++){
		//	for(int k=0;k<nVectors;k++){
		//		inMat(i,k) = ((float)inputWeights[k])*(input[k*vectorLength+i]-mean[i]);
		//	}
		//}

		//out_covMat = (inMat*inMat.transpose())*(1.0/((float)nVectors-1.0));

		for (int i=0; i<vectorLength; i++){
			for (int j=0; j<vectorLength; j++){
				double avg=0;
				double iMean=mean[i];
				double jMean=mean[j];
				double wSum=0;
				for (int k=0; k<nVectors; k++){
					double w=inputWeights[k];
					avg+=w*(input[k*vectorLength+i]-iMean)*(input[k*vectorLength+j]-jMean);
					wSum+=w;
				}
				avg/=wSum;
				out_covMat(i,j)=(float)avg;
			}
		}
	}
Esempio n. 4
0
template <typename PointInT, typename PointOutT> void
pcl::IntensitySpinEstimation<PointInT, PointOutT>::computeIntensitySpinImage (
      const PointCloudIn &cloud, float radius, float sigma, 
      int k,
      const std::vector<int> &indices, 
      const std::vector<float> &squared_distances, 
      Eigen::MatrixXf &intensity_spin_image)
{
  // Determine the number of bins to use based on the size of intensity_spin_image
  int nr_distance_bins = static_cast<int> (intensity_spin_image.cols ());
  int nr_intensity_bins = static_cast<int> (intensity_spin_image.rows ());

  // Find the min and max intensity values in the given neighborhood
  float min_intensity = std::numeric_limits<float>::max ();
  float max_intensity = -std::numeric_limits<float>::max ();
  for (int idx = 0; idx < k; ++idx)
  {
    min_intensity = (std::min) (min_intensity, cloud.points[indices[idx]].intensity);
    max_intensity = (std::max) (max_intensity, cloud.points[indices[idx]].intensity);
  }

  float constant = 1.0f / (2.0f * sigma_ * sigma_);
  // Compute the intensity spin image
  intensity_spin_image.setZero ();
  for (int idx = 0; idx < k; ++idx)
  {
    // Normalize distance and intensity values to: 0.0 <= d,i < nr_distance_bins,nr_intensity_bins
    const float eps = std::numeric_limits<float>::epsilon ();
    float d = static_cast<float> (nr_distance_bins) * std::sqrt (squared_distances[idx]) / (radius + eps);
    float i = static_cast<float> (nr_intensity_bins) * 
              (cloud.points[indices[idx]].intensity - min_intensity) / (max_intensity - min_intensity + eps);

    if (sigma == 0)
    {
      // If sigma is zero, update the histogram with no smoothing kernel
      int d_idx = static_cast<int> (d);
      int i_idx = static_cast<int> (i);
      intensity_spin_image (i_idx, d_idx) += 1;
    }
    else
    {
      // Compute the bin indices that need to be updated (+/- 3 standard deviations)
      int d_idx_min = (std::max)(static_cast<int> (floor (d - 3*sigma)), 0);
      int d_idx_max = (std::min)(static_cast<int> (ceil  (d + 3*sigma)), nr_distance_bins - 1);
      int i_idx_min = (std::max)(static_cast<int> (floor (i - 3*sigma)), 0);
      int i_idx_max = (std::min)(static_cast<int> (ceil  (i + 3*sigma)), nr_intensity_bins - 1);
   
      // Update the appropriate bins of the histogram 
      for (int i_idx = i_idx_min; i_idx <= i_idx_max; ++i_idx)  
      {
        for (int d_idx = d_idx_min; d_idx <= d_idx_max; ++d_idx)
        {
          // Compute a "soft" update weight based on the distance between the point and the bin
          float w = expf (-powf (d - static_cast<float> (d_idx), 2.0f) * constant - powf (i - static_cast<float> (i_idx), 2.0f) * constant);
          intensity_spin_image (i_idx, d_idx) += w;
        }
      }
    }
  }
}
Esempio n. 5
0
void v_disparity_data_to_matrix(const FastGroundPlaneEstimator::v_disparity_data_t &image_data,
                                Eigen::MatrixXf &image_matrix)
{
    typedef FastGroundPlaneEstimator::v_disparity_data_t::const_reference row_slice_t;

    const int rows = image_data.shape()[0], cols = image_data.shape()[1];
    image_matrix.setZero(rows, cols);
    for(int row=0; row < rows; row +=1)
    {
        row_slice_t row_slice = image_data[row];
        row_slice_t::const_iterator data_it = row_slice.begin();
        for(int col=0; col < cols; ++data_it, col+=1)
        {
            //printf("%.f\n", *data_it);
            image_matrix(row, col) = *data_it;
        } // end "for each column"

    } // end of "for each row"

    return;
}
Esempio n. 6
0
// Test getLinearAlignEquations
TEST_F(MLPTesting, getLinearAlignEquations) {
  Eigen::MatrixXf A;
  Eigen::MatrixXf b;
  b.setZero();
  c_.set_warp_identity();
  c_.set_c(cv::Point2f(imgSize_/2,imgSize_/2));
  mp_.extractMultilevelPatchFromImage(pyr2_,c_,nLevels_-1,true);
  c_.set_c(cv::Point2f(imgSize_/2+1,imgSize_/2+1));
  // NOTE: only works for patch size = 2, nLevels = 2
  ASSERT_EQ(mpa_.getLinearAlignEquations(pyr2_,mp_,c_,0,nLevels_-1,A,b),true);
  float meanError = (255+255*0.75)/8;
  ASSERT_EQ(b(0),255-meanError);
  ASSERT_EQ(b(1),-meanError);
  ASSERT_EQ(b(2),-meanError);
  ASSERT_EQ(b(3),-meanError);
  ASSERT_EQ(b(4),255*0.75-meanError);
  ASSERT_EQ(b(5),-meanError);
  ASSERT_EQ(b(6),-meanError);
  ASSERT_EQ(b(7),-meanError);
  float mean_diff_dx = 0;
  float mean_diff_dy = 0;
  for(unsigned int l=0;l<nLevels_;l++){
    for(unsigned int i=0;i<patchSize_;i++){
      for(unsigned int j=0;j<patchSize_;j++){
        mean_diff_dx += -pow(0.5,l)*mp_.patches_[l].dx_[i*patchSize_+j];
        mean_diff_dy += -pow(0.5,l)*mp_.patches_[l].dy_[i*patchSize_+j];
      }
    }
  }
  mean_diff_dx /= nLevels_*patchSize_*patchSize_;
  mean_diff_dy /= nLevels_*patchSize_*patchSize_;
  for(unsigned int l=0;l<nLevels_;l++){
    for(unsigned int i=0;i<patchSize_;i++){
      for(unsigned int j=0;j<patchSize_;j++){
        ASSERT_EQ(A(4*l+i*patchSize_+j,0),-pow(0.5,l)*mp_.patches_[l].dx_[i*patchSize_+j]-mean_diff_dx);
        ASSERT_EQ(A(4*l+i*patchSize_+j,1),-pow(0.5,l)*mp_.patches_[l].dy_[i*patchSize_+j]-mean_diff_dy);
      }
    }
  }
}
Esempio n. 7
0
template <typename PointInT, typename PointOutT> void
pcl::ROPSEstimation <PointInT, PointOutT>::getDistributionMatrix (const unsigned int projection, const Eigen::Vector3f& min, const Eigen::Vector3f& max, const PointCloudIn& cloud, Eigen::MatrixXf& matrix) const
{
  matrix.setZero ();

  const unsigned int number_of_points = static_cast <unsigned int> (cloud.points.size ());

  const unsigned int coord[3][2] = {
    {0, 1},
    {0, 2},
    {1, 2}};

  const float u_bin_length = (max (coord[projection][0]) - min (coord[projection][0])) / number_of_bins_;
  const float v_bin_length = (max (coord[projection][1]) - min (coord[projection][1])) / number_of_bins_;

  for (unsigned int i_point = 0; i_point < number_of_points; i_point++)
  {
    Eigen::Vector3f point (
      cloud.points[i_point].x,
      cloud.points[i_point].y,
      cloud.points[i_point].z);

    const float u_length = point (coord[projection][0]) - min[coord[projection][0]];
    const float v_length = point (coord[projection][1]) - min[coord[projection][1]];

    const float u_ratio = u_length / u_bin_length;
    unsigned int row = static_cast <unsigned int> (u_ratio);
    if (row == number_of_bins_) row--;

    const float v_ratio = v_length / v_bin_length;
    unsigned int col = static_cast <unsigned int> (v_ratio);
    if (col == number_of_bins_) col--;

    matrix (row, col) += 1.0f;
  }

  matrix /= static_cast <float> (number_of_points);
}
Esempio n. 8
0
int main(int argc, char **argv) {
	std::vector<color_keyframe::Ptr> frames;

	util U;
	U.load("http://localhost/corridor_map2", frames);
	timestamp_t t0 = get_timestamp();
	std::vector<std::pair<int, int> > overlapping_keyframes;
	int size;
	int workers = argc - 1;
	ros::init(argc, argv, "panorama");

	std::vector<
			actionlib::SimpleActionClient<rm_multi_mapper::WorkerSlamAction>*> ac_list;
	for (int i = 0; i < workers; i++) {
		actionlib::SimpleActionClient<rm_multi_mapper::WorkerSlamAction>* ac =
				new actionlib::SimpleActionClient<
						rm_multi_mapper::WorkerSlamAction>(
						std::string(argv[i + 1]), true);
		ac_list.push_back(ac);
	}

	sql::ResultSet *res;

	size = frames.size();
	get_pairs(overlapping_keyframes);
	std::vector<rm_multi_mapper::WorkerSlamGoal> goals;
	int keyframes_size = (int) overlapping_keyframes.size();

	for (int k = 0; k < workers; k++) {
		rm_multi_mapper::WorkerSlamGoal goal;

		int last_elem = (keyframes_size / workers) * (k + 1);
		if (k == workers - 1)
			last_elem = keyframes_size;

		for (int i = (keyframes_size / workers) * k; i < last_elem; i++) {
			rm_multi_mapper::KeyframePair keyframe;

			keyframe.first = overlapping_keyframes[i].first;
			keyframe.second = overlapping_keyframes[i].second;
			goal.Overlap.push_back(keyframe);
		}
		goals.push_back(goal);
	}

	ROS_INFO("Waiting for action server to start.");
	for (int i = 0; i < workers; i++) {
		ac_list[i]->waitForServer();
	}

	ROS_INFO("Action server started, sending goal.");

	// send a goal to the action
	for (int i = 0; i < workers; i++) {
		ac_list[i]->sendGoal(goals[i]);
	}

	//wait for the action to return
	std::vector<bool> finished;
	for (int i = 0; i < workers; i++) {
		bool finished_before_timeout = ac_list[i]->waitForResult(
				ros::Duration(30.0));
		finished.push_back(finished_before_timeout);
	}

	bool success = true;
	for (int i = 0; i < workers; i++) {
		success = finished[i] && success;
	}

	Eigen::MatrixXf acc_JtJ;
	acc_JtJ.setZero(size * 6, size * 6);
	Eigen::VectorXf acc_Jte;
	acc_Jte.setZero(size * 6);

	if (success) {

		for (int i = 0; i < workers; i++) {
			Eigen::MatrixXf JtJ;
			JtJ.setZero(size * 6, size * 6);
			Eigen::VectorXf Jte;
			Jte.setZero(size * 6);

			rm_multi_mapper::Vector rosJte = ac_list[i]->getResult()->Jte;
			rm_multi_mapper::Matrix rosJtJ = ac_list[i]->getResult()->JtJ;

			vector2eigen(rosJte, Jte);

			matrix2eigen(rosJtJ, JtJ);

			acc_JtJ += JtJ;
			acc_Jte += Jte;

		}

	} else {
		ROS_INFO("Action did not finish before the time out.");
		std::exit(0);
	}

	Eigen::VectorXf update = -acc_JtJ.ldlt().solve(acc_Jte);

	float iteration_max_update = std::max(std::abs(update.maxCoeff()),
			std::abs(update.minCoeff()));

	ROS_INFO("Max update %f", iteration_max_update);

	/*for (int i = 0; i < (int)frames.size(); i++) {

	 frames[i]->get_pos() = Sophus::SE3f::exp(update.segment<6>(i))
	 * frames[i]->get_pos();

	 std::string query = "UPDATE `positions` SET `q0` = " + 
	 boost::lexical_cast<std::string>(frames[i]->get_pos().so3().data()[0]) +
	 ", `q1` = " +
	 boost::lexical_cast<std::string>(frames[i]->get_pos().so3().data()[1]) +
	 ", `q2` = " +
	 boost::lexical_cast<std::string>(frames[i]->get_pos().so3().data()[2]) +
	 ", `q3` = " +
	 boost::lexical_cast<std::string>(frames[i]->get_pos().so3().data()[3]) +
	 ", `t0` = " +
	 boost::lexical_cast<std::string>(frames[i]->get_pos().translation()[0]) +
	 ", `t1` = " +
	 boost::lexical_cast<std::string>(frames[i]->get_pos().translation()[1]) +
	 ", `t2` = " +
	 boost::lexical_cast<std::string>(frames[i]->get_pos().translation()[2]) +
	 ", `int0` = " +
	 boost::lexical_cast<std::string>(frames[i]->get_intrinsics().array()[0]) +
	 ", `int1` = " +
	 boost::lexical_cast<std::string>(frames[i]->get_intrinsics().array()[1]) +
	 ", `int2` = " +
	 boost::lexical_cast<std::string>(frames[i]->get_intrinsics().array()[2]) +
	 " WHERE `id` = " +
	 boost::lexical_cast<std::string>(i) +
	 ";";

	 res = U.sql_query(query);
	 delete res;
	 

	 }*/
	timestamp_t t1 = get_timestamp();

	double secs = (t1 - t0) / 1000000.0L;
	std::cout << secs << std::endl;
	return 0;

}
Esempio n. 9
0
template <typename PointInT, typename GradientT, typename PointOutT> void
pcl::RIFTEstimation<PointInT, GradientT, PointOutT>::computeRIFT (
      const PointCloudIn &cloud, const PointCloudGradient &gradient, 
      int p_idx, float radius, const std::vector<int> &indices, 
      const std::vector<float> &sqr_distances, Eigen::MatrixXf &rift_descriptor)
{
  if (indices.empty ())
  {
    PCL_ERROR ("[pcl::RIFTEstimation] Null indices points passed!\n");
    return;
  }

  // Determine the number of bins to use based on the size of rift_descriptor
  int nr_distance_bins = static_cast<int> (rift_descriptor.rows ());
  int nr_gradient_bins = static_cast<int> (rift_descriptor.cols ());

  // Get the center point
  pcl::Vector3fMapConst p0 = cloud.points[p_idx].getVector3fMap ();

  // Compute the RIFT descriptor
  rift_descriptor.setZero ();
  for (size_t idx = 0; idx < indices.size (); ++idx)
  {
    // Compute the gradient magnitude and orientation (relative to the center point)
    pcl::Vector3fMapConst point = cloud.points[indices[idx]].getVector3fMap ();
    Eigen::Map<const Eigen::Vector3f> gradient_vector (& (gradient.points[indices[idx]].gradient[0]));

    float gradient_magnitude = gradient_vector.norm ();
    float gradient_angle_from_center = acosf (gradient_vector.dot ((point - p0).normalized ()) / gradient_magnitude);
    if (!pcl_isfinite (gradient_angle_from_center))
      gradient_angle_from_center = 0.0;

    // Normalize distance and angle values to: 0.0 <= d,g < nr_distances_bins,nr_gradient_bins
    const float eps = std::numeric_limits<float>::epsilon ();
    float d = static_cast<float> (nr_distance_bins) * sqrtf (sqr_distances[idx]) / (radius + eps);
    float g = static_cast<float> (nr_gradient_bins) * gradient_angle_from_center / (static_cast<float> (M_PI) + eps);

    // Compute the bin indices that need to be updated
    int d_idx_min = (std::max)(static_cast<int> (ceil (d - 1)), 0);
    int d_idx_max = (std::min)(static_cast<int> (floor (d + 1)), nr_distance_bins - 1);
    int g_idx_min = static_cast<int> (ceil (g - 1));
    int g_idx_max = static_cast<int> (floor (g + 1));

    // Update the appropriate bins of the histogram 
    for (int g_idx = g_idx_min; g_idx <= g_idx_max; ++g_idx)  
    {
      // Because gradient orientation is cyclical, out-of-bounds values must wrap around
      int g_idx_wrapped = ((g_idx + nr_gradient_bins) % nr_gradient_bins); 

      for (int d_idx = d_idx_min; d_idx <= d_idx_max; ++d_idx)
      {
        // To avoid boundary effects, use linear interpolation when updating each bin 
        float w = (1.0f - fabsf (d - static_cast<float> (d_idx))) * (1.0f - fabsf (g - static_cast<float> (g_idx)));

        rift_descriptor (d_idx, g_idx_wrapped) += w * gradient_magnitude;
      }
    }
  }

  // Normalize the RIFT descriptor to unit magnitude
  rift_descriptor.normalize ();
}