Skip to content

Commit 0a1671f

Browse files
author
plnegre
committed
Addapt the pointlcoud_to_webgl script to the new format of the website
1 parent 0250da4 commit 0a1671f

File tree

3 files changed

+88
-149
lines changed

3 files changed

+88
-149
lines changed

bag_tools/src/extract_images.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,28 @@
22
/// Systems, Robotics and Vision Group
33
/// University of the Balearican Islands
44
/// All rights reserved.
5-
///
5+
///
66
/// Redistribution and use in source and binary forms, with or without
77
/// modification, are permitted provided that the following conditions are met:
88
/// * Redistributions of source code must retain the above copyright
99
/// notice, this list of conditions and the following disclaimer.
1010
/// * Redistributions in binary form must reproduce the above copyright
1111
/// notice, this list of conditions and the following disclaimer in the
1212
/// documentation and/or other materials provided with the distribution.
13-
/// * Neither the name of Systems, Robotics and Vision Group, University of
14-
/// the Balearican Islands nor the names of its contributors may be used
15-
/// to endorse or promote products derived from this software without
13+
/// * Neither the name of Systems, Robotics and Vision Group, University of
14+
/// the Balearican Islands nor the names of its contributors may be used
15+
/// to endorse or promote products derived from this software without
1616
/// specific prior written permission.
17-
///
18-
/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19-
/// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20-
/// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
///
18+
/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
/// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
/// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2121
/// ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
2222
/// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2323
/// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2424
/// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2525
/// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26-
/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26+
/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2727
/// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828

2929
#include <ros/ros.h>
@@ -47,7 +47,7 @@
4747
class ImageSaver
4848
{
4949
public:
50-
ImageSaver(const std::string& save_dir, const std::string& filetype,
50+
ImageSaver(const std::string& save_dir, const std::string& filetype,
5151
const std::string& prefix) :
5252
save_dir_(save_dir), filetype_(filetype), prefix_(prefix), num_saved_(0)
5353
{}
@@ -108,7 +108,7 @@ int main(int argc, char** argv)
108108
std::string out_dir(argv[1]);
109109
std::string filetype(argv[2]);
110110
std::string image_topic(argv[3]);
111-
111+
112112
ros::Time::init();
113113

114114
std::string prefix("image");

pointcloud_tools/src/pointcloud_mapper.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ class PointCloudMapper
3232
nh_priv_.param("filter_map", filter_map_, false);
3333

3434
cloud_sub_ = nh_.subscribe<PointCloud>("input", 1, &PointCloudMapper::callback, this);
35-
bool latched = true;
36-
cloud_pub_ = nh_priv_.advertise<PointCloud>("output", 1, latched);
35+
cloud_pub_ = nh_priv_.advertise<PointCloud>("output", 1, true);
3736
pub_timer_ = nh_.createWallTimer(ros::WallDuration(3.0), &PointCloudMapper::publishCallback, this);
3837
}
3938

@@ -42,8 +41,8 @@ class PointCloudMapper
4241
ROS_INFO_STREAM("Received cloud with " << cloud->points.size() << " points.");
4342
PointCloud transformed_cloud;
4443
ros::Time points_time;
45-
points_time.fromNSec((*cloud).header.stamp);
46-
tf_listener_.waitForTransform(fixed_frame_, (*cloud).header.frame_id, points_time, ros::Duration(5.0));
44+
points_time.fromNSec(cloud->header.stamp);
45+
tf_listener_.waitForTransform(fixed_frame_, cloud->header.frame_id, points_time, ros::Duration(5.0));
4746
bool success = pcl_ros::transformPointCloud(fixed_frame_, *cloud, transformed_cloud, tf_listener_);
4847
if (success)
4948
{
@@ -55,6 +54,8 @@ class PointCloudMapper
5554
accumulated_cloud_ = *cloud_downsampled;
5655
}
5756

57+
ROS_INFO_STREAM("Map has " << accumulated_cloud_.points.size() << " points.");
58+
5859
// Publish the cloud
5960
if (cloud_pub_.getNumSubscribers() > 0)
6061
cloud_pub_.publish(accumulated_cloud_);
@@ -64,8 +65,6 @@ class PointCloudMapper
6465
{
6566
ROS_ERROR("Could not transform point cloud to %s", fixed_frame_.c_str());
6667
}
67-
68-
ROS_INFO_STREAM("Map has " << accumulated_cloud_.points.size() << " points.");
6968
}
7069

