Пример #1
0
void ExtractBuildPlane() {
	std::vector<int> inliers;	// build plane indices in the raw building point cloud
	pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr
		PlaneModel(new pcl::SampleConsensusModelPlane<pcl::PointXYZ>(build_cloud_raw)); // plane Model
	pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(PlaneModel);	// ransac
	// set attributes...
	ransac.setDistanceThreshold(0.01);
	ransac.computeModel();

	// get result
	ransac.getInliers(inliers);
	// copies all inliers of the model computed to another PointCloud
	pcl::PointCloud<pcl::PointXYZ>::Ptr build_cloud_plane(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::copyPointCloud<pcl::PointXYZ>(*build_cloud_raw, inliers, *build_cloud_plane);

	// get plane model
	ransac.getModelCoefficients(build_plane_coeff);

	// project the points to the plane to reduce error
	pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());
	coefficients->values.resize (4);
	coefficients->values[0] = build_plane_coeff(0);
	coefficients->values[1] = build_plane_coeff(1);
	coefficients->values[2] = build_plane_coeff(2);
	coefficients->values[3] = build_plane_coeff(3);

	pcl::ProjectInliers<pcl::PointXYZ> proj;
	proj.setModelType(pcl::SACMODEL_PLANE);
	proj.setInputCloud(build_cloud_plane);
	proj.setModelCoefficients(coefficients);
	proj.filter(*build_cloud_accurate_plane);
}
Пример #2
0
int
filterPlaneModel (pcl::PointCloud<pcl::PointXYZRGB>::Ptr &cloud, float distance)
{
  Eigen::VectorXf planecoeffs, coeffs;
  pcl::PointIndices::Ptr
    inliers (new pcl::PointIndices);
  pcl::SampleConsensusModelPlane<pcl::PointXYZRGB>::Ptr
    model_p (new pcl::SampleConsensusModelPlane<pcl::PointXYZRGB> (cloud));
  pcl::ExtractIndices<pcl::PointXYZRGB> extract;

  pcl::RandomSampleConsensus<pcl::PointXYZRGB> ransac (model_p);
  ransac.setDistanceThreshold (distance);
  ransac.computeModel ();
  ransac.getInliers (inliers->indices);
  ransac.getModelCoefficients (planecoeffs);

  model_p->optimizeModelCoefficients (inliers->indices, planecoeffs, coeffs);
  model_p->selectWithinDistance (coeffs, distance, inliers->indices);

  if (inliers->indices.empty ())
    return (-1);
    
  // Remove the points that fit a plane from the cloud
  pcl::ExtractIndices<pcl::PointXYZRGB> eifilter;
  eifilter.setInputCloud (cloud);
  eifilter.setIndices (inliers);
  eifilter.setNegative (true);
  eifilter.setKeepOrganized (true);
  eifilter.filter (*cloud);

  return (0);
}
Пример #3
0
//Finds the pole using the RANSAC algorithm
bool redblade_stereo::findPole(pcl::PointCloud<pcl::PointXYZ>::Ptr in,
			       pcl::PointCloud<pcl::PointXYZ>::Ptr pole){
  ROS_INFO("Size of input cloud %d",in->points.size());
  if(in->points.size()<sigSize){//Significance test
    return false;
  }
  Eigen::VectorXf coeff;
  coeff.resize(6);
  ransac(in,pole,coeff);
  ROS_INFO("Size of coefficients %d",coeff.size());
  if(coeff.size()==0){
    return false;
  }  
  ROS_INFO("Model Coefficients (x:%f,y:%f,z:%f)+(dx:%f,dy:%f,dz:%f)",
   	   coeff[0],coeff[1],coeff[2],coeff[3],coeff[4],coeff[5]);
  if(fabs(coeff[5])>verticalTolerance){     //Vertical line test
    if(pole->points.size()>sigSize){//Significance test
      // int clusters = cluster(pole,0.01); //1 cm
      // if(clusters==1){              //Test to see if the line is one contiguous segment
      ROS_INFO("Size of line %d",pole->points.size());
      // ROS_INFO("Model Coefficients (x:%f,y:%f,z:%f)+(dx:%f,dy:%f,dz:%f)",
      // 	       coeff[0],coeff[1],coeff[2],coeff[3],coeff[4],coeff[5]);
      return true;}}
  //}
  return false;
}
Пример #4
0
Matrix33 RansacEstimator::getEssentialRansac(vector<Correspondance *> *data)
{
    Ransac<Correspondance, ModelEssential8Point>
        ransac(trySize);

    ransac.data = data;

    ransac.inlierThreshold = treshold;
    ransac.inliersPercent = 1.0;
    ransac.iterationsNumber = maxIterations;

    ModelEssential8Point result = ransac.getModelRansac();
    for (unsigned i = 0; i < data->size(); i++)
    {
        bool fits = result.fits(*(data->operator[](i)), treshold);
        data->operator[](i)->flags |= (fits ? Correspondance::FLAG_PASSER : Correspondance::FLAG_FAILER);
    }

    for (unsigned i = 0; i < ransac.bestSamples.size(); i++)
    {
        ransac.bestSamples[i]->flags  |= Correspondance::FLAG_IS_BASED_ON;
    }

    return result.model;
}
Пример #5
0
int ransac_vertrapezoid(int *matched_points, int npoints,
                        int *num_inliers_by_motion, double *params_by_motion,
                        int num_desired_motions) {
  return ransac(matched_points, npoints, num_inliers_by_motion,
                params_by_motion, num_desired_motions, 4,
                is_degenerate_homography, find_vertrapezoid,
                project_points_double_vertrapezoid);
}
Пример #6
0
int ransac_translation(int *matched_points, int npoints,
                       int *num_inliers_by_motion, double *params_by_motion,
                       int num_desired_motions) {
  return ransac(matched_points, npoints, num_inliers_by_motion,
                params_by_motion, num_desired_motions, 3,
                is_degenerate_translation, find_translation,
                project_points_double_translation);
}
Пример #7
0
/*!
  Compute the pose from a set of n 2D point (x,y) in p and m 3D points
  (X,Y,Z) in P using the Ransac algorithm. It is not assumed that
  the 2D and 3D points are registred (there is nm posibilities)

  at least numberOfInlierToReachAConsensus of true correspondance are required
  to validate the pose

  the inliers are given in a list of vpPoint

  the pose is return in cMo
 */
void
vpPose::ransac(const int n,
	       const vpPoint *p,
	       const int m,
	       const vpPoint *P,
	       const int   numberOfInlierToReachAConsensus,
	       const double threshold,
	       int &ninliers,
	       vpList<vpPoint> &lPi,
	       vpHomogeneousMatrix &cMo)
{


  double *x, *y;
  x = new double [n];
  y = new double [n] ;
  int i;
  for (i=0 ; i < n ; i++)
  {
    x[i] = p[i].get_x() ;
    y[i] = p[i].get_y() ;
  }
  double *X, *Y, *Z;
  X = new double [m];
  Y = new double [m];
  Z = new double [m];
  for (i=0 ; i < m ; i++)
  {
    X[i] = P[i].get_oX() ;
    Y[i] = P[i].get_oY() ;
    Z[i] = P[i].get_oZ() ;
  }

  vpColVector xi,yi,Xi,Yi,Zi ;

  ransac(n,x,y,
	 m,X,Y,Z, numberOfInlierToReachAConsensus,
	 threshold,
	 ninliers,
	 xi,yi,Xi,Yi,Zi,
	 cMo) ;


  for(i=0 ; i < ninliers ; i++)
  {
    vpPoint Pi ;
    Pi.setWorldCoordinates(Xi[i],Yi[i], Zi[i]) ;
    Pi.set_x(xi[i]) ;
    Pi.set_y(yi[i]) ;
    lPi += Pi ;
  }

  delete [] x;
  delete [] y;
  delete [] X;
  delete [] Y;
  delete [] Z;
}
void Segmentation::doSegmentation(pcl::PointCloud<pcl::PointXYZRGBA>::Ptr &cloud)
{
    //MainPlane groundMainPlane;
    // Variables
    isComputed = false ;
    struct timeval tbegin,tend;
    double texec=0.0;

    // Start timer
    gettimeofday(&tbegin,NULL);

    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloudFiltered(new pcl::PointCloud<pcl::PointXYZRGBA>);
    //pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloudFilteredCopy(new pcl::PointCloud<pcl::PointXYZRGBA>);
    _mainCloud.reset(new pcl::PointCloud<pcl::PointXYZRGBA>);
    (void) passthroughFilter(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0, cloud, cloudFiltered); // 3.0, 3.0, -0.2, 2.0, -4.0, 4.0
    pcl::copyPointCloud(*cloudFiltered, *_mainCloud);

    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr ground (new pcl::PointCloud<pcl::PointXYZRGBA>);
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr Hullground (new pcl::PointCloud<pcl::PointXYZRGBA>);

    std::vector<pcl::PointIndices> vectorInliers(0);
    std::vector <pcl::ModelCoefficients> vectorCoeff(0);
    std::vector < pcl::PointCloud<pcl::PointXYZRGBA>::Ptr > vectorCloudinliers(0);
    std::vector < pcl::PointCloud<pcl::PointXYZRGBA>::Ptr > vectorHull(0);
    std::vector < pcl::PointCloud<pcl::PointXYZRGBA>::Ptr > vectorCluster(0);

    pcl::ModelCoefficients::Ptr coefficientsGround (new pcl::ModelCoefficients);
    pcl::PointIndices::Ptr inliersGround (new pcl::PointIndices);

    //    pcl::VoxelGrid< pcl::PointXYZRGBA > sor;
    //    sor.setInputCloud (_mainCloud);
    //    sor.setLeafSize (0.01f, 0.01f, 0.01f);
    //    sor.filter (*_mainCloud);
    //(void) findGround(_mainCloud,_ground);
    //isComputed = true;
    if(findGround(_mainCloud,_ground))
    {
        Eigen::Vector3f gravityVector(_ground.getCoefficients()->values[0], _ground.getCoefficients()->values[1], _ground.getCoefficients()->values[2]);

        //(void) findOtherPlanesRansac(_mainCloud,gravityVector,vectorCoeff , vectorCloudinliers,vectorHull);

        //(void) regionGrowing(vectorCloudinliers, vectorCluster);
        euclidianClustering(_mainCloud,vectorCloudinliers);
        ransac(vectorCloudinliers,gravityVector,vectorCluster );
        createPlane(vectorCluster);
        // End timer
    }

    gettimeofday(&tend,NULL);
    // Compute execution time
    texec = ((double)(1000*(tend.tv_sec-tbegin.tv_sec)+((tend.tv_usec-tbegin.tv_usec)/1000)))/1000;
    std::cout << "time : " << texec << std::endl;
}
Пример #9
0
// The main function
int main(void)
{
    // Generate noisy data from the truth
    LineObserver observer;
    std::vector<Point> data;
    std::vector<bool> trueInliers;
    Line trueModel(0.6, -0.8, 1);
    if (!observer.GenerateData(data, trueInliers, trueModel, 100, 0.1, 0.5)) return -1;

    // Find the best model using RANSAC
    LineEstimator estimator;
    RTL::RANSAC<Line, std::vector<Line>, Point, std::vector<Point> > ransac(&estimator);
    Line bestModel;
    double bestLoss = ransac.FindBest(bestModel, data, data.size());

    // Find inliers using the best model
    std::vector<bool> inliers;
    int numInliers = ransac.FindInliers(inliers, bestModel, data, data.size());

    // Print the data
	std::ios_base::fmtflags original_flags = std::cout.flags();

	std::cout << " No:      x         y     true ransac  xor" << std::endl;
    for (size_t i = 0; i < data.size(); i++) {
		std::cout.setf(std::ios_base::right, std::ios_base::adjustfield);
		std::cout.width(3);
        std::cout << i << ": ";
		std::cout.width(8);
		std::cout.setf(std::ios_base::right, std::ios_base::adjustfield);
		std::cout << std::fixed << std::setprecision(2) << data[i].x << ", ";
		std::cout.width(8);
		std::cout.setf(std::ios_base::right, std::ios_base::adjustfield);
		std::cout << std::fixed << std::setprecision(2) << data[i].y;
		std::cout << "    " << (trueInliers[i] ? "O" : "X");
		std::cout << "    " << (inliers[i] ? "O" : "X");
		std::cout << "    " << ((trueInliers[i] ^ inliers[i]) ? "*" : " ");
		std::cout << std::endl;
	}

	std::cout.flags(original_flags);                              //6

	// Print the result
    std::cout << "- True Model:  " << trueModel << std::endl;
    std::cout << "- Found Model: " << bestModel << " (Loss: " << bestLoss << ")" << std::endl;
    std::cout << "- The Number of Inliers: " << numInliers << std::endl;

    return 0;
}
Пример #10
0
void Align::laserCallback(const sensor_msgs::LaserScan::ConstPtr& msg)
{
	if(position == 4){
		ransac();
	}
		if(ready == 1 && position < 4){
		ROS_INFO("LaserCallBack Position: %d", position);
			ready = 0;
			for(int i = 0; i < 512; i++){
				double dist = msg->ranges[i];
				
				if(!isnan(dist) && dist != 0.0){
					points.push_back(point());
					points.at(counter).x = dist * cos(((M_PI / 511.0) * i) + (M_PI/2 * position));
					points.at(counter).y = dist * sin(((M_PI / 511.0) * i) + (M_PI/2 * position));
					switch(position){
						case 0:
						points[counter].y += 0.13;
						break;
						case 1:
						points[counter].x -= 0.13;
						break;
						case 2:
						points[counter].y -= 0.13;
						break;
						case 3:
						points[counter].x += 0.13;
						break;
						default: 
						break;
					}
					//if(i % 4 == 0){ 
					//ROS_INFO("PUSH i range: %d   dist: %f    x: %f  y: %f", i, dist, points.at(counter).x,points.at(counter).y);}
					counter++;

					//counter++;
				}
			}
			ROS_INFO("LaserCallBack points SIZE: %d", points.size());
			position++;
			rotateLeft(M_PI/2.0);
			

		}
		
	}
