00001
00064
00065 #include <boost/program_options.hpp>
00066
00067
00068 #include <pcl/point_types.h>
00069 #include <pcl/io/pcd_io.h>
00070
00071
00072 #include "cob_3d_mapping_common/point_types.h"
00073 #include "cob_3d_mapping_common/stop_watch.h"
00074 #include "cob_3d_features/organized_normal_estimation.h"
00075 #include "cob_3d_features/organized_curvature_estimation.h"
00076 #include "cob_3d_mapping_common/io.h"
00077
00078 using namespace std;
00079 using namespace pcl;
00080
00081 string file_in_;
00082 vector<string> file_out_(2,"");
00083 bool fixed_max_ = false, fixed_min_ = false;
00084 float max_pc1_ = 0, min_pc1_ = 0, th_;
00085 float max_pc2_ = 0, min_pc2_ = 0;
00086 int radius_;
00087 int circle_;
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", value<string>(&file_in_), "input pcd file")
00096 ("out", value< vector<string> >(&file_out_), "output files, first ppm, [second ppm]")
00097 ("radius,r", value<int>(&radius_)->default_value(5), "radius")
00098 ("circle,c", value<int>(&circle_)->default_value(2),"circle steps")
00099 ("threshold_modifier,t", value<float>(&th_)->default_value(4.0), "thresholdmodifier")
00100 ("max_pc,M", value<float>(&max_pc1_), "maximum value for pc1")
00101 ("min_pc,m", value<float>(&min_pc1_), "minimum value for pc1")
00102 ;
00103
00104 positional_options_description p_opt;
00105 p_opt.add("in", 1).add("out", 2);
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") || !vm.count("in") || !vm.count("out"))
00111 {
00112 cout << "Reads an raw organized point cloud and extracts \n"
00113 << "the principal curvatures as ppm file.\n"
00114 << "This ppm was used to label a point cloud manually" << endl;
00115 cout << options << endl;
00116 exit(0);
00117 }
00118 if (vm.count("max_pc"))
00119 fixed_max_ = true;
00120
00121 if (vm.count("min_pc"))
00122 fixed_min_ = true;
00123
00124 }
00125
00126 int main(int argc, char** argv)
00127 {
00128 readOptions(argc, argv);
00129
00130 PointCloud<PointXYZRGB>::Ptr p(new PointCloud<PointXYZRGB>);
00131 PointCloud<PointXYZRGB>::Ptr p2(new PointCloud<PointXYZRGB>);
00132 PointCloud<Normal>::Ptr n(new PointCloud<Normal>);
00133 PointCloud<PrincipalCurvatures>::Ptr pc(new PointCloud<PrincipalCurvatures>);
00134 PointCloud<PointLabel>::Ptr l(new PointCloud<PointLabel>);
00135 PCDReader r;
00136 if (r.read(file_in_, *p) == -1) return(0);
00137 *p2 = *p;
00138
00139 PrecisionStopWatch t;
00140 t.precisionStart();
00141 cob_3d_features::OrganizedNormalEstimation<PointXYZRGB, Normal, PointLabel>one;
00142 one.setInputCloud(p);
00143 one.setOutputLabels(l);
00144 one.setPixelSearchRadius(radius_,1,circle_);
00145 one.setSkipDistantPointThreshold(th_);
00146 one.compute(*n);
00147 cout << t.precisionStop() << "s\t for Organized Normal Estimation" << endl;
00148
00149 t.precisionStart();
00150 cob_3d_features::OrganizedCurvatureEstimation<PointXYZRGB,Normal,PointLabel,PrincipalCurvatures>oce;
00151 oce.setInputCloud(p);
00152 oce.setInputNormals(n);
00153 oce.setOutputLabels(l);
00154 oce.setPixelSearchRadius(radius_,1,circle_);
00155 oce.setSkipDistantPointThreshold(th_);
00156 oce.setEdgeClassThreshold(0.1);
00157 oce.compute(*pc);
00158 cout << t.precisionStop() << "s\t for Organized Curvature Estimation" << endl;
00159
00160 for (size_t i = 0; i < pc->points.size(); i++)
00161 {
00162 if (pcl_isnan(pc->points[i].pc1))
00163 continue;
00164 if(!fixed_max_)
00165 max_pc1_ = max (pc->points[i].pc1, max_pc1_);
00166 if(!fixed_min_)
00167 min_pc1_ = min (pc->points[i].pc1, min_pc1_);
00168
00169 max_pc2_ = max (pc->points[i].pc2, max_pc2_);
00170 min_pc2_ = min (pc->points[i].pc2, min_pc2_);
00171 }
00172 max_pc2_ = 0.1;
00173 min_pc2_ = 0.0;
00174 cout << "Max_pc1 = " << max_pc1_ << " | Min_pc1 = " << min_pc1_ << endl;
00175 cout << "Max_pc2 = " << max_pc2_ << " | Min_pc2 = " << min_pc2_ << endl;
00176
00177 double grd_position;
00178 uint8_t rgb[3];
00179
00180 for (size_t i = 0; i < pc->points.size(); i++)
00181 {
00182 if (!pcl_isnan(pc->points[i].pc1))
00183 {
00184 grd_position = (pc->points[i].pc1 - min_pc1_) / (max_pc1_ - min_pc1_);
00185 cob_3d_mapping_common::getGradientColor(grd_position, rgb);
00186 p->points[i].r = (int)rgb[0];
00187 p->points[i].g = (int)rgb[1];
00188 p->points[i].b = (int)rgb[2];
00189
00190 grd_position = (pc->points[i].pc2 - min_pc2_) / (max_pc2_ - min_pc2_);
00191 cob_3d_mapping_common::getGradientColor(grd_position, rgb);
00192 p2->points[i].r = (int)rgb[0];
00193 p2->points[i].g = (int)rgb[1];
00194 p2->points[i].b = (int)rgb[2];
00195 }
00196 else
00197 {
00198 p->points[i].r = 125;
00199 p->points[i].g = 125;
00200 p->points[i].b = 125;
00201
00202 p2->points[i].r = 125;
00203 p2->points[i].g = 125;
00204 p2->points[i].b = 125;
00205 }
00206 }
00207
00208 cob_3d_mapping_common::PPMWriter ppmW;
00209 if (file_out_[0] != "")
00210 ppmW.writeRGB(file_out_[0], *p);
00211
00212 if (file_out_[1] != "")
00213 ppmW.writeRGB(file_out_[1], *p2);
00214
00215 return 0;
00216 }