7170
void publishCallback(const ros::WallTimerEvent&)
Lines changed: 72 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,175 +1,115 @@
11
#include <ros/ros.h>
22

3-
#include <std_msgs/String.h>
3+
#include <boost/lexical_cast.hpp>
44

55
#include <pcl/point_types.h>
66
#include <pcl_ros/point_cloud.h>
77
#include <pcl/io/pcd_io.h>
8-
#include <pcl/filters/voxel_grid.h>
98
#include <pcl/common/centroid.h>
109

1110
class PointCloudToWebgl {
1211

13-
// ROS properties
14-
ros::NodeHandle nh_;
15-
ros::NodeHandle nh_private_;
16-
17-
std::string pcd_filename_;
18-
double max_ascii_file_size_;
19-
int pcd_type_;
20-
2112
public:
2213

2314
/**
2415
* Class constructor
2516
*/
26-
PointCloudToWebgl() : nh_private_("~")
17+
PointCloudToWebgl(const std::string& input_cloud, const int& cloud_format,
18+
const std::string& output_cloud) :
19+
input_cloud_(input_cloud), cloud_format_(cloud_format), output_cloud_(output_cloud)
20+
{}
21+
22+
/**
23+
* Convert the cloud
24+
*/
25+
void convert()
2726
{
28-
// Read the parameters from the parameter server (set defaults)
29-
nh_private_.param("pcd_filename", pcd_filename_, std::string("pointcloud_file.pcd"));
30-
nh_private_.param("max_ascii_file_size", max_ascii_file_size_, 4.0); // In MBytes
31-
nh_private_.param("pcd_type", pcd_type_, 0); // 0 -> XYZ | 1 -> XYZRGB
27+
ROS_INFO_STREAM("[PointCloudToWebgl:] Opening file " << input_cloud_);
3228

33-
ROS_INFO_STREAM("[PointCloudToWebgl:] Opening file " << pcd_filename_);
29+
// Init the cloud
30+
pcl::PointCloud<pcl::PointXYZRGB> cloud;
3431

3532
// Read point cloud
36-
if (pcd_type_ == 0)
33+
if (cloud_format_ == 0)
3734
{
3835
// NO RGB
39-
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);
40-
if (pcl::io::loadPCDFile<pcl::PointXYZ> (pcd_filename_, *cloud_ptr) == -1) //* load the file
41-
{
42-
ROS_ERROR_STREAM("[PointCloudToWebgl:] Couldn't read file " << pcd_filename_);
43-
}
44-
else
36+
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xyz (new pcl::PointCloud<pcl::PointXYZ>);
37+
if (pcl::io::loadPCDFile<pcl::PointXYZ> (input_cloud_, *cloud_xyz) == -1) //* load the file
4538
{
46-
// Convert the cloud
47-
pcl::PointCloud<pcl::PointXYZ> cloud = *cloud_ptr;
48-
int file_point_size = 27;
49-
int max_bytes = (int)round(max_ascii_file_size_ * 1024 * 1024);
50-
int desired_points = max_bytes / file_point_size;
51-
double voxel_size = 0.001;
52-
double offset = 0.0002;
53-
while ((int)cloud.size() > desired_points)
54-
{
55-
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_downsampled = filter(cloud.makeShared(), voxel_size);
56-
cloud = *cloud_downsampled;
57-
voxel_size = voxel_size + offset;
58-
}
59-
60-
// Compute the cloud centroid
61-
Eigen::Vector4f centroid;
62-
pcl::compute3DCentroid(cloud, centroid);
63-
64-
// Save int file
65-
int lastindex = pcd_filename_.find_last_of(".");
66-
std::string filename = pcd_filename_.substr(0, lastindex);
67-
filename = filename + ".txt";
68-
ROS_INFO_STREAM("[PointCloudToWebgl:] Saving webgl file to " << filename);
69-
std::fstream f_webgl(filename.c_str(), std::ios::out);
70-
for (unsigned int i=0; i<cloud.size(); i++)
71-
{
72-
f_webgl << cloud[i].x - centroid[0] << "," <<
73-
cloud[i].y - centroid[1] << "," <<
74-
cloud[i].z - centroid[2] << "," <<
75-
(int)(224) << "," <<
76-
(int)(224) << "," <<
77-
(int)(224) << std::endl;
78-
}
79-
f_webgl.close();
80-
ROS_INFO("[PointCloudToWebgl:] Saved!");
39+
ROS_ERROR_STREAM("[PointCloudToWebgl:] Couldn't read file " << input_cloud_);
40+
return;
8141
}
42+
copyPointCloud(*cloud_xyz, cloud);
8243
}
83-
else
44+
else if (cloud_format_ == 1)
8445
{
8546
// RGB
86-
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr (new pcl::PointCloud<pcl::PointXYZRGB>);
87-
if (pcl::io::loadPCDFile<pcl::PointXYZRGB> (pcd_filename_, *cloud_ptr) == -1) //* load the file
88-
{
89-
ROS_ERROR_STREAM("[PointCloudToWebgl:] Couldn't read file " << pcd_filename_);
90-
}
91-
else
47+
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_xyzrgb (new pcl::PointCloud<pcl::PointXYZRGB>);
48+
if (pcl::io::loadPCDFile<pcl::PointXYZRGB> (input_cloud_, *cloud_xyzrgb) == -1) //* load the file
9249
{
93-
// Convert the cloud
94-
pcl::PointCloud<pcl::PointXYZRGB> cloud = *cloud_ptr;
95-
int file_point_size = 37;
96-
int max_bytes = (int)round(max_ascii_file_size_ * 1024 * 1024);
97-
int desired_points = max_bytes / file_point_size;
98-
double voxel_size = 0.001;
99-
double offset = 0.0002;
100-
while ((int)cloud.size() > desired_points)
101-
{
102-
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_downsampled = filter(cloud.makeShared(), voxel_size);
103-
cloud = *cloud_downsampled;
104-
voxel_size = voxel_size + offset;
105-
}
106-
107-
// Compute the cloud centroid
108-
Eigen::Vector4f centroid;
109-
pcl::compute3DCentroid(cloud, centroid);
110-
111-
// Save int file
112-
int lastindex = pcd_filename_.find_last_of(".");
113-
std::string filename = pcd_filename_.substr(0, lastindex);
114-
filename = filename + ".txt";
115-
ROS_INFO_STREAM("[PointCloudToWebgl:] Saving webgl file to " << filename);
116-
std::fstream f_webgl(filename.c_str(), std::ios::out);
117-
for (unsigned int i=0; i<cloud.size(); i++)
118-
{
119-
f_webgl << cloud[i].x - centroid[0] << "," <<
120-
cloud[i].y - centroid[1] << "," <<
121-
cloud[i].z - centroid[2] << "," <<
122-
(int)cloud[i].r << "," <<
123-
(int)cloud[i].g << "," <<
124-
(int)cloud[i].b << std::endl;
125-
}
126-
f_webgl.close();
127-
ROS_INFO("[PointCloudToWebgl:] Saved!");
50+
ROS_ERROR_STREAM("[PointCloudToWebgl:] Couldn't read file " << input_cloud_);
51+
return;
12852
}
53+
copyPointCloud(*cloud_xyzrgb, cloud);
12954
}
130-
}
13155