Пример #11
0
/*!
 * \brief shot_detector::processCloud The service function. It process the clouds with shot and returns the pose of the object
 * \param req
 * \param res
 * \return
 */
bool shot_detector::processCloud(apc_msgs::shot_detector_srv::Request &req, apc_msgs::shot_detector_srv::Response &res)
{
    pcl_functions::convertMsg(req.targetcloud, model);
    //loadModel(*model,"/home/niko/projects/apc/catkin/src/apc_ros/apc_object_detection/optimized_poisson_textured_mesh.ply");
    pcl_functions::convertMsg(req.pointcloud, scene);
    //pcl::io::loadPCDFile("/home/niko/projects/apc/catkin/src/apc_ros/apc_object_detection/niko_file.pcd",*scene);
    std::cerr << "Originally positions" << std::endl;
    std::cerr << scene->points[1].x << std::endl;
    std::cerr << scene->points[1].y << std::endl;
    std::cerr << scene->points[1].z << std::endl;
    //Downsample the model and the scene so they have rougly the same resolution
    pcl::PointCloud<PointType>::Ptr scene_filter (new pcl::PointCloud<PointType> ());
    pcl_functions::voxelFilter(scene, scene_filter, voxel_sample_);
    scene = scene_filter;
    pcl::PointCloud<PointType>::Ptr model_filter (new pcl::PointCloud<PointType> ());
    pcl_functions::voxelFilter(model, model_filter, voxel_sample_);
    model = model_filter;
    // Randomly select a couple of keypoints so we don't calculte descriptors for everything
    sampleKeypoints(model, model_keypoints, model_ss_);
    sampleKeypoints(scene, scene_keypoints, scene_ss_);
    //Calculate the Normals
    calcNormals(model, model_normals);
    calcNormals(scene, scene_normals);
    //Calculate the shot descriptors at each keypoint in the scene
    calcSHOTDescriptors(model, model_keypoints, model_normals, model_descriptors);
    calcSHOTDescriptors(scene, scene_keypoints, scene_normals, scene_descriptors);
    ransac(rototranslations, model, scene);
    // Compare descriptors and try to find correspondences
    //  compare(model_descriptors,scene_descriptors);
    Eigen::Matrix4f pose;
    // if(model_scene_corrs->size ()!=0){
    //groupCorrespondences();
    pose = refinePose(rototranslations, model, scene);

    //}
    std::cerr << pose << std::endl;
    if(pose == Eigen::Matrix4f::Identity())
        return false;
    Eigen::Matrix4d md(pose.cast<double>());
    Eigen::Affine3d affine(md);
    geometry_msgs::Pose transform;
    tf::poseEigenToMsg(affine, transform);
    res.pose = transform;
    return true;
}
void cloud_cb (const sensor_msgs::PointCloud2ConstPtr& input)
{
  // Do data processing here...
  
  // run pass through filter to shrink point cloud
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_passthrough(new pcl::PointCloud<pcl::PointXYZRGB>);
  //passthrough_z(input, cloud_passthrough);
  passthrough_y(input,cloud_passthrough);
  //passthrough_x(cloud_passthrough);
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_outlier(new pcl::PointCloud<pcl::PointXYZRGB>);
  passthrough_oulier(input,cloud_outlier);
  pub_out.publish(*cloud_outlier);

  // run ransac to find floor
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_projected(new pcl::PointCloud<pcl::PointXYZRGB>);
  ransac(cloud_passthrough, cloud_projected);
  pub.publish(*cloud_projected);

}
Пример #13
0
/*************************************************************************************************
* Compute Ground Plane and return transform to align axis with ground
* if debug show plane in vtkRenderWindow
*************************************************************************************************/
void compute_ground_plane_transform(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, Eigen::Matrix4f *RBT_pcl, int debug)
{
  std::vector<int> inliers;

  pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr
  model_l(new pcl::SampleConsensusModelPlane<pcl::PointXYZ> (cloud));
	
  Eigen::VectorXf model_coefficients(4);
      
  pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_l);
  ransac.setDistanceThreshold (0.05);
  ransac.computeModel();
  ransac.getInliers(inliers);
  
  model_l->optimizeModelCoefficients(inliers,model_coefficients,model_coefficients);
  
  double nx,ny,nz,p;
  double a = model_coefficients[0];
  double b = model_coefficients[1];
  double c = model_coefficients[2];
  double d = model_coefficients[3];
  nx = a / sqrt(a*a + b*b + c*c);
  ny = b / sqrt(a*a + b*b + c*c);
  nz = c / sqrt(a*a + b*b + c*c);
  p = -d / sqrt(a*a + b*b + c*c);
  
  // Compute Rigid Body transform between plane axis and coordinate system axes
  pcl::PointCloud<pcl::PointXYZ> source_points;
  pcl::PointCloud<pcl::PointXYZ> target_points;

  target_points.push_back (pcl::PointXYZ (0,0,0));
  target_points.push_back (pcl::PointXYZ (1,0,0)); 
  target_points.push_back (pcl::PointXYZ (0,1,0));
      
  source_points.push_back (pcl::PointXYZ (nx*p,ny*p,nz*p));
  source_points.push_back (pcl::PointXYZ (nx*p+1,ny*p+0,nz*p+0)); 
  source_points.push_back (pcl::PointXYZ (nx*p+nx,ny*p+ny,nz*p+nz)); 

  pcl::registration::TransformationEstimationSVD<pcl::PointXYZ, pcl::PointXYZ> trans_pcl;
  trans_pcl.estimateRigidTransformation(source_points,target_points,*RBT_pcl);   
}
void RedlineExtractorNode::makeLineModels (void)
{
    std::vector<int> ransacIndices;
    pcl::PointCloud<PointT> ransacPoints;

    //  Setup ransac
    pcl::SampleConsensusModelLine<PointT>::Ptr lineModel(new pcl::SampleConsensusModelLine<PointT> (this->poiCloud.makeShared()));
    pcl::RandomSampleConsensus<PointT> ransac(lineModel);

    //  Extract line one if possible
    ransac.setDistanceThreshold(this->params.ransacDistance);
    this->models.lineOneFound = ransac.computeModel();
    ransac.getInliers(ransacIndices);
    ransac.getModelCoefficients(this->models.lineOne);

    //  Extract points from poiCloud to ransacLineOne
    pcl::copyPointCloud<pcl::PointXYZ>(this->poiCloud, ransacIndices, this->ransacLineOne);

    //  Remove points from poiCloud according to indices
    pcl::PointCloud<PointT>::iterator it;
    for (int i = ransacIndices.size() - 1; i >= 0; i--)
    {
        it = this->poiCloud.begin() + ransacIndices.at(i);
        this->poiCloud.erase(it);
    }

    //  Extract line two if possible
    pcl::SampleConsensusModelLine<PointT>::Ptr lineModel1(new pcl::SampleConsensusModelLine<PointT> (this->poiCloud.makeShared()));
    pcl::RandomSampleConsensus<PointT> ransac1(lineModel1);
    ransacIndices.clear();
    ransac1.setDistanceThreshold(this->params.ransacDistance);
    this->models.lineTwoFound = ransac1.computeModel();
    ransac1.getInliers(ransacIndices);
    ransac1.getModelCoefficients(this->models.lineTwo);

    //  Extract points from poiCloud to ransacLineTwo
    pcl::copyPointCloud<pcl::PointXYZ>(this->poiCloud, ransacIndices, this->ransacLineTwo);
}
Пример #15
0
int main(int argc, char** argv)
{
    int ratio = 3;
    int kernel_size = 3;
    int sigma = 200;

    //connection to camera 
    CvCapture* capture = cvCaptureFromCAM(CV_CAP_ANY);

    if(!capture)
    {
        std::cerr << "ERROR: capture is NULL\n";
        getchar();
        return -1;
    }

    /* ONLY NEEDED FOR TESTING PURPOSES

       cvNamedWindow("Camera Image", CV_WINDOW_AUTOSIZE);
    // Create a Trackbar for user to enter threshold
    cv::createTrackbar("Min Threshold:","Camera Image" , &lowThreshold, max_lowThreshold, DummyCallback);
    // Create a Trackbar for user to enter threshold
    cv::createTrackbar("Hough Threshold:","Camera Image" , &houghThreshold, max_houghThreshold, DummyCallback);
    // Create a Trackbar for user to enter threshold
    cv::createTrackbar("Sigma:","Camera Image" , &sigma, 1000, DummyCallback);

    cvNamedWindow("Edge Image", CV_WINDOW_AUTOSIZE);

*/

    ros::init(argc,argv, "circle_publisher");
    ros::NodeHandle nh;

    //Let's publish messages as defined in /msg/cirlce.msg on a topic called 'detected_circles' with a max. buffer of 1000 messages 
    ros::Publisher circle_publisher = nh.advertise<circle_detection::circle_msg>("detected_circles",1000); 

    ros::Rate loop_rate(10);

    //used to create an Image Id
    size_t id_count = 0;

    while(ros::ok)
    {
        // Get a frame
        IplImage* frame = cvQueryFrame(capture);

        if (!frame)
        {
            std::cerr << "ERROR: frame is null...\n" ;
            getchar();
            break;
        }

        // image id 
        id_count++;

        cv::Mat src(frame);
        cv::Mat src_gray;

        cv::Mat dst;
        cv::Mat detected_edges;

        dst.create(src.size(), src.type());

        // covert the image to gray
        cvtColor(src,src_gray,CV_BGR2GRAY);

        // Reduce the noise so we avoid false circle detection
        GaussianBlur(src_gray, detected_edges, cv::Size(9, 9), sigma/100.0, 0);

        equalizeHist(detected_edges, detected_edges);

        // Canny detector
        Canny(detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size);

        // Using Canny's output as a mask, we display our result
        dst = cv::Scalar::all(0);

        src.copyTo(dst, detected_edges);

        std::vector<Point> edgePoints;


        // iterate through the  pixels of the canny image
        for(int j=0;j<detected_edges.cols;j++)
        {
            for(int i=0;i<detected_edges.rows;i++)
            {
                unsigned char &color = *(detected_edges.data+detected_edges.step*i + j*detected_edges.elemSize());
                unsigned char &bb = *(src.data+src.step*i + j*src.elemSize());
                unsigned char &gg = *(src.data+src.step*i + j*src.elemSize() + 1);
                unsigned char &rr = *(src.data+src.step*i + j*src.elemSize() + 2);

                // check if the pixel is black or white (only edges are white)
                if(color)
                {
                    int max = max3(rr,gg,bb);
                    int min = min3(rr,gg,bb);
                    int delta = max - min;

                    // check saturation (only colorfull circles will be detacted
                    if(delta > 20)
                    {
                        edgePoints.push_back(Point((double) j,(double) i));
                    }
                    else
                    {
                        // mark pixel as no longer relevant, i.e. the pixel isn't recognized as edge
                        color = 0;
                    }
                }
            }
        }


        std::vector<Circle> detectedCircles;

        /* Apply the RANSAC algorithm to find circles in the camera image
         * Paramters: sink vector, points, eps, iterations, minSupporters, maxCircles
         */ 
        ransac(detectedCircles, edgePoints, 5.0, 10000, 100, 1);

        /* ONLY NEDDED FOR TESTIGN PURPOSES

        // Draw the circles detected
        for(size_t i = 0; i < detectedCircles.size(); i++)
        {
        cv::Point center(cvRound(detectedCircles[i].center.x), cvRound(detectedCircles[i].center.y));
        int radius = cvRound(detectedCircles[i].radius);

        //            assert(radius > 0);

        // circle center
        circle(src, center, 3, cv::Scalar(0,255,0), -1, 8, 0 );
        // circle outline
        circle(src, center, radius, cv::Scalar(0,0,255), 3, 8, 0 );
        }

        //Results
        imshow("Camera Image", src);
        imshow("Edge Image", detected_edges);

*/


        for(size_t i=0;i < detectedCircles.size();i++)
        {
            circle_detection::circle_msg msg;
            std::stringstream ss;

            ss << "IMG" << id_count;

            msg.image_id = ss.str();

            unsigned int radius = cvRound(detectedCircles[i].radius);

            msg.radius = radius;

            msg.center_x = cvRound(detectedCircles[i].center.x) ;
            msg.center_y = cvRound(detectedCircles[i].center.y);
            circle_publisher.publish(msg);

            ros::spinOnce();
            loop_rate.sleep();

        }



        //Do not release the frame!
        //If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
        //remove higher bits using AND operator
        //cvWaitKey() is used as delay between the frames
        if ( (cvWaitKey(100) & 255) == 27 ) break;
    }

    /* ONLY NEEDED FOR TESTING PURPOSES
     
    // Release the capture device housekeeping
       cvReleaseCapture( &capture );
       cvDestroyWindow( "Display Image" );

    */

    return 0;
}
Пример #16
0
void Panorama::remove_outliers()
{
	remove_too_few_match();
	ransac();
	fit_prob_model();
}
Пример #17
0
//**************************************************************************************************************************getMotion()
void PSMpositionNode::getMotion(const sensor_msgs::LaserScan& scan,  std::vector <depthPoint> *depthLine)
{
    ROS_DEBUG("Received kinectLine");

    // **** attmempt to match the two scans

    // PM scan matcher is used in the following way:
    // The reference scan (prevPMScan_) always has a pose of 0
    // The new scan (currPMScan) has a pose equal to the movement
    // of the laser in the world frame since the last scan (btTransform change)
    // The computed correction is then propagated using the tf machinery
    if (!initialized_)
    {
        initialized_ = initialize(scan);
        if (initialized_) ROS_INFO("Matcher Horizontal initialized");
        return;
    }

    prevPMScan_->rx = 0;
    prevPMScan_->ry = 0;
    prevPMScan_->th = 0;

    btTransform currWorldToBase;
    btTransform change;
    change.setIdentity();

    // what odometry model to use
    if (useTfOdometry_)
    {
        // get the current position of the base in the world frame
        // if no transofrm is available, we'll use the last known transform

        getCurrentEstimatedPose(currWorldToBase, scan);
        change = laserToBase_ * prevWorldToBase_.inverse() * currWorldToBase * baseToLaser_;
    }
    else if (useImuOdometry_)
    {
        imuMutex_.lock();
        double dTheta = currImuAngle_ - prevImuAngle_;
        prevImuAngle_ = currImuAngle_;
        change.getRotation().setRPY(0.0, 0.0, dTheta);
        imuMutex_.unlock();
    }

    PMScan * currPMScan = new PMScan(scan.ranges.size());

    rosToPMScan(scan, change, currPMScan);


    try
    {
        matcher_.pm_psm(prevPMScan_, currPMScan);
    }
    catch(int err)
    {
        ROS_WARN("Error in scan matching");
        delete prevPMScan_;
        prevPMScan_ = currPMScan;
        return;
    };

    // **** calculate change in position

    // rotate by -90 degrees, since polar scan matcher assumes different laser frame
    // and scale down by 100
    double dx =  currPMScan->ry / ROS_TO_PM;
    double dy = -currPMScan->rx / ROS_TO_PM;
    double da =  currPMScan->th;

    // change = scan match result for how much laser moved between scans,
    // in the world frame
    change.setOrigin(btVector3(dx, dy, 0.0));
    btQuaternion q;
    q.setRPY(0, 0, da);
    change.setRotation(q);


    // **** publish the new estimated pose as a tf
    if(take_vicon == true) {
        prevWorldToBase_.setOrigin(btVector3(pos_vicon[0],pos_vicon[1], pos_vicon[2]));
        btQuaternion vicon_q(quat_vicon.x(),quat_vicon.y(),quat_vicon.z(),quat_vicon.w());
        prevWorldToBase_.setRotation(vicon_q);
        prevWorldToBase_.setIdentity();
        take_vicon=false;
    }

    currWorldToBase = prevWorldToBase_ * baseToLaser_ * change * laserToBase_;

    heightLine = ransac(depthLine);

    frameP_ = worldFrame_;

    if (publishTf_  ) publishTf  (currWorldToBase, scan.header.stamp);

    if (publishPose_) publishPose(currWorldToBase, scan.header.stamp, frameP_, heightLine);

    // **** swap old and new

    delete prevPMScan_;
    prevPMScan_      = currPMScan;
    prevWorldToBase_ = currWorldToBase;

}
Пример #18
0
void PSMpositionNode::getMotion_can(const sensor_msgs::LaserScan& scan,  std::vector <depthPoint> *depthLine)//*********************************************getMotion_can()
{
    ROS_DEBUG("Received scan");


    // **** if this is the first scan, initialize and leave the function here

    if (!initialized_can)
    {
        initialized_can = initializeCan(scan);
        if (initialized_can) ROS_INFO("Matcher initialized");
        return;
    }

    // **** attmempt to match the two scans

    // CSM is used in the following way:
    // The reference scan (prevLDPcan_) always has a pose of 0
    // The new scan (currLDPScan) has a pose equal to the movement
    // of the laser in the world frame since the last scan (btTransform change)
    // The computed correction is then propagated using the tf machinery

    prevLDPScan_->odometry[0] = 0;
    prevLDPScan_->odometry[1] = 0;
    prevLDPScan_->odometry[2] = 0;

    prevLDPScan_->estimate[0] = 0;
    prevLDPScan_->estimate[1] = 0;
    prevLDPScan_->estimate[2] = 0;

    prevLDPScan_->true_pose[0] = 0;
    prevLDPScan_->true_pose[1] = 0;
    prevLDPScan_->true_pose[2] = 0;

    btTransform currWorldToBase;
    btTransform change;
    change.setIdentity();

    // what odometry model to use
    if (useTfOdometry_)
    {
        // get the current position of the base in the world frame
        // if no transofrm is available, we'll use the last known transform

        getCurrentEstimatedPose(currWorldToBase, scan);
        change = laserToBase_ * prevWorldToBase_.inverse() * currWorldToBase * baseToLaser_;
    }
    else if (useImuOdometry_)
    {
        imuMutex_.lock();
        double dTheta = currImuAngle_ - prevImuAngle_;
        prevImuAngle_ = currImuAngle_;
        change.getRotation().setRPY(0.0, 0.0, dTheta);
        imuMutex_.unlock();
    }

    geometry_msgs::Pose2D p;
    tfToPose2D(change, p);
    LDP currLDPScan = rosToLDPScan(scan, p);

    input_.laser_ref  = prevLDPScan_;
    input_.laser_sens = currLDPScan;
    input_.first_guess[0] = 0;
    input_.first_guess[1] = 0;
    input_.first_guess[2] = 0;

    sm_icp(&input_, &output_);

    if (!output_.valid)
    {
        ROS_WARN("Error in scan matching");
        ld_free(prevLDPScan_);
        prevLDPScan_ = currLDPScan;
        return;
    }

    // **** calculate change in position

    double dx = output_.x[0];
    double dy = output_.x[1];
    double da = output_.x[2];

    // change = scan match result for how much laser moved between scans,
    // in the world frame
    change.setOrigin(btVector3(dx, dy, 0.0));
    btQuaternion q;
    q.setRPY(0, 0, da);
    change.setRotation(q);

    frameP_ = worldFrame_;
    heightLine = ransac(depthLine);
    // **** publish the new estimated pose as a tf

    if(take_vicon == true) {
        prevWorldToBase_.setOrigin(btVector3(pos_vicon[0],pos_vicon[1], pos_vicon[2]));
        btQuaternion vicon_q(quat_vicon.x(),quat_vicon.y(),quat_vicon.z(),quat_vicon.w());
        prevWorldToBase_.setRotation(vicon_q);
    }

    currWorldToBase = prevWorldToBase_ * baseToLaser_ * change * laserToBase_;

    if (publishTf_  ) publishTf  (currWorldToBase, scan.header.stamp);
    if (publishPose_) publishPose(currWorldToBase, scan.header.stamp, frameP_, heightLine);

    // **** swap old and new

    ld_free(prevLDPScan_);
    prevLDPScan_ = currLDPScan;
    prevWorldToBase_ = currWorldToBase;

    // **** timing information - needed for profiling only

}
Пример #19
0
int main_cases(int c, char *v[])
{
	if (c != 6 && c != 7 && c != 8) {
		fprintf(stderr, "usage:\n\t%s {line,aff,affn,fm} "
		//                         0   1
		"ntrials maxerr minliers omodel [omask [oinliers]] <data\n",*v);
		//2      3      4        5       6      7
		return EXIT_FAILURE;
	}

	// parse input options
	char *model_id = v[1];
	int ntrials = atoi(v[2]);
	float maxerr = atof(v[3]);
	int minliers = atoi(v[4]);
	char *filename_omodel = c > 5 ? v[5] : 0;
	char *filename_omask = c > 6 ? v[6] : 0;
	char *filename_inliers = c > 7 ? v[7] : 0;

	// declare context variables
	int modeldim, datadim, nfit;
	ransac_error_evaluation_function *model_evaluation;
	ransac_model_generating_function *model_generation;
	ransac_model_accepting_function *model_acceptation = NULL;
	void *user_data = NULL;


	// fill context variables according to ransac case
	if (0 == strcmp(model_id, "line")) {
		datadim = 2;
		modeldim = 3;
		nfit = 2;
		model_evaluation = distance_of_point_to_straight_line;
		model_generation = straight_line_through_two_points;

	} else if (0 == strcmp(model_id, "aff")) {
		datadim = 4;
		modeldim = 6;
		nfit = 3;
		model_evaluation = affine_match_error;
		model_generation = affine_map_from_three_pairs;

	} else if (0 == strcmp(model_id, "affn")) {
		datadim = 4;
		modeldim = 6;
		nfit = 3;
		model_evaluation = affine_match_error;
		model_generation = affine_map_from_three_pairs;
		model_acceptation = affine_map_is_reasonable;

	} else if (0 == strcmp(model_id, "hom")) {
		datadim = 4;
		modeldim = 9;
		nfit = 4;
		model_evaluation = homographic_match_error;
		model_generation = homography_from_four;
		//model_acceptation = homography_is_reasonable;
		model_acceptation = NULL;

	} else if (0 == strcmp(model_id, "aff3d")) {
		datadim = 6;
		modeldim = 12;
		nfit = 4;
		model_evaluation = affine3d_match_error;
		model_generation = affine3d_map_from_four_pairs;

	} else if (0 == strcmp(model_id, "fm")) { // fundamental matrix
		datadim = 4;
		modeldim = 9;
		nfit = 7;
		model_evaluation = epipolar_error;
		model_generation = seven_point_algorithm;
		//model_acceptation = fundamental_matrix_is_reasonable;

	} else if (0 == strcmp(model_id, "fmn")) { // fundamental matrix
		int main_hack_fundamental_matrix(int,char*[]);
		return main_hack_fundamental_matrix(c-1, v+1);
	} else if (0 == strcmp(model_id, "fmnt")) { // fundamental matrix
		int main_hack_fundamental_trimatrix(int,char*[]);
		return main_hack_fundamental_trimatrix(c-1, v+1);
	} else {
		printf("unrecognized model \"%s\"\n", model_id);
		return EXIT_FAILURE;
	}

	// read input data
	int n;
	float *data = read_ascii_floats(stdin, &n);
	n /= datadim;

	// call the ransac function to fit a model to data
	float model[modeldim];
	bool *mask = xmalloc(n * sizeof*mask);
	int n_inliers = ransac(mask, model, data, datadim, n, modeldim,
			model_evaluation, model_generation,
			nfit, ntrials, minliers, maxerr,
			model_acceptation, user_data);


	// print a summary of the results
	if (n_inliers > 0) {
		printf("RANSAC found a model with %d inliers\n", n_inliers);
		printf("parameters =");
		for (int i = 0; i < modeldim; i++)
			printf(" %g", model[i]);
		printf("\n");
	} else printf("RANSAC found no model\n");

	// if requested, save the inlying data points
	if (filename_inliers) {
		FILE *f = xfopen(filename_inliers, "w");
		for (int i = 0; i < n; i++)
			if (mask[i]) {
				for(int d = 0; d < datadim; d++)
					fprintf(f,"%g ",data[i*datadim+d]);
				fprintf(f,"\n");
			}
		xfclose(f);
	}

	// if requested, save the inlier mask
	if (filename_omask) {
		FILE *f = xfopen(filename_omask, "w");
		for (int i = 0; i < n; i++)
			fprintf(f, mask[i]?" 1":" 0");
		fprintf(f, "\n");
		xfclose(f);
	}

	// if requested, save the model
	if (filename_omodel) {
		FILE *f = xfopen(filename_omodel, "w");
		for (int i = 0; i < modeldim; i++)
			fprintf(f, "%lf%c", model[i], i==modeldim-1?'\n':' ');
		xfclose(f);
	}


	return EXIT_SUCCESS;
}
Пример #20
0
void callback(const sensor_msgs::PointCloud2::ConstPtr& cloud)
{
    ros::Time whole_start = ros::Time::now();

    ros::Time declare_types_start = ros::Time::now();

    // filter
    pcl::VoxelGrid<sensor_msgs::PointCloud2> voxel_grid;
    pcl::PassThrough<sensor_msgs::PointCloud2> pass;
    pcl::ExtractIndices<pcl::PointXYZ> extract_indices;
    pcl::ExtractIndices<pcl::PointXYZ> extract_indices2;

    // Create the segmentation object
    pcl::SACSegmentation<pcl::PointXYZ> seg;

    // The plane and sphere coefficients
    pcl::ModelCoefficients::Ptr coefficients_plane (new pcl::ModelCoefficients ());
    pcl::ModelCoefficients::Ptr coefficients_sphere (new pcl::ModelCoefficients ());

    // The plane and sphere inliers
    pcl::PointIndices::Ptr inliers_plane (new pcl::PointIndices ());
    pcl::PointIndices::Ptr inliers_sphere (new pcl::PointIndices ());

    // The point clouds
    sensor_msgs::PointCloud2::Ptr passthrough_filtered (new sensor_msgs::PointCloud2);
    sensor_msgs::PointCloud2::Ptr plane_seg_output_cloud (new sensor_msgs::PointCloud2);
    sensor_msgs::PointCloud2::Ptr sphere_RANSAC_output_cloud (new sensor_msgs::PointCloud2);
    sensor_msgs::PointCloud2::Ptr rest_whole_cloud (new sensor_msgs::PointCloud2);
    sensor_msgs::PointCloud2::Ptr rest_cloud_filtered (new sensor_msgs::PointCloud2);
    sensor_msgs::PointCloud2::Ptr sphere_output_cloud (new sensor_msgs::PointCloud2);
    sensor_msgs::PointCloud2::Ptr whole_pc (new sensor_msgs::PointCloud2);
    sensor_msgs::PointCloud2::Ptr ball_candidate_output_cloud (new sensor_msgs::PointCloud2);

    // The PointCloud
    pcl::PointCloud<pcl::PointXYZ>::Ptr plane_seg_cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr plane_seg_output (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr remove_plane_cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr sphere_cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr sphere_output (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr sphere_RANSAC_output (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr remove_false_ball_candidate (new pcl::PointCloud<pcl::PointXYZ>);

    std::vector<int> inliers;

    ros::Time declare_types_end = ros::Time::now();

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /*
     * Pass through Filtering
     */
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    ros::Time pass_start = ros::Time::now();

    pass.setInputCloud (cloud);
    pass.setFilterFieldName ("z");
    pass.setFilterLimits (0, 2.5);
    pass.filter (*passthrough_filtered);

    passthrough_pub.publish(passthrough_filtered);

    ros::Time pass_end = ros::Time::now();

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /*
     * for plane features pcl::SACSegmentation
     */
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    ros::Time plane_seg_start = ros::Time::now();

    // Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud
    pcl::fromROSMsg (*passthrough_filtered, *plane_seg_cloud);

    // Optional
    seg.setOptimizeCoefficients (true);
    seg.setModelType (pcl::SACMODEL_PERPENDICULAR_PLANE);
    seg.setMethodType (pcl::SAC_RANSAC);
    seg.setAxis(Eigen::Vector3f (0, -1, 0));       // best plane should be perpendicular to z-axis
    seg.setMaxIterations (40);
    seg.setDistanceThreshold (0.05);
    seg.setInputCloud (plane_seg_cloud);
    seg.segment (*inliers_plane, *coefficients_plane);

    extract_indices.setInputCloud(plane_seg_cloud);
    extract_indices.setIndices(inliers_plane);
    extract_indices.setNegative(false);
    extract_indices.filter(*plane_seg_output);


    pcl::toROSMsg (*plane_seg_output, *plane_seg_output_cloud);
    plane_pub.publish(plane_seg_output_cloud);

    ros::Time plane_seg_end = ros::Time::now();

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /*
     * Extract rest plane and passthrough filtering
     */
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    ros::Time rest_pass_start = ros::Time::now();

    // Create the filtering object
    // Remove the planar inliers, extract the rest
    extract_indices.setNegative (true);
    extract_indices.filter (*remove_plane_cloud);
    plane_seg_cloud.swap (remove_plane_cloud);

    // publish result of Removal the planar inliers, extract the rest
    pcl::toROSMsg (*plane_seg_cloud, *rest_whole_cloud);
    rest_whole_pub.publish(rest_whole_cloud);          // 'rest_whole_cloud' substituted whole_pc

    ros::Time rest_pass_end = ros::Time::now();

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    ros::Time find_ball_start = ros::Time::now();
    int iter = 0;

    while(iter < 5)
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /*
         * for sphere features pcl::SACSegmentation
         */
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        // Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud
        pcl::fromROSMsg (*rest_whole_cloud, *sphere_cloud);

        ros::Time sphere_start = ros::Time::now();

        // Optional
        seg.setOptimizeCoefficients (false);
        // Mandatory
        seg.setModelType (pcl::SACMODEL_SPHERE);
        seg.setMethodType (pcl::SAC_RANSAC);
        seg.setMaxIterations (10000);
        seg.setDistanceThreshold (0.03);
        seg.setRadiusLimits (0.12, 0.16);
        seg.setInputCloud (sphere_cloud);
        seg.segment (*inliers_sphere, *coefficients_sphere);
        //std::cerr << "Sphere coefficients: " << *coefficients_sphere << std::endl;


        if (inliers_sphere->indices.empty())
            std::cerr << "[[--Can't find the Sphere Candidate.--]]" << std::endl;
        else {
            extract_indices.setInputCloud(sphere_cloud);
            extract_indices.setIndices(inliers_sphere);
            extract_indices.setNegative(false);
            extract_indices.filter(*sphere_output);
            pcl::toROSMsg (*sphere_output, *sphere_output_cloud);
            sphere_seg_pub.publish(sphere_output_cloud);          // 'sphere_output_cloud' means ball candidate point cloud
        }

        ros::Time sphere_end = ros::Time::now();

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /*
         * for sphere features pcl::SampleConsensusModelSphere
         */
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        ros::Time sphere_RANSAC_start = ros::Time::now();

        // created RandomSampleConsensus object and compute the appropriated model
        pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr model_s(new pcl::SampleConsensusModelSphere<pcl::PointXYZ> (sphere_output));

        pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_s);
        ransac.setDistanceThreshold (.01);
        ransac.computeModel();
        ransac.getInliers(inliers);

        // copies all inliers of the model computed to another PointCloud
        pcl::copyPointCloud<pcl::PointXYZ>(*sphere_output, inliers, *sphere_RANSAC_output);

        pcl::toROSMsg (*sphere_RANSAC_output, *sphere_RANSAC_output_cloud);

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /*
         * To discriminate a ball
         */
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        double w = 0;
        w = double(sphere_RANSAC_output_cloud->width * sphere_RANSAC_output_cloud->height)
            /double(sphere_output_cloud->width * sphere_output_cloud->height);

        if (w > 0.9) {
            BALL = true;
            std::cout << "can find a ball" << std::endl;
            true_ball_pub.publish(sphere_RANSAC_output_cloud);
            break;
        } else {
            BALL = false;
            std::cout << "can not find a ball" << std::endl;

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            /*
             * Exclude false ball candidate
             */
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            //ros::Time rest_pass_start = ros::Time::now();

            // Create the filtering object
            // Remove the planar inliers, extract the rest
            extract_indices2.setInputCloud(plane_seg_cloud);
            extract_indices2.setIndices(inliers_sphere);
            extract_indices2.setNegative (true);
            extract_indices2.filter (*remove_false_ball_candidate);
            sphere_RANSAC_output.swap (remove_false_ball_candidate);

            // publish result of Removal the planar inliers, extract the rest
            pcl::toROSMsg (*sphere_RANSAC_output, *ball_candidate_output_cloud);
            rest_ball_candidate_pub.publish(ball_candidate_output_cloud);
            rest_whole_cloud = ball_candidate_output_cloud;

        }
        iter++;
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        ros::Time sphere_RANSAC_end = ros::Time::now();

    }
    ros::Time find_ball_end = ros::Time::now();


    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    ros::Time whole_end = ros::Time::now();

    std::cout << "cloud size             : " << cloud->width * cloud->height << std::endl;
    std::cout << "plane size             : " << plane_seg_output_cloud->width * plane_seg_output_cloud->height << std::endl;
    std::cout << "rest size              : " << rest_whole_cloud->width * rest_whole_cloud->height << std::endl;
    std::cout << "sphere size            : " << sphere_output_cloud->width * sphere_output_cloud->height << std::endl;
    std::cout << "sphere RANSAC size     : " << sphere_RANSAC_output_cloud->width * sphere_RANSAC_output_cloud->height << "   " << sphere_RANSAC_output->points.size() << std::endl;
    std::cout << "sphereness             : " << double(sphere_RANSAC_output_cloud->width * sphere_RANSAC_output_cloud->height)
              /double(sphere_output_cloud->width * sphere_output_cloud->height) << std::endl;

    std::cout << "model coefficient      : " << coefficients_plane->values[0] << " "
              << coefficients_plane->values[1] << " "
              << coefficients_plane->values[2] << " "
              << coefficients_plane->values[3] << " " << std::endl;



    printf("\n");

    std::cout << "whole time             : " << whole_end - whole_start << " sec" << std::endl;
    std::cout << "declare types time     : " << declare_types_end - declare_types_start << " sec" << std::endl;
    std::cout << "passthrough time       : " << pass_end - pass_start << " sec" << std::endl;
    std::cout << "plane time             : " << plane_seg_end - plane_seg_start << " sec" << std::endl;
    std::cout << "rest and pass time     : " << rest_pass_end - rest_pass_start << " sec" << std::endl;
    std::cout << "find a ball time       : " << find_ball_end - find_ball_start << " sec" << std::endl;
    //std::cout << "sphere time            : " << sphere_end - sphere_start << " sec" << std::endl;
    //std::cout << "sphere ransac time     : " << sphere_RANSAC_end - sphere_RANSAC_start << " sec" << std::endl;
    printf("\n----------------------------------------------------------------------------\n");
    printf("\n");
}
Пример #21
0
/*!
  Compute the pose from a list lp of  2D point (x,y)  and  a list lP 3D points
  (X,Y,Z) in P using the Ransac algorithm. It is not assumed that
  the 2D and 3D points are registred

  At least numberOfInlierToReachAConsensus of true correspondance are required
  to validate the pose

  The inliers are given in a list of vpPoint lPi.

  The pose is returned in cMo.

  \param lp : List of 2d points (x and y attributes are used).
  \param lP : List of 3d points (oX, oY and oZ attributes are used).
  \param numberOfInlierToReachAConsensus : The minimum number of inlier to have
  to consider a trial as correct.
  \param threshold : The maximum error allowed between the 2d points and the
  reprojection of its associated 3d points by the current pose (in meter).
  \param ninliers : Number of inliers found for the best solution.
  \param lPi : List of points (2d and 3d) that are inliers for the best solution.
  \param cMo : The computed pose (best solution).
  \param maxNbTrials : Maximum number of trials before considering a solution
  fitting the required \e numberOfInlierToReachAConsensus and \e threshold
  cannot be found.
 */
void
vpPose::ransac(std::list<vpPoint> &lp,
               std::list<vpPoint> &lP,
               const int numberOfInlierToReachAConsensus,
               const double threshold,
               unsigned int &ninliers,
               std::list<vpPoint> &lPi,
               vpHomogeneousMatrix &cMo,
               const int maxNbTrials)
{
  unsigned int i;
  unsigned int n = lp.size() ;
  unsigned int m = lP.size() ;

  double *x, *y;
  x = new double [n];
  y = new double [n];

  vpPoint pin ;
  i = 0;
  for (std::list<vpPoint>::const_iterator it = lp.begin(); it != lp.end(); ++it)
  {
    pin = *it;
    x[i] = pin.get_x() ;
    y[i] = pin.get_y() ;
    ++ i;
  }

  double *X, *Y, *Z;
  X = new double [m];
  Y = new double [m];
  Z = new double [m];
  i = 0;
  for (std::list<vpPoint>::const_iterator it = lP.begin(); it != lP.end(); ++it)
  {
    pin = *it;
    X[i] = pin.get_oX() ;
    Y[i] = pin.get_oY() ;
    Z[i] = pin.get_oZ() ;
    ++i;
  }

  vpColVector xi,yi,Xi,Yi,Zi ;

  ransac(n,x,y,
         m,X,Y,Z, numberOfInlierToReachAConsensus,
         threshold,
         ninliers,
         xi,yi,Xi,Yi,Zi,
         cMo, maxNbTrials) ;

  for( i=0 ; i < ninliers ; i++)
  {
    vpPoint Pi ;
    Pi.setWorldCoordinates(Xi[i],Yi[i], Zi[i]) ;
    Pi.set_x(xi[i]) ;
    Pi.set_y(yi[i]) ;
    lPi.push_back(Pi);
  }

  delete [] x;
  delete [] y;
  delete [] X;
  delete [] Y;
  delete [] Z;

}
Пример #22
0
/*!
  Compute the pose from a list lp of  2D point (x,y)  and  a list lP 3D points
  (X,Y,Z) in P using the Ransac algorithm. It is not assumed that
  the 2D and 3D points are registred

  at least numberOfInlierToReachAConsensus of true correspondance are required
  to validate the pose

  the inliers are given in a list of lPi vpPoint

  the pose is return in cMo
 */
void
vpPose::ransac(vpList<vpPoint> &lp,
	       vpList<vpPoint> &lP,
	       const int numberOfInlierToReachAConsensus,
	       const double threshold,
	       int &ninliers,
	       vpList<vpPoint> &lPi,
	       vpHomogeneousMatrix &cMo)
{
  int n = lp.nbElement() ;
  int m = lP.nbElement() ;

  double *x, *y;
  x = new double [n];
  y = new double [n];

  vpPoint pin ;

  lp.front() ;
  int i = 0 ;
  while(!lp.outside())
  {
    pin = lp.value() ; lp.next() ;
    x[i] = pin.get_x() ;
    y[i] = pin.get_y() ;
    i++ ;
  }

  double *X, *Y, *Z;
  X = new double [m];
  Y = new double [m];
  Z = new double [m];
  lP.front() ;
   i = 0 ;
  while(!lP.outside())
  {
    pin = lP.value() ; lP.next() ;
    X[i] = pin.get_oX() ;
    Y[i] = pin.get_oY() ;
    Z[i] = pin.get_oZ() ;
    i++ ;
  }

  vpColVector xi,yi,Xi,Yi,Zi ;

  ransac(n,x,y,
	 m,X,Y,Z, numberOfInlierToReachAConsensus,
	 threshold,
	 ninliers,
	 xi,yi,Xi,Yi,Zi,
	 cMo) ;


  for( i=0 ; i < ninliers ; i++)
  {
    vpPoint Pi ;
    Pi.setWorldCoordinates(Xi[i],Yi[i], Zi[i]) ;
    Pi.set_x(xi[i]) ;
    Pi.set_y(yi[i]) ;
    lPi += Pi ;
  }


  delete [] x;
  delete [] y;
  delete [] X;
  delete [] Y;
  delete [] Z;

}
Пример #23
0
void inliers::checkThings()
{
 ransac();
std::cout<<std::endl<<" ransac finished start fundamental matrix approximation  "<<std::endl;
 estimateFundamentalMatrix();
}
Пример #24
0
int
main (int argc, char** argv)
{
  if (pcl::console::find_argument (argc, argv, "-h") >= 0)
  {
    print_help (argv[0]);
    return 0;
  }

  //pcl::PointCloud<pcl::PointXYZ>::Ptr initial_cloud(new pcl::PointCloud<pcl::PointXYZ>);
  //pcl::PointCloud<pcl::PointXYZ>::Ptr matched_cloud(new pcl::PointCloud<pcl::PointXYZ>);

  //cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);

  std::vector<int> pcd_file_indices = pcl::console::parse_file_extension_argument (argc, argv, ".pcd");

  if (pcd_file_indices.size () != 1)
  {
    std::cout << "Need input PCD file" << std::endl;
    return (-1);
  }
  
  std::string pcd_file_name = argv[pcd_file_indices[0]];

  std::cout << "Reading file \"" << pcd_file_name << "\"" << std::endl;
  
  if (pcl::io::loadPCDFile<pcl::PointXYZ> (pcd_file_name, *initial_cloud) == -1) //* load the file
  {
    std::cerr << "Couldn't read file " << pcd_file_name << std::endl;
    return (-1);
  }

  std::cout << "Loaded "
            << initial_cloud->width * initial_cloud->height
            << " data points from "
            << pcd_file_name
            << std::endl;

  pcl::visualization::CloudViewer viewer ("Simple Cloud Viewer");

  if (pcl::console::find_argument (argc, argv, "-j") >= 0)
  {
    std::cout << "Just Visualize example" << std::endl;
    viewer.runOnVisualizationThreadOnce(viewer_initial_cloud);
  }
  else if (pcl::console::find_argument (argc, argv, "-m") >= 0)
  {
    std::cout << "Match and visualize matched" << std::endl;

		std::vector<int> inliers;
		//boost::shared_ptr< std::vector<int> > inliers_ptr(inliers);

		pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr
		  model_sphere(new pcl::SampleConsensusModelSphere<pcl::PointXYZ> (initial_cloud, true));

		pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_sphere);
		ransac.setDistanceThreshold (2);
		ransac.computeModel(1);
		ransac.getInliers(inliers);

		std::cout << "Found "
		          << inliers.size()
		          << " inliers with RANSAC "
		          << std::endl;

    pcl::copyPointCloud<pcl::PointXYZ>(*initial_cloud, inliers, *matched_cloud);

    viewer.runOnVisualizationThreadOnce(viewer_matched_cloud);
  }
  else if (pcl::console::find_argument (argc, argv, "-e") >= 0)
  {
    std::cout << "Match and visualize remaining" << std::endl;

		std::vector<int> inliers;
		//boost::shared_ptr< std::vector<int> > inliers_ptr(inliers);

		pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr
		  model_sphere(new pcl::SampleConsensusModelSphere<pcl::PointXYZ> (initial_cloud, true));

		pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_sphere);
		ransac.setDistanceThreshold (2);
		ransac.computeModel(1);
		ransac.getInliers(inliers);

		std::cout << "Found "
		          << inliers.size()
		          << " inliers with RANSAC "
		          << std::endl;

		pcl::PointIndices::Ptr inliers_ptr (new pcl::PointIndices());
		inliers_ptr->indices = inliers;

		pcl::ExtractIndices<pcl::PointXYZ> ei_filter (true);
		ei_filter.setInputCloud (initial_cloud);
		ei_filter.setIndices (inliers_ptr);
		ei_filter.setNegative (true);
		ei_filter.filter (*matched_cloud);
		//ei_filter.setNegative (true);
		//ei_filter.filterDirectly (initial_cloud);

    //pcl::copyPointCloud<pcl::PointXYZ>(*initial_cloud, inliers, *matched_cloud);

    viewer.runOnVisualizationThreadOnce(viewer_matched_cloud);
    //viewer.runOnVisualizationThreadOnce(viewer_initial_cloud);
  }
  else if (pcl::console::find_argument (argc, argv, "-b") >= 0)
  {
    std::cout << "Match and visualize both" << std::endl;

		std::vector<int> inliers;
		//boost::shared_ptr< std::vector<int> > inliers_ptr(inliers);

		pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr
		  model_sphere(new pcl::SampleConsensusModelSphere<pcl::PointXYZ> (initial_cloud, true));

    double min_r = 0;
    double max_r = 0;
    model_sphere->setRadiusLimits(20, 120);
    model_sphere->getRadiusLimits(min_r, max_r);

    std::cout << "Min R = " << min_r
      << " Max R = " << max_r << std::endl;

    //pcl::LeastMedianSquares<pcl::PointXYZ> ransac (model_sphere);
    //pcl::MaximumLikelihoodSampleConsensus<pcl::PointXYZ> ransac (model_sphere);
    //pcl::MEstimatorSampleConsensus<pcl::PointXYZ> ransac (model_sphere);
    //pcl::RandomizedMEstimatorSampleConsensus<pcl::PointXYZ> ransac (model_sphere);
		//pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_sphere);
		//pcl::ProgressiveSampleConsensus<pcl::PointXYZ> ransac (model_sphere);
    pcl::RandomizedRandomSampleConsensus<pcl::PointXYZ> ransac (model_sphere);

		ransac.setDistanceThreshold (3);
    ransac.setMaxIterations(10000);
		ransac.computeModel();
		ransac.getInliers(inliers);

		std::cout << "Found "
		          << inliers.size()
		          << " inliers with RANSAC "
		          << std::endl;
/*
    std::vector<int> inliers4;
		inliers4.push_back(inliers[0]);
    inliers4.push_back(inliers[1]);
    inliers4.push_back(inliers[2]);
    inliers4.push_back(inliers[3]);

    Eigen::VectorXf model_coefficients;

    for (size_t i = 4; i < (inliers.size() - 4); i++)
    {
      bool coeffs = model_sphere->computeModelCoefficients(inliers4, model_coefficients);
      if (coeffs)
      {
        std::cout << "Valid coefficients: " << model_coefficients << std::endl;
        //pcl::PointXYZ o;
        o.x = model_coefficients[0];
        o.y = model_coefficients[1];
        o.z = model_coefficients[2];
        r = model_coefficients[3];
        //viewer.addSphere (o, r, "sphere", 0);
        if (r > 20 && r < 120) break;
      }
      else
      {
        //std::cout << "Invalid coefficients: " << model_coefficients<< std::endl;
      }
      inliers4.pop_back();
      inliers4.push_back(inliers[i]);
    }
*/

    //pcl::computeCentroid(*initial_cloud, inliers, o);
    //r = 30;

    Eigen::VectorXf model_coefficients;
    ransac.getModelCoefficients(model_coefficients);
    std::cout << "Valid coefficients: " << model_coefficients << std::endl;
    o.x = model_coefficients[0];
    o.y = model_coefficients[1];
    o.z = model_coefficients[2];
    r = model_coefficients[3];

		pcl::PointIndices::Ptr inliers_ptr (new pcl::PointIndices());
		inliers_ptr->indices = inliers;

		pcl::ExtractIndices<pcl::PointXYZ> ei_filter (true);
		ei_filter.setInputCloud (initial_cloud);
		ei_filter.setIndices (inliers_ptr);
		ei_filter.setNegative (false);
		ei_filter.filter (*matched_cloud);
		ei_filter.setNegative (true);
		ei_filter.filter (*initial_cloud);
		//ei_filter.setNegative (true);
		//ei_filter.filterDirectly (initial_cloud);

    //pcl::copyPointCloud<pcl::PointXYZ>(*initial_cloud, inliers, *matched_cloud);

    viewer.runOnVisualizationThreadOnce(viewer_matched_cloud);
    viewer.runOnVisualizationThreadOnce(viewer_initial_cloud);
  }
  else if (pcl::console::find_argument (argc, argv, "-a") >= 0)
  {
    //shapes = true;
    std::cout << "Shapes visualisation example" << std::endl;
  }
  else if (pcl::console::find_argument (argc, argv, "-v") >= 0)
  {
    //viewports = true;
    std::cout << "Viewports example" << std::endl;
  }
  else if (pcl::console::find_argument (argc, argv, "-i") >= 0)
  {
    //interaction_customization = true;
    std::cout << "Interaction Customization example" << std::endl;
  }
  else
  {
    print_help (argv[0]);
    return 0;
  }


  //pcl::copyPointCloud<pcl::PointXYZ>(*initial_cloud, inliers, *matched_cloud);
  //pcl::IndicesPtr inliers_ptr(new std::vector<int>(inliers));

