00001 #ifndef IMAGE_3D_TEMPLATE_HPP
00002 #define IMAGE_3D_TEMPLATE_HPP
00003
00004
00005 #include <GL/gl.h>
00006
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
00035
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
00084 Image3DTemplate();
00085 ~Image3DTemplate();
00086
00087
00088
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
00133
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
00151
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
00157
00158 void dropOuterPoints(double rho_min, double rho_max);
00159
00160 void saveToFile(char* fileName);
00161 void readFromFile(char* fileName);
00162
00163
00164
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
00227
00228
00233 friend std::ostream& operator<< (std::ostream& os,
00234 const Image3DTemplate<PointType>& im3d);
00235
00236
00237
00242 friend std::istream& operator>> (std::istream& is,
00243 Image3DTemplate<PointType>& im3d);
00244 };
00245
00246
00247
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
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);
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;
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
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
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
00535
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
00581
00582
00583
00584
00585
00586
00587
00588
00589
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
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 }
00659 }
00660
00661 #endif // IMAGE_3D_TEMPLATE_HPP