Skip to content

Commit 81c302f

Browse files
committed
Segmentation working
1 parent 39c710f commit 81c302f

File tree

4 files changed

+94
-27
lines changed

4 files changed

+94
-27
lines changed

cuboid_detection/CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ include
144144
## ADD YOUR PROGRAMS HERE
145145

146146
# add_executable(${PROJECT_NAME}_node src/cuboid_detection_node.cpp)
147-
add_executable(example src/example.cpp)
147+
# add_executable(example src/example.cpp)
148+
add_executable(ground_plane_segmentation src/ground_plane_segmentation.cpp)
148149

149150
## <<<<<<<<<<<<<<<<<<<<<<<
150151

@@ -165,4 +166,5 @@ add_executable(example src/example.cpp)
165166
# target_link_libraries(${PROJECT_NAME}
166167
# ${OpenCV_LIBS}
167168
# )
168-
target_link_libraries(example ${catkin_LIBRARIES})
169+
# target_link_libraries(example ${catkin_LIBRARIES})
170+
target_link_libraries(ground_plane_segmentation ${catkin_LIBRARIES})
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<launch>
3+
4+
<!-- Play rosbag file -->
5+
<include file="$(find cuboid_detection)/launch/play_rosbag.launch">
6+
<arg name="filename" value="2019-03-23-22-32-55.bag" />
7+
</include>
8+
9+
<!-- Run a VoxelGrid filter to clean NaNs and downsample the data -->
10+
<node
11+
pkg="cuboid_detection"
12+
type="ground_plane_segmentation"
13+
name="ground_plane_segmentation"
14+
output="screen">
15+
16+
<!-- Set topics and params -->
17+
<rosparam>
18+
<!-- invert (default: true): True > Box; False > Ground Plane -->
19+
invert: true
20+
<!-- voxel_size (default: 0.01): Lower the value, denser the point cloud, more CPU -->
21+
voxel_size: 0.005
22+
<!-- distance_threshold (default: 0.01): Lower the value, more of box + table noise -->
23+
distance_threshold: 0.015
24+
<!-- Topics -->
25+
input: "/camera/depth/color/points"
26+
output: "/ground_plane_segmentation/points"
27+
plane_coefficients: "/ground_plane_segmentation/coefficients"
28+
</rosparam>
29+
</node>
30+
31+
</launch>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<launch>
3+
4+
<arg name="filename" default="2019-03-23-22-32-55.bag" />
5+
6+
<!-- Play rosbag file -->
7+
<node
8+
pkg="rosbag"
9+
type="play"
10+
name="player"
11+
output="screen"
12+
args="--clock --loop $(find cuboid_detection)/bags/$(arg filename)" />
13+
14+
</launch>

cuboid_detection/src/ground_plane_segmentation.cpp

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,23 @@ target_link_libraries(ground_plane_segmentation ${catkin_LIBRARIES})
1515
#include <ros/ros.h>
1616
// PCL specific includes
1717
#include <sensor_msgs/PointCloud2.h>
18-
#include <pcl/conversions.h>
19-
#include <pcl_conversions/pcl_conversions.h>
20-
#include <pcl_ros/transforms.h>
21-
#include <pcl/point_cloud.h>
22-
#include <pcl/point_types.h>
2318
#include <pcl/ModelCoefficients.h>
2419
#include <pcl/sample_consensus/method_types.h>
2520
#include <pcl/sample_consensus/model_types.h>
2621
#include <pcl/segmentation/sac_segmentation.h>
27-
#include <pcl/filters/passthrough.h>
28-
#include <pcl/filters/voxel_grid.h>
29-
#include <pcl/filters/extract_indices.h>
22+
#include <pcl_ros/point_cloud.h>
23+
#include <pcl_ros/filters/passthrough.h>
24+
#include <pcl_ros/filters/voxel_grid.h>
25+
#include <pcl_ros/filters/extract_indices.h>
26+
#include <pcl_conversions/pcl_conversions.h>
3027

3128
// Publishers
32-
ros::Publisher coef_pub;
3329
ros::Publisher pcl_pub;
30+
ros::Publisher coef_pub;
3431

