00001 #ifndef MODELER_KINECT_MODELER_HPP
00002 #define MODELER_KINECT_MODELER_HPP
00003
00004 #include "fdetect/DetectionResult.hpp"
00005 #include "fdetect/Detector.hpp"
00006 #include "fdetect/FloatDescriptor.hpp"
00007 #include "fdetect/SURFDetector.hpp"
00008 #include "gfm/GroupsMatcher.hpp"
00009 #include "gfm/MatchingResult.hpp"
00010 #include "gfm/EngineTracking.hpp"
00011 #include "gfm/DescriptorsBasedMatcher.hpp"
00012 #include "image/Image.hpp"
00013 #include "jmath/jblas.hpp"
00014 #include "jmath/ublasExtra.hpp"
00015 #include "modeler/mesher.hpp"
00016 #include "modeler/bpa.hpp"
00017 #include "modeler/vcgDeclarations.hpp"
00018 #include "jmath/pca.hpp"
00019
00020 #include "geom/t3d.hpp"
00021 #include "geom/t3dPointTools.hpp"
00022 #include <pcl/point_types.h>
00023 #include <pcl/point_cloud.h>
00024 #include <pcl/registration/icp_nl.h>
00025 #include <boost/bind.hpp>
00026 #include <boost/bimap.hpp>
00027 #include <boost/graph/adjacency_list.hpp>
00028 #include <boost/graph/connected_components.hpp>
00029 #include <boost/graph/kruskal_min_spanning_tree.hpp>
00030 #include <boost/graph/graphviz.hpp>
00031
00032 namespace jafar {
00033 namespace modeler {
00034
00044 class KinectModeler {
00045 public:
00046 typedef ublas::bounded_vector<float, 3> fvec3;
00047 protected:
00048 typedef fdetect_v2::InterestFeatureWithData<fdetect_v2::FloatDescriptor, cv::Point3f> Feature;
00049 typedef fdetect_v2::DetectionResult<Feature> DR;
00050 typedef gfm_v2::MatchingResult<Feature> MR;
00051 typedef gfm_v2::GroupsMatcher<Feature> GroupsMatcher;
00052 typedef gfm_v2::MatchSourceInfo<Feature> MatchSourceInfoType;
00054 fdetect_v2::Detector<Feature> *detector;
00056 gfm_v2::Matcher<Feature> *matcher;
00058 gfm_v2::EngineTracking<Feature> *tracker;
00059 typedef boost::bimap<Feature*, unsigned int> bm_type;
00060 bm_type features_indices;
00061 typedef bm_type::left_map::const_iterator features_citerator;
00062 typedef bm_type::right_map::const_iterator indices_citerator;
00064 std::map<unsigned int, DR > sequence_detect;
00065 size_t counter;
00066 unsigned int index;
00067 unsigned int global;
00068 int status;
00070 struct vertex
00071 {
00073 JfrMesh::CoordType p;
00075 std::vector<unsigned int> origine;
00076 vertex() {};
00077 vertex(const JfrMesh::CoordType& _p,
00078 const std::vector<unsigned int>& _origine) :
00079 p(_p), origine(_origine) {};
00080 void setP(const jblas::vec3& c) { p[0] = c[0]; p[1] = c[1]; p[2] = c[2]; }
00081 };
00083 std::map<unsigned int, vertex> vertices;
00084
00085 public:
00086 KinectModeler(fdetect_v2::Detector<Feature> *_detector = new fdetect_v2::SURFDetectorT<Feature>(),
00087 gfm_v2::Matcher<Feature> *_matcher = new gfm_v2::GroupsMatcher<Feature>( new gfm::WindowMatchFocus(100000, 100000), 10, 10, 2, 20.0, 0.6, 0.6, 0.1, 0.2, 10000, 10, 0.4, 0.0)):
00088 detector(_detector), matcher(_matcher),
00089 counter(0), index(0), global(0), images_graph(3)
00090
00091 {}
00092 void add(const image::Image& color_img, const ublas::matrix<float>& depth_image);
00093
00094 void build();
00095 void analyse();
00096 inline void write(const std::string& filename) {
00097 std::ofstream outfile;
00098 outfile.open(filename.c_str());
00099 if(outfile.is_open())
00100 write_graphviz(outfile, images_graph);
00101 outfile.close();
00102 }
00103 private:
00104
00105
00106
00107
00108
00109 std::map<size_t, ublas::matrix<float> > depth_map;
00110 std::map<size_t, image::Image > images_map;
00111 std::map<size_t, pcl::PointCloud<pcl::PointXYZ> > cloud_map;
00112 std::map<size_t, MatchSourceInfoType *> match_infos;
00113 int previous_width;
00114 MatchSourceInfoType *m_source_info;
00115
00116
00118
00120 jblas::mat44 H;
00122 fvec3 ref_mean, match_mean, transformed_mean;
00124 std::vector<unsigned char> outliers;
00125
00126 struct edge_type{
00127 MR matches;
00128 geom::T3D *trans;
00129 double error;
00130 };
00131 typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS, boost::no_property, edge_type> Graph;
00132 Graph images_graph;
00133 typedef Graph::edge_descriptor Edge;
00134 typedef Graph::vertex_descriptor Vertex;
00135 int nb_componenets;
00137 inline bool is_invalid(const ublas::matrix<float>& M, size_t r)
00138 {
00139 return (std::abs(M(r,2)) == 0) ||
00140 (std::abs(M(r,1)) == 0) ||
00141 (std::abs(M(r,0)) == 0);
00142 }
00144 inline bool is_invalid(Feature* f, const ublas::matrix<float>& M, int width)
00145 {
00146 return is_invalid(M, (int(f->v())*width)+int(f->u()));
00147 }
00149 void means(const MR& paired, fvec3& ref_mean, fvec3& match_mean)
00150 {
00151 cv::Point3f ref_pt;
00152 cv::Point3f match_pt;
00153 for(MR::const_iterator it = paired.begin(); it != paired.end(); ++it) {
00154 ref_pt+=it->point_ref->getData();
00155 match_pt+=it->point_match->getData();
00156 }
00157 ref_mean[0] = ref_pt.x; ref_mean[1] = ref_pt.y; ref_mean[2] = ref_pt.z;
00158 match_mean[0] = match_pt.x; match_mean[1] = match_pt.y; match_mean[2] = match_pt.z;
00159 ref_mean/=paired.size();
00160 match_mean/=paired.size();
00161 }
00163 void erase(MR& mr, const std::vector<unsigned char>& outliers) {
00164 MR::iterator result = mr.begin();
00165 size_t counter = 0;
00166 for (MR::iterator first = mr.begin(); first != mr.end(); ++first, counter++)
00167 {
00168 cout << "outliers[counter] "<<outliers[counter]<<endl;
00169 if (!outliers[counter]) *result++ = *first;
00170 }
00171 if(result != mr.end())
00172 mr.erase(result, mr.end());
00173 }
00177 void fill_cloud_with_contours(size_t image_idx)
00178 {
00179 vector<vector<cv::Point> > contours;
00180 vector<cv::Vec4i> hierarchy;
00181 image::Image gray;
00182 images_map[image_idx].copyTo(gray);
00183 cv::threshold( gray, gray, 128, 255, CV_THRESH_BINARY );
00184 cv::findContours( gray, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
00185 if( contours.size() > 0 )
00186 {
00187 size_t nb_points = 0;
00188 for(vector<vector<cv::Point> >::const_iterator this_contour = contours.begin();
00189 this_contour != contours.end();
00190 ++this_contour)
00191 nb_points+=this_contour->size();
00192
00193 pcl::PointCloud<pcl::PointXYZ> &cloud = cloud_map[image_idx];
00194 cloud.width = 1;
00195 cloud.height = nb_points;
00196 cloud.points.resize(nb_points);
00197 cloud.is_dense = false;
00198
00199 size_t pos = 0;
00200 for(int counter =0; counter >= 0; counter = hierarchy[counter][0])
00201 {
00202
00203 for(std::vector<cv::Point>::iterator pit = contours[counter].begin();
00204 pit != contours[counter].end();
00205 ++pit, pos++)
00206 {
00207 size_t idx = (pit->x * images_map[idx].width()) + pit->y;
00208 const ublas::matrix<float> &entry = depth_map[image_idx];
00209 if(!is_invalid(entry, idx))
00210 {
00211 cloud.points[pos].x = entry(idx,0);
00212 cloud.points[pos].y = entry(idx,1);
00213 cloud.points[pos].z = entry(idx,2);
00214 }
00215 }
00216 }
00217 assert(pos == nb_points);
00218 }
00219 }
00220
00221 template <class InputIterator, class OutputIterator, class T>
00222 void copy_others ( InputIterator first, InputIterator last,
00223 OutputIterator result, const T& value )
00224 {
00225 for ( ; first != last; ++first)
00226 if (!(*first == value)) *result++ = first;
00227 }
00228 };
00229 }
00230 }
00231
00232 #endif