Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Image3DTemplate.hpp
00001 #ifndef IMAGE_3D_TEMPLATE_HPP
00002 #define IMAGE_3D_TEMPLATE_HPP
00003 
00004 
00005 #include <GL/gl.h>
00006 // for definition of HAVE_OPENGL
00007 #include "jafarConfig.h"
00008 
00009 #include "kernel/jafarException.hpp"
00010 #include "jmath/jblas.hpp"
00011 #include "model3d/point3D.hpp"
00012 #include "model3d/point3DVar.hpp"
00013 #include <iostream>
00014 #include <fstream>
00015 #include <vector>
00016 #include <cfloat>
00017 #include <stdlib.h>
00018 #include <fstream>
00019 
00020 
00021 namespace jafar {
00023   namespace model3d {
00024 
00025 #ifndef MAX
00026 #define MAX(a,b) ((a) > (b) ? (a) : (b))
00027 #endif
00028     
00029 #ifndef MIN
00030 #define MIN(a,b) ((a) < (b) ? (a) : (b))
00031 #endif
00032 
00033 
00034     // pre-declaration to avoid compiler error 
00035     // for template friend function
00036     template <class PointType> class Image3DTemplate;
00037     template <class PointType>  
00038     std::ostream& operator<< (std::ostream& os,
00039             const Image3DTemplate<PointType>& im3d);
00040     template <class PointType>  
00041     std::istream& operator>> (std::istream& is,
00042             Image3DTemplate<PointType>& im3d);
00043 
00044 
00050     template <class PointType>
00051     class Image3DTemplate
00052     {
00053     public:
00054 
00055       enum ROBOT_TYPE { NIL_ROBOT,
00056       ROBOT_ADAM,
00057       ROBOT_HILARE,
00058       ROBOT_HILARE2, 
00059       ROBOT_LAMA,
00060       ROBOT_EVE,
00061       ROBOT_DALA,
00062       ROBOT_DILIGENT,
00063       ROBOT_INCONNU};
00064 
00065       enum CAPTEUR_TYPE { NIL_CAPTEUR, 
00066         CAPTEUR_LASER1, 
00067         CAPTEUR_LASER2, 
00068         CAPTEUR_STEREO,
00069         CAPTEUR_STEREO_GEROMS94, 
00070         CAPTEUR_LASER_SIMULATION,
00071         CAPTEUR_STEREO_SIMULATION};
00072 
00073       enum REPERE_TYPE { NIL_REPERE,
00074        REPERE_CAPTEUR,
00075        REPERE_AUTRE};
00076       
00077       enum COORDINATES_TYPE { NIL_COORDONNEES, 
00078             COORDONNEES_CARTESIENNES,
00079             COORDONNEES_CYLINDRIQUES, 
00080             COORDONNEES_SPHERIQUES };  
00081       
00082       // --------------
00083       // constructor and destructor
00084       Image3DTemplate();
00085       ~Image3DTemplate();
00086 
00087       // --------------
00088       // methodes
00089 
00099       inline PointType* operator () (int i, int j)
00100       {
00101   return &m_vPoints[i*m_nWidth+j];
00102       }
00103 
00107       void initialize(int nWidth_, int nHeight_);
00108 
00112       void clear();
00113 
00117       void info();
00118 
00119 
00120 #ifdef HAVE_OPENGL
00121 
00126       void display(unsigned char r=0, 
00127        unsigned char g=0,
00128        unsigned char b=0);
00129       
00130 #endif // HAVE_OPENGL
00131 
00132       // temprary function to load data directly from
00133       // three files have the data , one for X, Y and Z
00134       void readBrutData(int nWidth_, char* xFile, char* yFiel, char* zFile);
00135 
00136 
00141       void minMax();
00142 
00143       void minMaxFilteredPoints();
00144 
00148       void lowPassfilter(double maxX_);
00149 
00150       // mark the points out of the cube given by these 
00151       // limits as not_good points
00152       void dropOuterPoints(double x_min, double x_max, 
00153                            double y_min, double y_max,
00154                            double z_min, double z_max);
00155 
00156       // mark the points out of the cube given by these 
00157       // limits as not_good points
00158       void dropOuterPoints(double rho_min, double rho_max);
00159 
00160       void saveToFile(char* fileName);
00161       void readFromFile(char* fileName);
00162 
00163       // --------------
00164       // data member
00165 
00169       std::vector<PointType> m_vPoints;
00170 
00174       std::vector<PointType> m_vFilteredPoints;
00175 
00179       int m_nNumberOfGoodPoints;
00180  
00186       int m_nWidth;
00190       int m_nHeight;
00191 
00193       double minX;
00195       double minY;
00197       double minZ;
00199       double maxX;
00201       double maxY;
00203       double maxZ;
00204 
00205 
00207       double fminX;
00209       double fminY;
00211       double fminZ;
00213       double fmaxX;
00215       double fmaxY;
00217       double fmaxZ;
00218 
00219 
00220       ROBOT_TYPE       robot_type;
00221       CAPTEUR_TYPE     capteur_type;
00222       REPERE_TYPE      repere_type;
00223       COORDINATES_TYPE coordinates_type;
00224 
00225       // --------------
00226       // io steraming
00227       // Attention the empty <> is necessary to have a template function
00228       // --------------
00233       friend std::ostream& operator<< (std::ostream& os,
00234                const Image3DTemplate<PointType>& im3d);
00235 
00236       //      friend std::ostream& operator<< <> (::std::ostream& os,
00237       //        const Image3DTemplate<PointType>& im3d);
00242       friend std::istream& operator>> (std::istream& is,
00243                Image3DTemplate<PointType>& im3d);
00244     };
00245 
00246     // -----------------------------------------------------
00247     // Implementation
00248     // -----------------------------------------------------
00249 
00250     template <class PointType>
00251     Image3DTemplate<PointType>::Image3DTemplate()
00252     {
00253       m_nNumberOfGoodPoints = 0;
00254     }
00255 
00256     template <class PointType>
00257     Image3DTemplate<PointType>::~Image3DTemplate()
00258     {
00259       m_vPoints.clear();
00260     }
00261 
00262     template <class PointType>
00263     void Image3DTemplate<PointType>::initialize(int nWidth_, int nHeight_)
00264     {
00265       JFR_PRECOND((nWidth_ > 0)&&(nHeight_>0), 
00266       "invalide negative width or height");
00267       m_nWidth = nWidth_;
00268       m_nHeight = nHeight_;
00269       m_vPoints.resize(m_nWidth*m_nHeight);
00270     }
00271 
00272     template <class PointType>
00273     void Image3DTemplate<PointType>::clear()
00274     {
00275       m_nWidth = 0;
00276       m_nHeight = 0;
00277       m_vPoints.clear();
00278       m_nNumberOfGoodPoints = 0;
00279     }
00280 
00281 
00282     template <class PointType>
00283     void Image3DTemplate<PointType>::info()
00284     {
00285       std::cout << "Image3D" << std::endl
00286     << "\tWidth= " << m_nWidth
00287     << "\tHeight= "<< m_nHeight<< std::endl
00288     << "\tNumber of Points = "<< m_vPoints.size() << std::endl
00289     << "\tNumber of Good points " << m_nNumberOfGoodPoints 
00290     << std::endl
00291     << "\t " <<  minX << " < X < " << maxX << std::endl
00292     << "\t " <<  minY << " < Y < " << maxY << std::endl
00293     << "\t " <<  minZ << " < Z < " << maxZ << std::endl;
00294     }
00295 
00296 
00297 #ifdef HAVE_OPENGL
00298 
00299     template <class PointType>
00300     void Image3DTemplate<PointType>::display(unsigned char uc_r,
00301                unsigned char uc_g,
00302                unsigned char uc_b)
00303     {
00304   
00305       typename std::vector<PointType>::iterator i;
00306   
00307       // push the current colors
00308       glPushAttrib(GL_CURRENT_BIT);
00309       glDisable(GL_CULL_FACE);
00310       glPushMatrix();
00311   
00312       glBegin(GL_POINTS);
00313           glColor3ub(uc_r,uc_g,uc_b);// black points
00314     for (i= m_vPoints.begin(); i!= m_vPoints.end(); i++) 
00315       if (i->isGoodPoint())
00316         glVertex3f(i->x(),i->y(),i->z());  
00317       glEnd();
00318 
00319       glPopMatrix();
00320       glPopAttrib();
00321     }
00322     
00323 #endif // HAVE_OPENGL
00324 
00325 
00326     template <class PointType>
00327     void Image3DTemplate<PointType>::minMax()
00328     {
00329       m_nNumberOfGoodPoints = 0;
00330  
00331       minX = DBL_MAX;
00332       minY = DBL_MAX;
00333       minZ = DBL_MAX;
00334       
00335       maxX = -DBL_MAX;
00336       maxY = -DBL_MAX;
00337       maxZ = -DBL_MAX;
00338 
00339       typename std::vector<PointType>::iterator i;
00340       for (i=m_vPoints.begin(); i != m_vPoints.end(); i++) {
00341   if (i->isGoodPoint()) { 
00342     minX = MIN(minX, i->x());
00343     minY = MIN(minY, i->y());
00344     minZ = MIN(minZ, i->z());
00345     
00346     maxX = MAX(maxX, i->x());
00347     maxY = MAX(maxY, i->y());
00348     maxZ = MAX(maxZ, i->z());
00349     m_nNumberOfGoodPoints++;
00350   }
00351       }
00352       if (m_nNumberOfGoodPoints == 0) {
00353   minX = 0;
00354   minY = 0;
00355   minZ = 0;
00356   maxX = 0;
00357   maxY = 0;
00358   maxZ = 0;
00359 
00360       }
00361       std::cout << m_nNumberOfGoodPoints << " good points !! " << std::endl;
00362     }
00363 
00364 
00365     template <class PointType>
00366     void Image3DTemplate<PointType>::minMaxFilteredPoints()
00367     {
00368       fminX = DBL_MAX;
00369       fminY = DBL_MAX;
00370       fminZ = DBL_MAX;
00371       
00372       fmaxX = -DBL_MAX;
00373       fmaxY = -DBL_MAX;
00374       fmaxZ = -DBL_MAX;
00375 
00376 
00377       if (m_vFilteredPoints.size() == 0) {
00378   fminX = 0;
00379   fminY = 0;
00380   fminZ = 0;  
00381   fmaxX = 0;
00382   fmaxY = 0;
00383   fmaxZ = 0;
00384       }
00385 
00386       typename std::vector<PointType>::iterator i;
00387       for (i=m_vFilteredPoints.begin(); i != m_vFilteredPoints.end(); i++) {
00388   fminX = MIN(fminX, i->x());
00389   fminY = MIN(fminY, i->y());
00390   fminZ = MIN(fminZ, i->z());
00391   
00392   fmaxX = MAX(fmaxX, i->x());
00393   fmaxY = MAX(fmaxY, i->y());
00394   fmaxZ = MAX(fmaxZ, i->z());
00395       }
00396 
00397       std::cout << "filtered points : " << std::endl
00398     << "\tMin X Y Z are : "  << fminX << "  " 
00399     << fminY << " " << fminZ << std::endl
00400     << "\tMax X Y Z are : " << fmaxX
00401     << " " << fmaxY << " " << fmaxZ
00402     << std::endl;
00403       
00404     }
00405 
00406 
00407     template <class PointType>
00408     void Image3DTemplate<PointType>::lowPassfilter(double maxX_)
00409     {
00410       double dbMeanX = 0;
00411       double dbMeanY = 0;
00412       double dbMeanZ = 0;
00413 
00414       double dbSigma2X = 0; // sigma2 of X
00415       double dbSigma2Y = 0;
00416       double dbSigma2Z = 0;
00417 
00418       if (m_nNumberOfGoodPoints == 0)
00419         return;
00420 
00421       typename std::vector<PointType>::iterator i;
00422 
00423       for (i=m_vPoints.begin(); i != m_vPoints.end(); i++) {
00424         if (i->isGoodPoint()) { 
00425           dbMeanX += i->x();
00426           dbMeanY += i->y();
00427           dbMeanZ += i->z();
00428         }
00429       }
00430 
00431       dbMeanX /= m_nNumberOfGoodPoints;
00432       dbMeanY /= m_nNumberOfGoodPoints;
00433       dbMeanZ /= m_nNumberOfGoodPoints;
00434 
00435       for (i=m_vPoints.begin(); i != m_vPoints.end(); i++) {
00436         if (i->isGoodPoint()) { 
00437           dbSigma2X += (i->x()-dbMeanX)*(i->x()-dbMeanX);
00438           dbSigma2Y += (i->y()-dbMeanY)*(i->y()-dbMeanY);
00439           dbSigma2Z += (i->z()-dbMeanZ)*(i->z()-dbMeanZ);
00440         }
00441       }
00442 
00443       dbSigma2X /= m_nNumberOfGoodPoints;
00444       dbSigma2Y /= m_nNumberOfGoodPoints;
00445       dbSigma2Z /= m_nNumberOfGoodPoints;
00446 
00447       int nNumberOfGoodFilteredPoints = 0;
00448       double dbSigmaX = sqrt(dbSigma2X);
00449       double dbSigmaY = sqrt(dbSigma2Y);
00450       double dbSigmaZ = sqrt(dbSigma2Z);
00451 
00452       for (i=m_vPoints.begin(); i != m_vPoints.end(); i++) {
00453         if (i->isGoodPoint()) {
00454           if ( (fabs(i->x()-dbMeanX) < 2*dbSigmaX) &&
00455                (i->x()<maxX_) &&
00456                (fabs(i->y()-dbMeanY) < 2*dbSigmaY) &&
00457                (fabs(i->z()-dbMeanZ) < 2*dbSigmaZ) )
00458             nNumberOfGoodFilteredPoints++;
00459         }
00460       }
00461       
00462       std::cout << "Mean X    Y     Z  are " << std::endl
00463                 << dbMeanX <<" " << dbMeanY << " "
00464                 << dbMeanZ << std::endl;
00465       std::cout << "Sigma  X    Y     Z  are " << std::endl
00466                 << dbSigmaX <<" " << dbSigmaY << " "
00467                 << dbSigmaZ << std::endl;
00468       std::cout << "number of filtered points " 
00469                 << nNumberOfGoodFilteredPoints
00470                 << std::endl;
00471       
00472       if (nNumberOfGoodFilteredPoints == 0) 
00473         return;
00474       
00475       m_vFilteredPoints.resize(nNumberOfGoodFilteredPoints);
00476       
00477       int j = 0;
00478       for (i=m_vPoints.begin(); i != m_vPoints.end(); i++) {
00479         if (i->isGoodPoint()) {
00480           if ( (fabs(i->x()-dbMeanX) < 2*dbSigmaX) &&
00481                (i->x()<maxX_) &&
00482                (fabs(i->y()-dbMeanY) < 2*dbSigmaY) &&
00483                (fabs(i->z()-dbMeanZ) < 2*dbSigmaZ) ) {
00484             
00485             m_vFilteredPoints[j] = *i;
00486             j++;
00487           }
00488         }
00489       }
00490       
00491       std::cout << "number of filtered points " 
00492                 << nNumberOfGoodFilteredPoints
00493                 << std::endl;
00494       
00495     }
00496     
00497 
00498 
00499     // mark the points out of the cube given by these limits as not_good points
00500     template <class PointType>
00501     void Image3DTemplate<PointType>::dropOuterPoints(double x_min, double x_max, 
00502                                                      double y_min, double y_max,
00503                                                      double z_min, double z_max)
00504     {
00505       
00506       typename std::vector<PointType>::iterator i;
00507       
00508       for (i=m_vPoints.begin(); i != m_vPoints.end(); i++) {
00509         if (i->isGoodPoint()) { 
00510           if ( (i->x()<x_min) || (i->x()>x_max) ||
00511                (i->y()<y_min) || (i->y()>y_max) ||
00512                (i->z()<z_min) || (i->z()>z_max) )
00513             i->state = Point3D::BAD_POINT;
00514         }
00515       }
00516     }
00517 
00518     // mark the points out of the cube given by these limits as not_good points
00519     template <class PointType>
00520     void Image3DTemplate<PointType>::dropOuterPoints(double rho_min, double rho_max)
00521     {
00522       typename std::vector<PointType>::iterator i;
00523       double r;
00524       for (i=m_vPoints.begin(); i != m_vPoints.end(); i++) {
00525         if (i->isGoodPoint()) { 
00526           r = sqrt(i->x()*i->x() + i->y()*i->y() + i->z()*i->z());
00527           if ( (r < rho_min) || (r > rho_max) )
00528             i->state = Point3D::BAD_POINT;
00529         }
00530       }
00531     }
00532     
00533 
00534     // temprary function to load data directly from
00535     // three files have the data , one for X, Y and Z
00536     template <class PointType>
00537     void Image3DTemplate<PointType>::readBrutData(int nWidth_,
00538                                                   char* xFile, 
00539                                                   char* yFile, 
00540                                                   char* zFile)
00541     {
00542       initialize(nWidth_, nWidth_);
00543       std::ifstream xstr;
00544       std::ifstream ystr;
00545       std::ifstream zstr;
00546       xstr.open(xFile);
00547       ystr.open(yFile);
00548       zstr.open(zFile);
00549       double x,y,z;
00550       int nPointCount = nWidth_*nWidth_;
00551       for (int i=0;i< nPointCount; i++) {
00552         xstr >> x;
00553         ystr >> y;
00554         zstr >> z;
00555         m_vPoints[i].setCoord(x,y,z);
00556       }
00557       
00558       minMax();
00559       lowPassfilter(10);
00560       minMaxFilteredPoints();
00561       
00562       xstr.close();
00563       ystr.close();
00564       zstr.close();      
00565     }
00566 
00567 
00568 
00569     template <class PointType>
00570     void Image3DTemplate<PointType>::saveToFile(char* fileName)
00571     {
00572       std::fstream file;
00573       file.open(fileName, std::fstream::out | std::fstream::trunc);
00574 
00575       if (! file.is_open()) {
00576   std::cout << "can't open file " << fileName << std::endl;
00577   return;
00578       }
00579       /*
00580       file << m_vPoints.size() << std::endl;
00581 
00582       file << m_nWidth  << std::endl;
00583       file << m_nHeight << std::endl;
00584 
00585 
00586       typename std::vector<PointType>::const_iterator i;
00587       for(i=m_vPoints.begin(); i!= m_vPoints.end(); i++)
00588   file << *i << std::endl;
00589       file << std::endl;
00590       */
00591 
00592       typename std::vector<PointType>::const_iterator i;
00593       for(i=m_vFilteredPoints.begin(); i!= m_vFilteredPoints.end(); i++)
00594   if (i->x() !=0 && i->y()!=0) 
00595     file << i->x()-3.0 << "  " << i->y()
00596          << "  " << i->z()+0.63 << std::endl;
00597       file << std::endl;
00598     }
00599     
00600 
00601     template <class PointType>
00602     void Image3DTemplate<PointType>::readFromFile(char* fileName)
00603     {
00604       std::fstream file;
00605       file.open(fileName, std::fstream::in);
00606 
00607       if (! file.is_open()) {
00608   std::cout << "can't open file " << fileName << std::endl;
00609   return;
00610       }
00611       m_vPoints.clear();
00612       int nSize;
00613       file >> nSize;
00614 
00615 
00616       if (nSize>0) {
00617   file >> m_nWidth;
00618   file >> m_nHeight;
00619   m_vPoints.resize(nSize);
00620   for (int i=0; i< nSize; i++) 
00621     file >> m_vPoints[i];
00622       }
00623     }
00624 
00625 
00626 
00627     //--------------------------------------------------------------------
00628     // friend functions for serialization
00629     //--------------------------------------------------------------------
00630     template <class PointType>
00631     std::ostream& operator << (std::ostream& os,
00632              const Image3DTemplate<PointType>& im3d)
00633     {
00634       os << im3d.m_vPoints.size() << std::endl;;
00635       typename std::vector<PointType>::const_iterator i;
00636       for(i=im3d.m_vPoints.begin(); i!= im3d.m_vPoints.end(); i++)
00637   os << *i << std::endl;
00638       os << std::endl;
00639       return os;
00640     }
00641 
00642 
00643     template <class PointType>
00644     std::istream& operator >> (std::istream& is,
00645              Image3DTemplate<PointType>& im3d)
00646     {
00647       im3d.m_vPoints.clear();
00648       int nSize;
00649       is >> nSize;
00650       if (nSize>0) {
00651   im3d.m_vPoints.resize(nSize);
00652   for (int i=0; i< nSize; i++) 
00653     is >> im3d.m_vPoints[i];
00654       }
00655       return is;
00656     }
00657    
00658   }// namespace model3d
00659 }// namespace jafar
00660 
00661 #endif // IMAGE_3D_TEMPLATE_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:25 for Jafar by doxygen 1.7.6.1
LAAS-CNRS