Go to the documentation of this file.00001
00065
00066
00067 #include <boost/random.hpp>
00068 #include <boost/random/normal_distribution.hpp>
00069
00070
00071 template<typename PointT>
00072 void
00073 preprocessing::KinectErrorGenerator<PointT>::applyFilter (PointCloud &pc_out)
00074 {
00075
00076 boost::mt19937 rng;
00077 rng.seed(clock());
00078
00079
00080 if(&*input_ == &pc_out)
00081 input_.reset(new PointCloud(pc_out));
00082 else
00083 pc_out = *input_;
00084
00085
00086 for(int x=0; x<(int)input_->width; x++) {
00087 for(int y=0; y<(int)input_->height; y++) {
00088
00089
00090
00091 float diff=0;
00092 int num=0;
00093 for(int dx=-2; dx<2; dx++) {
00094 for(int dy=-2; dy<2; dy++) {
00095 if(dx+x<0||dx+x>=(int)input_->width
00096 || dy+y<0||dy+y>=(int)input_->height)
00097 continue;
00098
00099 diff += input_->points[x+y*input_->width].z -
00100 input_->points[x+dx+(y+dy)*input_->width].z;
00101 ++num;
00102 }
00103 }
00104 diff/=num;
00105
00106 float mean=diff;
00107
00108 PointT &p = pc_out.points[x+y*input_->width];
00109
00110 diff = std::max(0.005f, std::abs(diff));
00111
00112 diff = 0.01;
00113 mean = 0;
00114
00115 diff *= p.z*p.z;
00116
00117 diff = std::min(diff, 2.f);
00118
00119 boost::normal_distribution<> nd(0, diff*standard_deviation_);
00120
00121 boost::variate_generator<boost::mt19937&,
00122 boost::normal_distribution<> > var_nor(rng, nd);
00123
00124 float add=0;
00125 do {
00126 add = var_nor();
00127 } while(std::abs(add)>std::max(p.z*p.z*0.005f,std::abs(mean)));
00128
00129 p.x /= p.z;
00130 p.y /= p.z;
00131
00132 p.z += add-mean;
00133
00134
00135 int raw_depth = ((1./p.z)-3.3309495161)/-0.0030711016;
00136
00137 p.z = 1.0 / (raw_depth * -0.0030711016 + 3.3309495161);
00138
00139 p.x *= p.z;
00140 p.y *= p.z;
00141
00142 }
00143 }
00144
00145 }
00146
00147
00148 #define PCL_INSTANTIATE_KinectErrorGenerator(T) template class preprocessing::KinectErrorGenerator<T>;