3532
// Topics
33+
bool invert;
34+
double voxel_size;
3635
double distance_threshold;
3736
std::string input_topic;
3837
std::string output_topic;
@@ -44,48 +43,52 @@ bool debug = false;
4443
void callback(const sensor_msgs::PointCloud2ConstPtr& input)
4544
{
4645
// Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud
47-
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr(new pcl::PointCloud<pcl::PointXYZ>);
48-
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_ptr(new pcl::PointCloud<pcl::PointXYZ>);
49-
pcl::fromROSMsg(*input, *cloud_ptr);
46+
pcl::PCLPointCloud2::Ptr cloud_ptr(new pcl::PCLPointCloud2);
47+
pcl::PCLPointCloud2::Ptr cloud_filtered_ptr(new pcl::PCLPointCloud2);
48+
pcl_conversions::toPCL(*input, *cloud_ptr);
5049
if (debug) std::cerr << "PointCloud before filtering: " << cloud_ptr->width << " " << cloud_ptr->height << " data points." << std::endl;
5150

5251
// Filter the points in z-axis
53-
pcl::PassThrough<pcl::PointXYZ> pass;
52+
pcl::PassThrough<pcl::PCLPointCloud2> pass;
5453
pass.setInputCloud(cloud_ptr);
5554
pass.setFilterFieldName("z");
5655
pass.setFilterLimits(0.0, 1.4);
5756
pass.filter(*cloud_filtered_ptr);
5857
if (debug) std::cerr << "PointCloud after filtering: " << cloud_filtered_ptr->width << " " << cloud_filtered_ptr->height << " data points." << std::endl;
5958

6059
// Downsample the points
61-
pcl::PointCloud<pcl::PointXYZ>::Ptr voxel_ptr(new pcl::PointCloud<pcl::PointXYZ>);
62-
pcl::VoxelGrid<pcl::PointXYZ> voxel;
63-
voxel.setInputCloud(cloud_filtered_ptr);
64-
voxel.setLeafSize(0.01, 0.01, 0.01);
65-
voxel.filter(*voxel_ptr);
60+
pcl::PCLPointCloud2::Ptr voxel_ptr(new pcl::PCLPointCloud2);
61+
pcl::VoxelGrid<pcl::PCLPointCloud2> downsample;
62+
downsample.setInputCloud(cloud_filtered_ptr);
63+
downsample.setLeafSize(voxel_size, voxel_size, voxel_size);
64+
downsample.filter(*voxel_ptr);
6665

6766
// Setup ground plane segmentation
6867
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
6968
pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
7069
pcl::SACSegmentation<pcl::PointXYZ> seg;
7170

71+
// Convert to the templated PointCloud
72+
pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_voxel_ptr(new pcl::PointCloud<pcl::PointXYZ>);
73+
pcl::fromPCLPointCloud2(*voxel_ptr, *pcl_voxel_ptr);
74+
7275
// Segmentation paramters
7376
seg.setOptimizeCoefficients(true);
7477
seg.setModelType(pcl::SACMODEL_PLANE);
7578
seg.setMethodType(pcl::SAC_RANSAC);
7679
seg.setMaxIterations(1000);
77-
seg.setDistanceThreshold(0.01);
80+
seg.setDistanceThreshold(distance_threshold);
7881

7982
// Segment the largest planar component from the cloud
80-
seg.setInputCloud(voxel_ptr);
83+
seg.setInputCloud(pcl_voxel_ptr);
8184
seg.segment(*inliers, *coefficients);
8285

8386
// Extract the inliers
84-
pcl::PointCloud<pcl::PointXYZ>::Ptr plane_cloud_ptr(new pcl::PointCloud<pcl::PointXYZ>);
85-
pcl::ExtractIndices<pcl::PointXYZ> extract;
87+
pcl::PCLPointCloud2::Ptr plane_cloud_ptr(new pcl::PCLPointCloud2);
88+
pcl::ExtractIndices<pcl::PCLPointCloud2> extract;
8689
extract.setInputCloud(voxel_ptr);
8790
extract.setIndices(inliers);
88-
extract.setNegative(true);
91+
extract.setNegative(invert);
8992
extract.filter(*plane_cloud_ptr);
9093
if (debug) std::cerr << "PointCloud representing the planar component: " << plane_cloud_ptr->width << " " << plane_cloud_ptr->height << " data points." << std::endl;
9194

@@ -96,7 +99,7 @@ void callback(const sensor_msgs::PointCloud2ConstPtr& input)
9699

97100
// Convert to ROS data type
98101
sensor_msgs::PointCloud2 output;
99-
pcl::toROSMsg(*plane_cloud_ptr, output);
102+
pcl_conversions::fromPCL(*plane_cloud_ptr, output);
100103
pcl_pub.publish(output);
101104
}
102105

@@ -107,11 +110,28 @@ int main(int argc, char** argv)
107110
ros::NodeHandle nh("~");
108111

109112
// Get params from launch file
113+
nh.getParam("invert", invert);
114+
nh.getParam("voxel_size", voxel_size);
110115
nh.getParam("distance_threshold", distance_threshold);
111116
nh.getParam("input", input_topic);
112117
nh.getParam("output", output_topic);
113-
nh.getParam("coefficients", coefficients_topic);
118+
nh.getParam("plane_coefficients", coefficients_topic);
119+
120+
// Params defaults
121+
nh.param<bool>("invert", invert, true);
122+
nh.param<double>("voxel_size", voxel_size, 0.01);
114123
nh.param<double>("distance_threshold", distance_threshold, 0.01);
124+
nh.param<std::string>("input", input_topic, "/camera/depth/color/points");
125+
nh.param<std::string>("output", output_topic, "/ground_plane_segmentation/points");
126+
nh.param<std::string>("plane_coefficients", coefficients_topic, "/ground_plane_segmentation/coefficients");
127+
128+
// Display params
129+
std::cout << "\nInvert Segmentation: " << invert << std::endl;
130+
std::cout << "Voxel Size: " << voxel_size << std::endl;
131+
std::cout << "Distance Threshold: " << distance_threshold << std::endl;
132+
std::cout << "Input Topic: " << input_topic << std::endl;
133+
std::cout << "Output Topic: " << output_topic << std::endl;
134+
std::cout << "Co-efficients Topic: " << coefficients_topic << std::endl;
115135

116136
// Create a ROS subscriber for the input point cloud
117137
ros::Subscriber sub = nh.subscribe(input_topic, 1, callback);

0 commit comments

Comments
 (0)