/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

Large files are truncated click here to view the full 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 & aP