//indices_rem = eifilter.getRemovedIndices ();
// The indices_rem array indexes all points of cloud_in that are not indexed by indices_in
  //ei_filter.setNegative (true);
  //ei_filter.filter (*indices_out);
// Alternatively: the indices_out array is identical to indices_rem
//eifilter.setNegative (false);
//eifilter.setUserFilterValue (1337.0);
//eifilter.filterDirectly (cloud_in);
// This will directly modify cloud_in instead of creating a copy of the cloud
// It will overwrite all fields of the filtered points by the user value: 1337

/*
  std::cout << "Extracted "
            << matched_cloud->width * matched_cloud->height
            << " data points with filter"
            << std::endl;

  std::cout << "Left "
            << initial_cloud->width * initial_cloud->height
            << " data points"
            << std::endl;
*/
  //pcl::visualization::CloudViewer viewer ("Simple Cloud Viewer");

  //boost::function2<void, pcl::visualization::PCLVisualizer&, int> viewer_green_cloud_f = &viewer_green_cloud;

  //viewer.runOnVisualizationThreadOnce(viewer_initial_cloud);
  //viewer.runOnVisualizationThreadOnce(viewer_matched_cloud);

  while (!viewer.wasStopped ())
  {
  }

  return (0);
}
Пример #25
0
int LDWS(unsigned char *img, int width, int height, PointKAIST *pt_left, PointKAIST *pt_right)
{

	int result = 0, result2 = 0, i = 0;

	///////////calibration(img, width, height, pt_left, pt_right);

	search_lane(img, width, height-bottom_margin, pt_left, pt_right);

	ransac(img, pt_left, pt_right, 10);

	lane_filtering(pt_left, pt_right, width, height);

	// 일정 프레임(현재 100)까지 calibration을 수행하도록 하는 구문
	if(calibration_frame < 100)
	{
		calibration(pt_left, pt_right, width, height);
		calibration_frame++;
	}

	//result = warning_system2(pt_left, pt_right);
	//tracking(pt_left, pt_right, width, height);


	if(pt_left[0].x == 0 && pt_left[0].y == 0)
		init(pt_left, pt_right);

	if(pt_right[0].x == 0 && pt_right[0].y == 0)
		init(pt_left, pt_right);

/**
	// 기준선 그리기
	for(i=0; i<width; i++)
	{
		img[horizontal_center*width+i-1] = 255;
		img[horizontal_center*width+i] = 255;
		img[horizontal_center*width+i+1] = 255;
	}

	for(i=0; i<height; i++)
	{
		img[i*width+vertical_center-1] = 255;
		img[i*width+vertical_center] = 255;
		img[i*width+vertical_center+1] = 255;
	}
**/
	//printf("noise : %f\n", get_noise(img, width, height, pt_left[1].x, pt_right[1].x, pt_left[1].y));
/*
	//printf("%d ", pt_left[0].x);
	if((pt_right[0].x - pt_left[0].x) > 300 && pt_right[0].x != 0 && pt_right[0].y != 0 && pt_left[0].x != 0 && pt_right[0].y != 0)
		// 한쪽만 움직인 경우는 제외함
	{
		if((prev_prev_pt_left[0].x - pt_left[0].x) != 0 && (prev_prev_pt_right[0].x - pt_right[0].x) != 0)
		//printf("%d %d\n", pt_left[0].x, pt_right[0].x);


		// vertical_center로 교체됨
			result = warning_system(vertical_center, (pt_right[0].x - pt_left[0].x) / 2 + pt_left[0].x, warning_val, pt_left[0].x, pt_right[0].x);
	}
	else
	{
		result = 0;
		init(pt_left, pt_right);
	}
*/
	result = warning_system(vertical_center, (pt_right[0].x - pt_left[0].x) / 2 + pt_left[0].x, warning_val, pt_left[0].x, pt_right[0].x);
	//draw_lane(img, width, height, pt_left[0].x, pt_left[0].y, pt_right[0].x, pt_right[0].y, pt_left[2].x, pt_left[2].y, pt_right[2].x, pt_right[2].y, pt_left, pt_right);

	// 오른쪽
	if(result==1)
	{
		// 튀는 경우 방지
		if(start == 0 && prev_warning > 0)
		{
			//draw_warning(img, width, height);
			result2 = result;

			init(pt_left, pt_right);
		}
		else
			result2 = 0;
	}

	// 왼쪽
	else if(result==2)
	{
		if(start == 0 && prev_warning > 0)
		{
			//draw_warning2(img, width, height);
			result2 = result;

			init(pt_left, pt_right);
		}
		else
			result2 = 0;
	}
	else
	{
		start = 0;
		result = 0;
		result2 = 0;
	}

	prev_prev_pt_left[0].x = pt_left[0].x;
	prev_prev_pt_left[0].y = pt_left[0].y;
	prev_prev_pt_left[1].x = pt_left[1].x;
	prev_prev_pt_left[1].y = pt_left[1].y;
	prev_prev_pt_left[2].x = pt_left[2].x;
	prev_prev_pt_left[2].y = pt_left[2].y;

	prev_prev_pt_right[0].x = pt_right[0].x;
	prev_prev_pt_right[0].y = pt_right[0].y;
	prev_prev_pt_right[1].x = pt_right[1].x;
	prev_prev_pt_right[1].y = pt_right[1].y;
	prev_prev_pt_right[2].x = pt_right[2].x;
	prev_prev_pt_right[2].y = pt_right[2].y;

//	draw_test(img, width, height);


	//printf("warning : %d %d\n", prev_warning, result);

	//오른쪽 차선 1
	if(prev_warning == 1 && result == 2)
	{
		//draw_warning(img, width, height);
		//init(pt_left, pt_right);
		return 1;
	}
	// 왼쪽 차선 2
	else if(prev_warning == 2 && result == 1)
	{
		//draw_warning2(img, width, height);
		//init(pt_left, pt_right);
		return 2;
	}

	prev_warning = result;

	return 0;
}
Пример #26
0
int ransac_rotzoom(int *matched_points, int npoints, int *num_inliers_by_motion,
                   double *params_by_motion, int num_desired_motions) {
  return ransac(matched_points, npoints, num_inliers_by_motion,
                params_by_motion, num_desired_motions, 3, is_degenerate_affine,
                find_rotzoom, project_points_double_rotzoom);
}
Пример #27
0
int
main(int argc, char** argv)
{
  // initialize PointClouds
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr final (new pcl::PointCloud<pcl::PointXYZ>);

  // populate our PointCloud with points
  cloud->width    = 500;
  cloud->height   = 1;
  cloud->is_dense = false;
  cloud->points.resize (cloud->width * cloud->height);
  for (size_t i = 0; i < cloud->points.size (); ++i)
  {
    if (pcl::console::find_argument (argc, argv, "-s") >= 0 || pcl::console::find_argument (argc, argv, "-sf") >= 0)
    {
      cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0);
      cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0);
      if (i % 5 == 0)
        cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0);
      else if(i % 2 == 0)
        cloud->points[i].z =  sqrt( 1 - (cloud->points[i].x * cloud->points[i].x)
                                      - (cloud->points[i].y * cloud->points[i].y));
      else
        cloud->points[i].z =  - sqrt( 1 - (cloud->points[i].x * cloud->points[i].x)
                                        - (cloud->points[i].y * cloud->points[i].y));
    }
    else
    {
      cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0);
      cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0);
      if( i % 2 == 0)
        cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0);
      else
        cloud->points[i].z = -1 * (cloud->points[i].x + cloud->points[i].y);
    }
  }

  std::vector<int> inliers;

  // created RandomSampleConsensus object and compute the appropriated model
  pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr
    model_s(new pcl::SampleConsensusModelSphere<pcl::PointXYZ> (cloud));
  pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr
    model_p (new pcl::SampleConsensusModelPlane<pcl::PointXYZ> (cloud));
  if(pcl::console::find_argument (argc, argv, "-f") >= 0)
  {
    pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_p);
    ransac.setDistanceThreshold (.01);
    ransac.computeModel();
    ransac.getInliers(inliers);
  }
  else if (pcl::console::find_argument (argc, argv, "-sf") >= 0 )
  {
    pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_s);
    ransac.setDistanceThreshold (.01);
    ransac.computeModel();
    ransac.getInliers(inliers);
  }

  // copies all inliers of the model computed to another PointCloud
  pcl::copyPointCloud<pcl::PointXYZ>(*cloud, inliers, *final);

  // creates the visualization object and adds either our orignial cloud or all of the inliers
  // depending on the command line arguments specified.
  boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
  if (pcl::console::find_argument (argc, argv, "-f") >= 0 || pcl::console::find_argument (argc, argv, "-sf") >= 0)
    viewer = simpleVis(final);
  else
