56 #include <visp/vpMatrix.h>
57 #include <visp/vpMath.h>
58 #include <visp/vpColVector.h>
59 #include <visp/vpPoint.h>
60 #include <visp/vpPose.h>
61 #include <visp/vpDisplay.h>
62 #include <visp/vpDisplayOpenCV.h>
63 #include <visp/vpDisplayX.h>
64 #include <visp/vpDisplayGDI.h>
65 #include <visp/vpPixelMeterConversion.h>
66 #include <visp/vpCameraParameters.h>
67 #include <visp/vpColor.h>
68 #include <visp/vpIoTools.h>
69 #include <visp/vpException.h>
70 #include <visp/vpImageIo.h>
71 #include <visp/vpMbTracker.h>
72 #include <visp/vpMatrixException.h>
73 #include <visp/vpIoTools.h>
77 #include <Inventor/nodes/SoSeparator.h>
78 #include <Inventor/VRMLnodes/SoVRMLIndexedFaceSet.h>
79 #include <Inventor/VRMLnodes/SoVRMLIndexedLineSet.h>
80 #include <Inventor/VRMLnodes/SoVRMLCoordinate.h>
81 #include <Inventor/actions/SoWriteAction.h>
82 #include <Inventor/actions/SoSearchAction.h>
83 #include <Inventor/misc/SoChildList.h>
84 #include <Inventor/actions/SoGetMatrixAction.h>
85 #include <Inventor/actions/SoGetPrimitiveCountAction.h>
86 #include <Inventor/actions/SoToVRML2Action.h>
87 #include <Inventor/VRMLnodes/SoVRMLGroup.h>
88 #include <Inventor/VRMLnodes/SoVRMLTransform.h>
89 #include <Inventor/VRMLnodes/SoVRMLShape.h>
130 : cam(), cMo(), oJo(6,6), isoJoIdentity(true), modelFileName(), modelInitialised(false),
131 poseSavingFilename(), computeCovariance(false), covarianceMatrix(), displayFeatures(false),
132 m_w(), m_error(), faces(), angleAppears(
vpMath::rad(89) ), angleDisappears(
vpMath::rad(89) ),
133 distNearClip(0.001), distFarClip(100), clippingFlag(
vpMbtPolygon::NO_CLIPPING), useOgre(false),
134 nbPoints(0), nbLines(0), nbPolygonLines(0), nbPolygonPoints(0), nbCylinders(0), nbCircles(0),
135 useLodGeneral(false), applyLodSettingInConfig(false), minLineLengthThresholdGeneral(50.0),
136 minPolygonAreaThresholdGeneral(2500.0), mapOfParameterNames()
183 std::string ext =
".init";
184 std::string str_pose =
"";
185 size_t pos = (
unsigned int)initFile.rfind(ext);
188 std::fstream finitpos ;
190 char s[FILENAME_MAX];
192 if( pos == initFile.size()-ext.size() && pos != 0)
193 str_pose = initFile.substr(0,pos) +
".0.pos";
195 str_pose = initFile +
".0.pos";
197 finitpos.open(str_pose.c_str() ,std::ios::in) ;
198 sprintf(s,
"%s", str_pose.c_str());
203 if(finitpos.fail() ){
204 std::cout <<
"cannot read " << s << std::endl <<
"cMo set to identity" << std::endl;
208 for (
unsigned int i = 0; i < 6; i += 1){
209 finitpos >> init_pos[i];
215 std::cout <<
"last_cMo : "<<std::endl << last_cMo <<std::endl;
222 std::cout <<
"No modification : left click " << std::endl;
223 std::cout <<
"Modify initial pose : right click " << std::endl ;
226 "left click to validate, right click to modify initial pose",
256 if( pos == initFile.size()-ext.size() && pos != 0)
257 sprintf(s,
"%s", initFile.c_str());
259 sprintf(s,
"%s.init", initFile.c_str());
261 std::cout <<
"Load 3D points from: " << s << std::endl ;
262 finit.open(s,std::ios::in) ;
264 std::cout <<
"cannot read " << s << std::endl;
272 if( pos == initFile.size()-ext.size() && pos != 0)
273 dispF = initFile.substr(0,pos) +
".ppm";
275 dispF = initFile +
".ppm";
278 std::cout <<
"Load image to help initialization: " << dispF << std::endl;
279 #if defined VISP_HAVE_X11
281 #elif defined VISP_HAVE_GDI
283 #elif defined VISP_HAVE_OPENCV
289 #if defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV)
291 "Where to initialize...") ;
308 while (!finit.fail() && (c ==
'#')) {
309 finit.ignore(256,
'\n');
316 finit.ignore(256,
'\n');
317 std::cout <<
"Number of 3D points " << n << std::endl ;
320 "Exceed the max number of points.");
324 for (
unsigned int i=0 ; i < n ; i++){
327 while (!finit.fail() && (c ==
'#')) {
328 finit.ignore(256,
'\n');
336 finit.ignore(256,
'\n');
338 std::cout <<
"Point " << i+1 <<
" with 3D coordinates: " << X <<
" " << Y <<
" " << Z << std::endl;
345 bool isWellInit =
false;
349 std::vector<vpImagePoint> mem_ip;
350 for(
unsigned int i=0 ; i< n ; i++)
352 std::ostringstream text;
353 text <<
"Click on point " << i+1;
356 for (
unsigned int k=0; k<mem_ip.size(); k++) {
361 std::cout <<
"Click on point " << i+1 <<
" ";
364 mem_ip.push_back(ip);
370 std::cout <<
"with 2D coordinates: " << ip << std::endl;
393 "left click to validate, right click to re initialize object",
430 std::cout <<
"cMo : "<<std::endl <<
cMo <<std::endl;
444 const std::string &displayFile)
452 for (
unsigned int i=0 ; i < points3D_list.size() ; i++)
453 P[i].setWorldCoordinates(points3D_list[i].get_oX(),points3D_list[i].get_oY(),points3D_list[i].get_oZ()) ;
459 std::cout <<
"Load image to help initialization: " << displayFile << std::endl;
460 #if defined VISP_HAVE_X11
462 #elif defined VISP_HAVE_GDI
464 #elif defined VISP_HAVE_OPENCV
469 #if defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV)
471 "Where to initialize...") ;
485 bool isWellInit =
false;
488 for(
unsigned int i=0 ; i< points3D_list.size() ; i++)
490 std::cout <<
"Click on point " << i+1 << std::endl ;
499 std::cout <<
"Click on point " << ip << std::endl;
522 "left click to validate, right click to re initialize object",
573 char s[FILENAME_MAX];
576 std::string ext =
".init";
577 size_t pos = initFile.rfind(ext);
579 if( pos == initFile.size()-ext.size() && pos != 0)
580 sprintf(s,
"%s", initFile.c_str());
582 sprintf(s,
"%s.init", initFile.c_str());
584 std::cout <<
"filename " << s << std::endl ;
585 finit.open(s,std::ios::in) ;
587 std::cout <<
"cannot read " << s << std::endl;
594 std::cout <<
"number of points " << size << std::endl ;
598 "Exceed the max number of points.");
604 for(
unsigned int i=0 ; i< size ; i++)
617 vpERROR_TRACE(
"vpMbTracker::initFromPoints(), Number of 2D points different to the number of 3D points." );
619 for(
unsigned int i=0 ; i< size ; i++)
657 const std::vector<vpPoint> &points3D_list )
659 if(points2D_list.size() != points3D_list.size())
660 vpERROR_TRACE(
"vpMbTracker::initFromPoints(), Number of 2D points different to the number of 3D points." );
662 size_t size = points3D_list.size();
666 for(
size_t i=0 ; i< size ; i++)
668 P[i].
setWorldCoordinates(points3D_list[i].get_oX(),points3D_list[i].get_oY(),points3D_list[i].get_oZ()) ;
713 char s[FILENAME_MAX];
717 std::string ext =
".pos";
718 size_t pos = initFile.rfind(ext);
720 if( pos == initFile.size()-ext.size() && pos != 0)
721 sprintf(s,
"%s", initFile.c_str());
723 sprintf(s,
"%s.pos", initFile.c_str());
725 std::cout <<
"filename " << s << std::endl ;
726 finit.open(s,std::ios::in) ;
728 std::cout <<
"cannot read " << s << std::endl;
732 for (
unsigned int i = 0; i < 6; i += 1){
733 finit >> init_pos[i];
772 std::fstream finitpos ;
773 char s[FILENAME_MAX];
775 sprintf(s,
"%s", filename.c_str());
776 finitpos.open(s, std::ios::out) ;
779 finitpos << init_pos;
785 const bool useLod,
const double minPolygonAreaThreshold,
const double minLineLengthThreshold)
787 std::vector<vpPoint> corners_without_duplicates;
788 corners_without_duplicates.push_back(corners[0]);
789 for (
unsigned int i=0; i < corners.size()-1; i++) {
790 if (std::fabs(corners[i].get_oX() - corners[i+1].get_oX()) > std::fabs(corners[i].get_oX())*std::numeric_limits<double>::epsilon()
791 || std::fabs(corners[i].get_oY() - corners[i+1].get_oY()) > std::fabs(corners[i].get_oY())*std::numeric_limits<double>::epsilon()
792 || std::fabs(corners[i].get_oZ() - corners[i+1].get_oZ()) > std::fabs(corners[i].get_oZ())*std::numeric_limits<double>::epsilon()) {
793 corners_without_duplicates.push_back(corners[i+1]);
798 polygon.
setNbPoint((
unsigned int)corners_without_duplicates.size());
816 for(
unsigned int j = 0; j < corners_without_duplicates.size(); j++) {
817 polygon.
addPoint(j, corners_without_duplicates[j]);
833 const int idFace,
const std::string &polygonName,
const bool useLod,
const double minPolygonAreaThreshold)
867 y[0] = plane.
getA() / norm_Y;
868 y[1] = plane.
getB() / norm_Y;
869 y[2] = plane.
getC() / norm_Y;
872 for (
unsigned int i=0; i< 3; i++) {
888 for(
unsigned int i=0; i<4; i++) {
891 w_p = wMc * cMc_90 * c_p;
914 const bool useLod,
const double minLineLengthThreshold)
976 loadModel( std::string(modelFile), verbose );
1007 std::string::const_iterator it;
1010 it = modelFile.end();
1011 if((*(it-1) ==
'o' && *(it-2) ==
'a' && *(it-3) ==
'c' && *(it-4) ==
'.') ||
1012 (*(it-1) ==
'O' && *(it-2) ==
'A' && *(it-3) ==
'C' && *(it-4) ==
'.') ){
1013 std::vector<std::string> vectorOfModelFilename;
1014 int startIdFace = 0;
1021 loadCAOModel(modelFile, vectorOfModelFilename, startIdFace, verbose,
true);
1023 else if((*(it-1) ==
'l' && *(it-2) ==
'r' && *(it-3) ==
'w' && *(it-4) ==
'.') ||
1024 (*(it-1) ==
'L' && *(it-2) ==
'R' && *(it-3) ==
'W' && *(it-4) ==
'.') ){
1073 #ifdef VISP_HAVE_COIN
1077 SbBool ok = in.openFile(modelFile.c_str());
1078 SoSeparator *sceneGraph;
1079 SoVRMLGroup *sceneGraphVRML2;
1086 if(!in.isFileVRML2())
1088 sceneGraph = SoDB::readAll(&in);
1089 if (sceneGraph == NULL) { }
1092 SoToVRML2Action tovrml2;
1093 tovrml2.apply(sceneGraph);
1095 sceneGraphVRML2 =tovrml2.getVRML2SceneGraph();
1096 sceneGraphVRML2->ref();
1097 sceneGraph->unref();
1101 sceneGraphVRML2 = SoDB::readAllVRML(&in);
1102 if (sceneGraphVRML2 == NULL) { }
1103 sceneGraphVRML2->ref();
1112 sceneGraphVRML2->unref();
1114 vpERROR_TRACE(
"coin not detected with ViSP, cannot load model : %s", modelFile.c_str());
1123 while (!fileId.fail() && (c ==
'#')) {
1124 fileId.ignore(256,
'\n');
1131 std::map<std::string, std::string> mapOfParams;
1134 while (!endLine.empty() && !exit) {
1137 for (std::map<std::string, std::string>::const_iterator it =
1140 endLine =
trim(endLine);
1142 std::string param(it->first +
"=");
1145 if (endLine.compare(0, param.size(), param) == 0) {
1147 endLine = endLine.substr(param.size());
1149 bool parseQuote =
false;
1150 if (it->second ==
"string") {
1152 if (endLine.size() > 2 && endLine[0] ==
'"') {
1154 endLine = endLine.substr(1);
1155 size_t pos = endLine.find_first_of(
'"');
1157 if (pos != std::string::npos) {
1158 mapOfParams[it->first] = endLine.substr(0, pos);
1159 endLine = endLine.substr(pos + 1);
1169 size_t pos1 = endLine.find_first_of(
' ');
1170 size_t pos2 = endLine.find_first_of(
'\t');
1171 size_t pos = pos1 < pos2 ? pos1 : pos2;
1173 mapOfParams[it->first] = endLine.substr(0, pos);
1174 endLine = endLine.substr(pos + 1);
1234 std::vector<std::string>& vectorOfModelFilename,
int& startIdFace,
1235 const bool verbose,
const bool parent) {
1236 std::ifstream fileId;
1237 fileId.exceptions(std::ifstream::failbit | std::ifstream::eofbit);
1238 fileId.open(modelFile.c_str(), std::ifstream::in);
1239 if (fileId.fail()) {
1240 std::cout <<
"cannot read CAO model file: " << modelFile << std::endl;
1245 std::cout <<
"Model file : " << modelFile << std::endl;
1247 vectorOfModelFilename.push_back(modelFile);
1260 fileId >> caoVersion;
1261 fileId.ignore(256,
'\n');
1264 <<
"in vpMbTracker::loadCAOModel() -> Bad parameter header file : use V0, V1, ...";
1266 "in vpMbTracker::loadCAOModel() -> Bad parameter header file : use V0, V1, ...");
1274 std::string prefix =
"load";
1278 bool header =
false;
1279 while(c ==
'l' || c ==
'L') {
1282 getline(fileId, line);
1283 if(!line.compare(0, prefix.size(), prefix)) {
1286 std::string headerPathname = line.substr(6);
1287 size_t firstIndex = headerPathname.find_first_of(
"\")");
1288 headerPathname = headerPathname.substr(0, firstIndex);
1290 std::string headerPath = headerPathname;
1296 bool cyclic =
false;
1302 for (std::vector<std::string>::const_iterator it =
1303 vectorOfModelFilename.begin();
1304 it != vectorOfModelFilename.end() - 1 && !cyclic;
1307 if (!headerModelFilename.compare(loadedModelFilename)) {
1314 loadCAOModel(headerPath, vectorOfModelFilename, startIdFace, verbose,
false);
1317 "file cannot be open");
1320 std::cout <<
"WARNING Cyclic dependency detected with file "
1321 << headerPath <<
" declared in " << modelFile << std::endl;
1334 unsigned int caoNbrPoint;
1335 fileId >> caoNbrPoint;
1336 fileId.ignore(256,
'\n');
1339 if(verbose || vectorOfModelFilename.size() == 1) {
1340 std::cout <<
"> " << caoNbrPoint <<
" points" << std::endl;
1343 if (caoNbrPoint > 100000) {
1345 "Exceed the max number of points in the CAO model.");
1348 if (caoNbrPoint == 0 && !header) {
1350 "in vpMbTracker::loadCAOModel() -> no points are defined");
1361 for (
unsigned int k = 0; k < caoNbrPoint; k++) {
1367 fileId.ignore(256,
'\n');
1369 if (caoVersion == 2) {
1383 std::map<std::pair<unsigned int, unsigned int>,
SegmentInfo > segmentTemporaryMap;
1384 unsigned int caoNbrLine;
1385 fileId >> caoNbrLine;
1386 fileId.ignore(256,
'\n');
1389 unsigned int *caoLinePoints = NULL;
1390 if(verbose || vectorOfModelFilename.size() == 1) {
1391 std::cout <<
"> " << caoNbrLine <<
" lines" << std::endl;
1394 if (caoNbrLine > 100000) {
1397 "Exceed the max number of lines in the CAO model.");
1401 caoLinePoints =
new unsigned int[2 * caoNbrLine];
1403 unsigned int index1, index2;
1405 int idFace = startIdFace;
1407 for (
unsigned int k = 0; k < caoNbrLine; k++) {
1416 fileId.getline(buffer, 256);
1417 std::string endLine(buffer);
1418 std::map<std::string, std::string> mapOfParams =
parseParameters(endLine);
1422 std::string segmentName =
"";
1425 if(mapOfParams.find(
"name") != mapOfParams.end()) {
1426 segmentName = mapOfParams[
"name"];
1428 if(mapOfParams.find(
"minLineLengthThreshold") != mapOfParams.end()) {
1429 minLineLengthThresh = std::atof(mapOfParams[
"minLineLengthThreshold"].c_str());
1431 if(mapOfParams.find(
"useLod") != mapOfParams.end()) {
1436 segmentInfo.
name = segmentName;
1437 segmentInfo.
useLod = useLod;
1440 caoLinePoints[2 * k] = index1;
1441 caoLinePoints[2 * k + 1] = index2;
1443 if (index1 < caoNbrPoint && index2 < caoNbrPoint) {
1444 std::vector<vpPoint> extremities;
1445 extremities.push_back(caoPoints[index1]);
1446 extremities.push_back(caoPoints[index2]);
1449 std::pair<unsigned int, unsigned int> key(index1, index2);
1451 segmentTemporaryMap[key] = segmentInfo;
1455 vpTRACE(
" line %d has wrong coordinates.", k);
1465 std::vector<std::pair<unsigned int, unsigned int> > faceSegmentKeyVector;
1466 unsigned int caoNbrPolygonLine;
1467 fileId >> caoNbrPolygonLine;
1468 fileId.ignore(256,
'\n');
1471 if(verbose || vectorOfModelFilename.size() == 1) {
1472 std::cout <<
"> " << caoNbrPolygonLine <<
" polygon lines" << std::endl;
1475 if (caoNbrPolygonLine > 100000) {
1477 delete[] caoLinePoints;
1479 "Exceed the max number of polygon lines.");
1483 for (
unsigned int k = 0; k < caoNbrPolygonLine; k++) {
1486 unsigned int nbLinePol;
1487 fileId >> nbLinePol;
1488 std::vector<vpPoint> corners;
1489 if (nbLinePol > 100000) {
1493 for (
unsigned int n = 0; n < nbLinePol; n++) {
1496 if(index >= caoNbrLine) {
1499 corners.push_back(caoPoints[caoLinePoints[2 * index]]);
1500 corners.push_back(caoPoints[caoLinePoints[2 * index + 1]]);
1502 std::pair<unsigned int, unsigned int> key(caoLinePoints[2 * index], caoLinePoints[2 * index + 1]);
1503 faceSegmentKeyVector.push_back(key);
1510 fileId.getline(buffer, 256);
1511 std::string endLine(buffer);
1512 std::map<std::string, std::string> mapOfParams =
parseParameters(endLine);
1516 std::string polygonName =
"";
1519 if(mapOfParams.find(
"name") != mapOfParams.end()) {
1520 polygonName = mapOfParams[
"name"];
1522 if(mapOfParams.find(
"minPolygonAreaThreshold") != mapOfParams.end()) {
1523 minPolygonAreaThreshold = std::atof(mapOfParams[
"minPolygonAreaThreshold"].c_str());
1525 if(mapOfParams.find(
"useLod") != mapOfParams.end()) {
1535 for(std::map<std::pair<unsigned int, unsigned int>,
SegmentInfo >::const_iterator it =
1536 segmentTemporaryMap.begin(); it != segmentTemporaryMap.end(); ++it) {
1537 if(std::find(faceSegmentKeyVector.begin(), faceSegmentKeyVector.end(), it->first) == faceSegmentKeyVector.end()) {
1539 it->second.minLineLengthThresh);
1549 unsigned int caoNbrPolygonPoint;
1550 fileId >> caoNbrPolygonPoint;
1551 fileId.ignore(256,
'\n');
1554 if(verbose || vectorOfModelFilename.size() == 1) {
1555 std::cout <<
"> " << caoNbrPolygonPoint <<
" polygon points"
1559 if (caoNbrPolygonPoint > 100000) {
1561 "Exceed the max number of polygon point.");
1564 for (
unsigned int k = 0; k < caoNbrPolygonPoint; k++) {
1567 unsigned int nbPointPol;
1568 fileId >> nbPointPol;
1569 if (nbPointPol > 100000) {
1571 "Exceed the max number of points.");
1573 std::vector<vpPoint> corners;
1574 for (
unsigned int n = 0; n < nbPointPol; n++) {
1576 if (index > caoNbrPoint - 1) {
1578 "Exceed the max number of points.");
1580 corners.push_back(caoPoints[index]);
1587 fileId.getline(buffer, 256);
1588 std::string endLine(buffer);
1589 std::map<std::string, std::string> mapOfParams =
parseParameters(endLine);
1593 std::string polygonName =
"";
1596 if(mapOfParams.find(
"name") != mapOfParams.end()) {
1597 polygonName = mapOfParams[
"name"];
1599 if(mapOfParams.find(
"minPolygonAreaThreshold") != mapOfParams.end()) {
1600 minPolygonAreaThreshold = std::atof(mapOfParams[
"minPolygonAreaThreshold"].c_str());
1602 if(mapOfParams.find(
"useLod") != mapOfParams.end()) {
1612 unsigned int caoNbCylinder;
1618 delete[] caoLinePoints;
1623 fileId >> caoNbCylinder;
1624 fileId.ignore(256,
'\n');
1627 if(verbose || vectorOfModelFilename.size() == 1) {
1628 std::cout <<
"> " << caoNbCylinder <<
" cylinders" << std::endl;
1631 if (caoNbCylinder > 100000) {
1633 "Exceed the max number of cylinders.");
1636 for (
unsigned int k = 0; k < caoNbCylinder; ++k) {
1640 unsigned int indexP1, indexP2;
1648 fileId.getline(buffer, 256);
1649 std::string endLine(buffer);
1650 std::map<std::string, std::string> mapOfParams =
parseParameters(endLine);
1654 std::string polygonName =
"";
1657 if(mapOfParams.find(
"name") != mapOfParams.end()) {
1658 polygonName = mapOfParams[
"name"];
1660 if(mapOfParams.find(
"minLineLengthThreshold") != mapOfParams.end()) {
1661 minLineLengthThreshold = std::atof(mapOfParams[
"minLineLengthThreshold"].c_str());
1663 if(mapOfParams.find(
"useLod") != mapOfParams.end()) {
1667 addPolygon(caoPoints[indexP1], caoPoints[indexP2], idFace, polygonName, useLod, minLineLengthThreshold);
1668 initCylinder(caoPoints[indexP1], caoPoints[indexP2], radius, idFace++, polygonName);
1673 <<
"Cannot get the number of cylinders. Defaulting to zero."
1680 unsigned int caoNbCircle;
1686 delete[] caoLinePoints;
1691 fileId >> caoNbCircle;
1692 fileId.ignore(256,
'\n');
1695 if(verbose || vectorOfModelFilename.size() == 1) {
1696 std::cout <<
"> " << caoNbCircle <<
" circles" << std::endl;
1699 if (caoNbCircle > 100000) {
1701 "Exceed the max number of cicles.");
1704 for (
unsigned int k = 0; k < caoNbCircle; ++k) {
1708 unsigned int indexP1, indexP2, indexP3;
1717 fileId.getline(buffer, 256);
1718 std::string endLine(buffer);
1719 std::map<std::string, std::string> mapOfParams =
parseParameters(endLine);
1723 std::string polygonName =
"";
1726 if(mapOfParams.find(
"name") != mapOfParams.end()) {
1727 polygonName = mapOfParams[
"name"];
1729 if(mapOfParams.find(
"minPolygonAreaThreshold") != mapOfParams.end()) {
1730 minPolygonAreaThreshold = std::atof(mapOfParams[
"minPolygonAreaThreshold"].c_str());
1732 if(mapOfParams.find(
"useLod") != mapOfParams.end()) {
1736 addPolygon(caoPoints[indexP1], caoPoints[indexP2],
1737 caoPoints[indexP3], radius, idFace, polygonName, useLod, minPolygonAreaThreshold);
1739 initCircle(caoPoints[indexP1], caoPoints[indexP2],
1740 caoPoints[indexP3], radius, idFace++, polygonName);
1744 std::cerr <<
"Cannot get the number of circles. Defaulting to zero."
1749 startIdFace = idFace;
1752 delete[] caoLinePoints;
1754 if(vectorOfModelFilename.size() > 1 && parent) {
1756 std::cout <<
"Global information for " <<
vpIoTools::getName(modelFile) <<
" :" << std::endl;
1757 std::cout <<
"Total nb of points : " <<
nbPoints << std::endl;
1758 std::cout <<
"Total nb of lines : " <<
nbLines << std::endl;
1759 std::cout <<
"Total nb of polygon lines : " <<
nbPolygonLines << std::endl;
1760 std::cout <<
"Total nb of polygon points : " <<
nbPolygonPoints << std::endl;
1761 std::cout <<
"Total nb of cylinders : " <<
nbCylinders << std::endl;
1762 std::cout <<
"Total nb of circles : " <<
nbCircles << std::endl;
1764 std::cout <<
"> " <<
nbPoints <<
" points" << std::endl;
1765 std::cout <<
"> " <<
nbLines <<
" lines" << std::endl;
1766 std::cout <<
"> " <<
nbPolygonLines <<
" polygon lines" << std::endl;
1767 std::cout <<
"> " <<
nbPolygonPoints <<
" polygon points" << std::endl;
1768 std::cout <<
"> " <<
nbCylinders <<
" cylinders" << std::endl;
1769 std::cout <<
"> " <<
nbCircles <<
" circles" << std::endl;
1773 std::cerr <<
"Cannot read line!" << std::endl;
1778 #ifdef VISP_HAVE_COIN
1790 SoVRMLTransform *sceneGraphVRML2Trasnform =
dynamic_cast<SoVRMLTransform *
>(sceneGraphVRML2);
1791 if(sceneGraphVRML2Trasnform){
1792 float rx, ry, rz, rw;
1793 sceneGraphVRML2Trasnform->rotation.getValue().getValue(rx,ry,rz,rw);
1798 tx = sceneGraphVRML2Trasnform->translation.getValue()[0];
1799 ty = sceneGraphVRML2Trasnform->translation.getValue()[1];
1800 tz = sceneGraphVRML2Trasnform->translation.getValue()[2];
1805 sx = sceneGraphVRML2Trasnform->scale.getValue()[0];
1806 sy = sceneGraphVRML2Trasnform->scale.getValue()[1];
1807 sz = sceneGraphVRML2Trasnform->scale.getValue()[2];
1810 for(
unsigned int i = 0 ; i < 3 ; i++)
1812 for(
unsigned int i = 0 ; i < 3 ; i++)
1814 for(
unsigned int i = 0 ; i < 3 ; i++)
1818 transform = transform * transformCur;
1821 int nbShapes = sceneGraphVRML2->getNumChildren();
1827 for (
int i = 0; i < nbShapes; i++)
1830 child = sceneGraphVRML2->getChild(i);
1832 if (child->getTypeId() == SoVRMLGroup::getClassTypeId()){
1833 extractGroup((SoVRMLGroup*)child, transform_recursive, idFace);
1836 if (child->getTypeId() == SoVRMLTransform::getClassTypeId()){
1837 extractGroup((SoVRMLTransform*)child, transform_recursive, idFace);
1840 if (child->getTypeId() == SoVRMLShape::getClassTypeId()){
1841 SoChildList * child2list = child->getChildren();
1842 for (
int j = 0; j < child2list->getLength(); j++)
1844 if (((SoNode*)child2list->get(j))->getTypeId() == SoVRMLIndexedFaceSet::getClassTypeId())
1846 SoVRMLIndexedFaceSet * face_set;
1847 face_set = (SoVRMLIndexedFaceSet*)child2list->get(j);
1848 if(!strncmp(face_set->getName().getString(),
"cyl",3)){
1854 if (((SoNode*)child2list->get(j))->getTypeId() == SoVRMLIndexedLineSet::getClassTypeId())
1856 SoVRMLIndexedLineSet * line_set;
1857 line_set = (SoVRMLIndexedLineSet*)child2list->get(j);
1876 std::vector<vpPoint> corners;
1881 int indexListSize = face_set->coordIndex.getNum();
1885 SoVRMLCoordinate *coord;
1887 for (
int i = 0; i < indexListSize; i++)
1889 if (face_set->coordIndex[i] == -1)
1891 if(corners.size() > 1)
1900 coord = (SoVRMLCoordinate *)(face_set->coord.getValue());
1901 int index = face_set->coordIndex[i];
1902 pointTransformed[0]=coord->point[index].getValue()[0];
1903 pointTransformed[1]=coord->point[index].getValue()[1];
1904 pointTransformed[2]=coord->point[index].getValue()[2];
1905 pointTransformed[3] = 1.0;
1907 pointTransformed = transform * pointTransformed;
1910 corners.push_back(pt);
1931 std::vector<vpPoint> corners_c1, corners_c2;
1932 SoVRMLCoordinate* coords = (SoVRMLCoordinate *)face_set->coord.getValue();
1934 unsigned int indexListSize = (
unsigned int)coords->point.getNum();
1936 if(indexListSize % 2 == 1){
1937 std::cout <<
"Not an even number of points when extracting a cylinder." << std::endl;
1940 corners_c1.resize(indexListSize / 2);
1941 corners_c2.resize(indexListSize / 2);
1947 for(
int i=0; i<coords->point.getNum(); ++i){
1948 pointTransformed[0]=coords->point[i].getValue()[0];
1949 pointTransformed[1]=coords->point[i].getValue()[1];
1950 pointTransformed[2]=coords->point[i].getValue()[2];
1951 pointTransformed[3] = 1.0;
1953 pointTransformed = transform * pointTransformed;
1957 if(i < (
int)corners_c1.size()){
1958 corners_c1[(
unsigned int)i] = pt;
1960 corners_c2[(
unsigned int)i-corners_c1.size()] = pt;
1968 dist[0] = p1.
get_oX() - corners_c1[0].get_oX();
1969 dist[1] = p1.
get_oY() - corners_c1[0].get_oY();
1970 dist[2] = p1.
get_oZ() - corners_c1[0].get_oZ();
1971 double radius_c1 = sqrt(dist.
sumSquare());
1972 dist[0] = p2.
get_oX() - corners_c2[0].get_oX();
1973 dist[1] = p2.
get_oY() - corners_c2[0].get_oY();
1974 dist[2] = p2.
get_oZ() - corners_c2[0].get_oZ();
1975 double radius_c2 = sqrt(dist.sumSquare());
1977 if(std::fabs(radius_c1 - radius_c2) > (std::numeric_limits<double>::epsilon() *
vpMath::maximum(radius_c1, radius_c2))){
1978 std::cout <<
"Radius from the two circles of the cylinders are different." << std::endl;
1996 std::vector<vpPoint> corners;
1999 int indexListSize = line_set->coordIndex.getNum();
2001 SbVec3f point(0,0,0);
2003 SoVRMLCoordinate *coord;
2005 for (
int i = 0; i < indexListSize; i++)
2007 if (line_set->coordIndex[i] == -1)
2009 if(corners.size() > 1)
2018 coord = (SoVRMLCoordinate *)(line_set->coord.getValue());
2019 int index = line_set->coordIndex[i];
2020 point[0]=coord->point[index].getValue()[0];
2021 point[1]=coord->point[index].getValue()[1];
2022 point[2]=coord->point[index].getValue()[2];
2025 corners.push_back(pt);
2030 #endif // VISP_HAVE_COIN
2045 std::cout <<
"Cannot extract center of gravity of empty set." << std::endl;
2053 for(
unsigned int i=0; i<pts.size(); ++i){
2055 oY += pts[i].get_oY();
2056 oZ += pts[i].get_oZ();
2072 std::pair<std::vector<vpPolygon>, std::vector<std::vector<vpPoint> > >
2081 std::vector<vpPolygon> polygonsTmp;
2082 std::vector<std::vector<vpPoint> > roisPtTmp;
2085 std::pair<std::vector<vpPolygon>, std::vector<std::vector<vpPoint> > > pairOfPolygonFaces;
2088 std::vector<vpImagePoint> roi;
2089 std::vector<vpPoint> roiPt;
2092 if((useVisibility &&
getPolygon(i)->isvisible) || !useVisibility) {
2096 double u = 0, v = 0;
2099 roiPt.push_back(pt);
2103 roisPtTmp.push_back(roiPt);
2110 std::vector<PolygonFaceInfo> listOfPolygonFaces;
2111 for(
unsigned int i = 0; i < polygonsTmp.size(); i++) {
2112 double x_centroid = 0.0, y_centroid = 0.0, z_centroid = 0.0;
2113 for(
unsigned int j = 0; j < roisPtTmp[i].size(); j++) {
2114 x_centroid += roisPtTmp[i][j].get_X();
2115 y_centroid += roisPtTmp[i][j].get_Y();
2116 z_centroid += roisPtTmp[i][j].get_Z();
2119 x_centroid /= roisPtTmp[i].size();
2120 y_centroid /= roisPtTmp[i].size();
2121 z_centroid /= roisPtTmp[i].size();
2123 double squared_dist = x_centroid*x_centroid + y_centroid*y_centroid + z_centroid*z_centroid;
2124 listOfPolygonFaces.push_back(
PolygonFaceInfo(squared_dist, polygonsTmp[i], roisPtTmp[i]));
2128 std::sort(listOfPolygonFaces.begin(), listOfPolygonFaces.end());
2130 polygonsTmp.resize(listOfPolygonFaces.size());
2131 roisPtTmp.resize(listOfPolygonFaces.size());
2134 for(std::vector<PolygonFaceInfo>::const_iterator it = listOfPolygonFaces.begin(); it != listOfPolygonFaces.end();
2136 polygonsTmp[cpt] = it->polygon;
2137 roisPtTmp[cpt] = it->faceCorners;
2140 pairOfPolygonFaces.first = polygonsTmp;
2141 pairOfPolygonFaces.second = roisPtTmp;
2143 pairOfPolygonFaces.first = polygonsTmp;
2144 pairOfPolygonFaces.second = roisPtTmp;
2147 return pairOfPolygonFaces;
2162 #ifndef VISP_HAVE_OGRE
2164 std::cout <<
"WARNING: ViSP doesn't have Ogre3D, basic visibility test will be used. setOgreVisibilityTest() set to false." << std::endl;
2178 vpTRACE(
"Far clipping value cannot be inferior than near clipping value. Far clipping won't be considered.");
2179 else if ( dist < 0 )
2180 vpTRACE(
"Far clipping value cannot be inferior than 0. Far clipping won't be considered.");
2184 for (
unsigned int i = 0; i <
faces.
size(); i ++){
2187 #ifdef VISP_HAVE_OGRE
2205 for (
unsigned int i = 0; i <
faces.
size(); i++)
2207 if(name.empty() ||
faces[i]->name == name) {
2208 faces[i]->setLod(useLod);
2224 for (
unsigned int i = 0; i <
faces.
size(); i++)
2226 if(name.empty() ||
faces[i]->name == name) {
2227 faces[i]->setMinLineLengthThresh(minLineLengthThresh);
2243 for (
unsigned int i = 0; i <
faces.
size(); i++)
2245 if(name.empty() ||
faces[i]->name == name) {
2246 faces[i]->setMinPolygonAreaThresh(minPolygonAreaThresh);
2260 vpTRACE(
"Near clipping value cannot be superior than far clipping value. Near clipping won't be considered.");
2261 else if ( dist < 0 )
2262 vpTRACE(
"Near clipping value cannot be inferior than 0. Near clipping won't be considered.");
2266 for (
unsigned int i = 0; i <
faces.
size(); i ++){
2269 #ifdef VISP_HAVE_OGRE
2286 for (
unsigned int i = 0; i <
faces.
size(); i ++)
2310 for(
unsigned int i = 0 ; i < 3 ; i++)
2320 LthetauInvAnalytic = -I3;
2322 if(theta / (2.0 * M_PI) > std::numeric_limits<double>::epsilon())
2326 for (
unsigned int i=0 ; i < 3 ; i++) {
2327 theta2u[i] = tu[i]/2.0 ;
2332 for (
unsigned int i=0 ; i < 3 ; i++) {
2333 u[i] = tu[i]/theta ;
2343 ctoInitSkew = ctoInitSkew * LthetauInvAnalytic;
2345 for(
unsigned int a = 0 ; a < 3 ; a++)
2346 for(
unsigned int b = 0 ; b < 3 ; b++)
2347 LpInv[a][b+3] = ctoInitSkew[a][b];
2349 for(
unsigned int a = 0 ; a < 3 ; a++)
2350 for(
unsigned int b = 0 ; b < 3 ; b++)
2351 LpInv[a+3][b+3] = LthetauInvAnalytic[a][b];
2357 vpColVector deltaP = (Js).pseudoInverse(Js.
getRows()*std::numeric_limits<double>::epsilon()) * deltaS;
2381 "Incorrect matrices size in computeJTR.");
2385 const unsigned int N = interaction.
getRows();
2387 for (
unsigned int i = 0; i < 6; i += 1){
2389 for (
unsigned int j = 0; j < N; j += 1){
2390 ssum += interaction[j][i] * error[j];
2411 for(
unsigned int i = 0 ; i < 6 ; i++)
2432 for(
unsigned int i = 0 ; i < 6 ; i++){
2434 if(std::fabs(v[i]) > std::numeric_limits<double>::epsilon()){
Definition of the vpMatrix class.
vpMatrix covarianceMatrix
Covariance matrix.
bool parseBoolean(std::string &input)
std::string & trim(std::string &s)
virtual void init(vpImage< unsigned char > &I, int x=-1, int y=-1, const char *title=NULL)=0
Class that defines generic functionnalities for display.
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
unsigned int nbLines
Number of lines in CAO model.
unsigned int getWidth() const
std::map< std::string, std::string > parseParameters(std::string &endLine)
unsigned int nbCircles
Number of circles in CAO model.
vpMbHiddenFaces< vpMbtPolygon > faces
Set of faces describing the object.
void setNearClippingDistance(const double &dist)
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
virtual void extractGroup(SoVRMLGroup *sceneGraphVRML2, vpHomogeneousMatrix &transform, int &idFace)
std::map< std::string, std::string > mapOfParameterNames
Map with [map.first]=parameter_names and [map.second]=type (string, number or boolean) ...
unsigned int nbCylinders
Number of cylinders in CAO model.
void setIdentity()
Basic initialisation (identity)
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
Point coordinates conversion from normalized coordinates in meter to pixel coordinates ...
double minLineLengthThresh
unsigned int nbPoints
Number of points in CAO model.
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 initCircle(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, const double radius, const int idFace=0, const std::string &name="")=0
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
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.
vpHomogeneousMatrix getPose() const
void setMinPolygonAreaThresh(const double min_polygon_area)
error that can be emited by ViSP classes.
void computeJTR(const vpMatrix &J, const vpColVector &R, vpMatrix &JTR)
void set_x(const double x)
Set the point x coordinate in the image plane.
virtual void loadCAOModel(const std::string &modelFile, std::vector< std::string > &vectorOfModelFilename, int &startIdFace, const bool verbose=false, const bool parent=true)
std::vector< vpPoint > faceCorners
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...
void setName(const std::string &face_name)
Provides simple mathematics computation tools that are not available in the C mathematics library (ma...
unsigned int nbpt
Number of points used to define the polygon.
bool useOgre
Use Ogre3d for visibility tests.
double get_y() const
Get the point y coordinate in the image plane.
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...
virtual void setEstimatedDoF(const vpColVector &v)
virtual void initFromPose(const vpImage< unsigned char > &I, const std::string &initFile)
static const vpColor green
virtual void extractLines(SoVRMLIndexedLineSet *line_set, int &idFace)
static void flush(const vpImage< unsigned char > &I)
static vpMatrix computeCovarianceMatrix(const vpMatrix &A, const vpColVector &x, const vpColVector &b)
void setFarClippingDistance(const double &dist)
static double sinc(double x)
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)
The vpRotationMatrix considers the particular case of a rotation matrix.
virtual void init(const vpImage< unsigned char > &I)=0
double distFarClip
Distance for near clipping.
std::vector< vpPoint > extremities
void addPoint(const unsigned int n, const vpPoint &P)
vpAROgre * getOgreContext()
Defines a generic 2D polygon.
virtual void setMinPolygonAreaThresh(const double minPolygonAreaThresh, const std::string &name="")
virtual void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, const unsigned int thickness=1, const bool displayFullModel=false)=0
vpMatrix oJo
The Degrees of Freedom to estimate.
void setIdentity(const double &val=1.0)
virtual void extractCylinders(SoVRMLIndexedFaceSet *face_set, vpHomogeneousMatrix &transform, int &idFace)
Implementation of a polygon of the model used by the model-based tracker.
bool operator<(const PolygonFaceInfo &pfi) const
static double sqr(double x)
void savePose(const std::string &filename)
double minLineLengthThresholdGeneral
Minimum line length threshold for LOD mode (general setting)
bool computePose(vpPoseMethodType methode, vpHomogeneousMatrix &cMo, bool(*func)(vpHomogeneousMatrix *)=NULL)
compute the pose for a given method
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
virtual void getCameraParameters(vpCameraParameters &camera) const
Class used for pose computation from N points (pose from point only).
virtual void initFaceFromCorners(vpMbtPolygon &polygon)=0
Generic class defining intrinsic camera parameters.
double get_oZ() const
Get the point Z coordinate in the object frame.
void set_y(const double y)
Set the point y coordinate in the image plane.
void extract(vpRotationMatrix &R) const
virtual void loadVRMLModel(const std::string &modelFile)
Defines a quaternion and its basic operations.
double get_x() const
Get the point x coordinate in the image plane.
static void displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color=vpColor::none, unsigned int thickness=1)
unsigned int nbPolygonLines
Number of polygon lines in CAO model.
void addPolygon(PolygonType *p)
virtual void initClick(const vpImage< unsigned char > &I, const std::string &initFile, const bool displayHelp=false)
void buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
Construction from translation vector and rotation matrix.
virtual void extractFaces(SoVRMLIndexedFaceSet *face_set, vpHomogeneousMatrix &transform, int &idFace)
static double rad(double deg)
virtual void setMinLineLengthThresh(const double minLineLengthThresh, const std::string &name="")
virtual vpColVector getEstimatedDoF()
std::string poseSavingFilename
Filename used to save the initial pose computed using the initClick() method. It is also used to read...
unsigned int size() const
void computeCovarianceMatrix(const vpHomogeneousMatrix &cMoPrev, const vpColVector &deltaS, const vpMatrix &Ls, const vpMatrix &W)
double get_oX() const
Get the point X coordinate in the object frame.
unsigned int nbPolygonPoints
Number of polygon points in CAO model.
double minPolygonAreaThresholdGeneral
Minimum polygon area threshold for LOD mode (general setting)
virtual void setOgreVisibilityTest(const bool &v)
virtual void loadModel(const char *modelFile, const bool verbose=false)
int getWindowYPosition() const
bool applyLodSettingInConfig
True if the CAO model is loaded before the call to loadConfigFile, (deduced by the number of polygons...
Class that provides a data structure for the column vectors as well as a set of operations on these v...
void setLod(const bool use_lod)
virtual void initFaceFromLines(vpMbtPolygon &polygon)=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.
virtual vpMbtPolygon * getPolygon(const unsigned int index)
error that can be emited by the vpMatrix class and its derivates
virtual unsigned int getNbPolygon() const
static vpMatrix skew(const vpColVector &v)
virtual void setClipping(const unsigned int &flags)
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 ...
void addPolygon(const std::vector< vpPoint > &corners, const int idFace=-1, const std::string &polygonName="", const bool useLod=false, const double minPolygonAreaThreshold=2500.0, const double minLineLengthThreshold=50.0)
static vpColVector crossProd(const vpColVector &a, const vpColVector &b)
Compute the cross product of two vectors C = a x b.
This class defines the container for a plane geometrical structure.
unsigned int clippingFlag
Flags specifying which clipping to used.
PolygonFaceInfo(const double dist, const vpPolygon &poly, const std::vector< vpPoint > &corners)
virtual void initFromPoints(const vpImage< unsigned char > &I, const std::string &initFile)
static void read(vpImage< unsigned char > &I, const char *filename)
unsigned int getRows() const
Return the number of rows of the matrix.
virtual void setFarClippingDistance(const double &dist)
virtual void setNbPoint(const unsigned int nb)
virtual std::pair< std::vector< vpPolygon >, std::vector< std::vector< vpPoint > > > getPolygonFaces(const bool orderPolygons=true, const bool useVisibility=true)
void addPoint(const vpPoint &P)
Add a new point in this array.
double distNearClip
Distance for near clipping.
bool useLodGeneral
True if LOD mode is enabled.
Class that consider the case of a translation vector.
Class that consider the case of the parameterization for the rotation.
virtual void displayPoint(const vpImagePoint &ip, const vpColor &color)=0
bool isoJoIdentity
Boolean to know if oJo is identity (for fast computation)
void removeComment(std::ifstream &fileId)
double computeResidual(const vpHomogeneousMatrix &cMo) const
Compute and return the residual expressed in meter for the pose matrix 'cMo'.
virtual void initCylinder(const vpPoint &p1, const vpPoint &p2, const double radius, const int idFace=0, const std::string &name="")=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 setMinLineLengthThresh(const double min_line_length)
int getWindowXPosition() const
std::vector< PolygonType * > & getPolygon()
virtual void setIndex(const int i)
void clearPoint()
suppress all the point in the array of point
virtual void setLod(const bool useLod, const std::string &name="")
virtual void setNearClippingDistance(const double &dist)