52 #include <visp/vpMatrix.h>
53 #include <visp/vpMath.h>
54 #include <visp/vpColVector.h>
55 #include <visp/vpPoint.h>
56 #include <visp/vpPose.h>
57 #include <visp/vpDisplay.h>
58 #include <visp/vpDisplayOpenCV.h>
59 #include <visp/vpDisplayX.h>
60 #include <visp/vpDisplayGDI.h>
61 #include <visp/vpPixelMeterConversion.h>
62 #include <visp/vpCameraParameters.h>
63 #include <visp/vpColor.h>
64 #include <visp/vpIoTools.h>
65 #include <visp/vpException.h>
66 #include <visp/vpImageIo.h>
67 #include <visp/vpMbTracker.h>
68 #include <visp/vpMatrixException.h>
69 #include <visp/vpIoTools.h>
74 #include <Inventor/nodes/SoSeparator.h>
75 #include <Inventor/VRMLnodes/SoVRMLIndexedFaceSet.h>
76 #include <Inventor/VRMLnodes/SoVRMLIndexedLineSet.h>
77 #include <Inventor/VRMLnodes/SoVRMLCoordinate.h>
78 #include <Inventor/actions/SoWriteAction.h>
79 #include <Inventor/actions/SoSearchAction.h>
80 #include <Inventor/misc/SoChildList.h>
81 #include <Inventor/actions/SoGetMatrixAction.h>
82 #include <Inventor/actions/SoGetPrimitiveCountAction.h>
83 #include <Inventor/actions/SoToVRML2Action.h>
84 #include <Inventor/VRMLnodes/SoVRMLGroup.h>
85 #include <Inventor/VRMLnodes/SoVRMLShape.h>
108 #ifdef VISP_HAVE_COIN
146 std::string ext =
".init";
147 std::string str_pose =
"";
148 unsigned int pos = _initFile.rfind(ext);
151 std::fstream finitpos ;
153 char s[FILENAME_MAX];
155 if( pos == _initFile.size()-ext.size() && pos != 0)
156 str_pose = _initFile.substr(0,pos) +
".0.pos";
158 str_pose = _initFile +
".0.pos";
160 finitpos.open(str_pose.c_str() ,std::ios::in) ;
161 sprintf(s,
"%s", str_pose.c_str());
166 if(finitpos.fail() ){
167 std::cout <<
"cannot read " << s << std::endl <<
"cMo set to identity" << std::endl;
171 for (
unsigned int i = 0; i < 6; i += 1){
172 finitpos >> init_pos[i];
178 std::cout <<
"last_cMo : "<<std::endl << last_cMo <<std::endl;
185 std::cout <<
"No modification : left click " << std::endl;
186 std::cout <<
"Modify initial pose : right click " << std::endl ;
189 "left click to validate, right click to modify initial pose",
217 if( pos == _initFile.size()-ext.size() && pos != 0)
218 sprintf(s,
"%s", _initFile.c_str());
220 sprintf(s,
"%s.init", _initFile.c_str());
222 std::cout <<
"filename " << s << std::endl ;
223 finit.open(s,std::ios::in) ;
225 std::cout <<
"cannot read " << s << std::endl;
230 if( pos == _initFile.size()-ext.size() && pos != 0)
231 dispF = _initFile.substr(0,pos) +
".ppm";
233 dispF = _initFile +
".ppm";
235 sprintf(s,
"%s", dispF.c_str());
239 #if defined VISP_HAVE_X11
241 #elif defined VISP_HAVE_GDI
243 #elif defined VISP_HAVE_OPENCV
249 #if defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV)
250 d.
init(Iref,10,500,
"Where to initialize...") ;
260 std::cout <<
"number of points " << n << std::endl ;
262 for (
unsigned int i=0 ; i < n ; i++){
272 bool isWellInit =
false;
276 for(
unsigned int i=0 ; i< n ; i++)
278 std::cout <<
"Click on point " << i+1 << std::endl ;
287 std::cout <<
"click sur point " << ip << std::endl;
310 "left click to validate, right click to re initialize object",
342 std::cout <<
"cMo : "<<std::endl <<
cMo <<std::endl;
362 for (
unsigned int i=0 ; i < points3D_list.size() ; i++)
363 P[i].setWorldCoordinates(points3D_list[i].get_oX(),points3D_list[i].get_oY(),points3D_list[i].get_oZ()) ;
367 #if defined VISP_HAVE_X11
369 #elif defined VISP_HAVE_GDI
371 #elif defined VISP_HAVE_OPENCV
375 if(displayFile !=
""){
377 std::cout << displayFile.c_str() << std::endl;
379 #if defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV)
380 d.
init(Iref,10,500,
"Where to initialize...") ;
389 bool isWellInit =
false;
392 for(
unsigned int i=0 ; i< points3D_list.size() ; i++)
394 std::cout <<
"Click on point " << i+1 << std::endl ;
403 std::cout <<
"Click on point " << ip << std::endl;
426 "left click to validate, right click to re initialize object",
473 char s[FILENAME_MAX];
476 std::string ext =
".init";
477 unsigned int pos = _initFile.rfind(ext);
479 if( pos == _initFile.size()-ext.size() && pos != 0)
480 sprintf(s,
"%s", _initFile.c_str());
482 sprintf(s,
"%s.init", _initFile.c_str());
484 std::cout <<
"filename " << s << std::endl ;
485 finit.open(s,std::ios::in) ;
487 std::cout <<
"cannot read " << s << std::endl;
494 std::cout <<
"number of points " << size << std::endl ;
498 for(
unsigned int i=0 ; i< size ; i++)
511 vpERROR_TRACE(
"vpMbTracker::initFromPoints(), Number of 2D points different to the number of 3D points." );
513 for(
unsigned int i=0 ; i< size ; i++)
552 if(points2D_list.size() != points3D_list.size())
553 vpERROR_TRACE(
"vpMbTracker::initFromPoints(), Number of 2D points different to the number of 3D points." );
555 unsigned int size = points3D_list.size();
559 for(
unsigned int i=0 ; i< size ; i++)
561 P[i].
setWorldCoordinates(points3D_list[i].get_oX(),points3D_list[i].get_oY(),points3D_list[i].get_oZ()) ;
606 char s[FILENAME_MAX];
610 std::string ext =
".pos";
611 unsigned int pos = _initFile.rfind(ext);
613 if( pos == _initFile.size()-ext.size() && pos != 0)
614 sprintf(s,
"%s", _initFile.c_str());
616 sprintf(s,
"%s.pos", _initFile.c_str());
618 std::cout <<
"filename " << s << std::endl ;
619 finit.open(s,std::ios::in) ;
621 std::cout <<
"cannot read " << s << std::endl;
625 for (
unsigned int i = 0; i < 6; i += 1){
626 finit >> init_pos[i];
665 std::fstream finitpos ;
666 char s[FILENAME_MAX];
668 sprintf(s,
"%s", filename.c_str());
669 finitpos.open(s, std::ios::out) ;
672 finitpos << init_pos;
689 std::string::const_iterator it;
692 it = _modelFile.end();
693 if((*(it-1) ==
'o' && *(it-2) ==
'a' && *(it-3) ==
'c' && *(it-4) ==
'.') ||
694 (*(it-1) ==
'O' && *(it-2) ==
'A' && *(it-3) ==
'C' && *(it-4) ==
'.') ){
697 else if((*(it-1) ==
'l' && *(it-2) ==
'r' && *(it-3) ==
'w' && *(it-4) ==
'.') ||
698 (*(it-1) ==
'L' && *(it-2) ==
'R' && *(it-3) ==
'W' && *(it-4) ==
'.') ){
736 #ifdef VISP_HAVE_COIN
742 SbBool ok = in.openFile(_modelFile.c_str());
743 SoSeparator *sceneGraph;
744 SoVRMLGroup *sceneGraphVRML2;
751 if(!in.isFileVRML2())
753 sceneGraph = SoDB::readAll(&in);
754 if (sceneGraph == NULL) { }
757 SoToVRML2Action tovrml2;
758 tovrml2.apply(sceneGraph);
759 sceneGraphVRML2 =tovrml2.getVRML2SceneGraph();
760 sceneGraphVRML2->ref();
765 sceneGraphVRML2 = SoDB::readAllVRML(&in);
766 if (sceneGraphVRML2 == NULL) { }
767 sceneGraphVRML2->ref();
772 int nbShapes = sceneGraphVRML2->getNumChildren();
776 for (
int i = 0; i < nbShapes; i++)
778 child = sceneGraphVRML2->getChild(i);
779 if (child->getTypeId() == SoVRMLShape::getClassTypeId())
781 SoChildList * child2list = child->getChildren();
782 for (
int j = 0; j < child2list->getLength(); j++)
784 if (((SoNode*)child2list->get(j))->getTypeId() == SoVRMLIndexedFaceSet::getClassTypeId())
786 SoVRMLIndexedFaceSet * face_set;
787 face_set = (SoVRMLIndexedFaceSet*)child2list->get(j);
788 if(!strncmp(face_set->getName().getString(),
"cyl",3)){
794 if (((SoNode*)child2list->get(j))->getTypeId() == SoVRMLIndexedLineSet::getClassTypeId())
796 SoVRMLIndexedLineSet * line_set;
797 line_set = (SoVRMLIndexedLineSet*)child2list->get(j);
804 sceneGraphVRML2->unref();
806 vpERROR_TRACE(
"coin not detected with ViSP, cannot load model : %s", _modelFile.c_str());
841 std::ifstream file_id;
842 file_id.open (_modelFile.c_str(), std::ifstream::in);
844 std::cout <<
"cannot read CAO model file: " << _modelFile << std::endl;
852 while( (file_id.get(c)!=NULL)&&(c ==
'#')) file_id.ignore(256,
'\n');
858 file_id >> caoVersion;
861 std::cout <<
"in vpMbEdgeTracker::loadCAOModel -> Bad parameter header file : use V0, V1, ...";
863 "in vpMbEdgeTracker::loadCAOModel -> Bad parameter header file : use V0, V1, ...");
866 while( (file_id.get(c)!=NULL)&&(c!=
'\n')) ;
867 while( (file_id.get(c)!=NULL)&&(c ==
'#')) file_id.ignore(256,
'\n') ;
871 unsigned int caoNbrPoint;
872 file_id >> caoNbrPoint;
873 std::cout <<
"> " << caoNbrPoint <<
" points" << std::endl;
876 caoPoints =
new vpPoint[caoNbrPoint];
886 for(
unsigned int k=0; k < caoNbrPoint; k++){
890 if (caoVersion == 2){
895 if(k != caoNbrPoint-1){
896 file_id.ignore(256,
'\n');
901 while( (file_id.get(c)!=NULL)&&(c!=
'\n')) ;
902 while( (file_id.get(c)!=NULL)&&(c ==
'#')) file_id.ignore(256,
'\n');
906 unsigned int caoNbrLine;
907 file_id >> caoNbrLine;
908 unsigned int *caoLinePoints = NULL;
909 std::cout <<
"> " << caoNbrLine <<
" lines" << std::endl;
911 caoLinePoints =
new unsigned int[2*caoNbrLine];
913 unsigned int index1, index2;
915 for(
unsigned int k=0; k < caoNbrLine ; k++){
919 caoLinePoints[2*k] = index1;
920 caoLinePoints[2*k+1] = index2;
922 if(index1 < caoNbrPoint && index2 < caoNbrPoint){
923 std::vector<vpPoint> extremities;
924 extremities.push_back(caoPoints[index1]);
925 extremities.push_back(caoPoints[index2]);
929 vpTRACE(
" line %d has wrong coordinates.", k);
932 if(k != caoNbrLine-1){
933 file_id.ignore(256,
'\n');
937 while( (file_id.get(c)!=NULL)&&(c!=
'\n')) ;
938 while( (file_id.get(c)!=NULL)&&(c ==
'#')) file_id.ignore(256,
'\n');
944 unsigned int caoNbrPolygonLine;
945 file_id >> caoNbrPolygonLine;
946 std::cout <<
"> " << caoNbrPolygonLine <<
" polygon line" << std::endl;
948 for(
unsigned int k = 0;k < caoNbrPolygonLine; k++){
949 unsigned int nbLinePol;
950 file_id >> nbLinePol;
951 std::vector<vpPoint> corners;
952 for(
unsigned int i = 0; i < nbLinePol; i++){
954 corners.push_back(caoPoints[caoLinePoints[2*index]]);
956 if(k != caoNbrPolygonLine-1){
957 file_id.ignore(256,
'\n');
962 while( (file_id.get(c)!=NULL)&&(c!=
'\n')) ;
963 while( (file_id.get(c)!=NULL)&&(c ==
'#')) file_id.ignore(256,
'\n');
967 unsigned int caoNbrPolygonPoint;
968 file_id >> caoNbrPolygonPoint;
969 std::cout <<
"> " << caoNbrPolygonPoint <<
" polygon point" << std::endl;
970 for(
unsigned int k = 0;k < caoNbrPolygonPoint; k++){
972 file_id >> nbPointPol;
973 std::vector<vpPoint> corners;
974 for(
int i = 0; i < nbPointPol; i++){
976 corners.push_back(caoPoints[index]);
978 if(k != caoNbrPolygonPoint-1){
979 file_id.ignore(256,
'\n');
985 while( (file_id.get(c)!=NULL)&&(c!=
'\n')) ;
986 while( (file_id.get(c)!=NULL)&&(c ==
'#')) file_id.ignore(256,
'\n');
991 delete[] caoLinePoints;
997 unsigned int caoNbCylinder;
998 file_id >> caoNbCylinder;
999 std::cout <<
"> " << caoNbCylinder <<
" cylinder" << std::endl;
1000 for(
unsigned int k=0; k<caoNbCylinder; ++k){
1002 unsigned int indexP1, indexP2;
1006 initCylinder(caoPoints[indexP1], caoPoints[indexP2], radius);
1010 std::cerr <<
"Cannot get the number of cylinder" << std::endl;
1014 delete[] caoLinePoints;
1020 #ifdef VISP_HAVE_COIN
1030 std::vector<vpPoint> corners;
1035 int indexListSize = _face_set->coordIndex.getNum();
1036 SbVec3f point(0,0,0);
1038 SoVRMLCoordinate *coord;
1040 unsigned int indexFace = 0;
1042 for (
int i = 0; i < indexListSize; i++)
1044 if (_face_set->coordIndex[i] == -1)
1046 if(corners.size() > 1)
1055 coord = (SoVRMLCoordinate *)(_face_set->coord.getValue());
1056 int index = _face_set->coordIndex[i];
1057 point[0]=coord->point[index].getValue()[0];
1058 point[1]=coord->point[index].getValue()[1];
1059 point[2]=coord->point[index].getValue()[2];
1061 corners.push_back(pt);
1080 std::vector<vpPoint> corners_c1, corners_c2;
1081 SoVRMLCoordinate* coords = (SoVRMLCoordinate *)_face_set->coord.getValue();
1083 unsigned int indexListSize = (
unsigned int)coords->point.getNum();
1085 if(indexListSize % 2 == 1){
1086 std::cout <<
"Not an even number of points when extracting a cylinder." << std::endl;
1089 corners_c1.resize(indexListSize / 2);
1090 corners_c2.resize(indexListSize / 2);
1091 SbVec3f point(0,0,0);
1096 for(
int i=0; i<coords->point.getNum(); ++i){
1097 point[0]=coords->point[i].getValue()[0];
1098 point[1]=coords->point[i].getValue()[1];
1099 point[2]=coords->point[i].getValue()[2];
1103 if(i < (
int)corners_c1.size()){
1104 corners_c1[(
unsigned int)i] = pt;
1106 corners_c2[(
unsigned int)i-corners_c1.size()] = pt;
1114 dist[0] = p1.
get_oX() - corners_c1[0].get_oX();
1115 dist[1] = p1.
get_oY() - corners_c1[0].get_oY();
1116 dist[2] = p1.
get_oZ() - corners_c1[0].get_oZ();
1117 double radius_c1 = sqrt(dist.
sumSquare());
1118 dist[0] = p2.
get_oX() - corners_c2[0].get_oX();
1119 dist[1] = p2.
get_oY() - corners_c2[0].get_oY();
1120 dist[2] = p2.
get_oZ() - corners_c2[0].get_oZ();
1121 double radius_c2 = sqrt(dist.sumSquare());
1123 if(std::fabs(radius_c1 - radius_c2) > (std::numeric_limits<double>::epsilon() *
vpMath::maximum(radius_c1, radius_c2))){
1124 std::cout <<
"Radius from the two circles of the cylinders are different." << std::endl;
1145 std::cout <<
"Cannot extract center of gravity of empty set." << std::endl;
1153 for(
unsigned int i=0; i<_pts.size(); ++i){
1155 oY += _pts[i].get_oY();
1156 oZ += _pts[i].get_oZ();
1173 std::vector<vpPoint> corners;
1176 int indexListSize = _line_set->coordIndex.getNum();
1178 SbVec3f point(0,0,0);
1180 SoVRMLCoordinate *coord;
1182 unsigned int indexFace = 0;
1184 for (
int i = 0; i < indexListSize; i++)
1186 if (_line_set->coordIndex[i] == -1)
1188 if(corners.size() > 1)
1197 coord = (SoVRMLCoordinate *)(_line_set->coord.getValue());
1198 int index = _line_set->coordIndex[i];
1199 point[0]=coord->point[index].getValue()[0];
1200 point[1]=coord->point[index].getValue()[1];
1201 point[2]=coord->point[index].getValue()[2];
1204 corners.push_back(pt);
1230 "Incorrect matrices size in computeJTR.");
1234 const unsigned int N = _interaction.
getRows();
1236 for (
unsigned int i = 0; i < 6; i += 1){
1238 for (
unsigned int j = 0; j < N; j += 1){
1239 ssum += _interaction[j][i] * _error[j];
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
Definition of the vpMatrix class.
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
virtual void loadModel(const std::string &_modelFile)
virtual void loadVRMLModel(const std::string &_modelFile)
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
void setIdentity()
Basic initialisation (identity)
Display for windows using GDI (available on any windows 32 platform).
vpPoint getGravityCenter(const std::vector< vpPoint > &_pts)
vpHomogeneousMatrix cMo
The current pose.
virtual void initFromPose(const vpImage< unsigned char > &_I, const std::string &_initFile)
void computeJTR(const vpMatrix &_J, const vpColVector &_R, vpMatrix &_JTR)
Define the X11 console to display images.
bool modelInitialised
Flag used to ensure that the CAD model is loaded before the initialisation.
double get_oY() const
Get the point Y coordinate in the object frame.
void set_x(const double x)
Set the point x coordinate in the image plane.
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
Point coordinates conversion from pixel coordinates to normalized coordinates in meter...
std::string modelFileName
The name of the file containing the model (it is used to create a file name.0.pos used to store the c...
double sumSquare() const
return sum of the Aij^2 (for all i, for all j)
bool computeCovariance
Flag used to specify if the covariance matrix has to be computed or not.
static const vpColor green
static void flush(const vpImage< unsigned char > &I)
virtual void display(const vpImage< unsigned char > &_I, const vpHomogeneousMatrix &_cMo, const vpCameraParameters &_cam, const vpColor &_col, const unsigned int _l=1, const bool displayFullModel=false)=0
bool cameraInitialised
Flag used to ensure that the camera is set before the initialisation.
Class that defines what is a point.
vpPoseVector buildFrom(const vpHomogeneousMatrix &M)
vpCameraParameters cam
The camera parameters.
static Type maximum(const Type &a, const Type &b)
virtual void initClick(const vpImage< unsigned char > &_I, const std::string &_initFile, const bool _displayHelp=false)
virtual void initFromPoints(const vpImage< unsigned char > &_I, const std::string &_initFile)
void savePose(const std::string &filename)
static void display(const vpImage< unsigned char > &I)
The vpDisplayOpenCV allows to display image using the opencv library.
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
Class used for pose computation from N points (pose from point only).
double computeResidual(vpHomogeneousMatrix &cMo)
Compute and return the residual expressed in meter for the pose matrix 'cMo'.
double get_oZ() const
Get the point Z coordinate in the object frame.
virtual void extractFaces(SoVRMLIndexedFaceSet *_face_set)
void set_y(const double y)
Set the point y coordinate in the image plane.
static void displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color, unsigned int thickness=1)
void buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
Construction from translation vector and rotation matrix.
virtual void extractLines(SoVRMLIndexedLineSet *_line_set)
std::string poseSavingFilename
Filename used to save the initial pose computed using the initClick() method. It is also used to read...
virtual void initCylinder(const vpPoint &_p1, const vpPoint _p2, const double _radius, const unsigned int _indexCylinder=0)=0
double get_oX() const
Get the point X coordinate in the object frame.
bool coinUsed
Flag used to specify that the Coin library has been loaded in order to load a vrml model (used to fre...
Class that provides a data structure for the column vectors as well as a set of operations on these v...
virtual void init(const vpImage< unsigned char > &_I)=0
virtual void displayCharString(const vpImagePoint &ip, const char *text, const vpColor &color=vpColor::green)=0
The pose is a complete representation of every rigid motion in the euclidian space.
unsigned int getCols() const
Return the number of columns of the matrix.
static void readPPM(vpImage< unsigned char > &I, const char *filename)
error that can be emited by the vpMatrix class and its derivates
virtual void loadCAOModel(const std::string &_modelFile)
virtual void initFaceFromCorners(const std::vector< vpPoint > &_corners, const unsigned int _indexFace=-1)=0
void computePose(vpPoseMethodType methode, vpHomogeneousMatrix &cMo)
compute the pose for a given method
virtual bool getClick(bool blocking=true)=0
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
virtual void extractCylinders(SoVRMLIndexedFaceSet *_face_set)
unsigned int getRows() const
Return the number of rows of the matrix.
void addPoint(const vpPoint &P)
Add a new point in this array.
virtual void displayPoint(const vpImagePoint &ip, const vpColor &color)=0
void setWorldCoordinates(const double ox, const double oy, const double oz)
Set the point world coordinates. We mean here the coordinates of the point in the object frame...
void clearPoint()
suppress all the point in the array of point