00001
00059
00060 #include <boost/program_options.hpp>
00061 #include <boost/timer.hpp>
00062
00063
00064 #include <pcl/io/pcd_io.h>
00065 #include <pcl/kdtree/kdtree_flann.h>
00066 #include <pcl/kdtree/kdtree.h>
00067 #include <pcl/surface/mls.h>
00068 #include <pcl/visualization/pcl_visualizer.h>
00069 #include <pcl/visualization/point_cloud_handlers.h>
00070
00071 #include "cob_3d_mapping_common/stop_watch.h"
00072 #include <cob_3d_mapping_tools/impl/sav_gol_smoothing_filter.hpp>
00073
00074 template class SavGolSmoothingFilter<pcl::PointXYZRGB, pcl::PointXYZRGB>;
00075
00076 using namespace std;
00077 using namespace pcl;
00078
00079 typedef visualization::PointCloudColorHandlerRGBField<PointXYZRGB> ColorHdlRGB;
00080
00081
00082 string file_, file_out_ ="";
00083 float th_;
00084 int th2_;
00085 int size_, poly_, size2nd_, poly2nd_;
00086 bool vis_, mls_;
00087
00088
00089 void readOptions(int argc, char* argv[])
00090 {
00091 using namespace boost::program_options;
00092 options_description options("Options");
00093 options.add_options()
00094 ("help", "produce help message")
00095 ("in,i", value<string>(&file_), "input pcd file")
00096 ("out,o", value<string>(&file_out_), "save the smoothed cloud if you want")
00097 ("threshold_modifier,t", value<float>(&th_)->default_value(4.0), "thresholdmodifier")
00098 ("other_threshold_modifier,T", value<int>(&th2_)->default_value(7), "other thresholdmodifier")
00099 ("size,s", value<int>(&size_)->default_value(33), "size")
00100 ("poly,p", value<int>(&poly_)->default_value(6), "order of polynomial")
00101 ("size2nd,S", value<int>(&size2nd_)->default_value(11), "size for second pass")
00102 ("poly2nd,P", value<int>(&poly2nd_)->default_value(4), "order of polynomial for second pass")
00103 ("vis,v", value<bool>(&vis_)->default_value(false), "enable visualization")
00104 ("mls,m", value<bool>(&mls_)->default_value(false), "enable mls smoothing")
00105 ;
00106
00107 positional_options_description p_opt;
00108 p_opt.add("in", 1);
00109 variables_map vm;
00110 store(command_line_parser(argc, argv).options(options).positional(p_opt).run(), vm);
00111 notify(vm);
00112
00113 if (vm.count("help"))
00114 {
00115 cout << options << endl;
00116 exit(0);
00117 }
00118 }
00119
00120 int main(int argc, char** argv)
00121 {
00122 readOptions(argc, argv);
00123 PointCloud<PointXYZRGB>::Ptr p(new PointCloud<PointXYZRGB>);
00124 PointCloud<PointXYZRGB>::Ptr p2(new PointCloud<PointXYZRGB>);
00125 PointCloud<PointXYZRGB>::Ptr out(new PointCloud<PointXYZRGB>);
00126 PointCloud<PointXYZRGB>::Ptr out2(new PointCloud<PointXYZRGB>);
00127 PointCloud<PointXYZRGB>::Ptr out3(new PointCloud<PointXYZRGB>);
00128
00129 PCDReader r;
00130 if (r.read(file_, *p) == -1) return(0);
00131 *p2 = *p;
00132 PrecisionStopWatch t;
00133
00134 if (mls_)
00135 {
00136 #ifdef PCL_MINOR_VERSION
00137 #if PCL_MINOR_VERSION < 6
00138 t.precisionStart();
00139
00140 #ifdef PCL_VERSION_COMPARE //fuerte
00141 pcl::search::KdTree<PointXYZRGB>::Ptr tree (new pcl::search::KdTree<PointXYZRGB>());
00142 #else //electric
00143 pcl::KdTreeFLANN<PointXYZRGB>::Ptr tree (new pcl::KdTreeFLANN<PointXYZRGB> ());
00144 #endif
00145 tree->setInputCloud(p);
00146 MovingLeastSquares<PointXYZRGB, Normal> mls;
00147 mls.setInputCloud(p);
00148 mls.setPolynomialFit(true);
00149 mls.setPolynomialOrder(4);
00150 mls.setSearchMethod(tree);
00151 mls.setSearchRadius(0.05);
00152 mls.reconstruct(*out3);
00153 cout << t.precisionStop() << "s\t for MLS" << endl;
00154 #else
00155 cout << "massive interface change of MLS in PCL1.7" << endl;
00156 #endif
00157 #endif
00158 }
00159
00160
00161
00162
00163 t.precisionStart();
00164 vector<size_t> indices;
00165 SavGolSmoothingFilter<pcl::PointXYZRGB, pcl::PointXYZRGB> savgol;
00166 savgol.setInputCloud(p);
00167 savgol.setFilterCoefficients(size_,poly_);
00168 savgol.setDistanceThreshold(0.05);
00169 savgol.reconstruct(*out, indices);
00170 cout << t.precisionStop() << "s\t for SavGol on depth data" << endl;
00171
00172 t.precisionStart();
00173
00174 for (size_t i = 0; i<p->size(); i++)
00175 {
00176 p->points[i].z = round(1090.0f - ( 345.0f / p->points[i].z ));
00177 }
00178 indices.clear();
00179 savgol.setInputCloud(p);
00180 savgol.setFilterCoefficients(size_,poly_);
00181 savgol.setDistanceThreshold(th2_);
00182 savgol.reconstruct(*out2, indices);
00183
00184 savgol.setFilterCoefficients(size2nd_,poly2nd_);
00185 savgol.setDistanceThreshold(th2_);
00186 savgol.reconstruct2ndPass(indices, *out2);
00187 for (size_t i = 0; i<p->size(); i++)
00188 {
00189 out2->points[i].z = 345.0f / (1090.0f - out2->points[i].z );
00190 }
00191 cout << t.precisionStop() << "s\t for SavGol on disparity data" << endl;
00192
00193 if (file_out_ != "")
00194 {
00195 io::savePCDFileASCII<PointXYZRGB>(file_out_, *out2);
00196 }
00197
00198 if (vis_)
00199 {
00200 visualization::PCLVisualizer v;
00201 ColorHdlRGB col_hdl(p);
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 int v1(0);
00213 v.createViewPort(0.0, 0.5, 0.5, 1.0, v1);
00214 v.setBackgroundColor(0,127,127, v1);
00215 v.addPointCloud<PointXYZRGB>(p2,col_hdl, "org", v1);
00216
00217
00218 int v2(0);
00219 v.createViewPort(0.5, 0.5, 1.0, 1.0, v2);
00220 v.setBackgroundColor(0,127,127, v2);
00221 v.addPointCloud<PointXYZRGB>(out,col_hdl, "savgol1", v2);
00222
00223
00224 int v3(0);
00225 v.createViewPort(0.0, 0.0, 0.5, 0.5, v3);
00226 v.setBackgroundColor(0,127,127, v3);
00227 v.addPointCloud<PointXYZRGB>(out2,col_hdl, "savgol2", v3);
00228
00229 int v4(0);
00230 v.createViewPort(0.5, 0.0, 1.0, 0.5, v4);
00231 v.setBackgroundColor(0,127,127, v4);
00232 v.addPointCloud<PointXYZRGB>(out3,col_hdl, "mls", v4);
00233
00234 while(!v.wasStopped())
00235 {
00236 v.spinOnce(100);
00237 usleep(100000);
00238 }
00239 }
00240 return(0);
00241 }