/src/uti_phgrm/Apero/cPose.cpp

https://github.com/micmacIGN/micmac · C++ · 3281 lines · 2180 code · 562 blank · 539 comment · 261 complexity · 021834cdcb99da422d8a9b2f5fe0ab62 MD5 · raw file

  1. /*Header-MicMac-eLiSe-25/06/2007
  2. MicMac : Multi Image Correspondances par Methodes Automatiques de Correlation
  3. eLiSe : ELements of an Image Software Environnement
  4. www.micmac.ign.fr
  5. Copyright : Institut Geographique National
  6. Author : Marc Pierrot Deseilligny
  7. Contributors : Gregoire Maillet, Didier Boldo.
  8. [1] M. Pierrot-Deseilligny, N. Paparoditis.
  9. "A multiresolution and optimization-based image matching approach:
  10. An application to surface reconstruction from SPOT5-HRS stereo imagery."
  11. In IAPRS vol XXXVI-1/W41 in ISPRS Workshop On Topographic Mapping From Space
  12. (With Special Emphasis on Small Satellites), Ankara, Turquie, 02-2006.
  13. [2] M. Pierrot-Deseilligny, "MicMac, un lociel de mise en correspondance
  14. d'images, adapte au contexte geograhique" to appears in
  15. Bulletin d'information de l'Institut Geographique National, 2007.
  16. Francais :
  17. MicMac est un logiciel de mise en correspondance d'image adapte
  18. au contexte de recherche en information geographique. Il s'appuie sur
  19. la bibliotheque de manipulation d'image eLiSe. Il est distibue sous la
  20. licences Cecill-B. Voir en bas de fichier et http://www.cecill.info.
  21. English :
  22. MicMac is an open source software specialized in image matching
  23. for research in geographic information. MicMac is built on the
  24. eLiSe image library. MicMac is governed by the "Cecill-B licence".
  25. See below and http://www.cecill.info.
  26. Header-MicMac-eLiSe-25/06/2007*/
  27. // #define _ELISE_ALGO_GEOM_QDT_H 1
  28. // #define _ELISE_ALGO_GEOM_QDT_IMPLEM_H 1
  29. // #define __QDT_INSERTOBJ__ 1
  30. #include "cPose.h"
  31. /* ========== cStructRigidInit ============*/
  32. cStructRigidInit::cStructRigidInit(cPoseCam * RigidMere,const ElRotation3D & aR) :
  33. mCMere (RigidMere),
  34. mR0m1L0 (aR)
  35. {
  36. }
  37. static const int NbMinCreateIm = 200;
  38. //class cPtAVGR;
  39. //class cAperoVisuGlobRes;
  40. /***************** classes moved to cPose.h *******************/
  41. /*=========== cPtAVGR ===========*/
  42. cPtAVGR::cPtAVGR(const Pt3dr & aP,double aRes) :
  43. mPt (Pt3df::P3ToThisT(aP)),
  44. mRes (aRes)
  45. {
  46. }
  47. /*class cFoncPtOfPtAVGR
  48. {
  49. public :
  50. Pt2dr operator () (cPtAVGR * aP) {return Pt2dr(aP->mPt.x,aP->mPt.y);}
  51. };*/
  52. /*=========== cAperoVisuGlobRes ===========*/
  53. /*typedef enum
  54. {
  55. eBAVGR_X,
  56. eBAVGR_Y,
  57. eBAVGR_Z,
  58. eBAVGR_Res
  59. } eBoxAVGR;
  60. class cAperoVisuGlobRes
  61. {
  62. public :
  63. void AddResidu(const Pt3dr & aP,double aRes);
  64. void DoResidu(const std::string & aDir,int aNbMes);
  65. cAperoVisuGlobRes();
  66. private :
  67. Interval CalculBox(double & aVMil,double & aResol,eBoxAVGR aMode,double PropElim,double Rab);
  68. Box2dr CalculBox_XY(double PropElim,double Rab);
  69. double ToEcartStd(double anE) const;
  70. double FromEcartStd(double anE) const;
  71. Pt3di ColOfEcart(double anE);
  72. typedef ElQT<cPtAVGR *,Pt2dr,cFoncPtOfPtAVGR> tQtTiepT;
  73. int mNbPts;
  74. std::list<cPtAVGR *> mLpt;
  75. tQtTiepT * mQt;
  76. double mResol;
  77. double mResolX;
  78. double mResolY;
  79. double mSigRes;
  80. double mMoyRes;
  81. cPlyCloud mPC;
  82. cPlyCloud mPCLeg; // Legende
  83. double mVMilZ;
  84. };*/
  85. cAperoVisuGlobRes::cAperoVisuGlobRes() :
  86. mNbPts (0),
  87. mQt (0)
  88. {
  89. }
  90. void cAperoVisuGlobRes::AddResidu(const Pt3dr & aP,double aRes)
  91. {
  92. cPtAVGR * aPVG = new cPtAVGR(aP,aRes);
  93. mLpt.push_back(aPVG);
  94. mNbPts++;
  95. }
  96. Interval cAperoVisuGlobRes::CalculBox(double & aVMil,double & aResol,eBoxAVGR aMode,double aPropElim,double aPropRab)
  97. {
  98. std::vector<float> aVVals;
  99. // double aSomV = 0;
  100. // double aSomV2 = 0;
  101. for (auto iT=mLpt.begin() ; iT!=mLpt.end() ; iT++)
  102. {
  103. double aVal = 0.0;
  104. if (aMode==eBAVGR_Res) aVal = (*iT)->mRes ;
  105. else if (aMode==eBAVGR_X) aVal = (*iT)->mPt.x;
  106. else if (aMode==eBAVGR_Y) aVal = (*iT)->mPt.y;
  107. else if (aMode==eBAVGR_Z) aVal = (*iT)->mPt.z;
  108. else
  109. {
  110. aVal = (*iT)->mPt.z;
  111. ELISE_ASSERT(false,"cAperoVisuGlobRes::CalculBox");
  112. }
  113. aVVals.push_back(aVal);
  114. // aSomV += aVal;
  115. // aSomV2 += ElSquare(aVal);
  116. }
  117. // aSomV /= mNbPts;
  118. // aSomV2 /= mNbPts;
  119. // aSomV2 -= ElSquare(aSomV);
  120. // Sigma = Larg / srqt(12) pour une distrib uniforme
  121. // double Larg = sqrt(12*aSomV2);
  122. double aV25 = KthValProp(aVVals,0.25);
  123. double aV75 = KthValProp(aVVals,0.75);
  124. aVMil = (aV75+aV25) / 2.0;
  125. double Larg = 2 * (aV75 - aV25);
  126. aResol = Larg / mNbPts;
  127. double aVMin = KthValProp(aVVals,aPropElim);
  128. double aVMax = KthValProp(aVVals,1-aPropElim);
  129. double aRab = (aVMax-aVMin) * aPropRab;
  130. aVMin -= aRab ;
  131. aVMax += aRab ;
  132. return Interval(aVMin,aVMax);
  133. }
  134. Box2dr cAperoVisuGlobRes::CalculBox_XY(double aPropElim,double aPropRab)
  135. {
  136. double aVMilX,aVMilY;
  137. Interval aIntX = CalculBox(aVMilX,mResolX,eBAVGR_X,aPropElim,aPropRab);
  138. Interval aIntY = CalculBox(aVMilY,mResolY,eBAVGR_Y,aPropElim,aPropRab);
  139. mResol = euclid(Pt2dr(mResolX,mResolY));
  140. return Box2dr(Pt2dr(aIntX._v0,aIntY._v0), Pt2dr(aIntX._v1,aIntY._v1));
  141. }
  142. double DirErFonc(double x);
  143. double InvErrFonc(double x);
  144. double cAperoVisuGlobRes::ToEcartStd(double anE) const
  145. {
  146. return DirErFonc((anE-mMoyRes)/mSigRes);
  147. }
  148. double cAperoVisuGlobRes::FromEcartStd(double anE) const
  149. {
  150. return mMoyRes + mSigRes *InvErrFonc(anE);
  151. }
  152. Pt3di cAperoVisuGlobRes::ColOfEcart(double anE)
  153. {
  154. Elise_colour aCol = Elise_colour::its(0.5,(1-anE)/3.0,1.0);
  155. return Pt3di (AdjUC(aCol.r()*255),AdjUC(aCol.g()*255),AdjUC(aCol.b()*255));
  156. }
  157. template <class Type> bool gen_std_isnan(const Type & aP)
  158. {
  159. return std_isnan(aP.x) || std_isnan(aP.y) ;
  160. }
  161. void cAperoVisuGlobRes::DoResidu(const std::string & aDir,int aNbMes)
  162. {
  163. {
  164. double aRR;
  165. CalculBox(mVMilZ,aRR,eBAVGR_Z,0.16,0.0);
  166. }
  167. Box2dr aBoxQt = CalculBox_XY(0.02,0.3);
  168. cFoncPtOfPtAVGR aFoncP;
  169. mQt = new tQtTiepT(aFoncP,aBoxQt,10,mResol*5);
  170. for (auto iT=mLpt.begin() ; iT!=mLpt.end() ; iT++)
  171. {
  172. (*iT)->mInQt= mQt->insert(*iT,true);
  173. }
  174. for (auto iTGlob=mLpt.begin() ; iTGlob!=mLpt.end() ; iTGlob++)
  175. {
  176. if ((*iTGlob)->mInQt)
  177. {
  178. // std::set<cPtAVGR *> aSet;
  179. Pt2dr aP = aFoncP(*iTGlob);
  180. // std::list<cPtAVGR *> aLVois = mQt->KPPVois(aP,aNbMes,1.5*mResol*sqrt(aNbMes));
  181. double aDist = mResol*sqrt(aNbMes);
  182. std::set<cPtAVGR *> aLVois;
  183. mQt->RVoisins(aLVois,aP,mResol*sqrt(aNbMes));
  184. double aSomP=0.0;
  185. double aSomPRes=0.0;
  186. for (auto itV=aLVois.begin() ; itV!=aLVois.end() ; itV++)
  187. {
  188. if (euclid((*iTGlob)->mPt-(*itV)->mPt) < aDist)
  189. {
  190. double aPds = 1.0;
  191. aSomP += aPds;
  192. aSomPRes += aPds * (*itV)->mRes;
  193. }
  194. }
  195. double aRes = aSomPRes / aSomP;
  196. (*iTGlob)->mResFiltr = aRes;
  197. }
  198. }
  199. double aRR; // Inutilise
  200. // Pour une gaussienne 68 % compris dans [-Sig,Sig]
  201. double aVMilRes;
  202. Interval aIntRes = CalculBox(aVMilRes,aRR,eBAVGR_Res,0.16,0.0);
  203. mSigRes = (aIntRes._v1 - aIntRes._v0) / 2.0;
  204. mMoyRes = (aIntRes._v1 + aIntRes._v0) / 2.0;
  205. for (auto iTGlob=mLpt.begin() ; iTGlob!=mLpt.end() ; iTGlob++)
  206. {
  207. if ((*iTGlob)->mInQt)
  208. {
  209. double anEcart = ToEcartStd( (*iTGlob)->mResFiltr);
  210. Pt3di aCol = ColOfEcart(anEcart);
  211. mPC.AddPt(aCol,Pt3dr::P3ToThisT((*iTGlob)->mPt));
  212. }
  213. }
  214. mPC.PutFile(aDir+"CloudResidual.ply");
  215. Pt2dr aP0 = aBoxQt._p0 - Pt2dr(0,-40) * mResol;
  216. double aPasLeg = mResol *100;
  217. double aZLeg = mVMilZ;
  218. int aNbLeg = 10;
  219. double aLargX = 10;
  220. int aLargY = 20;
  221. for (int aCpt=0 ; aCpt<=aNbLeg; aCpt++)
  222. {
  223. double aEcartStd = (aCpt-aNbLeg*0.5) /(0.5+aNbLeg*0.5);
  224. double aRes = FromEcartStd(aEcartStd);
  225. if (aRes >0)
  226. {
  227. char aBuf[100];
  228. sprintf(aBuf,"%.2f",aRes);
  229. std::string aStrRes (aBuf);
  230. mPCLeg.PutString
  231. (
  232. aStrRes,
  233. Pt3dr(aP0.x,aP0.y,aZLeg)+Pt3dr(0,aCpt*aPasLeg*aLargY,0) ,
  234. Pt3dr(1,0,0),
  235. Pt3dr(0,1,0),
  236. Pt3di(255,255,255),
  237. aLargX* aPasLeg, // La largeur des caractere
  238. aPasLeg, // espacement
  239. 4 // carre de 4x4
  240. );
  241. }
  242. }
  243. int DensLeg = 20;
  244. for (int aCpt= -DensLeg/2 ; aCpt<=((DensLeg*aNbLeg) + DensLeg/2) ; aCpt++)
  245. {
  246. double aCptN = aCpt/double(DensLeg);
  247. double aEcartStd = (aCptN-aNbLeg*0.5) /(0.5+aNbLeg*0.5);
  248. Pt3di aCol = ColOfEcart(aEcartStd);
  249. Pt3dr aPLine = Pt3dr(aP0.x,aP0.y,aZLeg)+Pt3dr(0,aCptN*aPasLeg*aLargY,0) ;
  250. for (int anX=0 ; anX<=DensLeg ; anX++)
  251. {
  252. Pt3dr aP = aPLine + Pt3dr(-(anX/double(DensLeg))*aPasLeg*aLargY,0,0);
  253. mPCLeg.AddPt(aCol,aP);
  254. }
  255. }
  256. mPCLeg.PutFile(aDir+"CloudResidual_Leg.ply");
  257. /*
  258. for (int aK=-10 ; aK<10 ; aK++)
  259. {
  260. double aV= aK*0.2;
  261. std::cout << "EErr " << aV << " " << erfcc(aV) << " " <<DirErFonc(aV) << " Dif=" << InvErrFonc(DirErFonc(aV)) - aV << "\n";
  262. }
  263. getchar();
  264. */
  265. }
  266. static cAperoVisuGlobRes mAVGR;
  267. //============================================
  268. /*class cInfoAccumRes
  269. {
  270. public :
  271. cInfoAccumRes(const Pt2dr & aPt,double aPds,double aResidu,const Pt2dr & aDir);
  272. Pt2dr mPt;
  273. double mPds;
  274. double mResidu;
  275. Pt2dr mDir;
  276. };*/
  277. cInfoAccumRes::cInfoAccumRes(const Pt2dr & aPt,double aPds,double aResidu,const Pt2dr & aDir) :
  278. mPt (aPt),
  279. mPds (aPds),
  280. mResidu (aResidu),
  281. mDir (aDir)
  282. {
  283. }
  284. /*class cAccumResidu
  285. {
  286. public :
  287. void Accum(const cInfoAccumRes &);
  288. cAccumResidu(Pt2di aSz,double aRed,bool OnlySign,int aDegPol);
  289. const Pt2di & SzRed() {return mSzRed;}
  290. void Export(const std::string & aDir,const std::string & aName,const cUseExportImageResidu &,FILE * );
  291. void ExportResXY(TIm2D<REAL4,REAL8>* aTResX,TIm2D<REAL4,REAL8>* aTResY);
  292. void ExportResXY(const Pt2di&,Pt2dr& aRes);
  293. private :
  294. void AccumInImage(const cInfoAccumRes &);
  295. std::list<cInfoAccumRes> mLIAR;
  296. int mNbInfo;
  297. double mSomPds;
  298. bool mOnlySign;
  299. double mResol;
  300. Pt2di mSz;
  301. Pt2di mSzRed;
  302. Im2D_REAL4 mPds;
  303. TIm2D<REAL4,REAL8> mTPds;
  304. Im2D_REAL4 mMoySign;
  305. TIm2D<REAL4,REAL8> mTMoySign;
  306. Im2D_REAL4 mMoyAbs;
  307. TIm2D<REAL4,REAL8> mTMoyAbs;
  308. bool mInit;
  309. int mDegPol;
  310. L2SysSurResol * mSys;
  311. };*/
  312. cAccumResidu::cAccumResidu(Pt2di aSz,double aResol,bool OnlySign,int aDegPol) :
  313. mNbInfo (0),
  314. mSomPds (0.0),
  315. mOnlySign (OnlySign),
  316. mResol (aResol),
  317. mSz (aSz),
  318. mSzRed (round_up(Pt2dr(aSz)/mResol)),
  319. mPds (1,1),
  320. mTPds (mPds),
  321. mMoySign (1,1),
  322. mTMoySign (mMoySign),
  323. mMoyAbs (1,1),
  324. mTMoyAbs (mMoyAbs),
  325. mInit (false),
  326. mDegPol (aDegPol),
  327. mSys (0)
  328. {
  329. }
  330. void cAccumResidu::Export(const std::string & aDir,const std::string & aName,const cUseExportImageResidu & aUEIR,FILE * aFP )
  331. {
  332. if (! mInit) return;
  333. fprintf(aFP,"=== %s =======\n",aName.c_str());
  334. fprintf(aFP," Nb=%d WAver=%f\n",mNbInfo,mSomPds/mNbInfo);
  335. Tiff_Im::CreateFromFonc
  336. (
  337. aDir+"RawWeight-"+aName+".tif",
  338. mSzRed,
  339. mPds.in() * (mNbInfo/mSomPds),
  340. GenIm::real4
  341. );
  342. int aNbPixel = mSzRed.x * mSzRed.y;
  343. double aNbMesByCase = mNbInfo / double(aNbPixel);
  344. double aTargetNbMesByC = aUEIR.NbMesByCase().Val();
  345. if (aTargetNbMesByC >= 0)
  346. {
  347. double aSigma = sqrt(aTargetNbMesByC / aNbMesByCase);
  348. FilterGauss(mPds,aSigma);
  349. FilterGauss(mMoySign,aSigma);
  350. FilterGauss(mMoyAbs,aSigma);
  351. }
  352. Tiff_Im::CreateFromFonc
  353. (
  354. aDir+"ResSign-"+aName+".tif",
  355. mSzRed,
  356. mMoySign.in() / Max(mPds.in(),1e-4),
  357. GenIm::real4
  358. );
  359. double aMoySign,aMoyAbsSign,aSomPds;
  360. ELISE_COPY
  361. (
  362. mPds.all_pts(),
  363. Virgule(mPds.in(),mMoySign.in(),Abs(mMoySign.in())),
  364. Virgule(sigma(aSomPds),sigma(aMoySign),sigma(aMoyAbsSign))
  365. );
  366. fprintf(aFP," AverSign=%f AverAbsSign=%f\n",aMoySign/aSomPds,aMoyAbsSign/aSomPds);
  367. if (!mOnlySign)
  368. {
  369. Tiff_Im::CreateFromFonc
  370. (
  371. aDir+"ResAbs-"+aName+".tif",
  372. mSzRed,
  373. mMoyAbs.in() / Max(mPds.in(),1e-4),
  374. GenIm::real4
  375. );
  376. }
  377. if (mSys)
  378. {
  379. bool aOk;
  380. Im1D_REAL8 aSol = mSys->Solve(&aOk);
  381. if (aOk)
  382. {
  383. double * aDS = aSol.data();
  384. Im2D_REAL4 aResX(mSzRed.x,mSzRed.y);
  385. TIm2D<REAL4,REAL8> aTRx(aResX);
  386. Im2D_REAL4 aResY(mSzRed.x,mSzRed.y);
  387. TIm2D<REAL4,REAL8> aTRy(aResY);
  388. Pt2di aPInd;
  389. for (aPInd.x=0 ; aPInd.x<mSzRed.x ; aPInd.x++)
  390. {
  391. for (aPInd.y=0 ; aPInd.y<mSzRed.y ; aPInd.y++)
  392. {
  393. Pt2dr aPFulRes = Pt2dr(aPInd) * mResol;
  394. Pt2dr aSzN = mSz/2.0;
  395. double aX = (aPFulRes.x-aSzN.x) / aSzN.x;
  396. double aY = (aPFulRes.y-aSzN.y) / aSzN.y;
  397. std::vector<double> aVMx; // Monome Xn
  398. std::vector<double> aVMy; // Monome Yn
  399. aVMx.push_back(1.0);
  400. aVMy.push_back(1.0);
  401. for (int aD=0 ; aD< mDegPol ; aD++)
  402. {
  403. aVMx.push_back(aVMx.back() * aX);
  404. aVMy.push_back(aVMy.back() * aY);
  405. }
  406. int anIndEq = 0;
  407. double aSX=0 ;
  408. double aSY=0 ;
  409. for (int aDx=0 ; aDx<= mDegPol ; aDx++)
  410. {
  411. for (int aDy=0 ; aDy<= mDegPol - aDx ; aDy++)
  412. {
  413. double aMonXY = aVMx[aDx] * aVMy[aDy]; // X ^ Dx * Y ^ Dy
  414. aSX += aDS[anIndEq++] * aMonXY;
  415. aSY += aDS[anIndEq++] * aMonXY;
  416. }
  417. }
  418. aTRx.oset(aPInd,aSX);
  419. aTRy.oset(aPInd,aSY);
  420. }
  421. }
  422. Tiff_Im::CreateFromFonc
  423. (
  424. aDir+"ResX-"+aName+".tif",
  425. mSzRed,
  426. aResX.in(),
  427. GenIm::real4
  428. );
  429. Tiff_Im::CreateFromFonc
  430. (
  431. aDir+"ResY-"+aName+".tif",
  432. mSzRed,
  433. aResY.in(),
  434. GenIm::real4
  435. );
  436. }
  437. }
  438. }
  439. void cAccumResidu::ExportResXY(const Pt2di& aPt,Pt2dr& aRes)
  440. {
  441. if (mSys)
  442. {
  443. bool aOk;
  444. Im1D_REAL8 aSol = mSys->Solve(&aOk);
  445. if (aOk)
  446. {
  447. double * aDS = aSol.data();
  448. std::vector<double> aVMx;
  449. std::vector<double> aVMy;
  450. aVMx.push_back(1.0);
  451. aVMy.push_back(1.0);
  452. Pt2dr aPFulRes = Pt2dr(aPt) * mResol;
  453. Pt2dr aSzN = mSz/2.0;
  454. double aX = (aPFulRes.x-aSzN.x) / aSzN.x;
  455. double aY = (aPFulRes.y-aSzN.y) / aSzN.y;
  456. for (int aD=0 ; aD< mDegPol ; aD++)
  457. {
  458. aVMx.push_back(aVMx.back() * aX);
  459. aVMy.push_back(aVMy.back() * aY);
  460. }
  461. int anIndEq = 0;
  462. double aSX=0 ;
  463. double aSY=0 ;
  464. for (int aDx=0 ; aDx<= mDegPol ; aDx++)
  465. {
  466. for (int aDy=0 ; aDy<= mDegPol - aDx ; aDy++)
  467. {
  468. double aMonXY = aVMx[aDx] * aVMy[aDy];
  469. aSX += aDS[anIndEq++] * aMonXY;
  470. aSY += aDS[anIndEq++] * aMonXY;
  471. }
  472. }
  473. aRes.x = aSX;
  474. aRes.y = aSY;
  475. }
  476. }
  477. }
  478. void cAccumResidu::ExportResXY(TIm2D<REAL4,REAL8>* aTRx,TIm2D<REAL4,REAL8>* aTRy)
  479. {
  480. if (mSys)
  481. {
  482. bool aOk;
  483. Im1D_REAL8 aSol = mSys->Solve(&aOk);
  484. if (aOk)
  485. {
  486. double * aDS = aSol.data();
  487. Pt2di aPInd;
  488. for (aPInd.x=0 ; aPInd.x<mSzRed.x ; aPInd.x++)
  489. {
  490. for (aPInd.y=0 ; aPInd.y<mSzRed.y ; aPInd.y++)
  491. {
  492. Pt2dr aPFulRes = Pt2dr(aPInd) * mResol;
  493. Pt2dr aSzN = mSz/2.0;
  494. double aX = (aPFulRes.x-aSzN.x) / aSzN.x;
  495. double aY = (aPFulRes.y-aSzN.y) / aSzN.y;
  496. std::vector<double> aVMx;
  497. std::vector<double> aVMy;
  498. aVMx.push_back(1.0);
  499. aVMy.push_back(1.0);
  500. for (int aD=0 ; aD< mDegPol ; aD++)
  501. {
  502. aVMx.push_back(aVMx.back() * aX);
  503. aVMy.push_back(aVMy.back() * aY);
  504. }
  505. int anIndEq = 0;
  506. double aSX=0 ;
  507. double aSY=0 ;
  508. for (int aDx=0 ; aDx<= mDegPol ; aDx++)
  509. {
  510. for (int aDy=0 ; aDy<= mDegPol - aDx ; aDy++)
  511. {
  512. double aMonXY = aVMx[aDx] * aVMy[aDy];
  513. aSX += aDS[anIndEq++] * aMonXY;
  514. aSY += aDS[anIndEq++] * aMonXY;
  515. }
  516. }
  517. aTRx->oset(aPInd,aSX);
  518. aTRy->oset(aPInd,aSY);
  519. }
  520. }
  521. }
  522. }
  523. }
  524. void cAccumResidu::AccumInImage(const cInfoAccumRes & anInfo)
  525. {
  526. Pt2dr aP = anInfo.mPt / mResol;
  527. mTPds.incr(aP,anInfo.mPds);
  528. mTMoySign.incr(aP,anInfo.mPds * anInfo.mResidu);
  529. if (!mOnlySign)
  530. {
  531. mTMoyAbs.incr(aP,anInfo.mPds*ElAbs(anInfo.mResidu));
  532. }
  533. if (mSys)
  534. {
  535. //
  536. Pt2dr aSzN = mSz/2.0;
  537. Pt2dr aN = anInfo.mDir * Pt2dr(0,1);
  538. // Pour precision matrice, mieux vaut coordonnees normalisees
  539. double aX = (anInfo.mPt.x-aSzN.x) / aSzN.x;
  540. double aY = (anInfo.mPt.y-aSzN.y) / aSzN.y;
  541. std::vector<double> aVMx; // Monome Xn
  542. std::vector<double> aVMy; // Monome Xn
  543. aVMx.push_back(1.0);
  544. aVMy.push_back(1.0);
  545. for (int aD=0 ; aD< mDegPol ; aD++)
  546. {
  547. aVMx.push_back(aVMx.back() * aX);
  548. aVMy.push_back(aVMy.back() * aY);
  549. }
  550. std::vector<double> anEq;
  551. for (int aDx=0 ; aDx<= mDegPol ; aDx++)
  552. {
  553. for (int aDy=0 ; aDy<= mDegPol - aDx ; aDy++)
  554. {
  555. double aMonXY = aVMx[aDx] * aVMy[aDy]; // X ^ Dx * Y ^ Dy
  556. anEq.push_back(aMonXY* aN.x);
  557. anEq.push_back(aMonXY* aN.y);
  558. // std::cout << " eq " << aDx << " " << aDx << " " << aVMx[aDx] << " " << aVMy[aDy] << " " << aN.x << " " << aN.y << " " << anInfo.mDir <<"\n";
  559. // std::cout << " eq " << aMonXY* aN.x << " " << aMonXY* aN.y << "\n";
  560. }
  561. }
  562. mSys->AddEquation(anInfo.mPds,VData(anEq),anInfo.mResidu);
  563. }
  564. }
  565. void cAccumResidu::Accum(const cInfoAccumRes & anInfo)
  566. {
  567. mSomPds += anInfo.mPds;
  568. mNbInfo++;
  569. if (mNbInfo<NbMinCreateIm)
  570. {
  571. mLIAR.push_back(anInfo);
  572. }
  573. else if (mNbInfo==NbMinCreateIm)
  574. {
  575. mInit = true;
  576. mLIAR.push_back(anInfo);
  577. mPds = Im2D_REAL4(mSzRed.x,mSzRed.y,0.0);
  578. mTPds = TIm2D<REAL4,REAL8>(mPds);
  579. mMoySign = Im2D_REAL4(mSzRed.x,mSzRed.y,0.0);
  580. mTMoySign = TIm2D<REAL4,REAL8>(mMoySign);
  581. if (! mOnlySign)
  582. {
  583. mMoyAbs = Im2D_REAL4(mSzRed.x,mSzRed.y,0.0);
  584. mTMoyAbs = TIm2D<REAL4,REAL8>(mMoyAbs);
  585. }
  586. if (mDegPol >=0)
  587. {
  588. mSys = new L2SysSurResol((1+mDegPol)*(mDegPol+2));
  589. }
  590. for (std::list<cInfoAccumRes>::const_iterator itI=mLIAR.begin() ;itI!=mLIAR.end() ; itI++)
  591. {
  592. AccumInImage(*itI);
  593. }
  594. mLIAR.clear();
  595. }
  596. else
  597. {
  598. AccumInImage(anInfo);
  599. }
  600. }
  601. // cAccumResidu(Pt2di aSz,double aRed,bool OnlySign);
  602. void cAppliApero::AddOneInfoImageResidu
  603. (
  604. const cInfoAccumRes & anInfo,
  605. const std::string & aName,
  606. Pt2di aSz,
  607. double aSzRed,
  608. bool OnlySign,
  609. int aDegPol
  610. )
  611. {
  612. if (aSzRed <=0) return;
  613. double aFactRed = dist8(aSz) / aSzRed;
  614. cAccumResidu * & aRef = mMapAR[aName];
  615. if (aRef==0)
  616. {
  617. aRef = new cAccumResidu(aSz,aFactRed,OnlySign,aDegPol);
  618. }
  619. aRef->Accum(anInfo);
  620. }
  621. void cAppliApero::AddInfoImageResidu
  622. (
  623. const Pt3dr & aPt,
  624. const cNupletPtsHomologues & aNupl,
  625. const std::vector<cGenPoseCam *> aVP,
  626. const std::vector<double> & aVpds
  627. )
  628. {
  629. if ((!Param().UseExportImageResidu().IsInit()) || (! IsLastEtapeOfLastIter()))
  630. return;
  631. const cUseExportImageResidu & aUEIR = Param().UseExportImageResidu().Val();
  632. double aSomPds = 0.0;
  633. double aSomPdsRes = 0.0;
  634. for (int aK1=0 ; aK1< aNupl.NbPts() ; aK1++)
  635. {
  636. double aPds1 = aVpds[aK1];
  637. if (aPds1>0)
  638. {
  639. for (int aK2=0 ; aK2< aNupl.NbPts() ; aK2++)
  640. {
  641. double aPds2 = aVpds[aK2];
  642. if ((aK1!=aK2) && (aPds2>0))
  643. {
  644. const cBasicGeomCap3D * aCam1 = aVP[aK1]->GenCurCam();
  645. const cBasicGeomCap3D * aCam2 = aVP[aK2]->GenCurCam();
  646. Pt2di aSzCam1 = aCam1->SzBasicCapt3D();
  647. Pt2dr aP1 = aNupl.PK(aK1);
  648. Pt2dr aP2 = aNupl.PK(aK2);
  649. Pt2dr aDir;
  650. double aRes = aCam1->EpipolarEcart(aP1,*aCam2,aP2,&aDir);
  651. cInfoAccumRes anInfo(aP1,ElMin(aPds1,aPds2),aRes,aDir);
  652. double aPds = aPds1 * aPds2;
  653. aSomPds += aPds;
  654. aSomPdsRes += aPds * ElAbs(aRes);
  655. if (aK1<aK2)
  656. {
  657. std::string aNamePair = "Pair-"+aVP[aK1]->Name() + "-" + aVP[aK2]->Name();
  658. AddOneInfoImageResidu(anInfo,aNamePair,aSzCam1,aUEIR.SzByPair().Val(),true,-1);
  659. }
  660. AddOneInfoImageResidu(anInfo,"Pose-"+aVP[aK1]->Name(),aSzCam1,aUEIR.SzByPose().Val(),false,5);
  661. cCalibCam * aCC1 = aVP[aK1]->CalibCam();
  662. if (aCC1)
  663. {
  664. AddOneInfoImageResidu(anInfo,"Cam-"+aCC1->KeyId(),aSzCam1,aUEIR.SzByCam().Val(),false,10);
  665. }
  666. }
  667. }
  668. }
  669. }
  670. if (aSomPds)
  671. {
  672. mAVGR.AddResidu(aPt,aSomPdsRes/aSomPds);
  673. }
  674. }
  675. void cAppliApero::ExportImageResidu(const std::string & aName,const cAccumResidu & anAccum)
  676. {
  677. const cUseExportImageResidu & aUEIR = Param().UseExportImageResidu().Val();
  678. // ELISE_fp::MkDirRec(mDirExportImRes);
  679. const_cast<cAccumResidu &>(anAccum).Export(mDirExportImRes,aName,aUEIR,mFileExpImRes);
  680. }
  681. void cAppliApero::ExportImageResidu()
  682. {
  683. if ((!Param().UseExportImageResidu().IsInit()) )
  684. return;
  685. const cUseExportImageResidu & aUEIR = Param().UseExportImageResidu().Val();
  686. mDirExportImRes = DC() + "Ori" + aUEIR.AeroExport() + "/ImResidu/";
  687. ELISE_fp::MkDirRec(mDirExportImRes);
  688. mFileExpImRes = FopenNN(mDirExportImRes+"StatRes.txt","w","cAppliApero::ExportImageResidu");
  689. for (auto it=mMapAR.begin() ; it!=mMapAR.end() ; it++)
  690. {
  691. ExportImageResidu(it->first,*(it->second));
  692. }
  693. fclose(mFileExpImRes);
  694. mAVGR.DoResidu(mDirExportImRes,aUEIR.NbMesByCase().Val());
  695. }
  696. //============================================
  697. int PROF_UNDEF() { return -1; }
  698. int cPoseCam::theCpt = 0;
  699. int TheDefProf2Init = 1000000;
  700. void cPoseCam::SetNameCalib(const std::string & aNameC)
  701. {
  702. mNameCalib = aNameC;
  703. }
  704. static int theNumCreate =0;
  705. cStructRigidInit * cPoseCam::GetSRI(bool SVP) const
  706. {
  707. if (!SVP && (mSRI==0))
  708. {
  709. ELISE_ASSERT(false,"NO SRI");
  710. }
  711. return mSRI;
  712. }
  713. void cPoseCam::SetSRI(cStructRigidInit * aSRI)
  714. {
  715. ELISE_ASSERT(mSRI==0,"Muliple SRI set");
  716. mSRI = aSRI;
  717. }
  718. cPreCompBloc * cPoseCam::GetPreCompBloc(bool SVP) const
  719. {
  720. if (!SVP && (mBlocCam==0))
  721. {
  722. ELISE_ASSERT(false,"NO Boc Cam");
  723. }
  724. return mBlocCam;
  725. }
  726. void cPoseCam::SetPreCompBloc(cPreCompBloc * aBloc)
  727. {
  728. ELISE_ASSERT(mBlocCam==0,"Muliple Bloc set");
  729. mBlocCam = aBloc;
  730. }
  731. cPreCB1Pose * cPoseCam::GetPreCB1Pose(bool SVP) const
  732. {
  733. if (!SVP && (mPoseInBlocCam==0))
  734. {
  735. ELISE_ASSERT(false,"NO Pose in Boc Cam");
  736. }
  737. return mPoseInBlocCam;
  738. }
  739. void cPoseCam::SetPreCB1Pose(cPreCB1Pose * aPoseInBloc)
  740. {
  741. ELISE_ASSERT(mPoseInBlocCam==0,"Muliple Bloc set");
  742. mPoseInBlocCam = aPoseInBloc;
  743. }
  744. void cPoseCam::SetOrInt(const cTplValGesInit<cSetOrientationInterne> & aTplSI)
  745. {
  746. if (! aTplSI.IsInit()) return;
  747. const cSetOrientationInterne & aSOI = aTplSI.Val();
  748. cSetName * aSelector = mAppli.ICNM()->KeyOrPatSelector(aSOI.PatternSel());
  749. if (! aSelector->IsSetIn(mName))
  750. return;
  751. std::string aNameFile = mAppli.DC() + mAppli.ICNM()->Assoc1To1(aSOI.KeyFile(),mName,true);
  752. cAffinitePlane aXmlAff = StdGetObjFromFile<cAffinitePlane>
  753. (
  754. aNameFile,
  755. StdGetFileXMLSpec("ParamChantierPhotogram.xml"),
  756. aSOI.Tag().Val(),
  757. "AffinitePlane"
  758. );
  759. ElAffin2D anAffM2C = Xml2EL(aXmlAff);
  760. if (! aSOI.M2C())
  761. anAffM2C = anAffM2C.inv();
  762. if (aSOI.AddToCur())
  763. mOrIntM2C= anAffM2C * mOrIntM2C ;
  764. else
  765. mOrIntM2C= anAffM2C;
  766. // Si on le fait avec les marques fiduciaires ca ecrase le reste
  767. mOrIntC2M = mOrIntM2C.inv();
  768. }
  769. cPoseCam * cPoseCam::DownCastPoseCamSVP() {return this;}
  770. const cPoseCam * cPoseCam::DownCastPoseCamSVP() const {return this;}
  771. cCalibCam * cPoseCam::CalibCam() const {return mCalib;}
  772. cGenPDVFormelle * cPoseCam::PDVF() {return mCF;}
  773. const cGenPDVFormelle * cPoseCam::PDVF() const {return mCF;}
  774. cPoseCam::cPoseCam
  775. (
  776. cAppliApero & anAppli,
  777. const cPoseCameraInc & aPCI,
  778. const std::string & aNamePose,
  779. const std::string & aNameCalib,
  780. cPoseCam * aPRat,
  781. cCompileAOI * aCompAOI
  782. ) :
  783. cGenPoseCam (anAppli,aNamePose),
  784. // mAppli (anAppli),
  785. mNameCalib (aNameCalib),
  786. // mName (aNamePose),
  787. mCpt (-1),
  788. mProf2Init (TheDefProf2Init),
  789. mPdsTmpMST (0.0),
  790. mPCI (&aPCI),
  791. mCalib(NULL),
  792. mPoseRat (aPRat),
  793. mPoseInitMST1 (0),
  794. mPoseInitMST2 (0),
  795. mCamRF (mPoseRat ? mPoseRat->mCF : 0),
  796. mCF(NULL),
  797. mRF(NULL),
  798. mAltiSol (ALTISOL_UNDEF()),
  799. mProfondeur (PROF_UNDEF()),
  800. mTime (TIME_UNDEF()),
  801. mPrioSetAlPr (-1),
  802. mLastCP (0),
  803. mCompAOI (aCompAOI),
  804. mFirstBoxImSet (false),
  805. mImageLoaded (false),
  806. mBoxIm (Pt2di(0,0),Pt2di(0,0)),
  807. mIm (1,1),
  808. mTIm (mIm),
  809. // mMasqH (mAppli.MasqHom(aNamePose)),
  810. // mTMasqH (mMasqH ? new TIm2DBits<1>(*mMasqH) : 0),
  811. // mObsCentre (0,0,0),
  812. mHasObsOnCentre (false),
  813. mHasObsOnVitesse (false),
  814. mLastItereHasUsedObsOnCentre (false),
  815. mNumBande (0),
  816. mPrec (NULL),
  817. mNext (NULL),
  818. mNumCreate (theNumCreate++),
  819. mNbPosOfInit (-1),
  820. mFidExist (false),
  821. mCamNonOrtho (0),
  822. mEqOffsetGPS (0),
  823. mSRI (nullptr),
  824. mBlocCam (nullptr),
  825. mNumTimeBloc (-1),
  826. mPoseInBlocCam (nullptr),
  827. mUseRappelPose (false),
  828. mRotURP (ElRotation3D::Id)
  829. {
  830. mPrec = this;
  831. mNext = this;
  832. std::string anIdGlob = mAppli.GetNewIdIma(aNamePose);
  833. mCalib = mAppli.CalibFromName(aNameCalib,this);
  834. // mCF = mCalib->PIF().NewCam(cNameSpaceEqF::eRotLibre,ElRotation3D::Id,mCamRF,aNamePose,true,false,mAppli.HasEqDr());
  835. mCF = mCalib->PIF().NewCam(cNameSpaceEqF::eRotLibre,ElRotation3D::Id,mCamRF,anIdGlob,true,false,mAppli.HasEqDr());
  836. mCF->SetNameIm(aNamePose);
  837. mRF = &mCF->RF();
  838. SetOrInt(mAppli.Param().GlobOrInterne());
  839. SetOrInt(aPCI.OrInterne());
  840. std::pair<std::string,std::string> aPair = mAppli.ICNM()->Assoc2To1("Key-Assoc-STD-Orientation-Interne",mName,true);
  841. std::string aNamePtsCam = aPair.first;
  842. std::string aNamePtsIm = aPair.second;
  843. if ((aPair.first!="NONE") && (ELISE_fp::exist_file(mAppli.OutputDirectory()+ aNamePtsIm)))
  844. {
  845. cMesureAppuiFlottant1Im aMesCam = mAppli.StdGetOneMAF(aNamePtsCam);
  846. // Correction du bug apparu lors du stage de Tibaut Sauter, lorsque les marques ont une origine tres
  847. // loin de zero, la box images est tres differente de par ex [0,0] [23x23], du coup le distorsion n'est pas coupe
  848. // au bon endroit
  849. Pt2dr aPMin(1e9,1e9);
  850. for
  851. (
  852. std::list<cOneMesureAF1I>::iterator itAp = aMesCam.OneMesureAF1I().begin();
  853. itAp != aMesCam.OneMesureAF1I().end();
  854. itAp++
  855. )
  856. {
  857. aPMin = Inf(aPMin,itAp->PtIm());
  858. }
  859. for
  860. (
  861. std::list<cOneMesureAF1I>::iterator itAp = aMesCam.OneMesureAF1I().begin();
  862. itAp != aMesCam.OneMesureAF1I().end();
  863. itAp++
  864. )
  865. {
  866. itAp->PtIm() = itAp->PtIm()-aPMin;
  867. }
  868. cMesureAppuiFlottant1Im aMesIm = mAppli.StdGetOneMAF(aNamePtsIm);
  869. ElPackHomologue aPack = PackFromCplAPF(aMesIm,aMesCam);
  870. ElAffin2D anAf = ElAffin2D::L2Fit(aPack);
  871. mOrIntM2C = anAf.inv();
  872. mFidExist = true;
  873. }
  874. mOrIntC2M = mOrIntM2C.inv();
  875. InitAvantCompens();
  876. if (aPCI.IdOffsetGPS().IsInit())
  877. {
  878. cAperoOffsetGPS * anOfs = mAppli.OffsetNNOfName(aPCI.IdOffsetGPS().Val());
  879. mEqOffsetGPS = mAppli.SetEq().NewEqOffsetGPS(*mCF,*(anOfs->BaseUnk()));
  880. }
  881. }
  882. cEqOffsetGPS * cPoseCam::EqOffsetGPS()
  883. {
  884. return mEqOffsetGPS;
  885. }
  886. int cPoseCam::NumCreate() const
  887. {
  888. return mNumCreate;
  889. }
  890. bool cPoseCam::AcceptPoint(const Pt2dr & aP) const
  891. {
  892. if (mCalib-> CamInit().IsScanned())
  893. {
  894. Pt2dr aSz = Pt2dr(mCalib->SzIm());
  895. if ((aP.x<=0) || (aP.y <=0) || (aP.x>=aSz.x) || (aP.y>=aSz.y))
  896. return false;
  897. }
  898. return true;
  899. }
  900. bool cPoseCam::FidExist() const
  901. {
  902. return mFidExist;
  903. }
  904. void cPoseCam::SetNumTimeBloc(int aNum)
  905. {
  906. mNumTimeBloc = aNum;
  907. }
  908. int cPoseCam::DifBlocInf1(const cPoseCam & aPC) const
  909. {
  910. if ((mNumTimeBloc==-1) || (aPC.mNumTimeBloc==-1)) return 1000;
  911. return ElAbs(mNumTimeBloc-aPC.mNumTimeBloc);
  912. }
  913. bool cPoseCam::IsInZoneU(const Pt2dr & aP) const
  914. {
  915. return mCalib->IsInZoneU(aP);
  916. }
  917. Pt2di cPoseCam::SzCalib() const
  918. {
  919. return Calib()->SzIm();
  920. }
  921. void cPoseCam::SetLink(cPoseCam * aPrec,bool OK)
  922. {
  923. mNumBande = aPrec->mNumBande;
  924. if (OK)
  925. {
  926. mPrec = aPrec;
  927. aPrec->mNext = this;
  928. }
  929. else
  930. {
  931. mNumBande++;
  932. }
  933. /*
  934. mNumBande = aNumBande;
  935. mPrec = aPrec;
  936. if (aPrec) aPrec->mNext = this;
  937. */
  938. }
  939. double GuimbalAnalyse(const ElRotation3D & aR,bool show)
  940. {
  941. // aR = aR.inv();
  942. // aR = ElRotation3D(Pt3dr(0,0,0),0,1.57,0);
  943. double aTeta01 = aR.teta01();
  944. double aTeta02 = aR.teta02();
  945. double aTeta12 = aR.teta12();
  946. double aEps = 1e-2;
  947. ElMatrix<double> aM1 = (ElRotation3D(aR.tr(),aTeta01+aEps,aTeta02,aTeta12).Mat()-aR.Mat())*(1/aEps);
  948. ElMatrix<double> aM2 = (ElRotation3D(aR.tr(),aTeta01,aTeta02+aEps,aTeta12).Mat()-aR.Mat())*(1/aEps);
  949. ElMatrix<double> aM3 = (ElRotation3D(aR.tr(),aTeta01,aTeta02,aTeta12+aEps).Mat()-aR.Mat())*(1/aEps);
  950. aM1 = aM1 * (1/sqrt(aM1.L2()));
  951. aM2 = aM2 * (1/sqrt(aM2.L2()));
  952. aM3 = aM3 * (1/sqrt(aM3.L2()));
  953. ElMatrix<double> aU1 = aM1;
  954. ElMatrix<double> aU2 = aM2 -aU1*aU1.scal(aM2);
  955. double aD2 = sqrt(aU2.L2());
  956. aU2 = aU2 *(1/aD2);
  957. ElMatrix<double> aU3 = aM3 -aU1*aU1.scal(aM3) -aU2*aU2.scal(aM3);
  958. double aD3 = sqrt(aU3.L2());
  959. if (show)
  960. {
  961. std::cout << aU2.scal(aU1) << " " << aU3.scal(aU1) << " " << aD2*aD3 << "\n";
  962. ShowMatr("M1",aM1);
  963. ShowMatr("M2",aM2);
  964. ShowMatr("M3",aM3);
  965. getchar();
  966. }
  967. return aD2 * aD3;
  968. }
  969. void cPoseCam::Trace() const
  970. {
  971. if (! mAppli.TracePose(*this))
  972. return;
  973. std::cout << mName ;
  974. if (RotIsInit())
  975. {
  976. ElRotation3D aR = CurRot() ;
  977. std::cout << " C=" << aR.tr() ;
  978. std::cout << " Teta=" << aR.teta01() << " " << aR.teta02() << " " << aR.teta12() ;
  979. if (mAppli.Param().TraceGimbalLock().Val())
  980. {
  981. std::cout << " GL-Score=" << GuimbalAnalyse(aR,false);
  982. }
  983. }
  984. std::cout << "\n";
  985. }
  986. double & cPoseCam::PdsTmpMST()
  987. {
  988. return mPdsTmpMST;
  989. }
  990. void cPoseCam::Set0Prof2Init()
  991. {
  992. mProf2Init = 0;
  993. }
  994. bool cPoseCam::ProfIsInit() const {return mProf2Init != TheDefProf2Init ;}
  995. double cPoseCam::Time() const
  996. {
  997. return mTime;
  998. }
  999. int cPoseCam::Prof2Init() const
  1000. {
  1001. return mProf2Init;
  1002. }
  1003. void cPoseCam::UpdateHeriteProf2Init(const cPoseCam & aC2)
  1004. {
  1005. if (mProf2Init==TheDefProf2Init)
  1006. mProf2Init = 0;
  1007. ElSetMax(mProf2Init,1+aC2.mProf2Init);
  1008. }
  1009. cPoseCam * cPoseCam::PoseInitMST1()
  1010. {
  1011. return mPoseInitMST1;
  1012. }
  1013. void cPoseCam::SetPoseInitMST1(cPoseCam * aPoseInitMST1)
  1014. {
  1015. mPoseInitMST1 = aPoseInitMST1;
  1016. }
  1017. cPoseCam * cPoseCam::PoseInitMST2()
  1018. {
  1019. return mPoseInitMST2;
  1020. }
  1021. void cPoseCam::SetPoseInitMST2(cPoseCam * aPoseInitMST2)
  1022. {
  1023. mPoseInitMST2 = aPoseInitMST2;
  1024. }
  1025. std::string cPoseCam::CalNameFromL(const cLiaisonsInit & aLI)
  1026. {
  1027. std::string aName2 = aLI.NameCam();
  1028. if (aLI.NameCamIsKeyCalc().Val())
  1029. {
  1030. aName2 = mAppli.ICNM()->Assoc1To1(aName2,mName,aLI.KeyCalcIsIDir().Val());
  1031. }
  1032. return aName2;
  1033. }
  1034. cRotationFormelle & cPoseCam::RF()
  1035. {
  1036. return *mRF;
  1037. }
  1038. ElRotation3D cPoseCam::CurRot() const
  1039. {
  1040. return mRF->CurRot();
  1041. }
  1042. const std::string & cPoseCam::NameCalib() const
  1043. {
  1044. return mCalib->CCI().Name();
  1045. }
  1046. void cPoseCam::SetRattach(const std::string & aNameRat)
  1047. {
  1048. if ((mPoseRat==0) || (mPoseRat != mAppli.PoseFromName(aNameRat)))
  1049. {
  1050. std::cout << mPoseRat << "\n";
  1051. std::cout << "Pour rattacher " << mName << " a " << aNameRat << "\n";
  1052. std::cout << "(Momentanement) : le ratachement doit etre prevu a l'initialisation";
  1053. ELISE_ASSERT(false,"Rattachement impossible");
  1054. }
  1055. }
  1056. void cPoseCam::VirtualInitAvantCompens()
  1057. {
  1058. mLastItereHasUsedObsOnCentre = false;
  1059. AssertHasNotCamNonOrtho();
  1060. }
  1061. const CamStenope * cPoseCam::CurCam() const
  1062. {
  1063. if (mCamNonOrtho) return mCamNonOrtho;
  1064. return mCF->CameraCourante() ;
  1065. }
  1066. CamStenope * cPoseCam::NC_CurCam()
  1067. {
  1068. if (mCamNonOrtho) return mCamNonOrtho;
  1069. return mCF->NC_CameraCourante() ;
  1070. }
  1071. const cBasicGeomCap3D * cPoseCam::GenCurCam () const { return CurCam(); }
  1072. cBasicGeomCap3D * cPoseCam::GenCurCam () { return NC_CurCam(); }
  1073. CamStenope * cPoseCam::DupCurCam() const
  1074. {
  1075. if (mCamNonOrtho) return mCamNonOrtho;
  1076. return mCF->DuplicataCameraCourante() ;
  1077. }
  1078. double cPoseCam::GetProfDyn(int & Ok) const
  1079. {
  1080. Ok = true;
  1081. if (PMoyIsInit())
  1082. {
  1083. Ok =1 ;
  1084. return ProfMoyHarmonik();
  1085. }
  1086. if (mLastEstimProfIsInit)
  1087. {
  1088. Ok =2 ;
  1089. return mLasEstimtProf;
  1090. }
  1091. if (mProfondeur != PROF_UNDEF())
  1092. {
  1093. Ok = 3 ;
  1094. return mProfondeur;
  1095. }
  1096. Ok = 0;
  1097. return 0;
  1098. }
  1099. void cPoseCam::ActiveContrainte(bool Stricte)
  1100. {
  1101. mAppli.SetEq().AddContrainte(mRF->StdContraintes(),Stricte);
  1102. }
  1103. void ShowResMepRelCoplan(cResMepRelCoplan aRMRC)
  1104. {
  1105. std::vector<cElemMepRelCoplan> aV = aRMRC.VElOk();
  1106. std::cout << " NB SOL = " << aV.size() << "\n";
  1107. for (int aKS=0; aKS<int(aV.size()) ; aKS++)
  1108. {
  1109. cElemMepRelCoplan aS = aV[aKS];
  1110. std::cout << "ANGLE " << aKS << " " << aS.AngTot() << "\n";
  1111. ElRotation3D aR = aS.Rot();
  1112. std::cout << aR.ImRecAff(Pt3dr(0,0,0)) << " "
  1113. << aR.teta01() << " "
  1114. << aR.teta02() << " "
  1115. << aR.teta12() << " "
  1116. << "\n";
  1117. }
  1118. }
  1119. /*
  1120. void ShowPrecisionLiaison(ElPackHomologue aPack,ElRotation3D aR1,ElRotation3D aR2)
  1121. {
  1122. CamStenopeIdeale aC1(1.0,Pt2dr(0.0,0.0));
  1123. aC1.SetOrientation(aR1.inv());
  1124. CamStenopeIdeale aC2(1.0,Pt2dr(0.0,0.0));
  1125. aC2.SetOrientation(aR2.inv());
  1126. double aSD=0;
  1127. double aSP=0;
  1128. for (ElPackHomologue::iterator itP= aPack.begin(); itP!=aPack.end() ; itP++)
  1129. {
  1130. ElSeg3D aS1 = aC1.F2toRayonR3(itP->P1());
  1131. ElSeg3D aS2 = aC2.F2toRayonR3(itP->P2());
  1132. Pt3dr aPTer = aS1.PseudoInter(aS2);
  1133. Pt2dr aQ1 = aC1.R3toF2(aPTer);
  1134. Pt2dr aQ2 = aC2.R3toF2(aPTer);
  1135. std::cout << aQ1 << aQ2 << euclid(aQ1,itP->P1()) << " " << euclid(aQ2,itP->P2()) << "\n";
  1136. aSP += 2;
  1137. aSD += euclid(aQ1,itP->P1()) + euclid(aQ2,itP->P2());
  1138. }
  1139. std::cout << "DMOYENNE " << aSD/aSP * 1e4 << "/10000\n";
  1140. }
  1141. */
  1142. ElMatrix<double> RFrom3P(const Pt3dr & aP1, const Pt3dr & aP2, const Pt3dr & aP3)
  1143. {
  1144. Pt3dr aU = aP2-aP1;
  1145. aU = aU / euclid(aU);
  1146. Pt3dr aW = aU ^(aP3-aP1);
  1147. aW = aW / euclid(aW);
  1148. Pt3dr aV = aW ^aU;
  1149. return ElMatrix<double>::Rotation(aU,aV,aW);
  1150. }
  1151. void TTTT (ElPackHomologue & aPack)
  1152. {
  1153. //
  1154. int aCpt=0;
  1155. Pt2dr aS1(0,0);
  1156. Pt2dr aS2(0,0);
  1157. double aSP=0;
  1158. std::cout << " ccccccccccc " << aPack.size() << "\n";
  1159. for
  1160. (
  1161. ElPackHomologue::iterator itP=aPack.begin() ;
  1162. itP!=aPack.end();
  1163. itP++
  1164. )
  1165. {
  1166. aS1 = aS1 + itP->P1() * itP->Pds();
  1167. aS2 = aS2 + itP->P2() * itP->Pds();
  1168. aSP += itP->Pds();
  1169. aCpt++;
  1170. if (euclid(itP->P1()) > 1e5)
  1171. std::cout << itP->P1() << itP->P2() << itP->Pds() << "\n";
  1172. }
  1173. std::cout << "SOMES :: "<< (aS1/aSP) << " " << (aS2/aSP) << "\n";
  1174. }
  1175. void TTTT (cElImPackHom & anIP)
  1176. {
  1177. ElPackHomologue aPack = anIP.ToPackH(0);
  1178. TTTT(aPack);
  1179. }
  1180. void cPoseCam::TenteInitAltiProf
  1181. (
  1182. int aPrio,
  1183. double anAlti,
  1184. double aProf
  1185. )
  1186. {
  1187. if ((aProf != PROF_UNDEF()) && (aPrio > mPrioSetAlPr))
  1188. {
  1189. mProfondeur = aProf;
  1190. mAltiSol = anAlti;
  1191. mPrioSetAlPr = aPrio;
  1192. }
  1193. }
  1194. extern bool AllowUnsortedVarIn_SetMappingCur;
  1195. cPoseCam * cPoseCam::Alloc
  1196. (
  1197. cAppliApero & anAppli,
  1198. const cPoseCameraInc & aPCI,
  1199. const std::string & aNamePose,
  1200. const std::string & aNameCalib,
  1201. cCompileAOI * aCompAOI
  1202. )
  1203. {
  1204. cPoseCam * aPRat=0;
  1205. if (aPCI.PosesDeRattachement().IsInit())
  1206. {
  1207. // En fait le tri sur les variables n'avait pas d'effet puisque la fonction est symetrique !!
  1208. AllowUnsortedVarIn_SetMappingCur = true;
  1209. aPRat = anAppli.PoseCSFromNameGen
  1210. (
  1211. aPCI.PosesDeRattachement().Val(),
  1212. aPCI.NoErroOnRat().Val()
  1213. );
  1214. }
  1215. cPoseCam * aRes = new cPoseCam(anAppli,aPCI,aNamePose,aNameCalib,aPRat,aCompAOI);
  1216. return aRes;
  1217. }
  1218. int cPoseCam::NbPosOfInit(int aDef)
  1219. {
  1220. return (mNbPosOfInit>=0) ? mNbPosOfInit : aDef;
  1221. }
  1222. void cPoseCam::SetNbPosOfInit(int aNbPosOfInit)
  1223. {
  1224. mNbPosOfInit = aNbPosOfInit;
  1225. }
  1226. void cPoseCam::DoInitIfNow()
  1227. {
  1228. mPreInit = true;
  1229. mAppli.AddRotPreInit();
  1230. if (mPCI->InitNow().Val())
  1231. {
  1232. InitRot();
  1233. }
  1234. }
  1235. /*
  1236. void cPoseCam::AddLink(cPoseCam * aPC)
  1237. {
  1238. if (! BoolFind(mVPLinked,aPC))
  1239. mVPLinked.push_back(aPC);
  1240. }
  1241. */
  1242. void cPoseCam::PCSetCurRot(const ElRotation3D & aRot)
  1243. {
  1244. ELISE_ASSERT(!mUseRappelPose,"Internam Error, probaly bascule + UseRappelPose");
  1245. AssertHasNotCamNonOrtho();
  1246. mCF->SetCurRot(aRot,aRot);
  1247. }
  1248. void cPoseCam::SetBascRig(const cSolBasculeRig & aSBR)
  1249. {
  1250. PCSetCurRot(aSBR.TransformOriC2M(CurRot()));
  1251. Pt3dr aP;
  1252. if (mSomPM)
  1253. {
  1254. aP = mPMoy / mSomPM;
  1255. mSomPM = 0;
  1256. }
  1257. else
  1258. {
  1259. const CamStenope * aCS = CurCam() ;
  1260. if (mProfondeur == PROF_UNDEF())
  1261. {
  1262. std::cout << "Warn : NoProfInBasc For camera =" << mName << "\n";
  1263. // ELISE_ASSERT( false,"No Profondeur in cPoseCam::SetBascRig");
  1264. return ;
  1265. }
  1266. aP = aCS->ImEtProf2Terrain(aCS->Sz()/2.0,mProfondeur);
  1267. aP = aSBR(aP);
  1268. }
  1269. const CamStenope * aCS = CurCam() ;
  1270. mAltiSol = aP.z;
  1271. mProfondeur = aCS->ProfondeurDeChamps(aP);
  1272. mLasEstimtProf = mProfondeur;
  1273. }
  1274. void cPoseCam::VirtualAddPMoy
  1275. (
  1276. const Pt2dr & aPIm,
  1277. const Pt3dr & aP,
  1278. int aKPoseThis,
  1279. const std::vector<double> * aVPds,
  1280. const std::vector<cGenPoseCam*>*
  1281. )
  1282. {
  1283. if (mAppli.UsePdsCalib())
  1284. mCalib->AddPds(aPIm,(*aVPds)[aKPoseThis]);
  1285. }
  1286. void cPoseCam::BeforeCompens()
  1287. {
  1288. mRF->ReactuFcteurRapCoU();
  1289. }
  1290. void cPoseCam::InitCpt()
  1291. {
  1292. if (mCpt<0)
  1293. {
  1294. mCpt = theCpt++;
  1295. mAppli.AddPoseInit(mCpt,this);
  1296. }
  1297. }
  1298. bool cPoseCam::HasObsOnCentre() const
  1299. {
  1300. return mHasObsOnCentre;
  1301. }
  1302. bool cPoseCam::LastItereHasUsedObsOnCentre() const
  1303. {
  1304. return mLastItereHasUsedObsOnCentre;
  1305. }
  1306. void cPoseCam::AssertHasObsCentre() const
  1307. {
  1308. if (!mHasObsOnCentre)
  1309. {
  1310. std::cout << "Name Pose = " << mName << "\n";
  1311. ELISE_ASSERT
  1312. (
  1313. false,
  1314. "Observation on centre (GPS) has no been associated to camera"
  1315. );
  1316. }
  1317. }
  1318. bool cPoseCam::HasObsOnVitesse() const
  1319. {
  1320. return mHasObsOnVitesse;
  1321. }
  1322. void cPoseCam::AssertHasObsVitesse() const
  1323. {
  1324. AssertHasObsCentre();
  1325. if (! mObsCentre.mVitesse.IsInit())
  1326. {
  1327. std::cout << "Name Pose = " << mName << "\n";
  1328. ELISE_ASSERT
  1329. (
  1330. false,
  1331. "No speed has been associated to camera"
  1332. );
  1333. }
  1334. }
  1335. const Pt3dr & cPoseCam::ObsCentre() const
  1336. {
  1337. AssertHasObsCentre();
  1338. return mObsCentre.mCentre;
  1339. }
  1340. Pt3dr cPoseCam::Vitesse() const
  1341. {
  1342. AssertHasObsVitesse();
  1343. return mObsCentre.mVitesse.Val();
  1344. }
  1345. bool cPoseCam::IsId(const ElAffin2D & anAff) const
  1346. {
  1347. Pt2dr aSz = Pt2dr(mCalib->SzIm());
  1348. Box2dr aBox(Pt2dr(0,0),aSz);
  1349. Pt2dr aCoins[4];
  1350. aBox.Corners(aCoins);
  1351. double aDiag = euclid(aSz);
  1352. // double aDiag2 = 0;
  1353. double aDMax = 0.0;
  1354. for (int aK=0 ; aK<4 ; aK++)
  1355. {
  1356. Pt2dr aP1 = aCoins[aK];
  1357. Pt2dr aP2 = anAff(aP1);
  1358. double aD = euclid(aP1,aP2) / aDiag;
  1359. ElSetMax(aDMax,aD);
  1360. }
  1361. return aDMax < 1e-3;
  1362. }
  1363. /*
  1364. */
  1365. double DistanceMatr(const ElRotation3D & aR1,const ElRotation3D & aR2)
  1366. {
  1367. ElMatrix<double> aMatr = aR1.inv().Mat() * aR2.Mat();
  1368. ElMatrix<double> aId(3,true);
  1369. return aId.L2(aMatr);
  1370. }
  1371. /*class cTransfo3DIdent : public cTransfo3D
  1372. {
  1373. public :
  1374. std::vector<Pt3dr> Src2Cibl(const std::vector<Pt3dr> & aSrc) const {return aSrc;}
  1375. };*/
  1376. extern bool DebugOFPA;
  1377. extern int aCPTOkOFA ;
  1378. extern int aCPTNotOkOFA ;
  1379. void cPoseCam::InitRot()
  1380. {
  1381. const cLiaisonsInit * theLiasInit = 0;
  1382. mNumInit = mAppli.NbRotInit();
  1383. if (mAppli.ShowMes())
  1384. std::cout << "NUM " << mNumInit << " FOR " << mName<< "\n";
  1385. /*
  1386. {
  1387. if (mNumInit==90)
  1388. {
  1389. BugFE=true;
  1390. }
  1391. else
  1392. {
  1393. std::cout << "END BUG FE \n";
  1394. BugFE=false;
  1395. }
  1396. BugFE=true;
  1397. }
  1398. */
  1399. if (mPCI->IdBDCentre().IsInit())
  1400. {
  1401. // std::cout << "CCCcccC : " << mName << " " << mAppli.HasObsCentre(mPCI->IdBDCentre().Val(),mName) << "\n";
  1402. if (mAppli.HasObsCentre(mPCI->IdBDCentre().Val(),mName))
  1403. {
  1404. mObsCentre = *( mAppli.ObsCentre(mPCI->IdBDCentre().Val(),mName).mVals );
  1405. mHasObsOnCentre = mObsCentre.mHasObsC;
  1406. mHasObsOnVitesse = mHasObsOnCentre && mObsCentre.mVitFiable && mObsCentre.mVitesse.IsInit();
  1407. // std::cout << "NameBDDCCC " << mName << " HasC " << mHasObsOnCentre << "\n";
  1408. }
  1409. }
  1410. // std::cout << mName << "::Prof=" << mProf2Init << "\n";
  1411. // std::cout << "Init Pose " << aNamePose << "\n";
  1412. InitCpt();
  1413. double aProfI = mPCI->ProfSceneImage().ValWithDef(mAppli.Param().ProfSceneChantier().Val());
  1414. ElRotation3D aRot(Pt3dr(0,0,0),0,0,0);
  1415. std::string aNZPl ="";
  1416. double aDZPl = -1;
  1417. double aDZPl2 = -1;
  1418. cPoseCam * aCam2PL = 0;
  1419. double aLambdaRot=1;
  1420. CamStenope* aCS1 = (mCalib->PIF().CurPIF());
  1421. double aProfPose = -1;
  1422. double anAltiSol = ALTISOL_UNDEF();
  1423. bool isMST = mPCI->MEP_SPEC_MST().IsInit();
  1424. if (isMST)
  1425. {
  1426. ELISE_ASSERT
  1427. (
  1428. mPCI->PoseFromLiaisons().IsInit(),
  1429. "MST requires PoseFromLiaisons"
  1430. );
  1431. }
  1432. bool isAPC = mAppli.Param().IsAperiCloud().Val();
  1433. bool isForISec = mAppli.Param().IsChoixImSec().Val();
  1434. bool initFromBD = false;
  1435. if (mSRI)
  1436. {
  1437. ElRotation3D aR1 = mSRI->mCMere->CurRot() ; // R1 to M
  1438. ElRotation3D aL1Bis = aR1 * mSRI->mR0m1L0;
  1439. aRot = aL1Bis;
  1440. }
  1441. else if (mPCI->PosId().IsInit())
  1442. {
  1443. aRot = ElRotation3D(Pt3dr(0,0,0),0,0,-PI);
  1444. }
  1445. else if (mPCI->PosFromBlockRigid().IsInit())
  1446. {
  1447. mAppli.PreInitBloc(mPCI->PosFromBlockRigid().Val());
  1448. aRot = GetPreCB1Pose(false)->mRot;
  1449. }
  1450. else if(mPCI->PosFromBDOrient().IsInit())
  1451. {
  1452. initFromBD = true;
  1453. const std::string & anId = mPCI->PosFromBDOrient().Val();
  1454. aRot =mAppli.Orient(anId,mName);
  1455. cObserv1Im<cTypeEnglob_Orient> & anObs = mAppli.ObsOrient(anId,mName);
  1456. bool Ok1 = IsId(anObs.mOrIntC2M);
  1457. bool Ok2 = IsId(anObs.mOrIntC2M * mOrIntC2M.inv());
  1458. ELISE_ASSERT
  1459. (
  1460. Ok1 || Ok2,
  1461. "Specicied Internal Orientation is incompatible with Fiducial marks"
  1462. );
  1463. aProfPose = anObs.mProfondeur;
  1464. anAltiSol = anObs.mAltiSol;
  1465. mTime = anObs.mTime;
  1466. }
  1467. else if (mPCI->PoseInitFromReperePlan().IsInit())
  1468. {
  1469. cPoseInitFromReperePlan aPP = mPCI->PoseInitFromReperePlan().Val();
  1470. ElPackHomologue aPack;
  1471. std::string aNamePose2 = aPP.NameCam();
  1472. std::string aNameCal2 = mAppli.NameCalOfPose(aNamePose2);
  1473. std::string aTestNameFile = mAppli.DC()+aPP.IdBD();
  1474. if (ELISE_fp::exist_file(aTestNameFile))
  1475. {
  1476. ELISE_ASSERT(false,"Obsolet Init Form repere plan");
  1477. // Onsolete, pas cohrent avec orient interen
  1478. // aPack = ElPackHomologue::- FromFile(aTestNameFile);
  1479. }
  1480. else
  1481. mAppli.InitPack(aPP.IdBD(),aPack,mName,aPP.NameCam());
  1482. CamStenope & aCS2 = mAppli.CalibFromName(aNameCal2,0)->CamInit();
  1483. // TTTT(aPack);
  1484. aPack = aCS1->F2toPtDirRayonL3(aPack,&aCS2);
  1485. cResMepRelCoplan aRMRC = aPack.MepRelCoplan(1.0,aPP.L2EstimPlan().Val());
  1486. cElemMepRelCoplan & aSP = aRMRC.RefBestSol();
  1487. // aM1 aM2 aM3 -> coordonnees monde, specifiees par l'utilisateur
  1488. // aC1 aC2 aC3 -> coordonnees monde
  1489. Pt3dr aM1,aM2,aM3;
  1490. Pt2dr aIm1,aIm2,aIm3;
  1491. Pt3dr aDirPl;
  1492. bool aModeDir = false;
  1493. if (aPP.MesurePIFRP().IsInit())
  1494. {
  1495. aM1 = aPP.Ap1().Ter();
  1496. aM2 = aPP.Ap2().Ter();
  1497. aM3 = aPP.Ap3().Ter();
  1498. aIm1 = aCS1->F2toPtDirRayonL3(aPP.Ap1().Im());
  1499. aIm2 = aCS1->F2toPtDirRayonL3(aPP.Ap2().Im());
  1500. aIm3 = aCS1->F2toPtDirRayonL3(aPP.Ap3().Im());
  1501. }
  1502. else if (aPP.DirPlan().IsInit())
  1503. {
  1504. aModeDir = true;
  1505. aDirPl = aPP.DirPlan().Val();
  1506. aM1 = Pt3dr(0,0,0);
  1507. Pt3dr aW = vunit(aPP.DirPlan().Val());
  1508. aM2 = OneDirOrtho(aW);
  1509. aM3 = aW ^ aM2;
  1510. // aIm1 = aCS1.Sz() /2.0;
  1511. // aIm2 = aIm1 + Pt2dr(1.0,0.0);
  1512. // aIm3 = aIm1 + Pt2dr(0.0,1.0);
  1513. aIm1 = Pt2dr(0,0);
  1514. aIm2 = aIm1 + Pt2dr(0.1,0.0);
  1515. aIm3 = aIm1 + Pt2dr(0.0,0.1);
  1516. }
  1517. Pt3dr aC1 = aSP.ImCam1(aIm1);
  1518. Pt3dr aC2 = aSP.ImCam1(aIm2);
  1519. Pt3dr aC3 = aSP.ImCam1(aIm3);
  1520. double aFMult=0;
  1521. if (aPP.DEuclidPlan().IsInit())
  1522. aFMult = aPP.DEuclidPlan().Val() / aSP.DistanceEuclid();
  1523. else
  1524. aFMult = euclid(aM2-aM1)/euclid(aC2-aC1);
  1525. aDZPl = aSP.DPlan() * aFMult;
  1526. aNZPl = aPP.OnZonePlane();
  1527. aC1 = aC1 * aFMult;
  1528. aC2 = aC2 * aFMult;
  1529. aC3 = aC3 * aFMult;
  1530. ElMatrix<double> aMatrM = RFrom3P(aM1,aM2,aM3);
  1531. ElMatrix<double> aMatrC = RFrom3P(aC1,aC2,aC3);
  1532. ElMatrix<double> aMatrC2M = aMatrM * gaussj(aMatrC);
  1533. Pt3dr aTr = aM1 - aMatrC2M * aC1;
  1534. if (aModeDir)
  1535. {
  1536. Pt3dr aC1 = aMatrC2M*Pt3dr(1,0,0);
  1537. Pt3dr aC2 = aMatrC2M*Pt3dr(0,1,0);
  1538. Pt3dr aC3 = aMatrC2M*Pt3dr(0,0,1);
  1539. double aScal = scal(aC3,aDirPl);
  1540. // std::cout << "CSAL = " << aScal << "\n";
  1541. // std::cout << aMatrC2M*Pt3dr(1,0,0) << aMatrC2M*Pt3dr(0,1,0) << aMatrC2M*Pt3dr(0,0,1) << "\n";
  1542. if (aScal <0)
  1543. {
  1544. aMatrC2M = ElMatrix<double>::Rotation(aC1,aC2*-1,aC3*-1);
  1545. }
  1546. // std::cout << aMatrC2M*Pt3dr(1,0,0) << aMatrC2M*Pt3dr(0,1,0) << aMatrC2M*Pt3dr(0,0,1) << "\n";
  1547. }
  1548. aRot = ElRotation3D(aTr,aMatrC2M,true);
  1549. anAltiSol = aM1.z;
  1550. aProfPose = euclid(aC1);
  1551. mAppli.AddPlan(aNZPl,aM1,aM2,aM3,false);
  1552. //Pt3dr uM =
  1553. }
  1554. else if(mPCI->PosFromBDAppuis().IsInit())
  1555. {
  1556. // DebugOFPA = (mName=="Im00523.png");
  1557. if (mAppli.ShowMes() || DebugOFPA)
  1558. std::cout << "InitByAppuis " << mName << "\n\n";
  1559. const cPosFromBDAppuis & aPFA = mPCI->PosFromBDAppuis().Val();
  1560. const std::string & anId = aPFA.Id();
  1561. std::list<Appar23> aL = mAppli.AppuisPghrm(anId,mName,mCalib);
  1562. tParamAFocal aNoPAF;
  1563. CamStenopeIdeale aCamId(true,1.0,Pt2dr(0.0,0.0),aNoPAF);
  1564. double aDMin;
  1565. Pt3dr aDirApprox;
  1566. Pt3dr * aPtrDirApprox=0;
  1567. if (aPFA.DirApprox().IsInit())
  1568. {
  1569. aDirApprox = aPFA.DirApprox().Val();
  1570. aPtrDirApprox = &aDirApprox;
  1571. }
  1572. // aRot = aCamId.CombinatoireOFPA(anAppli.Param().NbMaxAppuisInit().Val(),aL,&aDMin);
  1573. aRot = aCamId.RansacOFPA(true,aPFA.NbTestRansac(),aL,&aDMin,aPtrDirApprox);
  1574. /*
  1575. */
  1576. aRot = aRot.inv();
  1577. if (mAppli.ShowMes() || DebugOFPA)
  1578. std::cout << mName << " DIST-MIN = " << aDMin << aRot.ImAff(Pt3dr(0,0,0)) << " " << aRot.ImVect(Pt3dr(0,0,1)) << " OK " << aCPTOkOFA << " NotOk " << aCPTNotOkOFA << "\n\n";
  1579. // cObserv1Im<cTypeEnglob_Appuis> & anObs = mAppli.ObsAppuis(anId,mName);
  1580. // Pt3dr aCdg = anObs.mBarryTer;
  1581. Pt3dr aCdg = BarryImTer(aL).pter;
  1582. anAltiSol = aCdg.z;
  1583. Pt3dr aDirVisee = aRot.ImVect(Pt3dr(0,0,1));
  1584. aProfPose = scal(aDirVisee,aCdg-aRot.ImAff(Pt3dr(0,0,0)));
  1585. if (DebugOFPA) getchar();
  1586. DebugOFPA = false;
  1587. }
  1588. else if (mPCI->PoseFromLiaisons().IsInit())
  1589. {
  1590. cResolvAmbiBase * aRAB=0;
  1591. const std::vector<cLiaisonsInit> & aVL = mPCI->PoseFromLiaisons().Val().LiaisonsInit();
  1592. // bool aNormIsFixed = false;
  1593. int aNbL = (int)aVL.size();
  1594. ElPackHomologue aPack0;
  1595. ElRotation3D anOrAbs0 (Pt3dr(0,0,0),0,0,0);
  1596. Pt3dr aP0Pl,aP1Pl,aP2Pl;
  1597. double aMultPl=1.0;
  1598. std::vector<cPoseCam *> aVPC;
  1599. //cPoseCam * aCam00 = 0;
  1600. if (isMST)
  1601. {
  1602. if (PoseInitMST1()==0)
  1603. {
  1604. std::cout << "For : " << mName << "\n";
  1605. ELISE_ASSERT(false,"MST1 Incoh");
  1606. }
  1607. aNbL = PoseInitMST2() ? 2 : 1;
  1608. // std::cout << "isMST " << aNbL << " " << mName << "\n";
  1609. if (aVL[0].OnZonePlane().IsInit())
  1610. aNbL=1;
  1611. }
  1612. bool aRPure = false;
  1613. const cLiaisonsInit * pLI0 = 0;
  1614. for (int aK=0 ; aK<aNbL ; aK++)
  1615. {
  1616. const cLiaisonsInit & aLI = aVL[isMST?0:aK];
  1617. if (aK==0)
  1618. {
  1619. pLI0 = &aLI;
  1620. theLiasInit = pLI0;
  1621. }
  1622. std::string aName2;
  1623. cPoseCam * aCam2 = 0;
  1624. if (isMST)
  1625. {
  1626. aCam2 = (aK==0) ? PoseInitMST1() : PoseInitMST2();
  1627. aName2 = aCam2->Name();
  1628. ELISE_ASSERT
  1629. (
  1630. aLI.IdBD()==mAppli.SymbPack0(),
  1631. "MST must be used with first Pack "
  1632. );
  1633. }
  1634. else
  1635. {
  1636. aName2 = CalNameFromL(aLI);
  1637. aCam2 = mAppli.PoseFromName(aName2);
  1638. }
  1639. // ElSetMax(mProf2Init,1+aCam2->mProf2Init);
  1640. if (! aCam2->RotIsInit())
  1641. {
  1642. std::cout << "For " << mName << "/" << aName2;
  1643. ELISE_ASSERT(false,"Incohernce : Init based on Cam not init");
  1644. }
  1645. aVPC.push_back(aCam2);
  1646. CamStenope & aCS2 = aCam2->Calib()->CamInit();
  1647. bool aBaseFixee = false;
  1648. double aLBase=1.0;
  1649. if (aLI.LongueurBase().IsInit() && ((!isMST) || (aNbL==1)))
  1650. {
  1651. // Ce serait incoherent puisque les liaisons multiples servent a
  1652. // fixer la longueur de la base
  1653. ELISE_ASSERT(aNbL==1,"Ne peut fixe la longueur de base avec plusieurs liaisons");
  1654. aBaseFixee = true;
  1655. aLBase = aLI.LongueurBase().Val();
  1656. }
  1657. // if (aK==0) aCam0 = aCam;
  1658. // ElPackHomologue aPack = anAppli.PackPhgrmFromCple(&aCS1,aNamePose,&aCS2,aName2);
  1659. ElPackHomologue aPack;
  1660. mAppli.InitPackPhgrm(aLI.IdBD(),aPack,mName,aCS1,aName2,&aCS2);
  1661. double aProfC = aLI.ProfSceneCouple().ValWithDef(aProfI);
  1662. if (aK==0)
  1663. {
  1664. ElRotation3D aOrRel0(Pt3dr(0,0,0),0,0,0);
  1665. aPack0 = aPack;
  1666. anOrAbs0 = aCam2->CurRot() ;
  1667. if (aLI.InitOrientPure().Val())
  1668. {
  1669. ELISE_ASSERT(aNbL==1,"Multiple Liaison with InitOrientPure");
  1670. ElMatrix<REAL> aMat = aPack.MepRelCocentrique(aLI.NbTestRansacOrPure().Val(),aLI.NbPtsRansacOrPure().Val());
  1671. aOrRel0 = ElRotation3D(Pt3dr(0,0,0),aMat,true);
  1672. aRPure = true;
  1673. anAltiSol = aCam2->AltiSol();
  1674. aProfPose = aCam2->Profondeur();
  1675. }
  1676. else if (aLI.OnZonePlane().IsInit())
  1677. {
  1678. aNZPl = aLI.OnZonePlane().Val();
  1679. cResMepRelCoplan aRMRC = aPack.MepRelCoplan(aLBase,aLI.L2EstimPlan().Val());
  1680. cElemMepRelCoplan & aSP = aRMRC.RefBestSol();
  1681. aP0Pl = aSP.P0();
  1682. aP1Pl = aSP.P1();
  1683. aP2Pl = aSP.P2();
  1684. aOrRel0 = aSP.Rot();
  1685. if (aNbL==1)
  1686. {
  1687. double aMul=0;
  1688. if (DicBoolFind(aCam2->mDZP,aNZPl))
  1689. {
  1690. ELISE_ASSERT(!aBaseFixee,"Ne peut fixe la longueur de base avec liaison plane");
  1691. aMul = aCam2->mDZP[aNZPl] /aSP.DPlan2();
  1692. }
  1693. else
  1694. {
  1695. if (aBaseFixee)
  1696. aMul = 1;
  1697. else
  1698. {
  1699. aMul = aProfC / aPack.Profondeur(aOrRel0);
  1700. }
  1701. }
  1702. aOrRel0.tr() = aOrRel0.tr() * aMul;
  1703. aDZPl = aSP.DPlan() * aMul;
  1704. aCam2->mDZP[aNZPl] = aSP.DPlan2() * aMul;
  1705. aMultPl = aMul;
  1706. }
  1707. else
  1708. {
  1709. // Sinon il faudra, une fois connu le multiplicateur donne
  1710. // par les autres liaisons mettre a jour le plan
  1711. aDZPl = aSP.DPlan() ;
  1712. // Et eventuellement initialiser Plan2
  1713. if (! DicBoolFind(aCam2->mDZP,aNZPl))
  1714. {
  1715. aDZPl2 = aSP.DPlan2();
  1716. aCam2PL = aCam2;
  1717. }
  1718. }
  1719. }
  1720. else
  1721. {
  1722. if ((aNbL<2) && (NbPosOfInit(mAppli.NbRotInit()) >=2))
  1723. {
  1724. ELISE_ASSERT
  1725. (
  1726. mAppli.Param().AutoriseToujoursUneSeuleLiaison().Val(),
  1727. "Une seule liaison pour initialiser la pose au dela de 3"
  1728. );
  1729. }
  1730. bool L2 = aPack.size() > mAppli.Param().SeuilL1EstimMatrEss().Val();
  1731. double aDGen;
  1732. /*
  1733. std::cout << "TEST MEPS STD " << mName << " L2 " << L2
  1734. << " " << mAppli.Param().SeuilL1EstimMatrEss().Val()<< "\n";
  1735. */
  1736. aOrRel0 = aLI.TestSolPlane().Val() ?
  1737. aPack.MepRelGenSsOpt(aLBase,L2,aDGen) :
  1738. aPack.MepRelPhysStd(aLBase,L2) ;
  1739. if (aNbL==1 && (! aBaseFixee))
  1740. {
  1741. aPack.SetProfondeur(aOrRel0,aProfC);
  1742. }
  1743. }
  1744. aOrRel0 = aCam2->CurRot() * aOrRel0;
  1745. aRot = aOrRel0;
  1746. aRAB = new cResolvAmbiBase(aCam2->CurRot(),aOrRel0);
  1747. }
  1748. else
  1749. {
  1750. ELISE_ASSERT
  1751. (
  1752. (!aLI.OnZonePlane().IsInit()) || isMST,
  1753. "Seule la premiere liaison peut etre plane"
  1754. );
  1755. // ELISE_ASSERT(false,"Do not handle multi Liaison");
  1756. aRAB->AddHom(aPack,aCam2->CurRot());
  1757. }
  1758. }
  1759. if (aNbL > 1)
  1760. {
  1761. aRot = aRAB->SolOrient(aLambdaRot);
  1762. aMultPl= aLambdaRot;
  1763. }
  1764. delete aRAB;
  1765. // Calcul de l'alti et de la prof
  1766. if (aRPure)
  1767. {
  1768. }
  1769. else
  1770. {
  1771. CamStenopeIdeale aC1 = CamStenopeIdeale::CameraId(true,aRot.inv());
  1772. CamStenopeIdeale aC2 = CamStenopeIdeale::CameraId(true,anOrAbs0.inv());
  1773. double aD;
  1774. Pt3dr aCdg = aC1.CdgPseudoInter(aPack0,aC2,aD);
  1775. anAltiSol = aCdg.z;
  1776. aProfPose = aC1.ProfondeurDeChamps(aCdg) ;
  1777. for (int aK=0 ; aK<int(aVPC.size()) ; aK++)
  1778. {
  1779. CamStenopeIdeale aCK = CamStenopeIdeale::CameraId(true,aVPC[aK]->CurRot().inv());
  1780. double aPrK = aCK.ProfondeurDeChamps(aCdg) ;
  1781. aVPC[aK]->TenteInitAltiProf
  1782. (
  1783. (aK==0) ? 1 : 0,
  1784. aCdg.z,
  1785. aPrK
  1786. );
  1787. }
  1788. }
  1789. int aNbRAp = pLI0->NbRansacSolAppui().Val();
  1790. if (aNbRAp>0)
  1791. {
  1792. cObsLiaisonMultiple * anOLM = mAppli.PackMulOfIndAndNale(pLI0->IdBD(),mName);
  1793. anOLM->TestMEPAppuis(mAppli.ZuUseInInit(),aRot,aNbRAp,*pLI0);
  1794. }
  1795. if (aNZPl!="")
  1796. {
  1797. mAppli.AddPlan
  1798. (
  1799. aNZPl,
  1800. aRot.ImAff(aP0Pl*aMultPl),
  1801. aRot.ImAff(aP1Pl*aMultPl),
  1802. aRot.ImAff(aP2Pl*aMultPl),
  1803. true
  1804. );
  1805. }
  1806. }
  1807. else
  1808. {
  1809. ELISE_ASSERT(false,"cPoseCam::Alloc");
  1810. }
  1811. {
  1812. if (mSRI && MPD_MM())
  1813. {
  1814. #if (0)
  1815. ElRotation3D aR1 = mSRI->mCMere->CurRot() ; // R1 to M
  1816. ElRotation3D aL1Bis = aR1 * mSRI->mR0m1L0;
  1817. aRot = aL1Bis;
  1818. std::string aNameOri = "MPD-CmpPolygBlinis";
  1819. CamStenope * aCamR1 = mAppli.ICNM()->StdCamStenOfNames(mSRI->mCMere->Name(),aNameOri);
  1820. CamStenope * aCamL1 = mAppli.ICNM()->StdCamStenOfNames(Name(),aNameOri);
  1821. ElRotation3D aRefRotL1 = aCamL1->Orient().inv();
  1822. ElRotation3D aRefRotR1 = aCamR1->Orient().inv();
  1823. /*
  1824. ElRotation3D aL1Bis = aRotR1 * mSRI->mR0m1L0;
  1825. ElRotation3D aDif = aRotL1 * aL1Bis.inv();
  1826. ElMatrix<double> anId(3,true);
  1827. if (anId.L2(aDif.Mat()) > -1)
  1828. {
  1829. std::cout << "NAME= " << mName << " " << euclid(aRotL1.tr()-aL1Bis.tr()) << " " << anId.L2(aDif.Mat()) << "\n";
  1830. getchar();
  1831. }
  1832. */
  1833. ElRotation3D aL1 = aRot;
  1834. ElRotation3D aR1 = mSRI->mCMere->CurRot() ; // R1 to M
  1835. ElRotation3D aL1Bis = aR1 * mSRI->mR0m1L0;
  1836. ElRotation3D aPassL1 = aL1 * aRefRotL1.inv() ; // L1 to M
  1837. ElRotation3D aPassR1 = aR1 * aRefRotR1.inv() ; // L1 to M
  1838. static ElRotation3D FirsrtPass = aPassR1;
  1839. // ElRotation3D aDif = aL1.inv() * aRot;
  1840. ElMatrix<double> anId(3,true);
  1841. ElRotation3D aDif = aL1 * aL1Bis.inv();
  1842. if (1) // anId.L2(aDif.Mat()) > 0.01)
  1843. {
  1844. std::cout << "NAME= " << mName << " " << mRotIsInit
  1845. << " mere: " << mSRI->mCMere->mName << " " << mSRI->mCMere->mRotIsInit << "\n";
  1846. std::cout << " TR:" << euclid(aL1.tr()-aL1Bis.tr())
  1847. << " MAT:" << anId.L2(aDif.Mat())
  1848. << " PassRL " << DistanceMatr(aPassL1,aPassR1)
  1849. << " PassFirst-R " << DistanceMatr(FirsrtPass,aPassR1)
  1850. << " PassFirst-L " << DistanceMatr(FirsrtPass,aPassL1)
  1851. << "\n";
  1852. // getchar();
  1853. }
  1854. aRot = aL1Bis;
  1855. /*
  1856. else
  1857. aRot = aL1;
  1858. */
  1859. #endif
  1860. }
  1861. }
  1862. //GUIMBAL
  1863. if (isForISec && (! aRot.IsTrueRot()))
  1864. {
  1865. CamStenope* aCS = (mCalib->PIF().DupCurPIF());
  1866. aCS->UnNormalize();
  1867. aCS->SetProfondeur(aProfPose);
  1868. aCS->SetAltiSol(anAltiSol);
  1869. aCS->SetOrientation(aRot.inv());
  1870. aCS->SetIdentCam(mName);
  1871. std::vector<ElCamera *> aVCam;
  1872. aVCam.push_back(aCS);
  1873. cTransfo3DIdent aTransfo;
  1874. ElCamera::ChangeSys(aVCam,aTransfo,true,true);
  1875. ElRotation3D aRMod = aCS->Orient();
  1876. aRot = aRMod.inv();
  1877. // ShowMatr("Entree",aRot.Mat());
  1878. // ShowMatr("Sortie",aRMod.inv().Mat());
  1879. // getchar();
  1880. }
  1881. mRotURP = aRot;
  1882. mUseRappelPose = mAppli.PtrRP() && mAppli.PtrRP()->PatternApply()->Match(mName);
  1883. if (mUseRappelPose)
  1884. {
  1885. CamStenope * aCS = mAppli.ICNM()->StdCamStenOfNames(mName,mAppli.PtrRP()->IdOrient());
  1886. mRotURP = aCS->Orient().inv();
  1887. }
  1888. double aLMG = mAppli.Param().LimModeGL().Val();
  1889. double aGVal = GuimbalAnalyse(aRot,false);
  1890. if (((aLMG>0) && (aGVal<aLMG)) || mUseRappelPose)
  1891. {
  1892. std::cout << "GUIMBAL-INIT " << mName << " " << aGVal<< "\n";
  1893. mCF->SetGL(true,mRotURP);
  1894. }
  1895. else
  1896. {
  1897. std::cout << "NO GUIMBAL " << mName << " " << aGVal<< "\n";
  1898. }
  1899. mCF->SetCurRot(aRot,mRotURP);
  1900. if (isAPC)
  1901. {
  1902. CamStenope* aCS = (mCalib->PIF().DupCurPIF());
  1903. aCS->SetOrientation(aRot.inv());
  1904. SetCamNonOrtho(aCS);
  1905. ELISE_ASSERT(initFromBD,"IsAperiCloud requires init from BD");
  1906. }
  1907. if (aNZPl!="")
  1908. {
  1909. mDZP[aNZPl] = aDZPl * aLambdaRot;
  1910. if (aCam2PL)
  1911. {
  1912. if (! DicBoolFind(aCam2PL->mDZP,aNZPl))
  1913. aCam2PL->mDZP[aNZPl] = aDZPl2 * aLambdaRot;
  1914. }
  1915. }
  1916. TenteInitAltiProf(2,anAltiSol,aProfPose);
  1917. mRotIsInit = true;
  1918. /*
  1919. {
  1920. ElRotation3D aR = CurRot() ;
  1921. const CamStenope * aCS = mCF->CameraCourante() ;
  1922. std::cout << " " << mName << " " << aR.tr() << "\n";
  1923. std::cout << " " << aCS-> R3toF2(Pt3dr(0,0,10)) << " " << aCS->F2AndZtoR3(Pt2dr(1000,1000),6) << "\n";
  1924. getchar();
  1925. }
  1926. */
  1927. if (mCompAOI)
  1928. {
  1929. AffineRot();
  1930. }
  1931. mAppli.AddRotInit();
  1932. mCF->ResiduM2C() = mOrIntM2C;
  1933. Trace();
  1934. if (theLiasInit)
  1935. {
  1936. mAppli.CheckInit(theLiasInit,this);
  1937. }
  1938. }
  1939. void cPoseCam::UseRappelOnPose() const
  1940. {
  1941. if (! mUseRappelPose) return;
  1942. double aPdsC = 1/ElSquare(mAppli.PtrRP()->SigmaC());
  1943. Pt3dr aPtPdsC(aPdsC,aPdsC,aPdsC);
  1944. double aPdsR = 1/ElSquare(mAppli.PtrRP()->SigmaR());
  1945. Pt3dr aPtPdsR (aPdsR,aPdsR,aPdsR);
  1946. mRF->AddRappOnRot(mRotURP,aPtPdsC,aPtPdsR);
  1947. // std::cout << "NAME RAPPELE ON POSE =" << mName << "\n";
  1948. }
  1949. void cPoseCam::AffineRot()
  1950. {
  1951. for (int aK=0 ; aK<int(mCompAOI->mPats.size()) ; aK++)
  1952. {
  1953. if ( (mCompAOI->mPats[aK]->Match(mName))
  1954. || (mCompAOI->mPats[aK]->Match(ToString(mCpt)))
  1955. )
  1956. {
  1957. vector<cPoseCam *> aVC;
  1958. aVC.push_back(this);
  1959. vector<eTypeContraintePoseCamera> aVT;
  1960. aVT.push_back(mCompAOI->mCstr[aK]);
  1961. std::cout << " Opt " << mName << " :: " << mCpt << "\n";
  1962. mAppli.PowelOptimize(mCompAOI->mParam,aVC,aVT);
  1963. return;
  1964. }
  1965. }
  1966. }
  1967. void cPoseCam::SetFigee()
  1968. {
  1969. mRF->SetTolAng(-1);
  1970. mRF->SetTolCentre(-1);
  1971. mRF->SetModeRot(cNameSpaceEqF::eRotFigee);
  1972. }
  1973. void cPoseCam::SetDeFigee()
  1974. {
  1975. if (mLastCP)
  1976. SetContrainte(*mLastCP);
  1977. else
  1978. mRF->SetModeRot(cNameSpaceEqF::eRotLibre);
  1979. }
  1980. void cPoseCam::SetContrainte(const cContraintesPoses & aCP)
  1981. {
  1982. mLastCP = & aCP;
  1983. switch(aCP.Val())
  1984. {
  1985. case ePoseLibre :
  1986. cElWarning::ToleranceSurPoseLibre.AddWarn("",__LINE__,__FILE__);
  1987. /*
  1988. ELISE_ASSERT
  1989. (
  1990. (aCP.TolAng().Val()<=0)&&(aCP.TolCoord().Val()<=0),
  1991. "Tolerance inutile avec ePoseLibre"
  1992. );
  1993. */
  1994. mRF->SetModeRot(cNameSpaceEqF::eRotLibre);
  1995. break;
  1996. case ePoseFigee :
  1997. mRF->SetTolAng(aCP.TolAng().Val());
  1998. mRF->SetTolCentre(aCP.TolCoord().Val());
  1999. mRF->SetModeRot(cNameSpaceEqF::eRotFigee);
  2000. break;
  2001. case eCentreFige :
  2002. ELISE_ASSERT
  2003. (
  2004. (aCP.TolAng().Val()<=0),
  2005. "Tolerance angulaire avec eCentreFige"
  2006. );
  2007. mRF->SetTolCentre(aCP.TolCoord().Val());
  2008. mRF->SetModeRot(cNameSpaceEqF::eRotCOptFige);
  2009. break;
  2010. case eAnglesFiges :
  2011. ELISE_ASSERT
  2012. (
  2013. (aCP.TolCoord().Val()<=0),
  2014. "Tolerance angulaire avec eCentreFige"
  2015. );
  2016. mRF->SetTolAng(aCP.TolAng().Val());
  2017. mRF->SetModeRot(cNameSpaceEqF::eRotAngleFige);
  2018. break;
  2019. case ePoseBaseNormee :
  2020. case ePoseVraieBaseNormee :
  2021. ELISE_ASSERT
  2022. (
  2023. aCP.PoseRattachement().IsInit(),
  2024. "Rattachement non initialise !"
  2025. );
  2026. ELISE_ASSERT
  2027. (
  2028. (aCP.TolAng().Val()<=0),
  2029. "Tolerance angle inutile avec ePoseBaseNormee"
  2030. );
  2031. mRF->SetTolCentre(aCP.TolCoord().Val());
  2032. if (aCP.Val()==ePoseVraieBaseNormee)
  2033. {
  2034. SetRattach(aCP.PoseRattachement().Val());
  2035. mRF->SetModeRot(cNameSpaceEqF::eRotBaseU);
  2036. }
  2037. else
  2038. {
  2039. cPoseCam * aPR = mAppli.PoseFromName(aCP.PoseRattachement().Val());
  2040. mRF->SetRotPseudoBaseU(aPR->mRF);
  2041. mRF->SetModeRot(cNameSpaceEqF::eRotPseudoBaseU);
  2042. }
  2043. break;
  2044. }
  2045. }
  2046. // Gestion image
  2047. void cPoseCam::InitIm()
  2048. {
  2049. mFirstBoxImSet = false;
  2050. mImageLoaded = false;
  2051. }
  2052. bool cPoseCam::PtForIm(const Pt3dr & aPTer,const Pt2di & aRab,bool Add)
  2053. {
  2054. const CamStenope * aCS = CurCam() ;
  2055. Pt2dr aPIm = aCS->R3toF2(aPTer);
  2056. Box2di aCurBIm(round_down(aPIm)-aRab,round_up(aPIm)+aRab);
  2057. Box2di aFulBox(Pt2di(0,0),aCS->Sz());
  2058. if (! aCurBIm.include_in(aFulBox))
  2059. return false;
  2060. if (Add)
  2061. {
  2062. ELISE_ASSERT(!mImageLoaded,"cPoseCam::PtForIm : Im Loaded in Add");
  2063. if (mFirstBoxImSet)
  2064. {
  2065. mBoxIm = Sup(mBoxIm,aCurBIm);
  2066. }
  2067. else
  2068. {
  2069. mBoxIm = aCurBIm;
  2070. mFirstBoxImSet = true;
  2071. }
  2072. }
  2073. return true;
  2074. }
  2075. bool cPoseCam::ImageLoaded() const
  2076. {
  2077. return mImageLoaded;
  2078. }
  2079. void cPoseCam::AssertImL() const
  2080. {
  2081. if (!mImageLoaded)
  2082. {
  2083. std::cout << "For cam=" << mName << "\n";
  2084. ELISE_ASSERT(false,"Image not Loaded");
  2085. }
  2086. }
  2087. const Box2di & cPoseCam::BoxIm()
  2088. {
  2089. AssertImL();
  2090. return mBoxIm;
  2091. }
  2092. Im2D_U_INT2 cPoseCam::Im()
  2093. {
  2094. AssertImL();
  2095. return mIm;
  2096. }
  2097. void cPoseCam::CloseAndLoadIm(const Pt2di & aRab)
  2098. {
  2099. if (! mFirstBoxImSet)
  2100. return;
  2101. mImageLoaded = true;
  2102. {
  2103. Pt2di aP0 = Sup(mBoxIm._p0-aRab,Pt2di(0,0));
  2104. Pt2di aP1 = Inf(mBoxIm._p1+aRab,CurCam()->Sz());
  2105. mBoxIm = Box2di(aP0,aP1);
  2106. }
  2107. Pt2di aSz = mBoxIm.sz();
  2108. mIm.Resize(aSz);
  2109. mTIm = TIm2D<U_INT2,INT>(mIm);
  2110. Tiff_Im aTF = Tiff_Im::StdConvGen(mAppli.DC()+mName,1,true,false);
  2111. ELISE_COPY
  2112. (
  2113. mIm.all_pts(),
  2114. trans(aTF.in_proj(),mBoxIm._p0),
  2115. mIm.out()
  2116. );
  2117. }
  2118. // ACCESSEURS
  2119. cCalibCam * cPoseCam::Calib() const { return mCalib;}
  2120. cCameraFormelle * cPoseCam::CamF() {return mCF;}
  2121. double cPoseCam::AltiSol() const {return mAltiSol;}
  2122. double cPoseCam::Profondeur() const {return mProfondeur;}
  2123. int cPoseCam::NumInit() const {return mNumInit;}
  2124. /*
  2125. bool & cPoseCam::MMSelected() { return mMMSelected;}
  2126. double & cPoseCam::MMGain() { return mMMGain;}
  2127. double & cPoseCam::MMAngle() { return mMMAngle;}
  2128. Pt3dr & cPoseCam::MMDir() { return mMMDir;}
  2129. Pt2dr & cPoseCam::MMDir2D() { return mMMDir2D;}
  2130. std::vector<double> &cPoseCam::MMGainTeta() {return mMMGainTeta;}
  2131. double & cPoseCam::MMNbPts() { return mMMNbPts;}
  2132. double & cPoseCam::MMGainAng() { return mMMGainAng;}
  2133. */
  2134. /*********************************************************/
  2135. /* */
  2136. /* cAppliApero */
  2137. /* */
  2138. /*********************************************************/
  2139. void cAppliApero::LoadImageForPtsMul
  2140. (
  2141. Pt2di aRabIncl,
  2142. Pt2di aRabFinal,
  2143. const std::list<cOnePtsMult *> & aLMul
  2144. )
  2145. {
  2146. for (int aK=0; aK<int(mVecPose.size()) ; aK++)
  2147. {
  2148. mVecPose[aK]->InitIm();
  2149. }
  2150. for
  2151. (
  2152. std::list<cOnePtsMult *>::const_iterator itPM=aLMul.begin();
  2153. itPM!=aLMul.end();
  2154. itPM++
  2155. )
  2156. {
  2157. std::vector<double> aVPds;
  2158. const cResiduP3Inc * aRes = (*itPM)->ComputeInter(1.0,aVPds);
  2159. if (aRes)
  2160. {
  2161. for (int aK=0; aK<int(mVecPose.size()) ; aK++)
  2162. {
  2163. mVecPose[aK]->PtForIm(aRes->mPTer,aRabIncl,true);
  2164. }
  2165. }
  2166. }
  2167. mVecLoadedPose.clear();
  2168. for (int aK=0; aK<int(mVecPose.size()) ; aK++)
  2169. {
  2170. mVecPose[aK]->CloseAndLoadIm(aRabFinal);
  2171. if (mVecPose[aK]->ImageLoaded())
  2172. mVecLoadedPose.push_back(mVecPose[aK]);
  2173. }
  2174. }
  2175. const std::vector<cPoseCam*> & cAppliApero::VecLoadedPose()
  2176. {
  2177. return mVecLoadedPose;
  2178. }
  2179. std::vector<cPoseCam*> cAppliApero::VecLoadedPose(const cOnePtsMult & aPM,int aSz)
  2180. {
  2181. std::vector<cPoseCam*> aRes;
  2182. std::vector<cPoseCam*> aRes2;
  2183. std::vector<double> aVPds;
  2184. const cResiduP3Inc * aResidu = aPM.ComputeInter(1.0,aVPds);
  2185. Pt2di aPRab(aSz,aSz);
  2186. if (aResidu)
  2187. {
  2188. for (int aKp=0 ; aKp<int(mVecLoadedPose.size()) ; aKp++)
  2189. {
  2190. if (mVecLoadedPose[aKp]->PtForIm(aResidu->mPTer,aPRab,false))
  2191. {
  2192. if (mVecLoadedPose[aKp]==aPM.GenPose0()->DownCastPoseCamNN())
  2193. {
  2194. aRes.push_back(mVecLoadedPose[aKp]);
  2195. }
  2196. else
  2197. {
  2198. aRes2.push_back(mVecLoadedPose[aKp]);
  2199. }
  2200. }
  2201. }
  2202. std::cout << "NB ------- " << aRes.size() << " ## " << aRes2.size() << "\n";
  2203. if ((int(aRes.size())==1) && (int(aRes2.size())>= 1))
  2204. {
  2205. for (int aKp=0 ; aKp<int(aRes2.size()) ; aKp++)
  2206. {
  2207. aRes.push_back(aRes2[aKp]);
  2208. }
  2209. }
  2210. else
  2211. {
  2212. aRes.clear();
  2213. }
  2214. }
  2215. return aRes;
  2216. }
  2217. bool cPoseCam::DoAddObsCentre(const cObsCentrePDV & anObs)
  2218. {
  2219. if (! mHasObsOnCentre)
  2220. return false;
  2221. if (
  2222. (anObs.PatternApply().IsInit())
  2223. && (!anObs.PatternApply().Val()->Match(mName))
  2224. )
  2225. return false;
  2226. return true;
  2227. }
  2228. Pt3dr cPoseCam::CurCentre() const
  2229. {
  2230. return CurRot().ImAff(Pt3dr(0,0,0));
  2231. }
  2232. Pt3dr cPoseCam::CurCentreOfPt(const Pt2dr & ) const
  2233. {
  2234. return CurCentre();
  2235. }
  2236. Pt3dr cPoseCam::AddObsCentre
  2237. (
  2238. const cObsCentrePDV & anObs,
  2239. const cPonderateur & aPondPlani,
  2240. const cPonderateur & aPondAlti,
  2241. cStatObs & aSO
  2242. )
  2243. {
  2244. // cObsCentre aRes;
  2245. // mIncOnC
  2246. mLastItereHasUsedObsOnCentre = true;
  2247. ELISE_ASSERT(DoAddObsCentre(anObs),"cPoseCam::AddObsCentre");
  2248. if (mEqOffsetGPS)
  2249. {
  2250. Pt3dr aResidu = mEqOffsetGPS->Residu(mObsCentre.mCentre);
  2251. double aNormLA = euclid(mEqOffsetGPS->Base()->ValueBase());
  2252. std::cout << "Lever Arm, Cam: " << mName << " Residual " << aResidu << " LA: " << mEqOffsetGPS->Base()->ValueBase() << ", " << aNormLA << "\n";
  2253. double aPdsPX = aPondPlani.PdsOfError(euclid(Pt2dr(aResidu.x,aResidu.y))/sqrt(2.));
  2254. double aPdsPY = aPdsPX;
  2255. double aPdsZ = aPondAlti.PdsOfError(ElAbs(aResidu.z));
  2256. //std::cout << " cPoseCam::AddObsCentre " << mObsCentre.mIncOnC << " " << aPdsP << " " << aPdsZ << "\n";
  2257. Pt3dr aPInc = mObsCentre.mIncertOnC;
  2258. // Si il y a une incertitude
  2259. if (aPInc.x >0)
  2260. {
  2261. aPdsPX *= ElSquare(1/aPInc.x);
  2262. }
  2263. if (aPInc.y >0)
  2264. {
  2265. aPdsPY *= ElSquare(1/aPInc.y);
  2266. }
  2267. if (aPInc.z >0)
  2268. {
  2269. aPdsZ *= ElSquare(1/aPInc.z);
  2270. }
  2271. /*
  2272. if (1)
  2273. {
  2274. cBaseGPS * aBG = mEqOffsetGPS->Base();
  2275. Pt3d<Fonc_Num> BaseInc();
  2276. }
  2277. */
  2278. return mEqOffsetGPS->AddObs(mObsCentre.mCentre,Pt3dr(aPdsPX,aPdsPY,aPdsZ));
  2279. }
  2280. Pt3dr aC0 = CurRot().ImAff(Pt3dr(0,0,0));
  2281. Pt3dr aDif = aC0 - mObsCentre.mCentre;
  2282. Pt2dr aDifPlani(aDif.x,aDif.y);
  2283. double aPdsP = aPondPlani.PdsOfError(euclid(aDifPlani)/sqrt(2.));
  2284. double aPdsZ = aPondAlti.PdsOfError(ElAbs(aDif.z));
  2285. Pt3dr aPPds = aSO.AddEq() ? Pt3dr(aPdsP,aPdsP,aPdsZ) : Pt3dr(0,0,0) ;
  2286. Pt3dr aRAC = mRF->AddRappOnCentre(mObsCentre.mCentre,aPPds ,false);
  2287. double aSEP = aPdsP*(ElSquare(aRAC.x)+ElSquare(aRAC.y))+aPdsZ*ElSquare(aRAC.z);
  2288. // std::cout << "========= SEP " << aSEP << "\n";
  2289. aSO.AddSEP(aSEP);
  2290. mAppli.AddResiducentre(aDif);
  2291. if (aPondPlani.PPM().Show().Val() >=eNSM_Indiv)
  2292. {
  2293. std::cout << mName << " DeltaC " << euclid(aDif) << " " << aDif << "\n";
  2294. }
  2295. if (anObs.ShowTestVitesse().Val())
  2296. {
  2297. // Montre le linkage GPS
  2298. {
  2299. ElRotation3D aR = CurRot() ;
  2300. mAppli.COUT() << aR.teta01() << " ";
  2301. if (mPrec != mNext)
  2302. {
  2303. Pt3dr aVC = mNext->CurCentre()- mPrec->CurCentre() ;
  2304. double aDT = mNext->mTime - mPrec->mTime;
  2305. Pt2dr aV2C(aVC.x,aVC.y);
  2306. Pt3dr aVG = mNext->mObsCentre.mCentre - mPrec->mObsCentre.mCentre ;
  2307. Pt3dr aVitG = aVG / aDT;
  2308. Pt3dr aGC = CurCentre() -mObsCentre.mCentre;
  2309. double aRetard = scal(aGC,aVitG) /scal(aVitG,aVitG);
  2310. mAppli.AddRetard(aRetard);
  2311. Pt2dr aV2G(aVG.x,aVG.y);
  2312. mAppli.COUT() << " Retard " << aRetard
  2313. << " VIt " << euclid(aVitG)
  2314. << " Traj " << (aR.teta01() - atan2(aV2C.y,aV2C.x) -PI/2) << " "
  2315. << " TGps " << (aR.teta01() - atan2(aV2G.y,aV2G.x) -PI/2) << " ";
  2316. }
  2317. mAppli.COUT() << "\n";
  2318. }
  2319. /*
  2320. mAppli.COUT().precision(10);
  2321. mAppli.COUT() << "RESIDU CENTRE " << aDif << " pour " << mName
  2322. << " AERO=" << aC0 << " GPS=" << mObsCentre<< "\n";
  2323. */
  2324. }
  2325. return aDif;
  2326. }
  2327. /************************************************************/
  2328. /* */
  2329. /* cClassEquivPose */
  2330. /* cRelEquivPose */
  2331. /* */
  2332. /************************************************************/
  2333. // ======= cClassEquivPose ====
  2334. cClassEquivPose::cClassEquivPose(const std::string & anId) :
  2335. mId (anId)
  2336. {
  2337. }
  2338. void cClassEquivPose::AddAPose(cGenPoseCam * aPC)
  2339. {
  2340. if (BoolFind(mGrp,aPC))
  2341. {
  2342. std::cout << "For Pose : " << aPC->Name() << "\n";
  2343. ELISE_ASSERT(false,"cClassEquivPose::AddAPose multiple name");
  2344. }
  2345. mGrp.push_back(aPC);
  2346. }
  2347. const std::vector<cGenPoseCam *> & cClassEquivPose::Grp() const
  2348. {
  2349. return mGrp;
  2350. }
  2351. const std::string & cClassEquivPose::Id() const
  2352. {
  2353. return mId;
  2354. }
  2355. // ======= cRelEquivPose ====
  2356. /*
  2357. cRelEquivPose::cRelEquivPose(int aNum) :
  2358. mNum (aNum)
  2359. {
  2360. }
  2361. */
  2362. cRelEquivPose::cRelEquivPose()
  2363. {
  2364. }
  2365. cClassEquivPose * cRelEquivPose::AddAPose(cPoseCam * aPC,const std::string & aName)
  2366. {
  2367. cClassEquivPose * & aCEP = mMap[aName];
  2368. if (aCEP==0)
  2369. aCEP = new cClassEquivPose(aName);
  2370. aCEP->AddAPose(aPC);
  2371. mPos2C[aPC->Name()] = aCEP;
  2372. return aCEP;
  2373. }
  2374. cClassEquivPose & cRelEquivPose::ClassOfPose(const cGenPoseCam & aPC)
  2375. {
  2376. cClassEquivPose * aCEP = mPos2C[aPC.Name()];
  2377. if (aCEP==0)
  2378. {
  2379. std::cout << "For Pose " << aPC.Name() << "\n";
  2380. ELISE_ASSERT(false,"Can get Class in cRelEquivPose::ClassOfPose");
  2381. }
  2382. return *aCEP;
  2383. }
  2384. bool cRelEquivPose::SameClass(const cGenPoseCam & aPC1,const cGenPoseCam & aPC2)
  2385. {
  2386. return ClassOfPose(aPC1).Id() == ClassOfPose(aPC2).Id();
  2387. }
  2388. const std::map<std::string,cClassEquivPose *> & cRelEquivPose::Map() const
  2389. {
  2390. return mMap;
  2391. }
  2392. void cRelEquivPose::Show()
  2393. {
  2394. std::cout << "========== REL NUM ==================\n";
  2395. for
  2396. (
  2397. std::map<std::string,cClassEquivPose *>::const_iterator itM=mMap.begin();
  2398. itM!=mMap.end();
  2399. itM++
  2400. )
  2401. {
  2402. const cClassEquivPose& aCl = *(itM->second);
  2403. const std::vector<cGenPoseCam *> & aGrp = aCl.Grp() ;
  2404. if (aGrp.size() == 1)
  2405. std::cout << aCl.Id() << " :: " << aGrp[0]->Name()<< "\n";
  2406. else
  2407. {
  2408. std::cout << "## " << aCl.Id() << " ##\n";
  2409. for (int aK=0 ; aK<int(aGrp.size()) ; aK++)
  2410. std::cout << " --- " << aGrp[aK]->Name()<< "\n";
  2411. }
  2412. }
  2413. }
  2414. // ======= cAppliApero ====
  2415. cRelEquivPose * cAppliApero::RelFromId(const std::string & anId)
  2416. {
  2417. cRelEquivPose * aRes = mRels[anId];
  2418. if (aRes ==0)
  2419. {
  2420. std::cout << "For Id = " << anId << "\n";
  2421. ELISE_ASSERT(false,"cAppliApero::RelFromId do not exist");
  2422. }
  2423. return aRes;
  2424. }
  2425. bool cAppliApero::SameClass(const std::string& anId,const cGenPoseCam & aPC1,const cGenPoseCam & aPC2)
  2426. {
  2427. return RelFromId(anId)->SameClass(aPC1,aPC2);
  2428. }
  2429. void cAppliApero::AddObservationsRigidGrp(const cObsRigidGrpImage & anORGI,bool IsLastIter,cStatObs & aSO)
  2430. {
  2431. cRelEquivPose * aREP = RelFromId(anORGI.RefGrp());
  2432. const std::map<std::string,cClassEquivPose *> & aMap = aREP->Map();
  2433. for
  2434. (
  2435. std::map<std::string,cClassEquivPose *>::const_iterator itG=aMap.begin();
  2436. itG!=aMap.end();
  2437. itG++
  2438. )
  2439. {
  2440. const std::vector<cGenPoseCam *> & aGrp = itG->second->Grp();
  2441. int aNb = (int)aGrp.size();
  2442. if (aNb>=2)
  2443. {
  2444. for (int aK1=0 ; aK1<aNb ; aK1++)
  2445. {
  2446. for (int aK2=aK1+1 ; aK2<aNb ; aK2++)
  2447. {
  2448. cPoseCam * aCP1 = aGrp[aK1]->DownCastPoseCamSVP();
  2449. cPoseCam * aCP2 = aGrp[aK2]->DownCastPoseCamSVP();
  2450. if ((! aCP1) || (!aCP2))
  2451. {
  2452. std::cout << "For " << aGrp[aK1]->Name() << " "<< aGrp[aK2]->Name() << "\n";
  2453. ELISE_ASSERT(false,"Non stenope cam use in ddObservationsRigidGrp");
  2454. }
  2455. cRotationFormelle & aRF1 = aCP1->RF();
  2456. cRotationFormelle & aRF2 = aCP2->RF();
  2457. if (anORGI.ORGI_CentreCommun().IsInit())
  2458. {
  2459. Pt3dr aPInc = anORGI.ORGI_CentreCommun().Val().Incertitude();
  2460. double anInc[3];
  2461. aPInc.to_tab(anInc);
  2462. for (int aD=0 ; aD<3 ; aD++)
  2463. {
  2464. if (anInc[aD]>0)
  2465. {
  2466. double aR = mSetEq.AddEqEqualVar(ElSquare(1.0/anInc[aD]),aRF1.NumCentre(aD),aRF2.NumCentre(aD),true);
  2467. aSO.AddSEP(aR);
  2468. }
  2469. }
  2470. }
  2471. if (anORGI.ORGI_TetaCommun().IsInit())
  2472. {
  2473. Pt3dr aPInc = anORGI.ORGI_TetaCommun().Val().Incertitude();
  2474. double anInc[3];
  2475. aPInc.to_tab(anInc);
  2476. for (int aD=0 ; aD<3 ; aD++)
  2477. {
  2478. if (anInc[aD]>0)
  2479. {
  2480. double aR = mSetEq.AddEqEqualVar(ElSquare(1.0/anInc[aD]),aRF1.NumTeta(aD),aRF2.NumTeta(aD),true);
  2481. aSO.AddSEP(aR);
  2482. }
  2483. }
  2484. }
  2485. }
  2486. }
  2487. }
  2488. }
  2489. }
  2490. /***********************************************************/
  2491. /* */
  2492. /* */
  2493. /* */
  2494. /***********************************************************/
  2495. /*
  2496. class cIBC_ImsOneTime
  2497. {
  2498. public :
  2499. cIBC_ImsOneTime(int aNbCam,int aNum,const std::string& aNameTime) ;
  2500. void AddPose(cPoseCam *, int aNum);
  2501. private :
  2502. std::vector<cPoseCam *> mCams;
  2503. int mNum;
  2504. std::string mNameTime;
  2505. };
  2506. class cIBC_OneCam
  2507. {
  2508. public :
  2509. cIBC_OneCam(const std::string & ,int aNum);
  2510. const int & Num() const;
  2511. private :
  2512. std::string mNameCam;
  2513. int mNum;
  2514. };
  2515. class cImplemBlockCam
  2516. {
  2517. public :
  2518. static cImplemBlockCam * AllocNew(cAppliApero &,const cStructBlockCam);
  2519. private :
  2520. cImplemBlockCam(cAppliApero & anAppli,const cStructBlockCam );
  2521. cAppliApero & mAppli;
  2522. const cStructBlockCam & mSBC;
  2523. cRelEquivPose mRelGrp;
  2524. cRelEquivPose mRelId;
  2525. std::map<std::string,cIBC_OneCam *> mName2Cam;
  2526. std::vector<cIBC_OneCam *> mNum2Cam;
  2527. int mNbCam;
  2528. std::map<std::string,cIBC_ImsOneTime *> mName2ITime;
  2529. std::vector<cIBC_ImsOneTime *> mNum2ITime;
  2530. };
  2531. // =================================
  2532. // cIBC_ImsOneTime
  2533. // =================================
  2534. cIBC_ImsOneTime::cIBC_ImsOneTime(int aNb,int aNum,const std::string & aNameTime) :
  2535. mCams (aNb),
  2536. mNum (aNum),
  2537. mNameTime (aNameTime)
  2538. {
  2539. }
  2540. void cIBC_ImsOneTime::AddPose(cPoseCam * aPC, int aNum)
  2541. {
  2542. cPoseCam * aPC0 = mCams.at(aNum);
  2543. if (aPC0 != 0)
  2544. {
  2545. std::cout << "For cameras " << aPC->Name() << " and " << aPC0->Name() << "\n";
  2546. ELISE_ASSERT(false,"Conflicting name from KeyIm2TimeCam ");
  2547. }
  2548. mCams[aNum] = aPC;
  2549. }
  2550. // =================================
  2551. // cIBC_OneCam
  2552. // =================================
  2553. cIBC_OneCam::cIBC_OneCam(const std::string & aNameCam ,int aNum) :
  2554. mNameCam (aNameCam ),
  2555. mNum (aNum)
  2556. {
  2557. }
  2558. const int & cIBC_OneCam::Num() const {return mNum;}
  2559. // =================================
  2560. // cImplemBlockCam
  2561. // =================================
  2562. cImplemBlockCam::cImplemBlockCam(cAppliApero & anAppli,const cStructBlockCam aSBC) :
  2563. mAppli (anAppli),
  2564. mSBC (aSBC)
  2565. {
  2566. const std::vector<cPoseCam*> & aVP = mAppli.VecAllPose();
  2567. // On initialise les camera
  2568. for (int aKP=0 ; aKP<int(aVP.size()) ; aKP++)
  2569. {
  2570. cPoseCam * aPC = aVP[aKP];
  2571. std::string aNamePose = aPC->Name();
  2572. std::pair<std::string,std::string> aPair = mAppli.ICNM()->Assoc2To1(mSBC.KeyIm2TimeCam(),aNamePose,true);
  2573. std::string aNameCam = aPair.second;
  2574. if (! DicBoolFind(mName2Cam,aNameCam))
  2575. {
  2576. cIBC_OneCam * aCam = new cIBC_OneCam(aNameCam,mNum2Cam.size());
  2577. mName2Cam[aNameCam] = aCam;
  2578. mNum2Cam.push_back(aCam);
  2579. }
  2580. }
  2581. mNbCam = mNum2Cam.size();
  2582. // On regroupe les images prises au meme temps
  2583. for (int aKP=0 ; aKP<int(aVP.size()) ; aKP++)
  2584. {
  2585. cPoseCam * aPC = aVP[aKP];
  2586. std::string aNamePose = aPC->Name();
  2587. std::pair<std::string,std::string> aPair = mAppli.ICNM()->Assoc2To1(mSBC.KeyIm2TimeCam(),aNamePose,true);
  2588. std::string aNameTime = aPair.first;
  2589. std::string aNameCam = aPair.second;
  2590. cIBC_ImsOneTime * aIms = mName2ITime[aNameTime];
  2591. if (aIms==0)
  2592. {
  2593. aIms = new cIBC_ImsOneTime(mNbCam,mNum2ITime.size(),aNameTime);
  2594. mName2ITime[aNameTime] = aIms;
  2595. mNum2ITime.push_back(aIms);
  2596. }
  2597. cIBC_OneCam * aCam = mName2Cam[aNameCam];
  2598. aIms->AddPose(aPC,aCam->Num());
  2599. }
  2600. }
  2601. */
  2602. void cPoseCam::AddMajick(cMajickChek & aMC) const
  2603. {
  2604. aMC.Add(CurRot());
  2605. }
  2606. // CamNonOrtho
  2607. void cPoseCam::SetCamNonOrtho(CamStenope * aCS)
  2608. {
  2609. AssertHasNotCamNonOrtho();
  2610. mCamNonOrtho = aCS;
  2611. }
  2612. CamStenope * cPoseCam::GetCamNonOrtho() const
  2613. {
  2614. AssertHasCamNonOrtho();
  2615. return mCamNonOrtho;
  2616. }
  2617. bool cPoseCam::HasCamNonOrtho() const
  2618. {
  2619. return mCamNonOrtho != 0;
  2620. }
  2621. void cPoseCam::AssertHasCamNonOrtho() const
  2622. {
  2623. ELISE_ASSERT(HasCamNonOrtho(),"Camera Non Ortho expected");
  2624. }
  2625. void cPoseCam::AssertHasNotCamNonOrtho() const
  2626. {
  2627. ELISE_ASSERT(! HasCamNonOrtho(),"Unexpected Camera Non Ortho");
  2628. }
  2629. /*Footer-MicMac-eLiSe-25/06/2007
  2630. Ce logiciel est un programme informatique servant à la mise en
  2631. correspondances d'images pour la reconstruction du relief.
  2632. Ce logiciel est régi par la licence CeCILL-B soumise au droit français et
  2633. respectant les principes de diffusion des logiciels libres. Vous pouvez
  2634. utiliser, modifier et/ou redistribuer ce programme sous les conditions
  2635. de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA
  2636. sur le site "http://www.cecill.info".
  2637. En contrepartie de l'accessibilité au code source et des droits de copie,
  2638. de modification et de redistribution accordés par cette licence, il n'est
  2639. offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
  2640. seule une responsabilité restreinte pèse sur l'auteur du programme, le
  2641. titulaire des droits patrimoniaux et les concédants successifs.
  2642. A cet égard l'attention de l'utilisateur est attirée sur les risques
  2643. associés au chargement, à l'utilisation, à la modification et/ou au
  2644. développement et à la reproduction du logiciel par l'utilisateur étant
  2645. donné sa spécificité de logiciel libre, qui peut le rendre complexe à
  2646. manipuler et qui le réserve donc à des développeurs et des professionnels
  2647. avertis possédant des connaissances informatiques approfondies. Les
  2648. utilisateurs sont donc invités à charger et tester l'adéquation du
  2649. logiciel à leurs besoins dans des conditions permettant d'assurer la
  2650. sécurité de leurs systèmes et ou de leurs données et, plus généralement,
  2651. à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
  2652. Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
  2653. pris connaissance de la licence CeCILL-B, et que vous en avez accepté les
  2654. termes.
  2655. Footer-MicMac-eLiSe-25/06/2007*/