Пример #28
0
void callback(const sensor_msgs::PointCloud2::ConstPtr& cloud)
{
  ros::Time whole_start = ros::Time::now();

  ros::Time declare_types_start = ros::Time::now();

  // filter
  pcl::VoxelGrid<sensor_msgs::PointCloud2> voxel_grid;
  pcl::PassThrough<sensor_msgs::PointCloud2> pass;
  pcl::ExtractIndices<pcl::PointXYZ> extract_indices;

  // Create the segmentation object
  pcl::SACSegmentation<pcl::PointXYZ> seg;

  std::vector<int> inliers;

  // The plane and sphere coefficients
  pcl::ModelCoefficients::Ptr coefficients_sphere (new pcl::ModelCoefficients ());

  // The plane and sphere inliers
  pcl::PointIndices::Ptr inliers_sphere (new pcl::PointIndices ());

  // The point clouds
  sensor_msgs::PointCloud2::Ptr voxelgrid_filtered (new sensor_msgs::PointCloud2);
  sensor_msgs::PointCloud2::Ptr passthrough_filtered (new sensor_msgs::PointCloud2);
  sensor_msgs::PointCloud2::Ptr sphere_output_cloud (new sensor_msgs::PointCloud2);


  // The PointCloud
  pcl::PointCloud<pcl::PointXYZ>::Ptr sphere_cloud (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr sphere_output (new pcl::PointCloud<pcl::PointXYZ>);


  ros::Time declare_types_end = ros::Time::now();

  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  /*
   * Create Voxel grid Filtering
   */
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//  voxel_grid.setInputCloud (cloud);
//  voxel_grid.setLeafSize (0.01, 0.01, 0.01);
//  voxel_grid.filter (*voxelgrid_filtered);
//
//  // Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud
//  pcl::fromROSMsg (*voxelgrid_filtered, *transformed_cloud);

  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  /*
   * Pass through Filtering
   */
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  ros::Time pass_start = ros::Time::now();

  pass.setInputCloud (cloud);
  pass.setFilterFieldName ("z");
  pass.setFilterLimits (0, 3.5);
  pass.filter (*passthrough_filtered);

  pass.setInputCloud (passthrough_filtered);
  pass.setFilterFieldName ("y");
  pass.setFilterLimits (-0.1, 0.3);
  pass.filter (*passthrough_filtered);

  passthrough_pub.publish(passthrough_filtered);

  ros::Time pass_end = ros::Time::now();

  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  /*
   * for sphere features
   */
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  // Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud
  pcl::fromROSMsg (*passthrough_filtered, *sphere_cloud);

  ros::Time sphere_start = ros::Time::now();

  // created RandomSampleConsensus object and compute the appropriated model
  pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr model_s(new pcl::SampleConsensusModelSphere<pcl::PointXYZ> (sphere_cloud));

  pcl::RandomSampleConsensus<pcl::PointXYZ> ransac (model_s);
  ransac.setDistanceThreshold (.01);
  ransac.computeModel();
  ransac.getInliers(inliers);

  // copies all inliers of the model computed to another PointCloud
  pcl::copyPointCloud<pcl::PointXYZ>(*sphere_cloud, inliers, *sphere_output);

  pcl::toROSMsg (*sphere_output, *sphere_output_cloud);
  sphere_pub.publish(sphere_output_cloud);

//  // Optional
//  seg.setOptimizeCoefficients (true);
//  // Mandatory
//  seg.setModelType (pcl::SACMODEL_SPHERE);
//  seg.setMethodType (pcl::SAC_RANSAC);
//  seg.setMaxIterations (10000);
//  seg.setDistanceThreshold (0.05);
//  seg.setRadiusLimits (0, 0.15);
//  seg.setInputCloud (sphere_cloud);
//  seg.segment (*inliers_sphere, *coefficients_sphere);
//  //std::cerr << "Sphere coefficients: " << *coefficients_sphere << std::endl;
//
//
//  extract_indices.setInputCloud(sphere_cloud);
//  extract_indices.setIndices(inliers_sphere);
//  extract_indices.setNegative(false);
//  extract_indices.filter(*sphere_output);
//
//  if (sphere_output->points.empty ())
//     std::cerr << "Can't find the sphere component." << std::endl;
//
//  pcl::toROSMsg (*sphere_output, *sphere_output_cloud);
//  sphere_pub.publish(sphere_output_cloud);

  ros::Time sphere_end = ros::Time::now();

  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  /*
   * visualize normals
   */
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//  pcl::visualization::PCLVisualizer viewer("PCL Viewer");
//  viewer.setBackgroundColor (0.0, 0.0, 0.5);
//  viewer.addPointCloudNormals<pcl::PointXYZ,pcl::Normal>(sphere_cloud, cloud_normals3);
//  viewer.spin();

  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


  ros::Time whole_end = ros::Time::now();

  std::cout << "cloud size         : " << cloud->width * cloud->height << std::endl;
  std::cout << "pass_th size       : " << passthrough_filtered->width * passthrough_filtered->height << std::endl;
  std::cout << "sphere size        : " << sphere_output_cloud->width * sphere_output_cloud->height << std::endl;

  printf("\n");

  std::cout << "whole time             : " << whole_end - whole_start << " sec" << std::endl;
  std::cout << "declare types time     : " << declare_types_end - declare_types_start << " sec" << std::endl;
  std::cout << "passthrough time       : " << pass_end - pass_start << " sec" << std::endl;
  std::cout << "sphere time            : " << sphere_end - sphere_start << " sec" << std::endl;

  printf("\n----------------------------------------------------------------------------\n");
  printf("\n");
}
Пример #29
0
Line SegmentStitching::extractLineFromMeasurements(pcl::PointCloud<pcl::PointXYZ>::Ptr measurements,
                                                   float ransacThreshold,
                                                   std::vector<int>* inliers){
    // Create the sample consensus object for the received cloud
    pcl::SampleConsensusModelLine<pcl::PointXYZ>::Ptr
        modelLine(new pcl::SampleConsensusModelLine<pcl::PointXYZ>(measurements));
            
    pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(modelLine);
    ransac.setDistanceThreshold(ransacThreshold);
    ransac.computeModel();
    ransac.getInliers(*inliers);

    // Vector of 6 points
    // see http://docs.pointclouds.org/trunk/classpcl_1_1_sample_consensus_model_line.html
    Eigen::VectorXf coeff;
    ransac.getModelCoefficients(coeff);
    
    for (int i = 0; i < coeff.size(); i++){
        ROS_INFO("Coeff %d: %f", i, coeff[i]);
    }
    ROS_INFO("#Inliers: %d", (int)inliers->size());

    // Project inliers onto the line so that we end up with a cloud where
    // min+max can be found in order to define a line segment
    pcl::PointCloud<pcl::PointXYZ>::Ptr projected(new pcl::PointCloud<pcl::PointXYZ>);
    // project the inliers onto the model, without copying non-inliers over
    modelLine->projectPoints(*inliers, coeff, *projected, false);
    ROS_INFO("Projected size: %d", (int)projected->size());
    pcl::PointCloud<pcl::PointXYZ>::iterator it = projected->begin();

    // Segments have start and end points. A point is at the start or end of the
    // line if one of its coordinates corresponds to the minimum or maximum
    // value of either of the coordinate axes
    int xmaxInd = -1;
    int xminInd = -1;
    int ymaxInd = -1;
    int yminInd = -1;
    
    float xmax = -std::numeric_limits<float>::max();
    float ymax = -std::numeric_limits<float>::max();
    float xmin = std::numeric_limits<float>::max();
    float ymin = std::numeric_limits<float>::max();
    for (; it != projected->end(); it++) {
        // ROS_INFO_STREAM("Point " <<  (int)(it - projected->begin()) << ": " << *it);
        // std::cout << "x: " << it->x << ", max: " << xmax << " x bigger? " << (it->x > xmax) << std::endl;
        if (it->x > xmax){
            xmax = it->x;
            // index of this point is 
            xmaxInd = it - projected->begin();
            //ROS_INFO("X max ind: %d with val %f", xmaxInd, xmax);
        }
        if (it->y > ymax){
            ymax = it->y;
            // index of this point is 
            ymaxInd = it - projected->begin();
            //ROS_INFO("Y max ind: %d with val %f", ymaxInd, ymax);
        }
        if (it->x < xmin){
            xmin = it->x;
            // index of this point is 
            xminInd = it - projected->begin();
            //ROS_INFO("X min ind: %d with val %f", xminInd, xmin);
        }
        if (it->y < ymin){
            ymin = it->y;
            // index of this point is 
            yminInd = it - projected->begin();
            //ROS_INFO("Y min ind: %d with val %f", yminInd, ymin);
        }
    }
    ROS_INFO("xmin ind %d, xmax ind %d, ymin ind %d, ymax ind %d", 
             xminInd, xmaxInd, yminInd, ymaxInd);
    ROS_INFO("xmin %f, xmax %f, ymin %f, ymax %f", 
             xmin, xmax, ymin, ymax);

    // If the x or y coordinates are identical, then you have a vertical or
    // horizontal line - define start and end points of the line with the value
    // of xmin or max, and then assign values for the other coordinate to the
    // start and end point arbitrarily. You should be able to do this min/max
    // comparison based on the indices of xmin and xmax - they should be the same
    // if lines are horizontal or vertical
    if (xminInd == xmaxInd){
        return Line(pcl::PointXYZ(xmin, ymin, 0), pcl::PointXYZ(xmin, ymax, 0));
    } else if (yminInd == ymaxInd){
        return Line(pcl::PointXYZ(xmin, ymin, 0), pcl::PointXYZ(xmax, ymin, 0));
    } else {
        // TODO: Make sure this works correctly
        // This is a line which is not horizontal or vertical - the indices of
        // xmin,ymin or xmax, ymax should match. 
        if (xminInd == yminInd && xmaxInd == ymaxInd){
            return Line(pcl::PointXYZ(xmin, ymin, 0), pcl::PointXYZ(xmax, ymax, 0));
        } else if (xmaxInd == yminInd && xminInd == ymaxInd){
            return Line(pcl::PointXYZ(xmax, ymin, 0), pcl::PointXYZ(xmin, ymax, 0));
        }
    }
    ROS_ERROR("Reached end of extract line without getting anything!");
}
int main(int argc, char** argv) {
	//check if number of arguments is proper
	if(argc!=3){
		help();
		exit(0);
	}

	// initialize PointClouds
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr final(new pcl::PointCloud<pcl::PointXYZ>);

	if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) == -1) //* load the file
			{
		cerr << "Couldn't read file :" << argv[1] << "\n";
		return (-1);
	}

	std::vector<int> inliers;

	// created RandomSampleConsensus object and compute the appropriated model
	pcl::SampleConsensusModelSphere<pcl::PointXYZ>::Ptr model_s(new pcl::SampleConsensusModelSphere<pcl::PointXYZ>(cloud));
	pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr model_p(new pcl::SampleConsensusModelPlane<pcl::PointXYZ>(cloud));

	//RANSAC for Line model
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_line(new pcl::PointCloud<PointT>());
	if (pcl::console::find_argument(argc, argv, "-l") >= 0) {
		pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
		pcl::PointIndices::Ptr inliers_l(new pcl::PointIndices);
		// Create the segmentation object
		pcl::SACSegmentation<pcl::PointXYZ> seg;
		// Optional
		seg.setOptimizeCoefficients(true);
		// Mandatory
		seg.setModelType(pcl::SACMODEL_LINE);
		seg.setMethodType(pcl::SAC_RANSAC);
		seg.setDistanceThreshold(0.05);

		seg.setInputCloud(cloud);
		seg.segment(*inliers_l, *coefficients);
		// Write the line inliers to disk
		pcl::ExtractIndices<PointT> extract;
		extract.setInputCloud(cloud);
		extract.setIndices(inliers_l);
		extract.setNegative(false);

		extract.filter(*cloud_line);
	}


	if (pcl::console::find_argument(argc, argv, "-f") >= 0) {
		//RANSAC for Plane model
		pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_p);
		ransac.setDistanceThreshold(.01);
		ransac.computeModel();
		ransac.getInliers(inliers);
	} else if (pcl::console::find_argument(argc, argv, "-sf") >= 0) {
		//RANSAC for Sphere model
		pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_s);
		ransac.setDistanceThreshold(.01);
		ransac.computeModel();
		ransac.getInliers(inliers);
	}

	// copies all inliers of the model computed to another PointCloud
	pcl::copyPointCloud<pcl::PointXYZ>(*cloud, inliers, *final);

	// creates the visualization object and adds either our orignial cloud or all of the inliers
	// depending on the command line arguments specified.
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
	if (pcl::console::find_argument(argc, argv, "-f") >= 0 || pcl::console::find_argument(argc, argv, "-sf") >= 0) {
		viewer = simpleVis(final);
	} else if (pcl::console::find_argument(argc, argv, "-l") >= 0) {