Go to the documentation of this file.00001
00063 #ifndef __DOWNSAMPLE_FILTER_H__
00064 #define __DOWNSAMPLE_FILTER_H__
00065
00066 #include <pcl/point_cloud.h>
00067 #include <pcl/point_types.h>
00068
00069 #include "cob_3d_mapping_common/sensor_model.h"
00070
00071 namespace cob_3d_mapping_filters
00072 {
00073 template<typename PointT, typename SensorT = cob_3d_mapping::PrimeSense>
00074 class DownsampleFilter
00075 {
00076 public:
00077 typedef pcl::PointCloud<PointT> PointCloud;
00078 typedef typename pcl::PointCloud<PointT>::Ptr PointCloudPtr;
00079 typedef typename pcl::PointCloud<PointT>::ConstPtr PointCloudConstPtr;
00080
00081 public:
00082 DownsampleFilter ()
00083 {
00084 }
00085 ~DownsampleFilter ()
00086 {
00087 }
00088
00089 void
00090 setInputCloud (const PointCloudConstPtr& points)
00091 {
00092 surface_ = points;
00093 }
00094
00095 PointT
00096 convolve (size_t il, size_t i, size_t ir, const PointCloud& pc)
00097 {
00098 PointT p;
00099 if (pc[i].z != pc[i].z)
00100 {
00101 if (pc[ir].z == pc[ir].z)
00102 p = pc[ir];
00103 else
00104 p = pc[il];
00105 }
00106 else if (pc[ir].z != pc[ir].z || !SensorT::areNeighbors (pc[i].z, pc[ir].z))
00107 {
00108 if (pc[il].z != pc[il].z || !SensorT::areNeighbors (pc[i].z, pc[il].z))
00109 p = pc[i];
00110 else
00111 {
00112 p = pc[i];
00113 p.x = (2.0f / 3.0f) * pc[i].x + pc[il].x / 3.0f;
00114 p.y = (2.0f / 3.0f) * pc[i].y + pc[il].y / 3.0f;
00115 p.z = (2.0f / 3.0f) * pc[i].z + pc[il].z / 3.0f;
00116 }
00117 }
00118 else if (pc[il].z != pc[il].z || !SensorT::areNeighbors (pc[i].z, pc[il].z))
00119 {
00120 p = pc[i];
00121 p.x = (2.0f / 3.0f) * pc[i].x + pc[ir].x / 3.0f;
00122 p.y = (2.0f / 3.0f) * pc[i].y + pc[ir].y / 3.0f;
00123 p.z = (2.0f / 3.0f) * pc[i].z + pc[ir].z / 3.0f;
00124 }
00125 else
00126 {
00127 p = pc[i];
00128 p.x = 0.25f * pc[il].x + 0.5f * pc[i].x + 0.25f * pc[ir].x;
00129 p.y = 0.25f * pc[il].y + 0.5f * pc[i].y + 0.25f * pc[ir].y;
00130 p.z = 0.25f * pc[il].z + 0.5f * pc[i].z + 0.25f * pc[ir].z;
00131 }
00132 return p;
00133 }
00134
00135 void
00136 filter (PointCloud& out)
00137 {
00138 out.width = 0.5 * surface_->width;
00139 out.height = 0.5 * surface_->height;
00140 out.resize (out.width * out.height);
00141 PointCloud tmp;
00142 tmp.width = out.width;
00143 tmp.height = surface_->height;
00144 tmp.resize (tmp.width * tmp.height);
00145
00146 for (size_t y = 2 * tmp.width; y < tmp.size () - tmp.width; y += tmp.width)
00147 {
00148 for (size_t i = y + 1; i < y + tmp.width - 1; ++i)
00149 {
00150 int idx = 2 * i;
00151 tmp[i] = convolve (idx - 1, idx, idx + 1, *surface_);
00152 }
00153 }
00154
00155 for (size_t y = 1; y < out.height - 1; ++y)
00156 {
00157 for (size_t x = 1; x < out.width - 1; ++x)
00158 {
00159 int idx = (2 * y + 1) * out.width + x;
00160 out[y * out.width + x] = convolve (idx - out.width, idx, idx + out.width, tmp);
00161 }
00162 }
00163
00164 for (size_t i = 0; i < out.width; ++i)
00165 out[i].x = out[i].y = out[i].z = std::numeric_limits<float>::quiet_NaN ();
00166 for (size_t i = out.size () - out.width; i < out.size (); ++i)
00167 out[i].x = out[i].y = out[i].z = std::numeric_limits<float>::quiet_NaN ();
00168 for (size_t i = out.width; i < out.size (); i += out.width)
00169 {
00170 int i_end = i + out.width - 1;
00171 out[i].x = out[i].y = out[i].z = std::numeric_limits<float>::quiet_NaN ();
00172 out[i_end].x = out[i_end].y = out[i_end].z = std::numeric_limits<float>::quiet_NaN ();
00173 }
00174 }
00175
00176 private:
00177 PointCloudConstPtr surface_;
00178 };
00179 }
00180
00181 #endif