void pass_through(const pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out, const Eigen::VectorXf lims) { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_x (new pcl::PointCloud<pcl::PointXYZ> ()), cloud_filtered_y (new pcl::PointCloud<pcl::PointXYZ> ()); pcl::PassThrough<pcl::PointXYZ> pass; if(lims.size() != 6) { ROS_WARN("Limits for pass-through wrong size"); return; } pass.setInputCloud(cloud_in); pass.setFilterFieldName("x"); pass.setFilterLimits(lims(0), lims(1)); pass.filter(*cloud_filtered_x); pass.setInputCloud(cloud_filtered_x); pass.setFilterFieldName("y"); pass.setFilterLimits(lims(2), lims(3)); pass.filter(*cloud_filtered_y); pass.setInputCloud(cloud_filtered_y); pass.setFilterFieldName("z"); pass.setFilterLimits(lims(4), lims(5)); pass.filter(*cloud_out); return; }
void ptf_cb(const sensor_msgs::PointCloud2ConstPtr& cloud_msg){ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_x(new pcl::PointCloud<pcl::PointXYZ>), cloud_filtered_xy(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_xyz(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_temp(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_wall(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_wall_projected(new pcl::PointCloud<pcl::PointXYZ>); // the aim is to filter out the wall planes from the image .... pcl::fromROSMsg(*cloud_msg, *cloud); // ROS_INFO("cloud size here1 is %d, %d", cloud->width , cloud->height); ROS_INFO("number of points in cloud %d", cloud->points.size()); if(cloud->width * cloud->height > 0){ pcl::PassThrough<pcl::PointXYZ> pass_x; // removing nans and unimportant points. pass_x.setInputCloud(cloud); pass_x.setFilterFieldName("x"); pass_x.setFilterLimits(x_min, x_max); pass_x.filter(*cloud_filtered_x); ROS_INFO("cloud size here 2 is %d", cloud_filtered_x->points.size()); pcl::PassThrough<pcl::PointXYZ> pass_y; pass_y.setInputCloud(cloud_filtered_x); pass_y.setFilterFieldName("y"); pass_y.setFilterLimits(y_min, y_max); pass_y.filter(*cloud_filtered_xy); ROS_INFO("cloud size here 3 is %d", cloud_filtered_xy->points.size()); pub_cloud2.publish(cloud_filtered_xy); pcl::PassThrough<pcl::PointXYZ> pass_z; pass_z.setInputCloud(cloud_filtered_xy); pass_z.setFilterFieldName("z"); pass_z.setFilterLimits(z_min, z_max); pass_z.filter(*cloud_filtered_xyz); cloud_filtered_temp = cloud_filtered_xy; ROS_INFO("cloud size here 4 is %d", cloud_filtered_xyz->points.size()); if(cloud_filtered_xy->points.size() > 1000){ pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients); pcl::PointIndices::Ptr inliers(new pcl::PointIndices); pcl::SACSegmentation<pcl::PointXYZ> seg; seg.setOptimizeCoefficients(true); seg.setModelType (pcl::SACMODEL_PLANE); seg.setMethodType (pcl::SAC_RANSAC); seg.setMaxIterations(100); seg.setDistanceThreshold(0.05); seg.setInputCloud(cloud_filtered_temp); seg.segment(*inliers, *coefficients); int num_points = (int) cloud_filtered_temp->points.size(); if(inliers->indices.size() > POINT_THRESHOLD ){ pcl::ExtractIndices<pcl::PointXYZ> extract; extract.setInputCloud(cloud_filtered_temp); extract.setIndices (inliers); extract.setNegative(true); extract.filter(*cloud_filtered_temp); // pcl::SACSegmentation<pcl::PointXYZ> seg1; // seg1.setOptimizeCoefficients(true); // seg1.setModelType (pcl::SACMODEL_PLANE); // seg1.setMethodType (pcl::SAC_RANSAC); // seg1.setMaxIterations(1000); // seg1.setDistanceThreshold(0.01); // seg1.setInputCloud(cloud_filtered_temp); // seg1.segment(*inliers, *coefficients); } } ROS_INFO("cloud size here 5 is %d", cloud_filtered_temp->points.size()); // // seperate the walls pcl::PassThrough<pcl::PointXYZ> pass_wall; pass_wall.setInputCloud(cloud_filtered_xy); pass_wall.setFilterFieldName("y"); pass_wall.setFilterLimits(0.005, 0.55); pass_wall.filter(*cloud_filtered_wall); // pub_cloud1.publish(cloud_filtered_wall); // pub_cloud3.publish(cloud_filtered_wall); pcl::ModelCoefficients::Ptr wall_coefficients (new pcl::ModelCoefficients ()); wall_coefficients->values.resize (4); wall_coefficients->values[0] = wall_coefficients->values[1] = 0; wall_coefficients->values[2] = 1.0; wall_coefficients->values[3] = 0; // Create the filtering object pcl::ProjectInliers<pcl::PointXYZ> proj; proj.setModelType (pcl::SACMODEL_PLANE); proj.setInputCloud (cloud_filtered_temp); proj.setModelCoefficients (wall_coefficients); proj.filter(*cloud_wall_projected); pub_cloud3.publish(cloud_filtered_temp); // ROS_INFO("cloud size here 4 is %d", cloud_wall_projected->points.size()); } }
void marker_cb (const visualization_msgs::MarkerArray::ConstPtr& inputMarkerArray) { colour_recognizer::ObjectArray objectArrayTemp; visualization_msgs::MarkerArray tempMarkerArray; myPointCloud::Ptr cloud_filtered_sum (new myPointCloud); // myPointCloud::Ptr cloud_filtered_sum ; int flag=0; // find out mean of all points within a marker array for(int i=0;i<inputMarkerArray->markers.size();i++){ colour_recognizer::ObjectProperty objectTemp; float xSum=0.0; float ySum=0.0; float zSum=0.0; for(int j=0;j<inputMarkerArray->markers[i].points.size();j++){ xSum+=inputMarkerArray->markers[i].points[j].x; ySum+=inputMarkerArray->markers[i].points[j].y; zSum+=inputMarkerArray->markers[i].points[j].z; } float xPos=xSum/inputMarkerArray->markers[i].points.size(); float yPos=ySum/inputMarkerArray->markers[i].points.size(); float zPos=zSum/inputMarkerArray->markers[i].points.size(); // standard deviation of all points wihtin a marker array float xVarSum=0.0; float yVarSum=0.0; float zVarSum=0.0; for(int j=0;j<inputMarkerArray->markers[i].points.size();j++){ xVarSum+=pow(inputMarkerArray->markers[i].points[j].x - xPos,2); yVarSum+=pow(inputMarkerArray->markers[i].points[j].y - yPos,2); zVarSum+=pow(inputMarkerArray->markers[i].points[j].z - zPos,2); } float xStd=sqrt(xVarSum/inputMarkerArray->markers[i].points.size()); float yStd=sqrt(yVarSum/inputMarkerArray->markers[i].points.size()); float zStd=sqrt(zVarSum/inputMarkerArray->markers[i].points.size()); // making a marker cube with dimensions of 2 SD along the sides, 4 SD would ensure 98% of the points, but // the cloud does not align very well with a large cube. 2 SD seems satisfactory visualization_msgs::Marker tempMarker; tempMarker.header.frame_id = inputMarkerArray->markers[i].header.frame_id; tempMarker.header.stamp = ros::Time(); tempMarker.ns = "my_namespace"; tempMarker.id = inputMarkerArray->markers[i].id; tempMarker.type = visualization_msgs::Marker::CUBE; tempMarker.action = visualization_msgs::Marker::ADD; tempMarker.pose.position.x = xPos; tempMarker.pose.position.y = yPos; tempMarker.pose.position.z = zPos; tempMarker.pose.orientation.x = 0.0; tempMarker.pose.orientation.y = 0.0; tempMarker.pose.orientation.z = 0.0; tempMarker.pose.orientation.w = 1.0; tempMarker.scale.x = 2*xStd; tempMarker.scale.y = 2*yStd; tempMarker.scale.z = 2*zStd; tempMarker.color.a = 1.0; tempMarker.color.r = 0.0; tempMarker.color.g = 1.0; tempMarker.color.b = 0.0; tempMarkerArray.markers.push_back(tempMarker); myPointCloud::Ptr cloud_filtered_z (new myPointCloud); myPointCloud::Ptr cloud_filtered_y (new myPointCloud); myPointCloud::Ptr cloud_filtered_x (new myPointCloud); // myPointCloud::Ptr cloud_filtered_z; // myPointCloud::Ptr cloud_filtered_y; // myPointCloud::Ptr cloud_filtered_x; pcl::PassThrough<pcl::PointXYZRGB> pass_z(true); pcl::PassThrough<pcl::PointXYZRGB> pass_y; pcl::PassThrough<pcl::PointXYZRGB> pass_x; IndicesPtr zPointer (new std::vector<int>); IndicesPtr yPointer (new std::vector<int>); IndicesPtr xPointer (new std::vector<int>); pass_z.setInputCloud (globalCloud); pass_z.setFilterFieldName ("z"); pass_z.setFilterLimits (zPos-zStd, zPos+zStd); pass_z.filter (*zPointer); // pass_z.setFilterFieldName ("y"); // pass_z.setFilterLimits (yPos-yStd, yPos+yStd); pass_z.setIndices (zPointer); pass_z.setFilterFieldName ("x"); pass_z.setFilterLimits (xPos-xStd, xPos+xStd); pass_z.filter (*xPointer); pass_z.setIndices(xPointer); pass_z.setFilterFieldName ("y"); pass_z.setFilterLimits (yPos-yStd, yPos+yStd); // pass_z.filter (*zPointer); //pass.setFilterLimitsNegative (true); pass_z.filter (*cloud_filtered_y); // pass_y.setInputCloud (cloud_filtered_z); // pass_y.setFilterFieldName ("y"); // pass_y.setFilterLimits (yPos-yStd, yPos+yStd); // //pass.setFilterLimitsNegative (true); // pass_z.filter (*cloud_filtered_y); // pass_x.setInputCloud (cloud_filtered_y); // pass_x.setFilterFieldName ("x"); // pass_x.setFilterLimits (xPos-xStd, xPos+xStd); // //pass.setFilterLimitsNegative (true); // pass_x.filter (*cloud_filtered_x); int sizeCloud = cloud_filtered_y->size(); if(sizeCloud==0){ sizeCloud+=1; } if(flag==0){ flag=1; *cloud_filtered_sum=*cloud_filtered_y; // ROS_INFO("size: %zu",(*cloud_filtered_y).size()); int redColor=0; int blueColor=0; int greenColor=0; // float xLoc=0.0; // float yLoc=0.0; // float zLoc=0.0; for(int pointCount=0;pointCount<cloud_filtered_y->size();pointCount++){ redColor += (*cloud_filtered_y)[pointCount].r; greenColor += (*cloud_filtered_y)[pointCount].g; blueColor += (*cloud_filtered_y)[pointCount].b; // xLoc+= (*cloud_filtered_y)[pointCount].x; // yLoc+= (*cloud_filtered_y)[pointCount].y; // zLoc+= (*cloud_filtered_y)[pointCount].z; // ROS_INFO("G value: %d",(*cloud_filtered_y)[pointCount].g); // ROS_INFO("R value: %d",(*cloud_filtered_y)[pointCount].r); // ROS_INFO("B value: %d",(*cloud_filtered_y)[pointCount].b); // ROS_INFO("type : %s", typeid((*cloud_filtered_y)[pointCount].g).name()); } // ROS_INFO("end"); int redColorAvg = ((int)(redColor/sizeCloud)); int greenColorAvg = ((int)(greenColor/sizeCloud)); int blueColorAvg = ((int)(blueColor/sizeCloud)); int minDist = 999999; int minIndex = 0; for (int colourCount = 0;colourCount<colorNumbersUsed;colourCount++){ int colourDist = (redColorAvg - redArray[colourCount])*(redColorAvg - redArray[colourCount]) + (greenColorAvg - greenArray[colourCount])*(greenColorAvg - greenArray[colourCount]) + (blueColorAvg - blueArray[colourCount])*(blueColorAvg - blueArray[colourCount]) ; if(colourDist<minDist){ minDist = colourDist; minIndex = colourCount; } } colour_recognizer::ObjectProperty tempProperty; tempProperty.id=inputMarkerArray->markers[i].id; tempProperty.colour = colourNameArray[minIndex]; tempProperty.locationX=xPos; tempProperty.locationY=yPos; tempProperty.locationZ=zPos; tempProperty.objectType = "dunno"; tempProperty.colourHist[0]=redColorAvg; tempProperty.colourHist[1]=greenColorAvg; tempProperty.colourHist[2]=blueColorAvg; // arrayTemp[0]=int(redColor/cloud_filtered_y->size()); // arrayTemp[1]=int(greenColor/cloud_filtered_y->size(); // arrayTemp[2]=int(blueColor/cloud_filtered_y->size()); // tempProperty.colourHist=arrayTemp; objectArrayTemp.objects.push_back(tempProperty); } else{ *cloud_filtered_sum+=*cloud_filtered_y; int redColor=0; int blueColor=0; int greenColor=0; // float xLoc=0.0; // float yLoc=0.0; // float zLoc=0.0; for(int pointCount=0;pointCount<cloud_filtered_y->size();pointCount++){ redColor += (*cloud_filtered_y)[pointCount].r; greenColor += (*cloud_filtered_y)[pointCount].g; blueColor += (*cloud_filtered_y)[pointCount].b; // xLoc+= (*cloud_filtered_y)[pointCount].x; // yLoc+= (*cloud_filtered_y)[pointCount].y; // zLoc+= (*cloud_filtered_y)[pointCount].z; // ROS_INFO("G value: %d",(*cloud_filtered_y)[pointCount].g); // ROS_INFO("R value: %d",(*cloud_filtered_y)[pointCount].r); // ROS_INFO("B value: %d",(*cloud_filtered_y)[pointCount].b); // ROS_INFO("type : %s", typeid((*cloud_filtered_y)[pointCount].g).name()); } // ROS_INFO("end"); int redColorAvg = ((int)(redColor/sizeCloud)); int greenColorAvg = ((int)(greenColor/sizeCloud)); int blueColorAvg = ((int)(blueColor/sizeCloud)); int minDist = 999999; int minIndex = 0; for (int colourCount = 0;colourCount<colorNumbersUsed;colourCount++){ int colourDist = (redColorAvg - redArray[colourCount])*(redColorAvg - redArray[colourCount]) + (greenColorAvg - greenArray[colourCount])*(greenColorAvg - greenArray[colourCount]) + (blueColorAvg - blueArray[colourCount])*(blueColorAvg - blueArray[colourCount]) ; if(colourDist<minDist){ minDist = colourDist; minIndex = colourCount; } } colour_recognizer::ObjectProperty tempProperty; tempProperty.id=inputMarkerArray->markers[i].id; tempProperty.colour = colourNameArray[minIndex]; tempProperty.locationX=xPos; tempProperty.locationY=yPos; tempProperty.locationZ=zPos; tempProperty.objectType = "dunno"; tempProperty.colourHist[0]=redColorAvg; tempProperty.colourHist[1]=greenColorAvg; tempProperty.colourHist[2]=blueColorAvg; // arrayTemp[0]=int(redColor/cloud_filtered_y->size()); // arrayTemp[1]=int(greenColor/cloud_filtered_y->size(); // arrayTemp[2]=int(blueColor/cloud_filtered_y->size()); // tempProperty.colourHist=arrayTemp; objectArrayTemp.objects.push_back(tempProperty); } // cloud_filtered_x->~myPointCloud(); // cloud_filtered_y->~myPointCloud(); // cloud_filtered_z->~myPointCloud(); //pubObjectLocation.publish() } //publishing a delayed point cloud and the marker array // pubObjectLocation.publish(tempMarkerArray); pubObjectLocation.publish(objectArrayTemp); pubCloud.publish(*cloud_filtered_sum); }
pcl::PointCloud<pcl::PointXYZ>::Ptr ObjectDetector::filterCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud) { ROS_INFO("Before passthrough: %d", cloud->width * cloud->height); if((cloud->width * cloud->height) != 0){ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_x(new pcl::PointCloud<pcl::PointXYZ>), cloud_filtered_y (new pcl::PointCloud<pcl::PointXYZ>), cloud_filtered_z (new pcl::PointCloud<pcl::PointXYZ>); // Filter x outliers pcl::PassThrough<pcl::PointXYZ> pass_x; pass_x.setInputCloud (cloud); pass_x.setFilterFieldName ("x"); pass_x.setFilterLimits (-x_max, x_max); pass_x.filter (*cloud_filtered_x); // Filter y outliers pcl::PassThrough<pcl::PointXYZ> pass_y; pass_y.setInputCloud (cloud_filtered_x); pass_y.setFilterFieldName ("y"); pass_y.setFilterLimits (floor_threshold, y_max); pass_y.filter (*cloud_filtered_y); // Filter z outliers pcl::PassThrough<pcl::PointXYZ> pass_z; pass_z.setInputCloud (cloud_filtered_y); pass_z.setFilterFieldName ("z"); pass_z.setFilterLimits (-z_max, 0.0); pass_z.filter (*cloud_filtered_z); ROS_INFO("Before RANSAC: %d", cloud_filtered_z->width * cloud_filtered_z->height); if((cloud_filtered_z->width * cloud_filtered_z->height) > min_points_left) { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ransac (new pcl::PointCloud<pcl::PointXYZ>); cloud_ransac = cloud_filtered_z; pcl::ModelCoefficients::Ptr ransac_coefficients(new pcl::ModelCoefficients); pcl::PointIndices::Ptr inliers(new pcl::PointIndices); // Create the segmentation object pcl::SACSegmentation<pcl::PointXYZ> seg; // Optional seg.setOptimizeCoefficients (true); // Fit plane seg.setModelType (pcl::SACMODEL_PLANE); // Use RANSAC seg.setMethodType (pcl::SAC_RANSAC); // Set maximum number of iterations seg.setMaxIterations (max_it_runtime); // Set distance to the model threshold seg.setDistanceThreshold (wall_threshold); // Segment the largest planar component from the cloud seg.setInputCloud (cloud_ransac); seg.segment (*inliers, *ransac_coefficients); while(inliers->indices.size() > ransac_removal_threshold){ // Extract the inliers pcl::ExtractIndices<pcl::PointXYZ> extract; extract.setInputCloud (cloud_ransac); extract.setIndices (inliers); extract.setNegative (true); extract.filter (*cloud_ransac); pcl::SACSegmentation<pcl::PointXYZ> seg2; // Optional seg2.setOptimizeCoefficients (true); // Fit plane seg2.setModelType (pcl::SACMODEL_PLANE); // Use RANSAC seg2.setMethodType (pcl::SAC_RANSAC); // Set maximum number of iterations seg2.setMaxIterations (max_it_runtime); // Set distance to the model threshold seg2.setDistanceThreshold (wall_threshold); // Segment the largest planar component from the cloud seg2.setInputCloud (cloud_ransac); seg2.segment (*inliers, *ransac_coefficients); } ROS_INFO("After RANSAC: %d", cloud_ransac->width * cloud_ransac->height); if((cloud_ransac->width * cloud_ransac->height) > min_points_left){ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_inc_walls (new pcl::PointCloud<pcl::PointXYZ>), cloud_filtered_only_walls (new pcl::PointCloud<pcl::PointXYZ>), cloud_projected_iw (new pcl::PointCloud<pcl::PointXYZ>), cloud_projected_ow (new pcl::PointCloud<pcl::PointXYZ>), cloud_projected_filtered (new pcl::PointCloud<pcl::PointXYZ>); // Points containing both walls + objects pcl::PassThrough<pcl::PointXYZ> pass_iw; pass_iw.setInputCloud (cloud_ransac); pass_iw.setFilterFieldName ("y"); pass_iw.setFilterLimits (floor_threshold, object_wall_threshold); pass_iw.filter (*cloud_filtered_inc_walls); // Points only containing walls pcl::PassThrough<pcl::PointXYZ> pass_ow; pass_ow.setInputCloud (cloud_ransac); pass_ow.setFilterFieldName ("y"); pass_ow.setFilterLimits (object_wall_threshold, y_max); pass_ow.filter (*cloud_filtered_only_walls); if(((cloud_filtered_inc_walls->width * cloud_filtered_inc_walls->height) != 0) && ((cloud_filtered_only_walls->width * cloud_filtered_only_walls->height) != 0) ) { // Create a set of planar coefficients with X=Z=0,Y=1 pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ()); coefficients->values.resize (4); coefficients->values[0] = coefficients->values[2] = 0; coefficients->values[1] = 1.0; coefficients->values[3] = 0; // Eliminate y-axis by projection to 2D pcl::ProjectInliers<pcl::PointXYZ> proj1; proj1.setModelType (pcl::SACMODEL_PLANE); proj1.setInputCloud (cloud_filtered_inc_walls); proj1.setModelCoefficients (coefficients); proj1.filter (*cloud_projected_iw); pcl::ProjectInliers<pcl::PointXYZ> proj2; proj2.setModelType (pcl::SACMODEL_PLANE); proj2.setInputCloud (cloud_filtered_only_walls); proj2.setModelCoefficients (coefficients); proj2.filter (*cloud_projected_ow); // Remove projected walls from cloud_projected_iw if((cloud_projected_iw->width * cloud_projected_iw->height) != 0) { // Create kdtree pcl::KdTreeFLANN<pcl::PointXYZ> kdtree; kdtree.setInputCloud (cloud_projected_iw); double radius = wall_threshold; pcl::PointIndices::Ptr wallpoint_indices(new pcl::PointIndices); // Create a set of already included indices boost::unordered::unordered_set<int> inc_indices; // Iterate over all points in cloud containing only walls for (int i = 0; i < cloud_projected_ow->size(); i++) { pcl::PointXYZ owPoint = cloud_projected_ow->at(i) ; std::vector<int> k_indices; std::vector<float> k_distances; // Find points which are closes neighbors to the walls if(kdtree.radiusSearch (owPoint, radius, k_indices, k_distances) > 0){ // Iterate over points for(std::vector<int>::size_type i = 0; i != k_indices.size(); i++) { int index = k_indices[i]; // If no match is found for index, add to set & wallpoint indices if (inc_indices.find(index) == inc_indices.end()){ inc_indices.insert(index); wallpoint_indices->indices.push_back(index); } } } } if(wallpoint_indices->indices.size() > 0){ ROS_INFO("Filter points: %d", int(wallpoint_indices->indices.size())); // Remove the wall points pcl::ExtractIndices<pcl::PointXYZ> extract; extract.setInputCloud (cloud_filtered_inc_walls); extract.setIndices (wallpoint_indices); extract.setNegative (true); extract.filter (*cloud_projected_filtered); } else{ cloud_projected_filtered = cloud_filtered_inc_walls; } ROS_INFO("After WF: %d", cloud_projected_filtered->width * cloud_projected_filtered->height); return cloud_projected_filtered; } else { return cloud_filtered_inc_walls; // correct? } } else { return cloud_ransac; // correct? } } else { return cloud_ransac; } } else { return cloud_filtered_z; } } else { return cloud; } }