132-
pcl::PointCloud<pcl::PointXYZ>::Ptr filter(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, double voxel_size)
133-
{
134-
// Downsampling using voxel grid
135-
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_ptr(new pcl::PointCloud<pcl::PointXYZ>);
136-
pcl::VoxelGrid<pcl::PointXYZ> grid_;
137-
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_downsampled_ptr(new pcl::PointCloud<pcl::PointXYZ>);
138-
grid_.setLeafSize(voxel_size,
139-
voxel_size,
140-
voxel_size);
141-
grid_.setDownsampleAllData(true);
142-
grid_.setInputCloud(cloud);
143-
grid_.filter(*cloud_downsampled_ptr);
144-
return cloud_downsampled_ptr;
145-
}
56+
// Compute the cloud centroid
57+
Eigen::Vector4f centroid;
58+
pcl::compute3DCentroid(cloud, centroid);
14659

147-
pcl::PointCloud<pcl::PointXYZRGB>::Ptr filter(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud, double voxel_size)
148-
{
149-
// Downsampling using voxel grid
150-
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_filtered_ptr(new pcl::PointCloud<pcl::PointXYZRGB>);
151-
pcl::VoxelGrid<pcl::PointXYZRGB> grid_;
152-
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_downsampled_ptr(new pcl::PointCloud<pcl::PointXYZRGB>);
153-
154-
grid_.setLeafSize(voxel_size,
155-
voxel_size,
156-
voxel_size);
157-
grid_.setDownsampleAllData(true);
158-
grid_.setInputCloud(cloud);
159-
grid_.filter(*cloud_downsampled_ptr);
160-
return cloud_downsampled_ptr;
60+
// Save int file
61+
ROS_INFO_STREAM("[PointCloudToWebgl:] Saving webgl file to " << output_cloud_);
62+
std::fstream f_webgl(output_cloud_.c_str(), std::ios::out);
63+
for (unsigned int i=0; i<cloud.size(); i++)
64+
{
65+
int r = 224;
66+
int g = 224;
67+
int b = 224;
68+
if (cloud_format_ == 1)
69+
{
70+
r = (int)cloud[i].r;
71+
g = (int)cloud[i].g;
72+
b = (int)cloud[i].b;
73+
}
74+
f_webgl << cloud[i].x - centroid[0] << "," <<
75+
cloud[i].y - centroid[1] << "," <<
76+
cloud[i].z - centroid[2] << "," <<
77+
r << "," <<
78+
g << "," <<
79+
b << std::endl;
80+
81+
}
82+
f_webgl.close();
83+
ROS_INFO("[PointCloudToWebgl:] Saved!");
16184
}
16285

86+
private:
87+
std::string input_cloud_;
88+
std::string output_cloud_;
89+
int cloud_format_;
16390
};
16491

16592
/**
16693
* Main entry point of the code
16794
*/
16895
int main(int argc, char **argv)
16996
{
170-
ros::init(argc, argv, "pointcloud_to_webgl");
171-
PointCloudToWebgl node;
172-
ros::spin();
97+
if (argc < 4)
98+
{
99+
std::cout << "Usage: " << argv[0] << " INPUT_PCD FORMAT OUTPUT_CSV" << std::endl;
100+
std::cout << " Example: " << argv[0] << " input_cloud.pcd 0 output_cloud.csv" << std::endl;
101+
return 0;
102+
}
103+
104+
// Read inputs
105+
std::string input_cloud(argv[1]);
106+
std::string output_cloud(argv[3]);
107+
int cloud_format = boost::lexical_cast<int>(argv[2]);
108+
109+
// Convert
110+
PointCloudToWebgl converter(input_cloud, cloud_format, output_cloud);
111+
converter.convert();
112+
173113
return 0;
174114
}
175115

0 commit comments

Comments
 (0)