00001
00063 #include "cob_3d_mapping_tools/point_generator.h"
00064 #include <cob_3d_mapping_common/label_defines.h>
00065
00066 #include <boost/program_options.hpp>
00067
00068 #include <pcl/io/pcd_io.h>
00069 #include <pcl/point_cloud.h>
00070 #include <pcl/visualization/pcl_visualizer.h>
00071 #include <pcl/visualization/point_cloud_handlers.h>
00072 #include <pcl/kdtree/kdtree_flann.h>
00073 #include <pcl/filters/voxel_grid.h>
00074
00075 #include <math.h>
00076
00077 using namespace std;
00078 using namespace pcl;
00079
00080 typedef visualization::PointCloudColorHandlerRGBField<PointXYZRGBA> ColorHdlRGBA;
00081 typedef Eigen::Vector3f Vec;
00082
00083 string file;
00084 bool visualize;
00085 float noise;
00086 float corner_size;
00087
00088 void readOptions(int argc, char* argv[])
00089 {
00090 using namespace boost::program_options;
00091 options_description options("Options");
00092 options.add_options()
00093 ("help", "produce help message")
00094 ("out,o", value<string>(&file)->default_value(""),
00095 "output file, set to \"\" for no output")
00096 ("noise,n", value<float>(&noise)->default_value(0.00f),
00097 "gaussian noise level")
00098 ("vis,v", value<bool>(&visualize)->default_value(true),
00099 "enable visualization")
00100 ("corner,c", value<float>(&corner_size)->default_value(0.02f),
00101 "corner size")
00102 ;
00103
00104 positional_options_description p_opt;
00105 p_opt.add("out", 1);
00106 variables_map vm;
00107 store(command_line_parser(argc, argv).options(options).positional(p_opt).run(), vm);
00108 notify(vm);
00109
00110 if (vm.count("help"))
00111 {
00112 cout << "Creates a synthetic scene consisting of a table with various objects on it" << endl;
00113 cout << options << endl;
00114 exit(0);
00115 }
00116 }
00117
00125 void labelTableObjectIntersection(PointCloud<PointXYZRGBA>::Ptr & pc_table,
00126 PointCloud<PointXYZRGBA>::Ptr & pc_object,
00127 const float & radius)
00128 {
00129 vector<int> indices;
00130 vector<float> distances;
00131 KdTreeFLANN<PointXYZRGBA>::Ptr tree(new KdTreeFLANN<PointXYZRGBA>);
00132 tree->setInputCloud(pc_table);
00133 for (size_t i = 0; i < pc_object->size(); ++i)
00134 {
00135 indices.clear();
00136 tree->radiusSearch(pc_object->points[i], radius, indices, distances);
00137 if (indices.size() > 0)
00138 {
00139 pc_object->points[i].rgba = LBL_EDGE;
00140 for (size_t j = 0; j < indices.size(); ++j)
00141 {
00142 pc_table->points[indices[j]].rgba = LBL_EDGE;
00143 }
00144 }
00145 }
00146 }
00147
00151 int main(int argc, char** argv)
00152 {
00153 readOptions(argc, argv);
00154
00155 PointCloud<PointXYZRGBA>::Ptr pc_table (new PointCloud<PointXYZRGBA>);
00156 PointCloud<PointXYZRGBA>::Ptr pc_mug (new PointCloud<PointXYZRGBA>);
00157 PointCloud<PointXYZRGBA>::Ptr pc_mug_handle (new PointCloud<PointXYZRGBA>);
00158 PointCloud<PointXYZRGBA>::Ptr pc_bowl (new PointCloud<PointXYZRGBA>);
00159 PointCloud<PointXYZRGBA>::Ptr pc_milk (new PointCloud<PointXYZRGBA>);
00160 PointCloud<PointXYZRGBA>::Ptr pc_bottle (new PointCloud<PointXYZRGBA>);
00161 PointCloud<PointXYZRGBA>::Ptr pc_bottle_top (new PointCloud<PointXYZRGBA>);
00162 PointCloud<PointXYZRGBA>::Ptr pc_pan (new PointCloud<PointXYZRGBA>);
00163 PointCloud<PointXYZRGBA>::Ptr pc_pan_handles (new PointCloud<PointXYZRGBA>);
00164 PointCloud<PointXYZRGBA>::Ptr pc_apple (new PointCloud<PointXYZRGBA>);
00165 PointCloud<PointXYZRGBA>::Ptr pc_tea (new PointCloud<PointXYZRGBA>);
00166 PointCloud<PointXYZRGBA>::Ptr pc_herps (new PointCloud<PointXYZRGBA>);
00167 PointCloud<PointXYZRGBA>::Ptr pc_herps_top (new PointCloud<PointXYZRGBA>);
00168 PointCloud<PointXYZRGBA>::Ptr pc1 (new PointCloud<PointXYZRGBA>);
00169
00170 Vec o(0.0f, 0.5f, 1.0f);
00171 float s = 0.005f;
00172
00173
00174 Vec mug(-0.3f, 0.0f, 0.1f);
00175 Vec bowl(-0.4f, 0.0f, -0.3f);
00176 Vec milk(-0.55f, 0.0f, 0.15f);
00177 Vec bottle(0.05f, 0.0f, 0.3f);
00178 Vec pan(0.5f, 0.0f, 0.25f);
00179 Vec apple(0.0f, 0.0f, -0.25f);
00180 Vec tea(0.3f, 0.0f, -0.25f);
00181 Vec herps(-0.07f, 0.0f, 0.0f);
00182
00183 cob_3d_mapping_tools::PointGenerator<PointXYZRGBA> pg;
00184 if (noise != 0) pg.setGaussianNoise(noise);
00185 pg.setOutputCloud(pc_table);
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 pg.setOutputCloud(pc_mug);
00199 pg.generateCylinder(s, o + mug, -0.095f * Vec::UnitY(), 0.04f);
00200 pg.setOutputCloud(pc_mug_handle);
00201 pg.generateHandle(s, o + mug + Vec(-0.04f, -0.0475f, 0.0f),
00202 -Vec::UnitZ(), Vec(0.0f, -0.035f, 0.0f), 0.005f, M_PI);
00203 labelTableObjectIntersection(pc_mug, pc_mug_handle, corner_size);
00204
00205
00206
00207 pg.setOutputCloud(pc_bowl);
00208 pg.generateSphere(s, o + bowl + Vec(0.0f, -0.1f, 0.0f), Vec::UnitY(), 0.1f, 0.5 * M_PI);
00209
00210
00211
00212 Vec m_height(0.0f, -0.195f, 0.0f);
00213 Vec m_length(0.09f * sin(0.25 * M_PI), 0.0f, 0.09f * cos(0.25 * M_PI));
00214 Vec m_width = m_height.cross(m_length).normalized() * 0.06;
00215 pg.setOutputCloud(pc_milk);
00216 pg.generateBox(s, o + milk, m_height, m_length, m_width, corner_size);
00217
00218
00219
00220 pg.setOutputCloud(pc_bottle);
00221 pg.generateCylinder(s, o + bottle, -0.14f * Vec::UnitY(), 0.045f);
00222 pg.generateCone(s, o + bottle -0.14f * Vec::UnitY(), -0.12f * Vec::UnitY(), 0.045f, 0.015f);
00223 pg.generateCylinder(s, o + bottle -0.26f * Vec::UnitY() , -0.02f * Vec::UnitY(), 0.015f);
00224 pg.setOutputCloud(pc_bottle_top);
00225 pg.generateCirclePlane(s, o + bottle -0.28f * Vec::UnitY(), -Vec::UnitY(), 0.015f);
00226 labelTableObjectIntersection(pc_bottle, pc_bottle_top, corner_size);
00227
00228
00229
00230 pg.setOutputCloud(pc_pan);
00231 pg.generateCylinder(s, o + pan, -0.15 * Vec::UnitY(), 0.15f);
00232 pg.setOutputCloud(pc_pan_handles);
00233 pg.generateHandle(s, o + pan + Vec(-0.15f, -0.11f, 0.0f),
00234 -Vec::UnitY(), Vec(0.0f, 0.0f, 0.04f), 0.0075f, M_PI);
00235 pg.generateHandle(s, o + pan + Vec(0.15f, -0.11f, 0.0f),
00236 Vec::UnitY(), Vec(0.0f, 0.0f, 0.04f), 0.0075f, M_PI);
00237 labelTableObjectIntersection(pc_pan, pc_pan_handles, corner_size);
00238
00239
00240
00241 pg.setOutputCloud(pc_apple);
00242 pg.generateSphere(s, o + apple + -0.035 * Vec::UnitY(), 0.035f);
00243
00244
00245
00246 Vec t_height(0.0f, -0.065f, 0.0f);
00247 Vec t_length(0.12f * sin(-0.25 * M_PI), 0.0f, 0.12f * cos(-0.25 * M_PI));
00248 Vec t_width = t_height.cross(t_length).normalized() * 0.045;
00249 pg.setOutputCloud(pc_tea);
00250 pg.generateBox(s, o + tea, t_height, t_length, t_width, corner_size);
00251
00252
00253
00254 pg.setOutputCloud(pc_herps);
00255 pg.generateCylinder(s, o + herps, -0.1f * Vec::UnitY(), 0.02f);
00256 pg.setOutputCloud(pc_herps_top);
00257 pg.generateCirclePlane(s, o + herps -0.1f * Vec::UnitY(), -Vec::UnitY(), 0.02f);
00258 labelTableObjectIntersection(pc_herps, pc_herps_top, corner_size);
00259
00260
00261
00262 *pc1 += *pc_mug;
00263 *pc1 += *pc_mug_handle;
00264 *pc1 += *pc_bowl;
00265 *pc1 += *pc_milk;
00266 *pc1 += *pc_bottle;
00267 *pc1 += *pc_bottle_top;
00268 *pc1 += *pc_pan;
00269 *pc1 += *pc_pan_handles;
00270 *pc1 += *pc_apple;
00271 *pc1 += *pc_tea;
00272 *pc1 += *pc_herps;
00273 *pc1 += *pc_herps_top;
00274
00275 VoxelGrid<PointXYZRGBA> vox;
00276 vox.setInputCloud(pc1);
00277 vox.setLeafSize(0.001f, 0.001f, 0.001f );
00278 vox.filter(*pc1);
00279
00280 cout << "Generated new Point Cloud:\n" << *pc1 << endl;
00281 if (file != "")
00282 {
00283 io::savePCDFileASCII(file, *pc1);
00284 cout << "Saved Point Cloud to: " << file << endl;
00285 }
00286
00287 if (visualize)
00288 {
00289 visualization::PCLVisualizer v;
00290 v.setBackgroundColor(255, 255, 255);
00291 v.addCoordinateSystem(0.1);
00292 ColorHdlRGBA hdl(pc1);
00293 v.addPointCloud<PointXYZRGBA>(pc1, hdl, "cloud");
00294
00295 while(!v.wasStopped())
00296 {
00297 v.spinOnce(100);
00298 usleep(100000);
00299 }
00300 }
00301 else
00302 {
00303 cout << "Visualization disabled." << endl;
00304 }
00305 return 0;
00306 }