diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b9bebcb7f..b3132a0210 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,9 @@ option(BUILD_BENCH "compile low-level test bench" OFF) # Interfaces de saisie des param�tres option(WITH_QT5 "compile Qt interfaces" OFF) +# Graphiz library +option(WITH_GRAPHVIZ "Use graphviz" OFF) + # Compilateur C++11 option(WITH_CPP11 "Compilateur C++11" ON) @@ -669,6 +672,15 @@ configure_file( set_source_files_properties("src/tiff/el_dcraw.c" elise PROPERTIES COMPILE_FLAGS "-O2 -Wall" COMPILE_DEFINITIONS "") +if(${WITH_GRAPHVIZ}) + INCLUDE(FindPkgConfig) + PKG_SEARCH_MODULE(gvc REQUIRED libgvc libcgraph libcdt) + LINK_DIRECTORIES(${gvc_LIBRARY_DIRS}) + INCLUDE_DIRECTORIES(${gvc_INCLUDE_DIRS}) + + message(STATUS "-----> using graphviz library") +endif() + #~ message("QT_QMAKE_EXECUTABLE = ${QT_QMAKE_EXECUTABLE}") #~ message("QT_MOC_EXECUTABLE = ${QT_MOC_EXECUTABLE}") #~ print_list(QT_LIBRARIES) diff --git a/CodeGenere/File2String/Str_ParamApero.cpp b/CodeGenere/File2String/Str_ParamApero.cpp index 6008a6c4cd..540d8d23bd 100644 --- a/CodeGenere/File2String/Str_ParamApero.cpp +++ b/CodeGenere/File2String/Str_ParamApero.cpp @@ -1,5 +1,5 @@ #include "StdAfx.h" -const char * theNameVar_ParamApero[1845] = { +const char * theNameVar_ParamApero[1855] = { "\n", "\n", "\n", @@ -975,6 +975,16 @@ const char * theNameVar_ParamApero[1845] = { "\n", "\n", " \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +"\n", +" \n", +" \n", "\n", " \n", " \n", +" \n", " \n", " \n", " \n", @@ -1770,6 +1772,7 @@ const char * theNameVar_ParamChantierPhotogram[2124] = { "-->\n", " \n", " \n", +" \n", "\n", " \n", " \n", @@ -2111,6 +2114,43 @@ const char * theNameVar_ParamChantierPhotogram[2124] = { " \n", "\n", "\n", +"\n", +"\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +"\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +"\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +"\n", +"\n", +"\n", "\n", "// };\n", "\n", diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..eeea6bb847 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +FROM ubuntu:latest +MAINTAINER Ewelina Rupnik + +ARG DEBIAN_FRONTEND=noninteractive + +# Set the working directory +ENV foo /etc/opt/ +WORKDIR ${foo} + +#IGN server specifique +#RUN export http_proxy="http://proxy.ign.fr:3128" +#RUN export https_proxy="https://proxy.ign.fr:3128" + +#MicMac dependencies +RUN apt-get update && apt-get install -y \ + build-essential \ + make \ + cmake \ + git \ + proj-bin \ + exiv2 \ + exiftool \ + imagemagick \ + xorg \ + openbox \ + qt5-default \ + meshlab \ + vim + + +#MicMac clone +#IGN-specific proxy setting +#RUN git config --global http.proxy http://proxy.ign.fr:3128 +#RUN git config --global https.proxy https://proxy.ign.fr:3128 +RUN git clone https://github.com/micmacIGN/micmac.git + +#MicMac build & compile +WORKDIR micmac +RUN mkdir build +WORKDIR build +RUN cmake ../ && make install -j8 + +#MicMac add environmental variable to executables +ENV PATH=$foo"micmac/bin/:${PATH}" +RUN echo $foo"micmac/bin/:${PATH}" diff --git a/MMVII/Doc/Doc2007.tex b/MMVII/Doc/Doc2007.tex index b228a9b9f1..3a486396ac 100755 --- a/MMVII/Doc/Doc2007.tex +++ b/MMVII/Doc/Doc2007.tex @@ -151,6 +151,7 @@ \part{Generalities} \part{Methodologies} \include{Methods/TiePoints} +\include{Methods/Vrac} diff --git a/MMVII/Doc/Methods/Vrac.tex b/MMVII/Doc/Methods/Vrac.tex new file mode 100755 index 0000000000..83407e4030 --- /dev/null +++ b/MMVII/Doc/Methods/Vrac.tex @@ -0,0 +1,11 @@ + + +\chapter{Several stuff unfinished} + + +%--------------------------------------------- +%--------------------------------------------- +%--------------------------------------------- + +%\section{Co-variance propagation} + diff --git a/MMVII/bin/Mk-MMVII.makefile b/MMVII/bin/Mk-MMVII.makefile index 3ccb59379b..acebaa94a1 100644 --- a/MMVII/bin/Mk-MMVII.makefile +++ b/MMVII/bin/Mk-MMVII.makefile @@ -97,11 +97,15 @@ SrcCalcDescriptPCar=$(wildcard ${MMV2DirCalcDescriptPCar}*.cpp) ObjCalcDescriptPCar=$(SrcCalcDescriptPCar:.cpp=.o) # # +MMV2DirMatchTieP=${MMV2DirSrc}MatchTieP/ +SrcMatchTieP=$(wildcard ${MMV2DirMatchTieP}*.cpp) +ObjMatchTieP=$(SrcMatchTieP:.cpp=.o) +# # => Le Main MAIN=${MMV2DirSrc}main.cpp #============ Calcul des objets # -OBJ= ${ObjCalcDescriptPCar} ${ObjImagesBase} ${ObjMMV1} ${ObjUtiMaths} ${ObjImagesInfoExtract} ${ObjImagesFiltrLinear} ${ObjCmdSpec} ${ObjBench} ${ObjMatrix} ${ObjAppli} ${ObjDIB} ${ObjTLE} ${ObjMkf} ${ObjUtils} ${ObjSerial} ${ObjPerso} +OBJ= ${ObjMatchTieP} ${ObjCalcDescriptPCar} ${ObjImagesBase} ${ObjMMV1} ${ObjUtiMaths} ${ObjImagesInfoExtract} ${ObjImagesFiltrLinear} ${ObjCmdSpec} ${ObjBench} ${ObjMatrix} ${ObjAppli} ${ObjDIB} ${ObjTLE} ${ObjMkf} ${ObjUtils} ${ObjSerial} ${ObjPerso} # #========= Header ======== # @@ -112,7 +116,7 @@ HEADER=$(wildcard ${MMV2DirIncl}*.h) #== CFLAGS etc... # CXX=g++ -CFlags="-std=c++14" "-Wall" "-Werror" "-O4" "-march=native" -I${MMV2Dir} -I${MMDir}/include/ -I${MMDir} +CFlags= "-std=c++14" "-Wall" "-Werror" "-O4" "-march=native" -I${MMV2Dir} -I${MMDir}/include/ -I${MMDir} BOOST_LIBS= -lboost_system -lboost_serialization -lboost_regex -lboost_filesystem QTAnnLibs= -lXext /usr/lib/x86_64-linux-gnu/libQt5Core.so /usr/lib/x86_64-linux-gnu/libQt5Gui.so /usr/lib/x86_64-linux-gnu/libQt5Xml.so /usr/lib/x86_64-linux-gnu/libQt5OpenGL.so -lGLU -lGL -ldl -lpthread /usr/lib/x86_64-linux-gnu/libQt5Xml.so /usr/lib/x86_64-linux-gnu/libQt5Concurrent.so /usr/lib/x86_64-linux-gnu/libQt5OpenGL.so /usr/lib/x86_64-linux-gnu/libQt5Widgets.so /usr/lib/x86_64-linux-gnu/libQt5Gui.so /usr/lib/x86_64-linux-gnu/libQt5Core.so ../../lib/libANN.a LibsFlags= ${MMV2ElisePath} -lX11 ${BOOST_LIBS} ${QTAnnLibs} @@ -132,6 +136,8 @@ ${MMV2ResultInstal} : ${MMV2SrcInstal} # # ================ Objects ================== # +${MMV2DirMatchTieP}%.o : ${MMV2DirMatchTieP}%.cpp ${HEADER} + ${CXX} -c $< ${CFlags} -o $@ ${MMV2DirCalcDescriptPCar}%.o : ${MMV2DirCalcDescriptPCar}%.cpp ${HEADER} ${CXX} -c $< ${CFlags} -o $@ ${MMV2DirPerso}%.o : ${MMV2DirPerso}%.cpp ${HEADER} diff --git a/MMVII/include/MMVII_AimeTieP.h b/MMVII/include/MMVII_AimeTieP.h index bde1002bd8..3f4dc1b054 100644 --- a/MMVII/include/MMVII_AimeTieP.h +++ b/MMVII/include/MMVII_AimeTieP.h @@ -5,6 +5,7 @@ namespace MMVII { class cAimeDescriptor; class cAimePCar; +class cSetAimePCAR; /// Proto-class for Aime TieP @@ -84,14 +85,24 @@ class cAimeDescriptor : public cMemCheck const std::vector & DirPrinc() const; ///< const accesor to main directions std::vector & DirPrinc() ; ///< non const accessor + + /// this[x] / AD2[x+aShift] + double DistanceFromIShift(const cAimeDescriptor & aAD2,int aShift,const cSetAimePCAR & aSet) const; + // X1 and X2 are the peek, supposed to be homologous in + double DistanceFrom2RPeek(double aX1,const cAimeDescriptor & aAD2,double aX2,const cSetAimePCAR & aSet) const; + // IPeek is an index from DirPrinc + double DistanceFromStdPeek(int aIPeek,const cAimeDescriptor & aAD2,const cSetAimePCAR & aSet) const; + // Compute best match from all Dir Princ + cWhitchMin DistanceFromBestPeek(const cAimeDescriptor & aAD2,const cSetAimePCAR & aSet) const; + private : - cIm2D mILP; ///< mImLogPol + cIm2D mILP; ///< mImLogPol std::vector mDirPrinc ; ///< Principal directions options }; /** Class to store Aime Pts Car = Descriptor + localization */ -class cAimePCar +class cAimePCar : public cMemCheck { public : cAimeDescriptor & Desc(); @@ -103,21 +114,30 @@ class cAimePCar /** Class to store aSet of AimePcar = vector + some common caracteritic on type */ -class cSetAimePCAR +class cSetAimePCAR : public cMemCheck { public : // cSetAimePCAR(); - cSetAimePCAR(eTyPyrTieP aType,bool IsMax); + cSetAimePCAR(eTyPyrTieP aType,bool IsMax); ///< "Real" constructor + cSetAimePCAR(); ///< Sometime need a default constructor int & IType(); eTyPyrTieP Type(); bool& IsMax(); + bool& Census(); + const bool& Census() const; + double& Ampl2N(); + const double& Ampl2N() const; std::vector& VPC(); void SaveInFile(const std::string &) const; + void InitFromFile(const std::string &) ; + // For census, as the value are strictly in [-1,1] we can use a universall value for normalize + static const double TheCensusMult; private : - int mType; ///< Type registered as int, easier for AddData, in fact a eTyPyrTieP - bool mIsMax; ///< Is it a maxima or a minima of its caracteristic - std::vector mVPC; ///< Vector of Aime points - + int mType; ///< Type registered as int, easier for AddData, in fact a eTyPyrTieP + bool mIsMax; ///< Is it a maxima or a minima of its caracteristic + std::vector mVPC; ///< Vector of Aime points + bool mCensus; ///< Is it Census mode + double mAmpl2N; ///< Ampl between the normalized value IPL = Norm*Ampl }; diff --git a/MMVII/include/MMVII_Bench.h b/MMVII/include/MMVII_Bench.h index cf6608823c..2323139c7e 100644 --- a/MMVII/include/MMVII_Bench.h +++ b/MMVII/include/MMVII_Bench.h @@ -54,6 +54,10 @@ void BenchStat(); void BenchUnbiasedStdDev(); ///< Test one specific function currently not correct, by default test not activated void BenchSupport(); ///< Test support function that could/should exist in standard libs +void BenchMyJets(); ///< Test on Jets, correctness and efficience +void BenchJetsCam(); ///< Test specifique to camera projection +void MMV1_GenerateCodeTestCam(); ///< To generate code of derivative MMV1-like (for comparing with jets) + }; diff --git a/MMVII/include/MMVII_DeclareAllCmd.h b/MMVII/include/MMVII_DeclareAllCmd.h index 396d8e8c04..691b285873 100644 --- a/MMVII/include/MMVII_DeclareAllCmd.h +++ b/MMVII/include/MMVII_DeclareAllCmd.h @@ -17,12 +17,14 @@ extern cSpecMMVII_Appli TheSpecEditSet; extern cSpecMMVII_Appli TheSpecEditRel; extern cSpecMMVII_Appli TheSpecWalkman; extern cSpecMMVII_Appli TheSpecDaisy; +extern cSpecMMVII_Appli TheSpecCatVideo; extern cSpecMMVII_Appli TheSpec_TestEigen; extern cSpecMMVII_Appli TheSpec_ComputeParamIndexBinaire; extern cSpecMMVII_Appli TheSpecTestRecall; extern cSpecMMVII_Appli TheSpecScaleImage; extern cSpecMMVII_Appli TheSpecCalcDiscIm; extern cSpecMMVII_Appli TheSpecCalcDescPCar; +extern cSpecMMVII_Appli TheSpecMatchTieP; }; diff --git a/MMVII/include/MMVII_Derivatives.h b/MMVII/include/MMVII_Derivatives.h new file mode 100644 index 0000000000..4e0c9822b9 --- /dev/null +++ b/MMVII/include/MMVII_Derivatives.h @@ -0,0 +1,455 @@ +#ifndef _MMVII_Derivatives_H_ +#define _MMVII_Derivatives_H_ + +#include "ExternalInclude/Eigen/Dense" + +namespace MMVII +{ + +/** \file MMVII_Derivatives.h + \brief Contains stuff necessary for computing derivatives, dont know if MMVII + will use jets or generate code, for now it's interface for test +*/ + +class cInterfaceTestCam; // Interface for tested derivative +struct cVarEpsNum; // More or less like Ceres +template struct cEpsNum; // Sparse implementation of jets + + +/* *********************************************** */ +/* */ +/* :: */ +/* */ +/* *********************************************** */ + + +/** Class that is can interface for computing derivative of a camera (projection fonction) + derived are typically jets or generated code */ + +class cInterfaceTestCam +{ + public : + + /// initialize parameteres from "raw" vector + virtual void InitFromParams(const std::vector &) = 0; + /// compute values and derivatives and fill in VVals and VDer + virtual void Compute(std::vector & VVals,std::vector > & VDer)=0; + /// Makes Nb computation (time bench ...) + virtual void Compute(int aNb) =0; + /// Allocate a MMV1 object + static cInterfaceTestCam * AllocMMV1(); +}; + +/* ************************************** */ +/* */ +/* cVarEpsNum */ +/* */ +/* ************************************** */ + +/** cVarEpsNum functionnaly equivalent to cEpsNum, but are a tentative of optimization + taking into account the sparseness. The implementation use a vector of non null indexes. +*/ + +struct cVarEpsNum +{ + // ====================== Data =========== + private : + // ----- static data for buffering + static const int SzBuf = 1000; + static double BufEps[SzBuf]; + static bool IsInit; + public : + // ----- member data + double mNum; ///< Real value + std::vector mVInd; ///< Index of non 0 epsilon value + std::vector mVEps; ///< Value of non 0 + // ====================== Methods =========== + + /// Constructor for a "pure" number + inline cVarEpsNum(double aNum) : + mNum (aNum) + { + Init(); + } + /// Default Constructor convenient + inline cVarEpsNum() : + cVarEpsNum (0.0) + { + } + /// Constructor for number + dXk + inline cVarEpsNum(double aNum,int aK) : + cVarEpsNum (aNum) + { + AddVal(1.0,aK); + } + + /// Add aVal * dXk + inline void AddVal(double aVal,int aK) + { + mVEps.push_back(aVal); + mVInd.push_back(aK); + } + /** This constructor can be used in any "functionnal" composition + for exemple cos(g) => (g,cos(g.mNum),-sin(g.mNum)) */ + inline cVarEpsNum(const cVarEpsNum & aVEN,double aNum,double aMul) : + mNum (aNum), + mVInd (aVEN.mVInd), + mVEps (aVEN.mVEps) + { + for (auto & aEps : mVEps) + aEps *= aMul; + } + + inline cVarEpsNum(const double & aNum,const std::vector&aVInd,const std::vector&aVEps) : + mNum (aNum), + mVInd (aVInd), + mVEps (aVEps) + { + } + /// som + inline cVarEpsNum operator+(const cVarEpsNum& g) const + { + cVarEpsNum aRes(mNum+g.mNum); + + SetInBuf(); + g.AddToBuf(); + + BuffAdd(aRes); + g.BuffAdd(aRes); + + return aRes; + } + + /// products + inline cVarEpsNum operator*(const cVarEpsNum& g) const + { + cVarEpsNum aRes(mNum*g.mNum); + + AddToBuf(g.mNum); + g.AddToBuf(mNum); + + BuffAdd(aRes); + g.BuffAdd(aRes); + + return aRes; + } + /// Diff + cVarEpsNum operator-(const cVarEpsNum& g) const + { + cVarEpsNum aRes(mNum-g.mNum); + + SetInBuf(); + g.SubToBuf(); + + BuffAdd(aRes); + g.BuffAdd(aRes); + + return aRes; + } + /// Div + cVarEpsNum operator/(const cVarEpsNum& g) const + { + cVarEpsNum aRes(mNum/g.mNum); + + AddToBuf(1.0/g.mNum); + g.AddToBuf(-mNum/Square(g.mNum)); + + BuffAdd(aRes); + g.BuffAdd(aRes); + + return aRes; + } + + + /// Ensure that BufEps is clear + static void Init() + { + if (IsInit) return; // If not first time, job already done + IsInit = true; // next will not be first + for (int aK=0 ; aK */ +/* */ +/* ************************************** */ + +/** cEpsNum are more or less equivalent to Ceres jets : + it's a number + infininetely small in R^N + + Just wanted to be independant of Ceres during tests. +*/ + + +template struct cEpsNum { + + // ====================== Data =========== + + double mNum; ///< The number + Eigen::Matrix mEps; ///< The infinitely small part + + // ====================== Methods =========== + + /// Full constructor from Num + small + cEpsNum(const double & aNum,const Eigen::Matrix & aEps) : + mNum (aNum), + mEps (aEps) + { + } + + /// constructor only numeric + cEpsNum(double aNum) : + cEpsNum (aNum,Eigen::Matrix::Zero()) + { + } + + /// constructor Num + dXk + cEpsNum(const double & aNum,int aK) : + cEpsNum (aNum) + { + mEps(aK) = 1.0; + } + /// sometime need a def constructor + cEpsNum() : + cEpsNum(0.0) + { + } + cVarEpsNum ToVEN() const; + static cEpsNum Random(double Densite) + { + cEpsNum aRes(N*RandUnif_C()); + for (int aK=0 ; aK cEpsNum operator+(const cEpsNum& f, const cEpsNum& g) { + return cEpsNum(f.mNum + g.mNum, f.mEps + g.mEps); +} + +template cEpsNum operator+(const double & f, const cEpsNum& g) { + return cEpsNum(f + g.mNum, g.mEps); +} +template cEpsNum operator+(const cEpsNum& g,const double & f) { + return f+g; +} + // ====== operator - ============= + +template cEpsNum operator-(const cEpsNum& f, const cEpsNum& g) { + return cEpsNum(f.mNum - g.mNum, f.mEps - g.mEps); +} + +template cEpsNum operator-(const double & f, const cEpsNum& g) { + return cEpsNum(f - g.mNum, -g.mEps); +} +template cEpsNum operator-(const cEpsNum& g,const double & f) { + return cEpsNum(g.mNum -f, g.mEps); +} + + // ====== operator * ============= + +template cEpsNum operator*(const cEpsNum& f, const cEpsNum& g) { + return cEpsNum(f.mNum * g.mNum, g.mNum * f.mEps + f.mNum * g.mEps); +} +template cEpsNum operator*(const double & f, const cEpsNum& g) { + return cEpsNum(f*g.mNum,f*g.mEps); +} +template cEpsNum operator*(const cEpsNum& g,const double & f) { + return f*g; +} + + // ====== operator / ============= + +template cEpsNum operator/(const cEpsNum& f, const cEpsNum& g) { + return cEpsNum(f.mNum / g.mNum, (f.mEps / g.mNum) - g.mEps *(f.mNum/Square(g.mNum))); +} + +template cEpsNum square(const cEpsNum& f) { + return cEpsNum(Square(f.mNum) , 2* f.mNum* f.mEps ); +} + +template cEpsNum cube(const cEpsNum& f) { + return cEpsNum(Cube(f.mNum) , (3*Square(f.mNum)) * f.mEps ); +} + + // = conversion to Sparse + +template cVarEpsNum cEpsNum::ToVEN() const +{ + cVarEpsNum aRes(mNum); + for (int aK=0 ; aK cEpsNum COS(const cEpsNum& f) { + return cEpsNum(cos(f.mNum),-sin(f.mNum)*f.mEps); +} + +/* ************************************** */ +/* */ +/* :: */ +/* */ +/* ************************************** */ + +inline double COS(const double & v) {return cos(v);} + +/** Compute de difference between a sparse jet and a standard jet, used + to check the consistency of the jets */ + +template double EpsDifference(const cEpsNum & aEps,const cVarEpsNum & aVarEps) +{ + cVarEpsNum::Init(); + // take into account the standard value + double aRes= std::abs(aEps.mNum - aVarEps.mNum); + cEpsNum aEps2; // will be used to convert aVarEps + + for (unsigned int aK=0 ; aK=N) // Is over size, do as if value was 0 + aRes += std::abs(aVal); + else // else put it in the non sparse representation + aEps2.mEps[aInd] += aVal; + } + // now add the difference of value under N + for (int aK=0 ; aK=The_MMVII_DebugLevel_UserError ) \ +#define MMVII_INTERNAL_ASSERT_User(aTest,aRef,aMes)\ + if ((The_MMVII_DebugLevel>=The_MMVII_DebugLevel_UserError) && (!(aTest))) \ { MMVII_UsersErrror(aRef,aMes);} - +void MMVII_UnclasseUsEr(const std::string & aMes); #define MMVII_INTERNAL_ASSERT_always(aTest,aMes)\ @@ -100,7 +100,8 @@ void MMVII_UsersErrror(const eTyUEr &,const std::string & aMes); MMVII_INTERNAL_ASSERT_tiny(ValidInvertibleFloatValue(VALUE),"Non invertible value") -template void IgnoreUnused( const T& ) { }; +template void IgnoreUnused( const T& ) { }; /// To avoid some warning on TEMPORARILY unused variable +void DoNothingWithIt(void *); /// Used to avoid compiler optimization, make believe it can be used }; diff --git a/MMVII/include/MMVII_FormDer_BinaryOp.h b/MMVII/include/MMVII_FormDer_BinaryOp.h new file mode 100644 index 0000000000..4e4e3427cc --- /dev/null +++ b/MMVII/include/MMVII_FormDer_BinaryOp.h @@ -0,0 +1,619 @@ +#ifndef _MMVII_FormDer_BinaryOp_H_ +#define _MMVII_FormDer_BinaryOp_H_ + +/** \file MMVII_FormDer_BinaryOp.h + \brief File for definition of binary operators inside formula + +*/ + + + +namespace NS_MMVII_FormalDerivative +{ + +/* *************************************************** */ +/* *************************************************** */ +/* * * */ +/* * BINARY FORMULA * */ +/* * * */ +/* *************************************************** */ +/* *************************************************** */ + + + /* ---------------------------------------------------------- + Class implementing binary operation on formula + MOTHER CLASS : cBinaryF + DERIVED : cSumF / cMulF / cSubF / cDivF / cPowF + ----------------------------------------------------------------*/ + +template class cBinaryF : public cImplemF +{ + public : + typedef cImplemF tImplemF; + typedef typename tImplemF::tCoordF tCoordF; + typedef typename tImplemF::tFormula tFormula; + typedef typename tImplemF::tBuf tBuf; + + /// An operator must describe its name + /// We can compute print of binary formula using operator name + std::string InfixPPrint() const override + { + return "("+ this->NameOperator() + " "+ mF1->InfixPPrint() + " " + mF2->InfixPPrint() + ")"; + } + /// Is it an associative operator where order does not matters + static bool IsAssociatif() {return false;} + static bool IsDistribExt() {return false;} // like +,- + + /// We need a default value to compile in associative + static tFormula FOperation(const tFormula & aV1,const tFormula & aV2) + { + InternalError("No operation defined"); + return aV1; + } + protected : + void AssocSortedVect(std::vector & aV); + void EmpileAssoc (const cFormula & aF, std::vector & aV); + + std::vector Ref() const override{return std::vector{mF1,mF2};} + inline cBinaryF(tFormula aF1,tFormula aF2,const std::string & aName): + tImplemF (aF1->CoordF(),aName), + mF1 (aF1), + mDataF1 (aF1->DataBuf()), + mF2 (aF2), + mDataF2 (aF2->DataBuf()) + { + // It doesn't work to mix formula from different context + if (mF1->CoordF()!=mF2->CoordF()) + UserSError("Mix formula from different context"); + } + + tFormula mF1; ///< First argument of operator + const TypeElem *mDataF1; ///< Fast access to data of buf F1 + tFormula mF2; ///< Second argument of operator + const TypeElem *mDataF2; ///< Fast access to data of buf F2 +}; + +/// for example if F = (A+B)+ (C+(D+E)) push on V "A B C D E" +template void cBinaryF::EmpileAssoc + ( + const cFormula & aF, + std::vector & aV + ) +{ + if (aF->NameOperator() != this->NameOperator()) + { + aV.push_back(aF); + return; + } + for (auto aSubF : aF->Ref()) + EmpileAssoc(aSubF,aV); +} + +template void SortOnName(std::vector > & aV) +{ + std::sort + ( + aV.begin(),aV.end(), + [](const cFormula & f1,const cFormula & f2) {return f1->Name()Name();} + ); +} +template void cBinaryF::AssocSortedVect(std::vector & aV) +{ + EmpileAssoc(mF1,aV); + EmpileAssoc(mF2,aV); + SortOnName(aV); +} + + +template class cSumF : public cBinaryF +{ + public : + using cBinaryF::mF1; + using cBinaryF::mF2; + using cBinaryF::mDataF1; + using cBinaryF::mDataF2; + using cImplemF::mDataBuf; + typedef typename cBinaryF ::tFormula tFormula; + + inline cSumF(cFormula aF1,cFormula aF2,const std::string & aName) : + cBinaryF (aF1,aF2,aName) + { } + + // ============== BEHAVIOUR FOR REDUCTION ============= + + /// Required by constant reduction in cGenOperatorBinaire + static TypeElem Operation(const TypeElem & aV1,const TypeElem & aV2) {return aV1+aV2;}; + /// It is associative + static bool IsAssociatif() {return true;} + /// For assoc reduc + /// For distributivity + static bool IsDistribExt() {return true;} + static tFormula FOperation(const tFormula & aV1,const tFormula & aV2) {return aV1+aV2;} + + cImplemF * ReducAssoc() override ; + + private : + const std::string & NameOperator() const override {static std::string s("+"); return s;} + + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override {return mF1->Derivate(aK) + mF2->Derivate(aK);} +}; + +template cImplemF * cSumF::ReducAssoc() +{ + if (! REDUCE_ASSOCP) + return this; + + static int aSzCum=0; ///< Stat to see num of + operation + std::vector aVF; + this->AssocSortedVect(aVF); + aSzCum += aVF.size(); + + // Now we try to make reduction between last reduced formula and next one + // using distributivity + + std::vector aVR; ///< Current vector of reduced formulas + + bool ReduceDone = true; + + while (ReduceDone) + { + SortOnName(aVF); + aVR.clear(); + aVR.push_back(aVF[0]); + ReduceDone = false; + for (int aKIn=1 ; aKIn 2*A + if (aFA->Name() == aFB->Name()) + { + ReduceDone = true; + SHOW_REDUCE("ApA"); + aVR.back() = aFA * CreateCste(2.0,aFA); + } + else if (aFA->IsMult()) // A1 A2 +B + { + tFormula A1 = aFA->Ref().at(0); + tFormula A2 = aFA->Ref().at(1); + if (aFB->IsMult()) // A1 A2 + B1 B2 + { + tFormula B1 = aFB->Ref().at(0); + tFormula B2 = aFB->Ref().at(1); + if (A1->Name()== B1->Name()) // A1 A2 + A1 B2 => A1 (A2+B2) + { + ReduceDone = true; + SHOW_REDUCE("AB + AC"); + aVR.back() = A1 * (A2+B2); + } + else if (A2->Name()== B2->Name()) // A1 A2 + B1 A2 => (A1+B1) * A2 + { + ReduceDone = true; + SHOW_REDUCE("AB + CB"); + aVR.back() = (A1+B1) *A2; + } + else if (A1->Name()== B2->Name()) // A1 A2 + B1 A1 => A1 * (A2+B1) + { + ReduceDone = true; + SHOW_REDUCE("AB + CA"); + aVR.back() = A1 * (A2+B1); + } + else if (A2->Name()== B1->Name()) // A1 A2 + A2 B2 => A2 * (A1+B2) + { + ReduceDone = true; + SHOW_REDUCE("AB + BC"); + aVR.back() = A2 * (A1+B2); + } + else + aVR.push_back(aFB); + } + else + { + if (A1->Name()== aFB->Name()) // A1 A2 + A1 => A1 * (A2+1) + { + ReduceDone = true; + SHOW_REDUCE("BA+B"); + aVR.back() = A1 * (A2+CreateCste(1.0,aFA)); + } + else if (A2->Name()== aFB->Name()) // A1 A2 + A2 => A2 * (A1+1) + { + ReduceDone = true; + SHOW_REDUCE("AB+B"); + aVR.back() = A2 * (A1+CreateCste(1.0,aFA)); + } + else + aVR.push_back(aFB); + } + } + else if (aFB->IsMult()) // A1 A2 + B1 B2 + { + tFormula B1 = aFB->Ref().at(0); + tFormula B2 = aFB->Ref().at(1); + if (aFA->Name()== B1->Name()) // B1 + B1 B2 => B2 * (B2+1) + { + ReduceDone = true; + SHOW_REDUCE("A+AB"); + aVR.back() = B1 * (B2+CreateCste(1.0,aFA)); + } + if (aFA->Name()== B2->Name()) // B2 + B1 B2 => B2 * (B1+1) + { + ReduceDone = true; + SHOW_REDUCE("A+BA"); + aVR.back() = B2 * (B1+CreateCste(1.0,aFA)); + } + else + aVR.push_back(aFB); + } + else + aVR.push_back(aFB); + + } + aVF = aVR; + } + tFormula aRes = aVR.back(); + for (int aK=aVR.size()-2 ; aK>=0 ; aK--) + aRes = aVR[aK] + aRes; + return aRes.RawPtr(); +} + +template class cMulF : public cBinaryF +{ + public : + using cBinaryF::mF1; + using cBinaryF::mF2; + using cBinaryF::mDataF1; + using cBinaryF::mDataF2; + using cImplemF::mDataBuf; + typedef typename cBinaryF ::tFormula tFormula; + + inline cMulF(cFormula aF1,cFormula aF2,const std::string & aName) : + cBinaryF (aF1,aF2,aName) + { } + // ============== BEHAVIOUR FOR REDUCTION ============= + + bool IsMult() const {return true;} + + /// Required by constant reduction in cGenOperatorBinaire + static TypeElem Operation(const TypeElem & aV1,const TypeElem & aV2) {return aV1*aV2;} + /// It is associative + static bool IsAssociatif() {return true;} + /// For assoc reduc + static tFormula FOperation(const tFormula & aV1,const tFormula & aV2) {return aV1*aV2;} + + /// For distributivity + virtual bool IsDistribInt() const override {return true;} + tFormula VOper2 (const tFormula & aV1,const tFormula & aV2) const override {return aV1*aV2;} + private : + const std::string & NameOperator() const override {static std::string s("*"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return mF2*mF1->Derivate(aK) + mF1*mF2->Derivate(aK); + } +}; + +template class cSubF : public cBinaryF +{ + public : + /// Required by constant reduction in cGenOperatorBinaire + static TypeElem Operation(const TypeElem & aV1,const TypeElem & aV2) {return aV1-aV2;} + using cBinaryF::mF1; + using cBinaryF::mF2; + using cBinaryF::mDataF1; + using cBinaryF::mDataF2; + using cImplemF::mDataBuf; + typedef typename cBinaryF ::tFormula tFormula; + + inline cSubF(cFormula aF1,cFormula aF2,const std::string & aName) : + cBinaryF (aF1,aF2,aName) + { } + + // ============== BEHAVIOUR FOR REDUCTION ============= + /// For distributivity + static bool IsDistribExt() {return true;} + static tFormula FOperation(const tFormula & aV1,const tFormula & aV2) {return aV1-aV2;} + private : + const std::string & NameOperator() const override {static std::string s("-"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override {return mF1->Derivate(aK) - mF2->Derivate(aK);} +}; + +template class cDivF : public cBinaryF +{ + public : + /// Required by constant reduction in cGenOperatorBinaire + static TypeElem Operation(const TypeElem & aV1,const TypeElem & aV2) {return aV1/aV2;} + using cBinaryF::mF1; + using cBinaryF::mF2; + using cBinaryF::mDataF1; + using cBinaryF::mDataF2; + using cImplemF::mDataBuf; + typedef typename cBinaryF ::tFormula tFormula; + + inline cDivF(cFormula aF1,cFormula aF2,const std::string & aName) : + cBinaryF (aF1,aF2,aName) + { } + /// For distributivity + virtual bool IsDistribInt() const override {return true;} + tFormula VOper2 (const tFormula & aV1,const tFormula & aV2) const override {return aV1/aV2;} + private : + const std::string & NameOperator() const override {static std::string s("/"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return (mF1->Derivate(aK)*mF2 - mF2->Derivate(aK)*mF1)/square(mF2); + } +}; + +template class cPowF : public cBinaryF +{ + public : + /// Required by constant reduction in cGenOperatorBinaire + static TypeElem Operation(const TypeElem & aV1,const TypeElem & aV2) {return std::pow(aV1,aV2);} + using cBinaryF::mF1; + using cBinaryF::mF2; + using cBinaryF::mDataF1; + using cBinaryF::mDataF2; + using cImplemF::mDataBuf; + + inline cPowF(cFormula aF1,cFormula aF2,const std::string & aName) : + cBinaryF (aF1,aF2,aName) + { } + private : + const std::string & NameOperator() const override {static std::string s("^"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return pow(mF1,mF2) * ( (mF1->Derivate(aK)/mF1)*mF2 + mF2->Derivate(aK)*log(mF1)) ; + } +}; + + + /* ---------------------------------------*/ + /* Global Function on unary op */ + /* ---------------------------------------*/ + + + +/** A Helper class to avoid code duplication on the process , see detailed comment in cGenOperatorUnaire (analogous) */ + +template class cGenOperatorBinaire +{ + public : + typedef typename TypeCompiled::tElem tElem; + typedef typename TypeCompiled::tCoordF tCoordF; + typedef typename TypeCompiled::tImplemF tImplemF; + typedef typename tImplemF::tFormula tFormula; + + static tFormula Generate(tFormula aF1,tFormula aF2,const std::string & aNameOp) + { + // Extract context (take F1 ou F2, does not matter, they must be the same) + tCoordF * aPCont = aF1->CoordF(); + std::string aNameForm = aF1.NameFormulaBin(aNameOp,aF2); + + if (aPCont->ExistFunc(aNameForm)) + return aPCont->FuncOfName(aNameForm); + + // Maybe the two operand are constant ? Then we can reduce + if (REDUCE_CSTE) + { + const tElem * aC1 = aF1->ValCste(); + const tElem * aC2 = aF2->ValCste(); + if (aC1 && aC2) + { + SHOW_REDUCE("Cste x Cste"); + tElem aC12= TypeCompiled::Operation(*aC1,*aC2); + return CreateCste(aC12,aF1); + } + } + + if ( + REDUCE_DISTRIB + && TypeCompiled::IsDistribExt() + && aF1->IsDistribInt() + && aF2->IsDistribInt() + && (aF2->NameOperator() == aF2->NameOperator()) + ) + { + // Add IsMult, we dont want to reduce a/b+a/c + if ((aF1->Ref()[0]->Name()==aF2->Ref()[0]->Name()) && aF1->IsMult()) + { + SHOW_REDUCE("(A$B)#(A$C) => A$(B#C)"); + return aF1->VOper2(aF1->Ref()[0],TypeCompiled::FOperation(aF1->Ref()[1],aF2->Ref()[1])); + } + if (aF1->Ref()[1]->Name()==aF2->Ref()[1]->Name()) + { + SHOW_REDUCE("(A$B)#(C$B) => (A#C)$B"); + return aF1->VOper2(TypeCompiled::FOperation(aF1->Ref()[0],aF2->Ref()[0]),aF1->Ref()[1]); + } + } + + tFormula aResult (new TypeCompiled(aF1,aF2,aNameForm)); + aPCont->AddFormula(aResult); + return aResult; + } +}; + + + +template +cFormula operator + + ( + const cFormula & aF1, + const cFormula & aF2 + ) +{ + // Use the fact that 0 is neutral element to simplify + if (aF1->IsCste0()) return aF2; + if (aF2->IsCste0()) return aF1; + + // Use commutativity of + to have a unique representation + if (aF1->Name() > aF2->Name()) + return aF2+aF1; + + // Use commutativity of + to have a unique representation + if (false && REDUCE_ApA && (aF1->Name() == aF2->Name()) ) + { + SHOW_REDUCE("ApA"); + return aF1 * CreateCste(2.0,aF1); + } + + return cGenOperatorBinaire >::Generate(aF1,aF2,"+"); +} + +template +cFormula operator - + ( + const cFormula & aF1, + const cFormula & aF2 + ) +{ + // Use the fact that 0 is neutral element to simplify + if (aF1->IsCste0()) return -aF2; + if (aF2->IsCste0()) return aF1; + + // A - (-B) = A + B + if (REDUCE_MM && (aF2->NameOperator()=="-") && (aF2->Ref().size()==1)) + { + SHOW_REDUCE("a-(-b))"); + return aF1 + aF2->Ref()[0]; + } + + return cGenOperatorBinaire >::Generate(aF1,aF2,"-"); +} + +template +cFormula operator * + ( + const cFormula & aF1, + const cFormula & aF2 + ) +{ + // Use the fact that 1 is neutral element to simplify + if (aF1->IsCste1()) return aF2; + if (aF2->IsCste1()) return aF1; + + // Use the fact that 0 is absorbant element to simplify + if (aF1->IsCste0()) return aF1; + if (aF2->IsCste0()) return aF2; + + + // Use commutativity of + to have a unique representation + if (aF1->Name() > aF2->Name()) + return aF2 * aF1; + + return cGenOperatorBinaire >::Generate(aF1,aF2,"*"); +} + +template +cFormula operator / + ( + const cFormula & aF1, + const cFormula & aF2 + ) +{ + if (aF1->IsCste0()) return aF1; // 0/F2 -> 0 + if (aF2->IsCste1()) return aF1; // F1/1 -> F1 + + return cGenOperatorBinaire >::Generate(aF1,aF2,"/"); +} + +template +cFormula pow + ( + const cFormula & aF1, + const cFormula & aF2 + ) +{ + return cGenOperatorBinaire >::Generate(aF1,aF2,"^"); +} + + /* ----------------------------------------------------------*/ + /* Binary Operator between Formula and constants */ + /* ----------------------------------------------------------*/ + + // ++++++++++++++++++++++++ +template +inline cFormula operator +(const TypeElem & aV1,const cFormula & aF2) +{ + return aF2->CoordF()->CsteOfVal(aV1) + aF2; +} +template +inline cFormula operator +(const cFormula & aF1,const TypeElem & aV2) +{ + return aV2+aF1; +} + // ************************ +template +inline cFormula operator *(const TypeElem & aV1,const cFormula & aF2) +{ + return aF2->CoordF()->CsteOfVal(aV1) * aF2; +} +template +inline cFormula operator *(const cFormula & aF1,const TypeElem & aV2) +{ + return aV2*aF1; +} + // -------------------------- +template +inline cFormula operator -(const TypeElem & aV1,const cFormula & aF2) +{ + return aF2->CoordF()->CsteOfVal(aV1) - aF2; +} +template +inline cFormula operator -(const cFormula & aF1,const TypeElem & aV2) +{ + return aF1-aF1->CoordF()->CsteOfVal(aV2) ; +} + // ///////////////////////// +template +inline cFormula operator /(const TypeElem & aV1,const cFormula & aF2) +{ + return aF2->CoordF()->CsteOfVal(aV1) / aF2; +} +template +inline cFormula operator /(const cFormula & aF1,const TypeElem & aV2) +{ + return aF1/aF1->CoordF()->CsteOfVal(aV2) ; +} + + // powpowpowpowpowpowpow + +template cFormula pow (const TypeElem & aV1,const cFormula & aF2) +{ + return exp(log(aV1)*aF2); +} + + + +}; // NS_MMVII_FormalDerivative + + +#endif // _MMVII_FormDer_BinaryOp_H_ diff --git a/MMVII/include/MMVII_FormDer_UnaryOp.h b/MMVII/include/MMVII_FormDer_UnaryOp.h new file mode 100644 index 0000000000..a011ba5807 --- /dev/null +++ b/MMVII/include/MMVII_FormDer_UnaryOp.h @@ -0,0 +1,422 @@ +#ifndef _MMVII_FormDer_UnaryOp_H_ +#define _MMVII_FormDer_UnaryOp_H_ + +/** \file MMVII_FormDer_UnaryOp.h + \brief File for unary operator on formal derivative +*/ + + +namespace NS_MMVII_FormalDerivative +{ + +/* *************************************************** */ +/* *************************************************** */ +/* * * */ +/* * UNARY FORMULA * */ +/* * * */ +/* *************************************************** */ +/* *************************************************** */ + + + /* ---------------------------------------------------------- + Class implementing unary operation on formula + MOTHER CLASS : cUnaryF + DERIVED : cSquareF / cExpF / cMin1F / cLogF + ----------------------------------------------------------------*/ + +template class cUnaryF : public cImplemF +{ + public : + typedef cImplemF tImplemF; + typedef typename tImplemF::tCoordF tCoordF; + typedef typename tImplemF::tFormula tFormula; + typedef typename tImplemF::tBuf tBuf; + + virtual std::string PostName() const {return "";} + std::string InfixPPrint() const override + { + return this->NameOperator() + " "+ mF->InfixPPrint() + PostName() ; + } + + /// In the cas an additional parameter is used, as "powc F30 3.14" + TypeElem Extrac1Param (const std::string & aString) + { + std::string aBuf1,aBuf2; + TypeElem aVal; + + std::stringstream aStream(aString); + + aStream >> aBuf1 >> aBuf2 >> aVal; + return aVal; + } + + protected : + std::vector Ref() const override{return std::vector{mF};} + inline cUnaryF(tFormula aF,const std::string & aName) : + tImplemF (aF->CoordF(),aName), + mF (aF), + mDataF (mF->DataBuf()) + { } + tFormula mF; ///< The formula argument of unary operator + const TypeElem* mDataF; ///< Fast access to data of buf +}; + + +/** Classes for square */ +template class cSquareF : public cUnaryF +{ + public : + using cUnaryF::mF; + using cUnaryF::mDataF; + using cImplemF::mDataBuf; + + cSquareF (cFormula aF,const std::string & aName) : + cUnaryF (aF,aName) + { } + private : + const std::string & NameOperator() const override {static std::string s("square"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return 2.0 * mF->Derivate(aK) * mF; + } +}; + +template class cCubeF : public cUnaryF +{ + public : + using cUnaryF::mF; + using cUnaryF::mDataF; + using cImplemF::mDataBuf; + + cCubeF (cFormula aF,const std::string & aName) : + cUnaryF (aF,aName) + { } + private : + const std::string & NameOperator() const override {static std::string s("cube"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return 3.0 * mF->Derivate(aK) * square(mF); + } +}; + +template class cPow4 : public cUnaryF +{ + public : + using cUnaryF::mF; + using cUnaryF::mDataF; + using cImplemF::mDataBuf; + + cPow4 (cFormula aF,const std::string & aName) : + cUnaryF (aF,aName) + { } + private : + const std::string & NameOperator() const override {static std::string s("pow4"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return 4.0 * mF->Derivate(aK) * cube(mF); + } +}; +template class cPow5 : public cUnaryF +{ + public : + using cUnaryF::mF; + using cUnaryF::mDataF; + using cImplemF::mDataBuf; + + cPow5 (cFormula aF,const std::string & aName) : + cUnaryF (aF,aName) + { } + private : + const std::string & NameOperator() const override {static std::string s("pow5"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return 5.0 * mF->Derivate(aK) * pow4(mF); + } +}; +template class cPow6 : public cUnaryF +{ + public : + using cUnaryF::mF; + using cUnaryF::mDataF; + using cImplemF::mDataBuf; + + cPow6 (cFormula aF,const std::string & aName) : + cUnaryF (aF,aName) + { } + private : + const std::string & NameOperator() const override {static std::string s("pow6"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return 6.0 * mF->Derivate(aK) * pow5(mF); + } +}; +template class cPow7 : public cUnaryF +{ + public : + using cUnaryF::mF; + using cUnaryF::mDataF; + using cImplemF::mDataBuf; + + cPow7 (cFormula aF,const std::string & aName) : + cUnaryF (aF,aName) + { } + private : + const std::string & NameOperator() const override {static std::string s("pow7"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return 7.0 * mF->Derivate(aK) * pow6(mF); + } +}; + + +template class cExpF : public cUnaryF +{ + public : + using cUnaryF::mF; + using cUnaryF::mDataF; + using cImplemF::mDataBuf; + + cExpF (cFormula aF,const std::string & aName) : + cUnaryF (aF,aName) + { } + private : + const std::string & NameOperator() const override {static std::string s("exp"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return mF->Derivate(aK) * exp(mF); + } +}; + +template class cMin1F : public cUnaryF +{ + public : + using cUnaryF::mF; + using cUnaryF::mDataF; + using cImplemF::mDataBuf; + + cMin1F (cFormula aF,const std::string & aName) : + cUnaryF (aF,aName) + { } + private : + const std::string & NameOperator() const override {static std::string s("-"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return - mF->Derivate(aK) ; + } +}; + +template class cLogF : public cUnaryF +{ + public : + using cUnaryF::mF; + using cUnaryF::mDataF; + using cImplemF::mDataBuf; + + cLogF (cFormula aF,const std::string & aName) : + cUnaryF (aF,aName) + { } + private : + const std::string & NameOperator() const override {static std::string s("log"); return s;} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return mF->Derivate(aK) / mF ; + } +}; + + +template class cPowCste : public cUnaryF +{ + public : + using cUnaryF::mF; + using cUnaryF::mDataF; + using cImplemF::mDataBuf; + + cPowCste (cFormula aF,const std::string & aName) : + cUnaryF (aF,aName), + mExp (cUnaryF::Extrac1Param (aName)) + { + } + private : + const std::string & NameOperator() const override {static std::string s("powc"); return s;} + virtual std::string PostName() const {return " " + std::to_string(mExp);} + void ComputeBuf(int aK0,int aK1) override + { + for (int aK=aK0 ; aK Derivate(int aK) const override + { + return (mExp*mF->Derivate(aK)) * pow(mF,mExp-1.0); + } + + TypeElem mExp; +}; + + + /* ---------------------------------------*/ + /* Global Functio on unary op */ + /* ---------------------------------------*/ + +/** A Helper class to avoid code duplication on the process : + * compute name + * test existence + * eventualy create + Template parameter is the class created +*/ + +template class cGenOperatorUnaire +{ + public : + typedef typename TypeCompiled::tCoordF tCoordF; + typedef typename TypeCompiled::tImplemF tImplemF; + typedef typename tImplemF::tFormula tFormula; + + static tFormula Generate(tFormula aF,const std::string & aNameOp,const std::string & Aux="") + { + tCoordF* aPCont = aF->CoordF(); // Get the context from the formula + std::string aNameForm = aF.NameFormulaUn(aNameOp,Aux); // Compute the name formula should have + + if (aPCont->ExistFunc(aNameForm)) // If it already exist + return aPCont->FuncOfName(aNameForm); // Then return formula whih this name + + tFormula aResult (new TypeCompiled(aF,aNameForm)); // else create it + aPCont->AddFormula(aResult); // indicate to the context to remember this new formula + return aResult; // return it + } +}; + +template +inline cFormula square(const cFormula & aF) +{ + return cGenOperatorUnaire >::Generate(aF,"square"); +} + +template +inline cFormula cube(const cFormula & aF) +{ + return cGenOperatorUnaire >::Generate(aF,"cube"); +} +template +inline cFormula pow4(const cFormula & aF) +{ + return cGenOperatorUnaire >::Generate(aF,"pow4"); +} +template +inline cFormula pow5(const cFormula & aF) +{ + return cGenOperatorUnaire >::Generate(aF,"pow5"); +} +template +inline cFormula pow6(const cFormula & aF) +{ + return cGenOperatorUnaire >::Generate(aF,"pow6"); +} +template +inline cFormula pow7(const cFormula & aF) +{ + return cGenOperatorUnaire >::Generate(aF,"pow7"); +} + + +template +inline cFormula exp(const cFormula & aF) +{ + return cGenOperatorUnaire >::Generate(aF,"exp"); +} +template +inline cFormula operator - (const cFormula & aF) +{ + // rule - (- x) == x + if (REDUCE_MM && (aF->NameOperator()=="-")) + { + if (aF->Ref().size()==1) + { + SHOW_REDUCE("-(-x)"); + return aF->Ref()[0]; + } + } + + return cGenOperatorUnaire >::Generate(aF,"-"); +} + +template +inline cFormula log (const cFormula & aF) +{ + return cGenOperatorUnaire >::Generate(aF,"log"); +} + +template +inline cFormula pow (const cFormula & aF,const TypeElem& aVal ) +{ + if (aVal==TypeElem(2)) return square(aF); + if (aVal==TypeElem(3)) return cube(aF); + return cGenOperatorUnaire >::Generate(aF,"powc",std::to_string(aVal)); +} +template +inline cFormula pow (const cFormula & aF,const int & aVal ) +{ + return pow(aF,TypeElem(aVal)); +} + +template inline cFormula pow8 (const cFormula & aF){return pow(aF,8);} +template inline cFormula pow9 (const cFormula & aF){return pow(aF,9);} +}; // NS_MMVII_FormalDerivative + + + +#endif // _MMVII_FormDer_UnaryOp_H_ diff --git a/MMVII/include/MMVII_FormalDerivatives.h b/MMVII/include/MMVII_FormalDerivatives.h new file mode 100644 index 0000000000..01e0b0e8d3 --- /dev/null +++ b/MMVII/include/MMVII_FormalDerivatives.h @@ -0,0 +1,1082 @@ +#ifndef _MMVII_FormalDerivative_H_ +#define _MMVII_FormalDerivative_H_ +using namespace std; + + + +#define WITH_MMVII false +#define WITH_EIGEN false + + +#if WITH_EIGEN +#include "ExternalInclude/Eigen/Dense" // TODO => replace with standard eigen file +#define EIGEN_ALLIGNMENT_IN_MMVII EIGEN_MAKE_ALIGNED_OPERATOR_NEW +#else +#define EIGEN_ALLIGNMENT_IN_MMVII +#endif +/* +*/ + +/** \file MMVII_FormalDerivate.h + \brief File for generating formal derivate + + Classes for generated formal derivative. All classes are single template classes. + The template parameter indicate the numerical type used for storage/computation + (float, double ...) + + This file is the only file to include. It contains : + + * declaration of operators + * definition of "main" classes : cFormula , cCoordinatorF , cImplemF " ; + * the 3 class for Atomic formula who will (probably) stay the same : Unkown, Observation, Constants + + This file include 2 files corresponding to following type of formula : + + * classes for "unary" formulas in "MMVII_FormDer_UnaryOp.h" + * classes for "binary" formulas in "MMVII_FormDer_BinaryOp.h" + + These 2 files have "vocation" to be extended during the future. + + ------------------------------------------------- + + * cFormula : represent a mathematicall formula; as in math : + - if F is a formula, exp(F), log(F) ....are formulas + - if F1 and F2 are formulas, F1+F2 , F1*F2 ... are formulas + - there exist some atomic formulas like constants, unknown and observations + - if F is a formula F->Derivate(k) is a formula corresponding to is derivate dF/dXk + Formulas are a complete algebric type. + + + * cCoordinatorF : is the "coordinator" class. + This class has, between others, the responsability of : + - creating the initial atomic formula corresponding to unknowns and observation + - maintain an inventory of existing formulas for efficiency purpose + + * Using this library is mainly : + - create a coordinator with a given number of unkown and observations + - create a formula using atoms an operator, generally the user function creating a + formula will be a template that can operate on any complete algebric type + (double, float, Formula , jets ...) + - indicate to the coordinator the formula you want work on, with generally its derivate + - evaluate the values of the formula for given unknows and observations + + cFormula is no more than an encapsulation of a pointer on the "concrete" class cImplemF. + + * cImplemF : is the mother class of all the formula. It's a pure abstract class, it contains + several pure virtual methods. The two main methods are "Derivate" and "ComputeBuf", this is + the two methods the users will have to define when extension to the library with new + operator is required. + + - cFormula Derivate(int aK) return the formula of its derivate by Xk. Heres is + two example extract from the code, one for multiplication, other from unknowns : + + o return mF2*mF1->Derivate(aK) + mF1*mF2->Derivate(aK); // From cMulF : (FG)' = F'G + FG' + o return (aK==mNumUnk) ? tImplemF::mCoordF->Cste1() : tImplemF::mCoordF->Cste0(); // from cUnknownF + + + - void ComputeBuf(int aK0,int aK1) : update the buffer of its data, once it subformula has + been updated, this is method that does the real job. Here an extract from cExpF and cDivF : + + o for (int aK=aK0 ; aK +#include +#include +#include +#include "memory.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif //========================================================== WITH_MMVI + +// REDUCTION RULES +// TODO => REPLACE BY METHOD ON COORDINATOR WHEN THEY IMPROVE THINGS .... +#define DOREDUCE false + +#define REDUCE_CSTE DOREDUCE // Cste+Cste => cste +#define REDUCE_MM DOREDUCE // - - x => x ; a-(-b) => a+b +#define REDUCE_ASSOCP DOREDUCE /* B + (A + C) = > A + ( B + C), + more generally order the + operator, could be done with '*' */ +#define REDUCE_DISTRIB DOREDUCE // A#B ~ A#C=> A#(B~C) ; # in "*/" and ~ in "+-" +#define REDUCE_ApA DOREDUCE // A+A => 2*A, not good by itself, but may creat other reduc +#define REDUCE_DIST1 DOREDUCE // A + A*C => A *(1+C) si C est csteto have all constant close +void SHOW_REDUCE(const std::string & aMes) {} // std::cout << "REDUCE " << aMes << "\n";} + + +namespace NS_MMVII_FormalDerivative +{ + +/* *************************************************** */ +/* */ +/* P0-Definition of global functions */ +/* */ +/* *************************************************** */ + + +/// The CreateCste is required for formula, so we need it also on num type +template inline Type CreateCste(const Type & aV,const Type &) { return aV; } + +/// because pow is defined in std and there is cast int->float that would make it unaccessible +template inline Type pow(const Type & aV,const int & aExp) +{ + return std::pow(aV,Type(aExp)); +} + +/* These functions are required if we want to have same operation on numbers double and formulas + They are suposed to be optimized implementation of pow for integer low value + of the exponent +*/ +template inline Type square(const Type & aV) {return aV*aV;} +template inline Type cube(const Type & aV) {return aV*aV*aV;} +template inline Type pow4(const Type & aV) {return square(square(aV));} +template inline Type pow5(const Type & aV) {return aV *pow4(aV);} +template inline Type pow6(const Type & aV) {return square(cube(aV));} +template inline Type pow7(const Type & aV) {return aV *pow6(aV);} +template inline Type pow8(const Type & aV) {return square(pow4(aV));} +template inline Type pow9(const Type & aV) {return aV *pow8(aV);} + + + //============= BASIC ERROR HANDLING ============== + + +void Error(const std::string & aMes,const std::string & aExplanation) +{ + std::cout << "In MMVII_FormalDerivative a fatal error" << "\n"; + std::cout << " Likely Source ["<< aExplanation << "\n"; + std::cout << " Message ["<< aMes << "]\n"; + assert(false); +} + /// Error due probably to internal mistake +void InternalError(const std::string & aMes) +{ + Error(aMes,"Internal Error of the Library"); +} + /// Error probably due to bas usage of the library (typically out limit vector access) +void UserSError(const std::string & aMes) +{ + Error(aMes,"Probable error on user's side due to unapropriate usage of the library"); +} + + /// Check equality in test, taking account numericall error +void AssertAlmostEqual(const double & aV1,const double & aV2,const double & aEps) +{ + if ( (std::abs(aV1-aV2)> aEps*(std::abs(aV1)+std::abs(aV2))) ) + InternalError("Test equality failed"); +} + + +/** This function computes derivates by finites difference + It is used in the tests to check correction of formal derivatives. Also used + in didactic parts. +*/ + +template +std::vector NumericalDerivate + ( + TypeFct & aFctr, ///< Function + const std::vector & aVUk, ///< Unknown + const std::vector & aVObs, ///< Observations + int aNumVar, ///< Num of unknown we derivate by + const Type & aEpsilon ///< "Small" number to compute variations + ) + +{ + + std::vector aVPlus = aVUk; + aVPlus.at(aNumVar) += aEpsilon; + std::vector aResPlus = aFctr( aVPlus,aVObs); + + std::vector aVMinus = aVUk; + aVMinus.at(aNumVar) -= aEpsilon; + std::vector aResMinus = aFctr( aVMinus,aVObs); + + std::vector aDerivate; + for (size_t aK=0 ; aK class cFormula ; + +/** Class for managing the "context", i.e. coordinating all the formula + and their derivative corresponding to a single use . +*/ +template class cCoordinatorF; + + + + + // -------- Declaration all binary operators ---------------- + + // For each operator with have the 3 versions "Formula x Formula" , + // "Number x Formula" and "Formula x Number" , the two last are rather + // syntactic suggar (i.e. make usage easier, but do not extend the library power) + + + // Operator + +template cFormula + operator +(const cFormula & aF1 ,const cFormula & aF2); +template cFormula operator +(const TypeElem & aV1,const cFormula & aF2); +template cFormula operator +(const cFormula & aF1,const TypeElem & aV2); + // Operator * +template cFormula + operator *(const cFormula & aF1 ,const cFormula & aF2); +template cFormula operator *(const TypeElem & aV1,const cFormula & aF2); +template cFormula operator *(const cFormula & aF1,const TypeElem & aV2); + // Operator - +template cFormula + operator -(const cFormula & aF1 ,const cFormula & aF2); +template cFormula operator -(const TypeElem & aV1,const cFormula & aF2); +template cFormula operator -(const cFormula & aF1,const TypeElem & aV2); + // Operator / +template cFormula + operator /(const cFormula & aF1 ,const cFormula & aF2); +template cFormula operator /(const TypeElem & aV1,const cFormula & aF2); +template cFormula operator /(const cFormula & aF1,const TypeElem & aV2); + // pow +template cFormula + pow (const cFormula & aF1 ,const cFormula & aF2); +template cFormula pow (const TypeElem & aV1,const cFormula & aF2); + /// This one defined in MMVII_FormDer_UnaryOp.h +template cFormula pow (const cFormula & aF1,const TypeElem & aV2); +template cFormula pow (const cFormula & aF1,const int & aV2); + + + // -------- integer low power ---------------- +template cFormula square(const cFormula & aF); +template cFormula cube(const cFormula & aF); +template cFormula pow4(const cFormula & aF); +template cFormula pow5(const cFormula & aF); +template cFormula pow6(const cFormula & aF); +template cFormula pow7(const cFormula & aF); +template cFormula pow8(const cFormula & aF); +template cFormula pow9(const cFormula & aF); + + // --- other unary operator +template cFormula exp(const cFormula & aF); +template cFormula operator - (const cFormula & aF); +template cFormula log(const cFormula & aF); + + // ---- sometime we need a templetized way to create constants +template cFormula CreateCste(const T & aV,const cFormula & aF); + + + /// --- powI , return pow of integral exponent, + +template Type powI(const Type & aV,const int & aExp) +{ + switch (aExp) + { + // case 0 : return Type(1.0); + case 0 : return CreateCste(1.0,aV); + case 1 : return aV; + case 2 : return square(aV); + case 3 : return cube(aV); + case 4 : return pow4(aV); + case 5 : return pow5(aV); + case 6 : return pow6(aV); + case 7 : return pow7(aV); + case 8 : return pow8(aV); + case 9 : return pow9(aV); + } + // else use the classical pow + return pow(aV,aExp); +} + + // -------- Declaration of Coordinator class ---------------- + +template class cCoordinatorF : public cMemCheck +{ + public : + + typedef cFormula tFormula; + typedef std::vector tOneRes; + + // --------------------------- Constructors / Destructor ------------------- + /// Constructor with explicit Id for Unknown/Observation. Used if we want to analyze the generated code + inline cCoordinatorF(int SzBuf,const std::vector & aVecUK,const std::vector & aVecObs); + /// Constructor with basic Id (used if we dont generate code, or dont want to analyse it by human) + inline cCoordinatorF(int SzBuf,int aNbUnknown,int aNbObservation); + /// Destructeur will free allocated formulas + ~cCoordinatorF(); + /// Copies are not allowed on this kind of object. + cCoordinatorF(const cCoordinatorF &) = delete; + + // --------------------------- Accessors to Atomic Formulas ------------------- + const std::vector& VUk() const {return mVFormUnknowns;} ///< Unknowns + const std::vector& VObs() const {return mVFormObservations;} ///< Observations + + // --------------------------- Manipulation ------------------- + + /// Set the formulas that with be used for computation + void SetCurFormulas(const std::vector &); + + /** SetCurFormulas + all its derivative , order of storage will be + VF0 dVF0/dX0 dVF0/dX1 .... VF1 dVF1/dX0 ... */ + void SetCurFormulasWithDerivative(const std::vector & aVF); + + /// Add a new set of vals (unknown + Obs) inside de evaluation "queue" + void PushNewEvals(const std::vector & aVUK,const std::vector & aVObs); + + bool BufIsFull() const {return mNbInBuf == mSzBuf;} ///< Can we push more value ? + size_t SzBuf() const {return mSzBuf;} ///< Number of value we can add + + /** Make the evaluation of current functions on pushe valuse . Let V be the result + (*V[0]) is the vector of containing current formula for first SetCur + !! => Warn the same memory space is recycled ... + */ + const std::vector & EvalAndClear(); + /// Retur value computed taking into account order of storage + const TypeElem & ValComp(int aNumPush,int aKElem) + { + return mBufRes.at(aNumPush)->at(mSzInterval*aKElem); + } + /// Retur value of derivate computed taking into account order of storage + const TypeElem & DerComp(int aNumPush,int aKElem,int aKVarDer) + { + if (! mWithDer) UserSError("Acces to derivate wich were not computed"); + return mBufRes.at(aNumPush)->at(mSzInterval*aKElem +1 + aKVarDer); + } + + /** Generate code, class cName , file cName.h, cName.cpp */ + void GenerateCode(const std::string & Name); + + private : // END-USER + /* ================================================================================= + ABOVE WAS THE REAL PUBLIC PART OF cCoordinatorF FOR USER OF LIBRARY. THE REST + IS PUBLIC FOR IMPLEMENTERS BUT NOT NEEDED BY USER + =====================================================================================*/ + public : + + // Result of several evaluation are stored in a buffer, Eigen vector are used + // as they implement efficiently arithmeticall operation + // typedef Eigen::Array tBuf; + typedef std::vector tBuf; + + + // --------------------------- Acces to function from names, values ------------------- + /// Indicate if the formula corresponding to a given string allreay exist + inline bool ExistFunc(const std::string & aName) const + { + return (mDicoFunc.find(aName) != mDicoFunc.end()); + } + /// Func of given name, Error if don't exist + inline tFormula FuncOfName(const std::string & aName) const ; + /// Add a function (put it in dico), Error if already exist + inline void AddFormula(tFormula aPF) + { + if (ExistFunc(aPF->Name())) InternalError ("Multiple add of identic name :[" + aPF->Name() + "]"); + mDicoFunc[aPF->Name()] = aPF; + mVAllFormula.push_back(aPF); + aPF->TryReducAssoc(); + } + + /// Func of given constant, create if don't exist + inline tFormula CsteOfVal(const TypeElem & aCste) ; + tFormula Cste0() const {return mCste0;} ///< Acces to a current constant + tFormula Cste1() const {return mCste1;} ///< Another Acces to a current constant + tFormula Cste2() const {return mCste2;} ///< Yet another Acces to a current constant + /// Tuning --- Print the stack of function as a tree + inline void ShowStackFunc() const; + /// Formula used for computation, + const std::vector& VReached() const {return mVReachedF;} + + + size_t NbCurFonc() const {return mVAllFormula.size();} + private : + + /// Called by PushNewEvals to Set Unknown/Observations + void SetNewVals(std::vector & aVF,const std::string & aMes,const std::vector & aVVals); + + /// Used to generate automatically Id for Unknown/Observatio, when we dont need to control them explicitely + static std::vector MakeAutomId(const std::string & aPrefix,int aNb); + + size_t mSzBuf; ///< Capacity of bufferirsation + size_t mNbCste; ///< Number Cste + size_t mNbUK; ///< Dim=number of unkown + size_t mNbObs; ///< Number of obserbation variable + std::vector mVFormUnknowns; ///< Vector of All Unknowns + std::vector mVFormObservations; ///< Vector of All Observations + std::map mDicoFunc; ///< Map Name => Func + std::vector mVAllFormula; ///< Vector of All Func, allow to parse them in creation order + std::map mDicoCste; ///< Map Value => Func Constant + tFormula mCste0; ///< Fonc constant null + tFormula mCste1; ///< Fonc constant 1 + tFormula mCste2; ///< Fonc constant 1 + size_t mNbInBuf; ///< Number of Unknown/Obs vect currenlty loaded in buf + bool mWithDer; ///< Done With Derivate + int mSzInterval; ///< Size between two val, depends if computation done with deriv + std::vector mVCurF; ///< Current evaluted formulas + std::vector mVReachedF; ///< Formula "reachable" i.e. necessary to comput mVCurF + std::vector mBufLineRes; ///< Reserve memory for each line + std::vector mBufRes; ///< Reserve memory for result itself + +}; + +/* ************************************************** + * * + * Pre-Declaration of all classes * + * Not required by compilation * + * (Except for cImplemF )but I like to have * + * a quick view of all existing classes * + * * + * **************************************************/ + +/** "Mother" Interface class of all classes implementing the service , + abstract class with pure virtual method +*/ + +template class cImplemF ; + + // --------------- "Atomic" function : Unknown, constant, observation----------------- +template class cAtomicF ; ///< Mother Class of all atomic formulas + /// "Observations" corresponding to user constant (change for each evaluation) +template class cObservationF ; + /// "Constant" function +template class cConstantF ; + /// "Unknown" for representing coordinates function X0,X1,X2 .... +template class cUnknownF; + + // ----------------------------- Unary operator ------------------------------------ +template class cUnaryF ; ///< Mother Class of all unary operator +template class cSquareF ; ///< Class for square operator +template class cExpF ; ///< Class for exponential operator +template class cMin1F ; ///< Class for Unary Minus +template class cLogF ; ///< Class for neperien log + + // -------------------------------- Binary operator ------------------------------------- +template class cBinaryF ; ///< Mother class of binary operators +template class cSumF ; ///< Class for sum of 2 functions +template class cMulF ; ///< Class for multiplication of 2 functions +template class cSubF ; ///< Class for substraction of 2 functions +template class cDivF ; ///< Class for division of 2 functions +template class cPowF ; ///< Class for division of 2 functions + + +/* *************************************************** */ +/* *************************************************** */ +/* * * */ +/* * Definition of all classes * */ +/* * * */ +/* *************************************************** */ +/* *************************************************** */ + + // ------------------- 2 "Main" Classes ------------------------- + // cFormula / cImplemF + // ---------------------------------------------------------------- + +template class cImplemF : public cMemCheck +{ + public : + // See eigen documentation, this macro is mandatory for alignment reason + // EIGEN_MAKE_ALIGNED_OPERATOR_NEW + EIGEN_ALLIGNMENT_IN_MMVII + + typedef TypeElem tElem; + typedef cCoordinatorF tCoordF; + typedef typename tCoordF::tBuf tBuf; + typedef typename tCoordF::tFormula tFormula; + + //----------- For derivation and reduction-------------- + virtual bool IsCste0() const {return false;} ///< To redefine in constant func, Used for simplification in "/ * + -" + virtual bool IsCste1() const {return false;} ///< To redefine in constant func, Used for simplification in "/ *" + virtual bool IsDistribInt() const {return false;} ///< To redefine in *,/ for distributivity + + virtual tFormula Derivate(int aK) const = 0; ///< Compute the formula of it's derivative to Kth unknown + + /** In this functionwe try to make reduction using associativity (and maybe others), + as we want to do it only on maximal chains of + (or *) this has to be run by the father of + the chain + */ + void TryReducAssoc(); + virtual cImplemF * ReducAssoc() {return this;} + virtual bool IsMult() const {return false;} + virtual bool IsSum() const {return false;} + bool ReducAssocTried() const {return mReducAssocTried;} + virtual cFormula VOper2(const tFormula &,const tFormula &) const; ///< Use in distributive reducion to recal the operator binaire if suitable + + // -------------- For Computation ------------------------- + /// Method that wil compute data inside mBuf + virtual void ComputeBuf(int aK0,int aK1) =0; + + /// Return "Sub"-formula referenced + virtual std::vector Ref() const =0; + + // ---------- Accessors --------------- + const std::string & Name() const {return mName;} ///< Standard accessor + tCoordF * CoordF() const {return mCoordF;} ///< Standard accesor + int NumGlob() const {return mNumGlob;} ///< Standard accessor + // ---------- Acces to Buf data --------------- + void SetBuf(size_t anIndex,const TypeElem & aVal) {mBuf.at(anIndex) = aVal;} + const TypeElem & GetBuf(size_t anIndex) {return mBuf.at(anIndex);} + TypeElem * DataBuf() {return mDataBuf;} + // ---------- Reached Flag --------------- + bool Reached() const {return mReached;} ///< Standard accessor + void SetReached(bool IsReached) {mReached = IsReached;} ///< Fix Reached + /// Compute in the reference graphe and put formal explored in VReached + void CalcRecursiveDepth(std::vector & VReached) ; + int Depth() const {return mDepth;} ///< Standard accessor + void SetDepth(int aDepth) {mDepth = aDepth;} ///< Fix Reached + + + // ---------- Tuning / Debugging / Analysing --------------- + /// Used to print constant from generic formula + virtual const TypeElem * ValCste() const {return nullptr;} + /// Infixed "Pretty" Print . For tuning and checking (i.e correction of reduction, derivative, rewrite ...) + virtual std::string InfixPPrint() const =0; + /// Number of reference that would occur without reduction on identic formula (to test performance in paper) + int RecursiveRec() const; + + /// Access at global level is 4 reducing, also it is used 4 implemant in Unary & Binary + virtual const std::string & NameOperator() const = 0; + + + // -------------------- Destructor / Constructor -------------------------- + virtual ~cImplemF () {} ///< Add a virtual ~X() when we have virtual methods, who knows ... + protected : + inline cImplemF (tCoordF * aCoordF,const std::string & aName) : + mCoordF (aCoordF), + mBuf (mCoordF->SzBuf(),TypeElem(0.0)), + mDataBuf (mBuf.data()), + mName (aName), + mNumGlob (mCoordF->NbCurFonc()), + mReached (false), + mDepth (-1), + mReducAssocTried (false) + { + } + + tCoordF * mCoordF; ///< Coordinator that manage all the funcion cooperating + tBuf mBuf; ///< Buf to store values + TypeElem * mDataBuf; ///< Raw pointer + const std::string mName; ///< string represention of the formula as for ex : C2, X1, V0 , square F3, F18/F3 ... + int mNumGlob; ///< Global number (!= Num in class) + bool mReached; ///< Flag to know if a formula is usefull for compute current + int mDepth; ///< Used for topological sort + private : + + cImplemF (const cImplemF &) = delete; ///< No Copy + bool mReducAssocTried; +}; + +template class cFormula +{ + public : + typedef cCoordinatorF tCoordF; + typedef cImplemF tImplemF; + typedef typename tCoordF::tFormula tFormula; + + // -------------------- constructor ------------------- + /// Construct from a pointer, standard + cFormula (tImplemF * aRawPtr) : + mPtr (aRawPtr) + { + } + /// Default constructor, required by some code (vector ?) + cFormula (): + cFormula (nullptr) + { + } + // --------------- operator on pointer --------------------- + + // UNUSED 4 NOW tImplemF & operator*() const {return *mPtr;} ///< Standard behaviour of a pointer + tImplemF * operator->() const {return mPtr;} ///< Standard behaviour of a pointer + tImplemF * RawPtr() const {return mPtr;} ///< Explicit acces + // DO NOT WORK const std::unique_ptr operator->() const {return std::unique_ptr;} + bool IsNull() const {return mPtr==nullptr;} ///< Safer than giving acces to raw pointer + + // --------------- Naming --------------------- + + /// Generate the unique indentifier of a binary expression + std::string NameFormulaBin(const std::string & aNameOper,const tFormula & aF2) const + { + return "F"+ std::to_string((*this)->NumGlob()) + aNameOper + "F" + std::to_string(aF2->NumGlob()); + } + + /// Generate the unique indentifier of a unary expression, Aux is used for add parameter like pow(F,Cste) + std::string NameFormulaUn(const std::string & aNameOper,const std::string& Aux) const + { + std::string aRes = aNameOper + " F" + std::to_string((*this)->NumGlob()) ; + if (Aux!="") aRes += " " + Aux; + return aRes; + } + /// To allow destruction without giving access to raw pointer + void FreeMem() {delete mPtr; mPtr=nullptr;} + + private : + tImplemF* mPtr; ///< Faster than shared and deallocation is easy as object controlled by context +}; + +/* *************************************************** */ +/* *************************************************** */ +/* * * */ +/* * ATOMIC FORMULA * */ +/* * * */ +/* *************************************************** */ +/* *************************************************** */ + + /* ---------------------------------------------------------- + Class for atomic formula + MOTHER CLASS : cAtomicF + DERIVED : cUnknownF / cObservationF / cConstantF + ----------------------------------------------------------------*/ + +template class cAtomicF : public cImplemF +{ + public : + typedef cImplemF tImplemF; + typedef typename tImplemF::tCoordF tCoordF; + typedef typename tCoordF::tFormula tFormula; + + /// Should work always + std::string InfixPPrint() const override {return tImplemF::Name();} + /// Rule deriv=0 , work by default (constant and observations) + tFormula Derivate(int aK) const override {return tImplemF::mCoordF->Cste0();} + + /// Generally nothing to do in atomic, their buffer has been filled witj adequate values + void ComputeBuf(int aK0,int aK1) override { } + std::vector Ref() const override{return std::vector();} + protected : + inline cAtomicF(tCoordF * aCoordF,const std::string& aName) : + tImplemF (aCoordF,aName) + { } +}; + +template class cUnknownF : public cAtomicF +{ + public : + typedef cAtomicF tAtom; + typedef typename tAtom::tImplemF tImplemF; + typedef typename tImplemF::tCoordF tCoordF; + typedef typename tCoordF::tFormula tFormula; + + const std::string & NameOperator() const override {static std::string s("UK"); return s;} + + std::string InfixPPrint() const override {return tImplemF::Name();} + /// rule : dXi/dXj = delta(i,j) + tFormula Derivate(int aK) const override + { + return (aK==mNumUnk) ? tImplemF::mCoordF->Cste1() : tImplemF::mCoordF->Cste0(); + } + + friend tCoordF; + private : + inline cUnknownF(tCoordF * aCoordF,const std::string& aName,int aNum) : + tAtom (aCoordF,aName), + mNumUnk (aNum) + { } + + int mNumUnk; ///< Number of the Unknown; like : 0 for X0, 1 for X1 ... +}; + +template class cObservationF : public cAtomicF +{ + public : + typedef cAtomicF tAtom; + typedef typename tAtom::tImplemF tImplemF; + typedef typename tImplemF::tCoordF tCoordF; + typedef typename tCoordF::tFormula tFormula; + friend tCoordF; + + const std::string & NameOperator() const override {static std::string s("Obs"); return s;} + private : + inline cObservationF(tCoordF * aCoordF,const std::string & aName,int aNum) : + tAtom (aCoordF,aName), + mNum (aNum) + { } + int mNum; ///< Number of the Observation; like : 0 for V0, 1 for V1 ... +}; + +template class cConstantF : public cAtomicF +{ + public : + typedef cAtomicF tAtom; + typedef typename tAtom::tImplemF tImplemF; + typedef typename tImplemF::tCoordF tCoordF; + typedef typename tCoordF::tFormula tFormula; + typedef typename tCoordF::tBuf tBuf; + friend tCoordF; + + bool IsCste0() const override {return mVal==0.0;} ///< Here we know if we are constant 0 + bool IsCste1() const override {return mVal==1.0;} ///< Here we know if we are constant 1 + const TypeElem * ValCste() const override {return &mVal;} + const std::string & NameOperator() const override {static std::string s("Cste"); return s;} + protected : + inline cConstantF(tCoordF * aCoordF,const std::string & aName,int aNum,const TypeElem& aVal) : + tAtom (aCoordF,aName), + mNum (aNum), + mVal (aVal) + { + for (auto & aV : tImplemF::mBuf) aV = aVal; // Initialize buf with const val + } + int mNum; + const TypeElem mVal; +}; + + +/* *************************************************** */ +/* *************************************************** */ +/* * * */ +/* * cFormula / cImplemF / cCoordinatorF * */ +/* * External Definition of methods * */ +/* * * */ +/* *************************************************** */ +/* *************************************************** */ + + /* ---------------------- */ + /* cFormula */ + /* ---------------------- */ + +template cFormula CreateCste(const T & aV,const cFormula & aF) +{ + return aF->CoordF()->CsteOfVal(aV); +} + + + /* ---------------------- */ + /* cImplemF */ + /* ---------------------- */ + +template int cImplemF::RecursiveRec() const +{ + int aRes = 1; + for (const auto & aF : Ref()) + { + aRes += aF->RecursiveRec(); + } + return aRes; +} + +template void cImplemF::CalcRecursiveDepth(std::vector & aVReached) +{ + if (mDepth != -1) return; // if we were already here , nothing to do + for (const auto & aF : Ref()) + { + aF->CalcRecursiveDepth(aVReached); // parse sub formula + mDepth = std::max(mDepth,aF->mDepth); // Memo max depth + } + mDepth++; // my depth is 1 + max of depth of my referenced formulas + aVReached.push_back(tFormula(this)); +} + +template void cImplemF::TryReducAssoc() +{ + for (auto & aF : Ref()) + { + // F will not belong to the terminal command that will have to reparsed + // If we are in the config (A+B) + .. maybe the chain will grow later + if (aF->NameOperator() != NameOperator()) + { + aF = aF->ReducAssoc(); + } + aF->mReducAssocTried = true; + } +} + +template cFormula cImplemF::VOper2(const tFormula & aF1,const tFormula &) const +{ + InternalError("Uncorrect virtula binary operation"); + return aF1; +} + + /* ---------------------- */ + /* cCoordinatorF */ + /* ---------------------- */ + +template +std::vector cCoordinatorF::MakeAutomId(const std::string & aPrefix,int aNb) +{ + std::vector aRes; + for (int aK=0 ; aK +cCoordinatorF::cCoordinatorF +( + int aSzBuf, + const std::vector & aVNameUK, + const std::vector & aVNameObs +) : + mSzBuf (aSzBuf), + mNbCste (0), + mNbUK (aVNameUK.size()), + mNbObs (aVNameObs.size()), + mCste0 (CsteOfVal(0.0)), + mCste1 (CsteOfVal(1.0)), + mCste2 (CsteOfVal(2.0)), + mNbInBuf (0), + mBufLineRes (mSzBuf), + mBufRes () + +{ + mBufRes.reserve(mSzBuf); + // Generate all the function corresponding to unknown + for (size_t aNumUK=0 ; aNumUK(this,aVNameUK[aNumUK],aNumUK)); // Create it + mVFormUnknowns.push_back(aFuncUK); // Push it in vector of coordinat func + AddFormula(aFuncUK); // Add to all func + } + + // Generate all the function corresponding to observations + for (size_t aNumObs=0 ; aNumObs(this,aVNameObs[aNumObs],aNumObs)); // Create it + mVFormObservations.push_back(aFuncObs); // Push it in vector of coordinat func + AddFormula(aFuncObs); // Add to all func + } +} + +template +cCoordinatorF::cCoordinatorF(int aSzBuf,int aNbUK,int aNbObs) : + cCoordinatorF(aSzBuf,MakeAutomId("X",aNbUK),MakeAutomId("V",aNbObs)) +{ +} + +template +cCoordinatorF::~cCoordinatorF() +{ + for (auto & aForm : mVAllFormula) + { + aForm.FreeMem(); + } +} + +template +cFormula cCoordinatorF::CsteOfVal(const TypeElem & aCste) +{ + tFormula & aRef = mDicoCste[aCste]; + if (aRef.IsNull()) // If it was not existing, the map contain now the def element + { + // The ! is used to make constant first in alphab order, used for reduction ? + aRef=tFormula(new cConstantF(this,"_C"+std::to_string(mNbCste),mNbCste,aCste)); + mNbCste++; + AddFormula(aRef); + } + + return aRef; +} + +template +cFormula cCoordinatorF::FuncOfName(const std::string & aName) const +{ + const auto & anIt = mDicoFunc.find(aName); + if (anIt == mDicoFunc.end()) InternalError ("Try to acces non existing name :[" + aName + "]"); + return anIt->second; +} + +template +void cCoordinatorF::SetNewVals + ( + std::vector & aVF, + const std::string & aMes, + const std::vector & aVVals + ) +{ + if (aVF.size() != aVVals.size()) // Check size are coherents + { + UserSError("Bad size in " + aMes); + } + for (size_t aK=0 ; aKSetBuf(mNbInBuf,aVVals[aK]); + } +} + +template +void cCoordinatorF::PushNewEvals + ( + const std::vector & aVUK, + const std::vector & aVObs + ) +{ + + if (mNbInBuf >= mSzBuf) + { + UserSError("Push exceed buffer capacity"); + } + SetNewVals(mVFormUnknowns,"Unknowns",aVUK); + SetNewVals(mVFormObservations,"Observations",aVObs); + mNbInBuf++; +} + + +template +void cCoordinatorF::SetCurFormulasWithDerivative(const std::vector & aVF) +{ + std::vector aVWDer; + for (const auto & aF : aVF) + { + aVWDer.push_back(aF); + for (size_t aUK=0 ; aUKDerivate(aUK)); + } + } + SetCurFormulas(aVWDer); + mWithDer = true; + mSzInterval = 1+mNbUK; +} + +template +void cCoordinatorF::SetCurFormulas(const std::vector & aVF0) +{ + std::vector aVF; + for(auto aF : aVF0) + { + if (! aF->ReducAssocTried()) + { + aF = tFormula(aF->ReducAssoc()); + // std::cout << "GGGGGGGG " << aF->Name() << " \n"; + } + aVF.push_back(aF); + } + mWithDer=false; + mSzInterval = 1; + mVCurF = aVF; + + // Erase previous + for (auto & aF : mVReachedF) + aF->SetDepth(-1); + mVReachedF.clear(); + + // Compute depth for topologicall sort + for (auto & aF : mVCurF) + { + aF->CalcRecursiveDepth(mVReachedF); + } + + // Use depth to have topological sort + // In fact it is probably not necessary to make this sort, initial order of reaching order + // should work; by the way : no dammage .. + std::sort + ( + mVReachedF.begin(), + mVReachedF.end(), + [](const tFormula & aF1,const tFormula &aF2) {return aF1->Depth() < aF2->Depth();} + ); + + + // Make Buf of Res to have right size + for (auto & aLine : mBufLineRes) + { + aLine.resize(mVCurF.size()); + } +} + +template +const std::vector *> & cCoordinatorF::EvalAndClear() +{ + // Make the real hard stuff, compute the data, the depedancy ordering should make it coherent + for (auto & aF : mVReachedF) + { + aF->ComputeBuf(0,mNbInBuf); + } + + mBufRes.clear(); + for (size_t aKLine=0 ; aKLine & aLine = mBufLineRes[aKLine]; + mBufRes.push_back(&aLine); + for (size_t aKFunc=0 ; aKFunc< mVCurF.size() ; aKFunc++) + aLine[aKFunc] = mVCurF[aKFunc]->GetBuf(aKLine); + } + mNbInBuf = 0; + + return mBufRes; +} + +template +void cCoordinatorF::ShowStackFunc() const +{ + for (const auto & aForm : mVAllFormula) + { + if (aForm->Depth()==-1) + std::cout << "---" ; + else + std::cout << "-" << aForm->Depth() << "-"; + + std::cout << " Form[" << aForm->NumGlob() << "] => " << aForm->Name(); + const TypeElem * aPV = aForm->ValCste(); + if (aPV) + std::cout << " ; Val=" << *aPV; + std::cout << "\n"; + } + + std::cout << "REACHED "; + for (const auto & aForm : mVReachedF) + { + std::cout << aForm->NumGlob() << " "; + } + std::cout << "\n"; + + std::cout << "CUR "; + for (const auto & aForm : mVCurF) + { + std::cout << aForm->NumGlob() << " "; + } + std::cout << "\n"; +} + + +}; // NS_MMVII_FormalDerivative + +#include "MMVII_FormDer_UnaryOp.h" +#include "MMVII_FormDer_BinaryOp.h" + + + +/* +https://www.itl.nist.gov/div898/strd/nls/data/ratkowsky3.shtml +http://en.wikipedia.org/wiki/Automatic_differentiation +https://git.irc.umbc.edu/photorig/openMVG/blob/260584fda68dce095e279362efd24a2d7d7cf5d9/src/third_party/ceres-solver/include/ceres/jet.h + +https://mc-stan.org/ +http://www.met.reading.ac.uk/clouds/adept/array_features.html +http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.89.7749&rep=rep1&type=pdf +http://www.autodiff.org/ +*/ + +#endif // _MMVII_FormalDerivative_H_ diff --git a/MMVII/include/MMVII_Images.h b/MMVII/include/MMVII_Images.h index f82f74d788..14e9485748 100644 --- a/MMVII/include/MMVII_Images.h +++ b/MMVII/include/MMVII_Images.h @@ -506,6 +506,7 @@ template class cDataIm2D : public cDataTypedIm /// Raw image, lost all waranty is you use it... tVal ** ExtractRawData2D() {return mRawData2D;} + const tPVal * ExtractRawData2D() const {return mRawData2D;} protected : private : void PostInit(); diff --git a/MMVII/include/MMVII_NonLinear2DFiltering.h b/MMVII/include/MMVII_NonLinear2DFiltering.h index 92b075dc69..258c9aae91 100644 --- a/MMVII/include/MMVII_NonLinear2DFiltering.h +++ b/MMVII/include/MMVII_NonLinear2DFiltering.h @@ -14,12 +14,16 @@ namespace MMVII /* */ /* *********************************************** */ +/// Curvature in the level-line direction ; +or- corner detector template cIm2D CourbTgt(cIm2D aImIn); +/// Idem but apply to itself template void SelfCourbTgt(cIm2D aImIn); +/// Majoritar label in a given neighbouhoord template void SelfLabMaj(cIm2D aImIn,const cBox2di &); +/// Basic laplacien cIm2D Lapl(cIm2D aImIn); // Well linear ... diff --git a/MMVII/include/MMVII_Sys.h b/MMVII/include/MMVII_Sys.h index 741e83d63a..47dc3193a4 100644 --- a/MMVII/include/MMVII_Sys.h +++ b/MMVII/include/MMVII_Sys.h @@ -44,7 +44,7 @@ const eSYS TheSYS = eSYS::MacOs; int mmvii_NbProcSys(); int mmvii_GetPId(); -int SysCall(const std::string &, bool SVP=false); ///< call system, if SVP=false error not EXIT_SUCCESS +int GlobSysCall(const std::string &, bool SVP=false); ///< call system, if SVP=false error not EXIT_SUCCESS /// A fake function, to stop momentarilly warnings about unused variable ... diff --git a/MMVII/include/MMVII_all.h b/MMVII/include/MMVII_all.h index 961371d381..00df1443cf 100644 --- a/MMVII/include/MMVII_all.h +++ b/MMVII/include/MMVII_all.h @@ -70,6 +70,7 @@ // communication MMVII/MMv1 #include "MMVII_MMV1Compat.h" +// #include "MMVII_Derivatives.h" => not include by default now, requires => time consuming #endif // _MMVII_ALL_H_ diff --git a/MMVII/include/MMVII_enums.h b/MMVII/include/MMVII_enums.h index 5e8d39aac5..3bbf2394e2 100644 --- a/MMVII/include/MMVII_enums.h +++ b/MMVII/include/MMVII_enums.h @@ -55,13 +55,15 @@ enum class eApF enum class eApDT { Ori, ///< Orientation + PCar, ///< Tie Points TieP, ///< Tie Points - Image, ///< Tie Points + Image, ///< Image Ply, ///< Ply file None, ///< Nothing Console, ///< Console Xml, ///< Xml-files FileSys, ///< Input is the file system (list of file) + Media, ///< Input is the file system (list of file) eNbVals ///< Tag for number of value }; @@ -117,6 +119,7 @@ enum class eTyUEr eParseError, eBadDimForPt, eBadSize4Vect, + eMultiplePostifx, eUnClassedError, eNbVals }; diff --git a/MMVII/include/MMVII_nums.h b/MMVII/include/MMVII_nums.h index beb154f6f8..67212a693d 100644 --- a/MMVII/include/MMVII_nums.h +++ b/MMVII/include/MMVII_nums.h @@ -409,6 +409,7 @@ inline tREAL8 FracPart(tREAL8 r) {return r - round_down(r);} template Type Square(const Type & aV) {return aV*aV;} +template Type Cube(const Type & aV) {return aV*aV*aV;} template TCast TSquare(const Type & aV) {return aV* TCast(aV);} template tREAL8 R8Square(const Type & aV) {return TSquare(aV);} ///< To avoid oveflow with int type @@ -449,10 +450,10 @@ tREAL8 CubAppGaussVal(const tREAL8&); /* Witch Min and Max */ /* ********************************** */ -template class cWitchMin +template class cWhitchMin { public : - cWitchMin(const TypeIndex & anIndex,const TypeVal & aVal) : + cWhitchMin(const TypeIndex & anIndex,const TypeVal & aVal) : mIndexMin (anIndex), mVMin (aVal) { @@ -471,10 +472,10 @@ template class cWitchMin TypeIndex mIndexMin; TypeVal mVMin; }; -template class cWitchMax +template class cWhitchMax { public : - cWitchMax(const TypeIndex & anIndex,const TypeVal & aVal) : + cWhitchMax(const TypeIndex & anIndex,const TypeVal & aVal) : mIndexMax (anIndex), mVMax (aVal) { @@ -493,10 +494,10 @@ template class cWitchMax TypeIndex mIndexMax; TypeVal mVMax; }; -template class cWitchMinMax +template class cWhitchMinMax { public : - cWitchMinMax(const TypeIndex & anIndex,const TypeVal & aVal) : + cWhitchMinMax(const TypeIndex & anIndex,const TypeVal & aVal) : mMin(anIndex,aVal), mMax(anIndex,aVal) { @@ -506,12 +507,12 @@ template class cWitchMinMax mMin.Add(anIndex,aVal); mMax.Add(anIndex,aVal); } - const cWitchMin & Min() const {return mMin;} - const cWitchMax & Max() const {return mMax;} + const cWhitchMin & Min() const {return mMin;} + const cWhitchMax & Max() const {return mMax;} private : - cWitchMin mMin; - cWitchMax mMax; + cWhitchMin mMin; + cWhitchMax mMax; }; diff --git a/MMVII/include/MMVII_util.h b/MMVII/include/MMVII_util.h index c627dcb054..89ac971a25 100644 --- a/MMVII/include/MMVII_util.h +++ b/MMVII/include/MMVII_util.h @@ -67,6 +67,8 @@ void SplitStringArround(std::string & aBefore,std::string & aAfter,const std::s std::string Prefix(const std::string & aStr,char aSep='.',bool SVP=false,bool PrivPref=true); std::string Postfix(const std::string & aStr,char aSep='.',bool SVP=false,bool PrivPref=true); +std::string LastPostfix(const std::string & aStr,char aSep='.'); ///< No error: a=> "" a.b.c => "c" + // Direcytory and files names, Rely on boost void MakeNameDir(std::string & aDir); ///< Add a '/', or equiv, to make a name of directory @@ -128,6 +130,8 @@ int FromHexaCode(char aC); try to offer them from a more secured way. The Write(const Type & ) are typed ; it calss VoidWrite which check the number of byte written (if enough debug) + + No need for close() as it done automatically at destroy in std::ofstream. */ class cMMVII_Ofs : public cMemCheck { diff --git a/MMVII/include/cMMVII_Appli.h b/MMVII/include/cMMVII_Appli.h index 4640c3c99a..151aaec55b 100644 --- a/MMVII/include/cMMVII_Appli.h +++ b/MMVII/include/cMMVII_Appli.h @@ -308,7 +308,11 @@ class cMMVII_Appli : public cMMVII_Ap_NameManip, cMultipleOfs & HelpOut(); cMultipleOfs & ErrOut(); - ///< MMVII call itself + ///< External call sys : use GlobalSysCall + register the command in log files + int ExtSysCall(const std::string & aCom, bool SVP); + + + /// MMVII call itself int ExeCallMMVII(const cSpecMMVII_Appli & aCom,const cColStrAObl&,const cColStrAOpt&,bool ByLineCom=true); void ExeMultiAutoRecallMMVII ( const std::string & aNameOpt , //! Name of parameter to substitue @@ -337,6 +341,7 @@ class cMMVII_Appli : public cMMVII_Ap_NameManip, void InitParam(); ///< Parse the parameter list + const std::string & TopDirMMVII() const; ///< main directory of MMVII , upon include,src .. const std::string & TmpDirTestMMVII() const; ///< where to put binary file for bench, Export for global bench funtion const std::string & InputDirTestMMVII() const; ///< where are input files for bench , Export for global bench funtion diff --git a/MMVII/src/Appli/MMVI_Errors.cpp b/MMVII/src/Appli/MMVI_Errors.cpp index e9ee9729da..030c74bf9c 100644 --- a/MMVII/src/Appli/MMVI_Errors.cpp +++ b/MMVII/src/Appli/MMVI_Errors.cpp @@ -54,6 +54,10 @@ void MMVII_UsersErrror(const eTyUEr & aRef,const std::string & aMes) ); } +void MMVII_UnclasseUsEr(const std::string & aMes) +{ + MMVII_UsersErrror(eTyUEr::eUnClassedError,aMes); +} /// Warning : temporary version /** Will evolve significativelly as MMVII grows diff --git a/MMVII/src/Appli/cMMVII_Appli.cpp b/MMVII/src/Appli/cMMVII_Appli.cpp index feb27b831f..15c0b5f0f5 100644 --- a/MMVII/src/Appli/cMMVII_Appli.cpp +++ b/MMVII/src/Appli/cMMVII_Appli.cpp @@ -70,7 +70,7 @@ int cParamCallSys::Execute() const else { // StdOut() << "EXTERN cParamCallSys:: \n"; - int aRes = SysCall(mCom,false); + int aRes = GlobSysCall(mCom,false); // StdOut() << " ##### EXTERN cParamCallSys:: " << aRes << " \n"; return aRes; } @@ -306,6 +306,15 @@ void cMMVII_Appli::InitParam() { mArgFac << AOpt2007(mCarPPrefOut,"CarPOut","Name for Output caracteristic points",{eTA2007::HDV}); } + if (HasSharedSPO(eSharedPO::eSPO_CarPI)) + { + mArgFac << AOpt2007(mCarPPrefIn,"CarPIn","Name for Input caracteristic points",{eTA2007::HDV}); + } + + + + + // To not put intervals in help/parameters when they are not usefull { bool HasMain0 = false; @@ -409,18 +418,15 @@ void cMMVII_Appli::InitParam() MMVII_INTERNAL_ASSERT_always(false,"\""+ aName +"\" is multiple in specification"); } // Same name was used several time - if (aSpec->NbMatch() !=0) - { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eMulOptParam,"\""+aName +"\" was used multiple time"); - } + MMVII_INTERNAL_ASSERT_User + ( aSpec->NbMatch()==0 ,eTyUEr::eMulOptParam,"\""+aName +"\" was used multiple time"); aSpec->IncrNbMatch(); } } // Name does not correspond to spec - if (aNbSpecGot==0) - { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eBadOptParam,"\""+aName +"\" is not a valide optionnal value"); - } + MMVII_INTERNAL_ASSERT_User + ( aNbSpecGot!=0 ,eTyUEr::eBadOptParam,"\""+aName +"\" is not a valide optionnal value"); + aVValues.push_back(aValue); } else @@ -443,7 +449,7 @@ void cMMVII_Appli::InitParam() GenerateHelp(); return; } - MMVII_INTERNAL_ASSERT_user + MMVII_UsersErrror ( eTyUEr::eInsufNbParam, "Not enough Arg, expecting " + ToS(aNbObl) + " , Got only " + ToS(aNbArgGot) @@ -621,7 +627,7 @@ void cMMVII_Appli::InitParam() // Why should user init interval if there no set ? if (IsInit(&mIntervFilterMS[aNum]) && (! mVMainSets.at(aNum).IsInit())) { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eIntervWithoutSet,"Interval without filter for num:"+ToStr(aNum)); + MMVII_UsersErrror(eTyUEr::eIntervWithoutSet,"Interval without filter for num:"+ToStr(aNum)); } if (aNum>0) { @@ -992,6 +998,7 @@ void cMMVII_Appli::MMVII_WARNING(const std::string & aMes) // Accessors const std::string & cMMVII_Appli::TmpDirTestMMVII() const {return mTmpDirTestMMVII;} const std::string & cMMVII_Appli::InputDirTestMMVII() const {return mInputDirTestMMVII;} +const std::string & cMMVII_Appli::TopDirMMVII() const {return mTopDirMMVII;} void cMMVII_Appli::InitOutFromIn(std::string &aFileOut,const std::string& aFileIn) @@ -1138,6 +1145,24 @@ std::list cMMVII_Appli::ListStrCallMMVII return aRes; } +int cMMVII_Appli::ExtSysCall(const std::string & aCom, bool SVP) +{ + std::string aName = NameFileLog(false); + { + cMMVII_Ofs aOfs(aName,true); + aOfs.Ofs() << " --- begining at : " << StrDateCur() << "\n"; + aOfs.Ofs() << " ExtCom : [" << aCom << "]\n"; + aOfs.Ofs().close(); + } + int aResult = GlobSysCall(aCom,SVP); + { + cMMVII_Ofs aOfs(aName,true); + aOfs.Ofs() << " --- ending at : " << StrDateCur() << "\n\n"; + aOfs.Ofs().close(); + } + return aResult; +} + int cMMVII_Appli::ExeCallMMVII @@ -1149,7 +1174,7 @@ int cMMVII_Appli::ExeCallMMVII ) { cParamCallSys aComGlob = StrCallMMVII(aCom2007,anAObl,anAOpt,!ByLineCom); - return SysCall(aComGlob.Com(),false); + return GlobSysCall(aComGlob.Com(),false); } int cMMVII_Appli::ExeComSerial(const std::list & aL) diff --git a/MMVII/src/Appli/cSpecMMVII_Appli.cpp b/MMVII/src/Appli/cSpecMMVII_Appli.cpp index 92308767ce..49f18d8c16 100644 --- a/MMVII/src/Appli/cSpecMMVII_Appli.cpp +++ b/MMVII/src/Appli/cSpecMMVII_Appli.cpp @@ -131,12 +131,14 @@ std::vector & cSpecMMVII_Appli::InternVecAll() TheVecAll.push_back(&TheSpecEditRel); TheVecAll.push_back(&TheSpecWalkman); TheVecAll.push_back(&TheSpecDaisy); + TheVecAll.push_back(&TheSpecCatVideo); TheVecAll.push_back(&TheSpec_TestEigen); TheVecAll.push_back(&TheSpec_ComputeParamIndexBinaire); TheVecAll.push_back(&TheSpecTestRecall); TheVecAll.push_back(&TheSpecScaleImage); TheVecAll.push_back(&TheSpecCalcDiscIm); TheVecAll.push_back(&TheSpecCalcDescPCar); + TheVecAll.push_back(&TheSpecMatchTieP); std::sort(TheVecAll.begin(),TheVecAll.end(),CmpCmd); } diff --git a/MMVII/src/Bench/BenchGlob.cpp b/MMVII/src/Bench/BenchGlob.cpp index c772a180a3..20e4cb9ada 100644 --- a/MMVII/src/Bench/BenchGlob.cpp +++ b/MMVII/src/Bench/BenchGlob.cpp @@ -219,6 +219,8 @@ int cAppli_MMVII_Bench::Exe() CreateDirectories(TmpDirTestMMVII(),true ); RemoveRecurs(TmpDirTestMMVII(),true,false); + // Test jets + BenchMyJets(); // On teste les macro d'assertion MMVII_INTERNAL_ASSERT_bench((1+1)==2,"Theoreme fondamental de l'arithmetique"); @@ -477,11 +479,22 @@ class cAppli_MPDTest : public cMMVII_Appli cAppli_MPDTest(const std::vector & aVArgs,const cSpecMMVII_Appli & aSpec); int Exe() override; cCollecSpecArg2007 & ArgObl(cCollecSpecArg2007 & anArgObl) override {return anArgObl;} - cCollecSpecArg2007 & ArgOpt(cCollecSpecArg2007 & anArgOpt) override {return anArgOpt;} + cCollecSpecArg2007 & ArgOpt(cCollecSpecArg2007 & anArgOpt) override ; + private : + bool mMMV1_GenCodeTestCam; }; +cCollecSpecArg2007 & cAppli_MPDTest::ArgOpt(cCollecSpecArg2007 & anArgOpt) +{ + return + anArgOpt + << AOpt2007(mMMV1_GenCodeTestCam,"V1_GCTC","Generate code for Test Cam") + ; +} + cAppli_MPDTest:: cAppli_MPDTest(const std::vector & aVArgs,const cSpecMMVII_Appli & aSpec) : - cMMVII_Appli (aVArgs,aSpec) + cMMVII_Appli (aVArgs,aSpec), + mMMV1_GenCodeTestCam (false) { } @@ -581,6 +594,20 @@ void ShowAdr(double & anAdr) // #include int cAppli_MPDTest::Exe() { + if (mMMV1_GenCodeTestCam) + { + //StdOut() << "kkk=[" << mTopDirMMVII <<"]\n"; + MMV1_GenerateCodeTestCam(); + return EXIT_SUCCESS; + } + { + // Si on le met a 10h => reveil a 6h20 + double t = 8.0; + sleep(3600.0 * t); + std::string aName= "/home/mpd/Bureau/Perso1/Musik/Bach/bach-goldberg-variations-bwv-988-glenn-gould-1981.mp3"; + aName = "cvlc " + aName; + StdOut() << system(aName.c_str()) << "\n";; + } { cPt3dr * anAdr = nullptr; StdOut () << "ADDDDDr " << anAdr << "\n"; diff --git a/MMVII/src/Bench/BenchMatrix.cpp b/MMVII/src/Bench/BenchMatrix.cpp index 174c970841..830364c9c6 100644 --- a/MMVII/src/Bench/BenchMatrix.cpp +++ b/MMVII/src/Bench/BenchMatrix.cpp @@ -523,8 +523,9 @@ template void BenchSysSur(cSysSurResolu& aSys,bool Exact) aNewV(aK) = aSol(aK) + aEps * RandUnif_C(); Type aRN = Residual(aSys,aNewV,aLWeight,aLVec,aLVal); + // StdOut() << "RRRRR " << aRN-aR0 << "\n"; - MMVII_INTERNAL_ASSERT_bench(aRN>aR0,"Bench residual "); + MMVII_INTERNAL_ASSERT_bench(aRN>=aR0-1e-7,"Bench residual "); // double aD = aSol.DIm().L2Dist(aNewV.DIm()); // StdOut() << " D=" << aD << "Dif " << (aRN-aR0) /Square(aD) << "\n"; diff --git a/MMVII/src/CalcDescriptPCar/cAimeTieP.cpp b/MMVII/src/CalcDescriptPCar/cAimeTieP.cpp index 541d8000cc..d48484951f 100644 --- a/MMVII/src/CalcDescriptPCar/cAimeTieP.cpp +++ b/MMVII/src/CalcDescriptPCar/cAimeTieP.cpp @@ -19,12 +19,69 @@ cIm2D cAimeDescriptor::ILP() {return mILP;} const std::vector & cAimeDescriptor::DirPrinc() const {return mDirPrinc;} std::vector & cAimeDescriptor::DirPrinc() {return mDirPrinc;} +double cAimeDescriptor::DistanceFromIShift(const cAimeDescriptor & aAD2,int aShift,const cSetAimePCAR & aSet) const +{ + const cDataIm2D & aDIm1(mILP.DIm()); + cPt2di aSz1= aDIm1.Sz(); + tU_INT1 * const * aData1 = aDIm1.ExtractRawData2D(); + + const cDataIm2D & aDIm2(aAD2.mILP.DIm()); + cPt2di aSz2= aDIm2.Sz(); + tU_INT1 * const * aData2 = aDIm2.ExtractRawData2D(); + + MMVII_INTERNAL_ASSERT_tiny(aSz1==aSz2,"cAimeDescriptor::Distance"); + int aNbX = aSz1.x(); + aShift = mod(aShift,aNbX); + int aIRes = 0; + + for (int aY=0 ; aY cAimeDescriptor::DistanceFromBestPeek(const cAimeDescriptor & aAD2,const cSetAimePCAR & aSet) const +{ + cWhitchMin aWMin(-1,1e60); + for (int aK=0 ; aK bool cProtoAimeTieP::FillAPC(const cFilterPCar& aFP if (aCensusMode) { // double aVN = aV0/aVCentral; - aValRes = 128 * (1+ NormalisedRatio(aV0,aVCentral)); + aValRes = 128 + cSetAimePCAR::TheCensusMult * NormalisedRatio(aV0,aVCentral); } else { @@ -252,24 +309,45 @@ template bool cProtoAimeTieP::TestFillAPC(const cFilterPCar& a /* cSetAimePCAR */ /* ================================= */ +const double cSetAimePCAR::TheCensusMult = 128.0; + cSetAimePCAR::cSetAimePCAR(eTyPyrTieP aType,bool IsMax) : mType ((int)aType), mIsMax (IsMax) { } +cSetAimePCAR::cSetAimePCAR(): + cSetAimePCAR(eTyPyrTieP::eNbVals,true) +{ +} + + eTyPyrTieP cSetAimePCAR::Type() {return eTyPyrTieP(mType);} int & cSetAimePCAR::IType() {return mType;} bool& cSetAimePCAR::IsMax() {return mIsMax;} std::vector& cSetAimePCAR::VPC() {return mVPC;} +bool& cSetAimePCAR::Census() {return mCensus;} +const bool& cSetAimePCAR::Census() const {return mCensus;} +double& cSetAimePCAR::Ampl2N() {return mAmpl2N;} +const double& cSetAimePCAR::Ampl2N() const {return mAmpl2N;} + void AddData(const cAuxAr2007 & anAux,cSetAimePCAR & aSPC) { AddData(cAuxAr2007("Type",anAux),aSPC.IType()); AddData(cAuxAr2007("Max",anAux),aSPC.IsMax()); AddData(cAuxAr2007("VPC",anAux),aSPC.VPC() ); + AddData(cAuxAr2007("Census",anAux),aSPC.Census() ); + AddData(cAuxAr2007("Ampl2N",anAux),aSPC.Ampl2N() ); } +void cSetAimePCAR::InitFromFile(const std::string & aName) +{ + ReadFromFile(*this,aName); +} + + void cSetAimePCAR::SaveInFile(const std::string & aName) const { MMVII::SaveInFile(*this,aName); diff --git a/MMVII/src/CalcDescriptPCar/cAppliCalcPCar.cpp b/MMVII/src/CalcDescriptPCar/cAppliCalcPCar.cpp index 946ecc98cb..ce27027a76 100644 --- a/MMVII/src/CalcDescriptPCar/cAppliCalcPCar.cpp +++ b/MMVII/src/CalcDescriptPCar/cAppliCalcPCar.cpp @@ -49,6 +49,7 @@ template class cTplAppliCalcDescPCar cRect2 mBoxIn; ///< Current Input Box cPt2di mSzIn; ///< Current size of inputs cRect2 mBoxOut; ///< Current Output Box, inside wich we muste save data + int mNbTiles; ///< Number of tiles, usefull to know if we need to merge at end // To adapt dynamic StoredVal = (RealVal-mVC) / mDyn tREAL4 mVC; ///< Central Value @@ -112,6 +113,8 @@ template cTplAppliCalcDescPCar::cTplAppliCalcDescPCar(cAppliCa template void cTplAppliCalcDescPCar::ExeGlob() { cParseBoxInOut<2> aPBI = cParseBoxInOut<2>::CreateFromSizeCste(cRect2(cPt2di(0,0),mDFI.Sz()),mAppli.mSzTile); + mNbTiles = aPBI.BoxIndex().NbElem(); + MMVII_INTERNAL_ASSERT_always(mNbTiles==1,"Merge of Tiling to do ..."); for (const auto & anIndex : aPBI.BoxIndex()) { @@ -122,7 +125,6 @@ template void cTplAppliCalcDescPCar::ExeGlob() template void cTplAppliCalcDescPCar::ExeOneBox(const cPt2di & anIndex,const cParseBoxInOut<2>& aPBI) { - // std::string aPref = "Tile"+ToStr(anIndex.x())+ToStr(anIndex.y()) ; // Initialize Box, Params, gaussian pyramid mBoxIn = aPBI.BoxIn(anIndex,mAppli.mOverlap); @@ -130,7 +132,8 @@ template void cTplAppliCalcDescPCar::ExeOneBox(const cPt2di & mBoxOut = aPBI.BoxOut(anIndex); cGP_Params aGP(mSzIn,mAppli.mNbOct,mAppli.mNbLevByOct,mAppli.mNbOverLapByO,&mAppli); - aGP.mNumTile = anIndex; + // Value cPt2di(-1,-1) : special value indicating that tiles must not be written at end + aGP.mNumTile = (mNbTiles==1) ? cPt2di(-1,-1) : anIndex; // aGP.mPrefixSave = mAppli.mPrefixOut ; aGP.mScaleDirOrig = mAppli.mSDON ; aGP.mConvolIm0 = mAppli.mCI0 ; @@ -341,7 +344,7 @@ cSpecMMVII_Appli TheSpecCalcDescPCar "Compute caracteristic points and descriptors, using Aime method", {eApF::TieP,eApF::ImProc}, {eApDT::Image}, - {eApDT::TieP}, + {eApDT::PCar}, __FILE__ ); diff --git a/MMVII/src/MMV1/DenseMapCorresp.cpp b/MMVII/src/MMV1/DenseMapCorresp.cpp new file mode 100644 index 0000000000..fd97a4d4b3 --- /dev/null +++ b/MMVII/src/MMV1/DenseMapCorresp.cpp @@ -0,0 +1,8 @@ +#include "include/V1VII.h" + + +//extern std::string MM3DFixeByMMVII; + +namespace MMVII +{ +}; diff --git a/MMVII/src/MMV1/GenCodeTestCam.cpp b/MMVII/src/MMV1/GenCodeTestCam.cpp new file mode 100644 index 0000000000..e76ec19ef6 --- /dev/null +++ b/MMVII/src/MMV1/GenCodeTestCam.cpp @@ -0,0 +1,197 @@ +#include "include/V1VII.h" +#include "cGeneratedCodeTestCam.h" +#include "include/MMVII_Derivatives.h" + + +namespace MMVII +{ +/** \file GenCodeTestCam.cpp + \brief Make benchmark on generated formal code + + This file contain test to generate formal class, and use them + to make benchmark between jets and computed analyticall + +*/ + + +class cGenCodeTestCam +{ + public : + cGenCodeTestCam(); + void Generate(); + void Init(cGeneratedCodeTestCam &aGCTC); + + private : + cIncListInterv mLInterv; + cSetEqFormelles mSet; + AllocateurDInconnues & mAlloc; + cMatr_Etat_PhgrF mRot0; + cP2d_Etat_PhgrF mMesIm; + + cP3dFormel mPTer; + cP3dFormel mCCam; + cP3dFormel mOmega; + cP2dFormel mCDist; + cValFormel mK2; + cValFormel mK4; + cValFormel mK6; + cP2dFormel mPP; + cValFormel mFoc; +}; + +class cMMV1_TestCam : public cInterfaceTestCam +{ + public : + void InitFromParams(const std::vector &) override; + void Compute(std::vector & Vals,std::vector > & ) override; + void Compute(int aNb) override; + cMMV1_TestCam (); + private : + cGenCodeTestCam mGenerator; + cGeneratedCodeTestCam mCamGen; +}; + +/* *********************************************** */ +/* */ +/* cMMV1_TestCam */ +/* */ +/* *********************************************** */ + +void cMMV1_TestCam::InitFromParams(const std::vector & aVals) +{ + mCamGen.SetCoordCur(aVals.data()); +// MesIm_x + *(mCamGen.AdrVarLocFromString("MesIm_x")) = 0.0; + *(mCamGen.AdrVarLocFromString("MesIm_y")) = 0.0; + + *(mCamGen.AdrVarLocFromString("R0_0_0")) = 1.0; + *(mCamGen.AdrVarLocFromString("R0_1_0")) = 0.0; + *(mCamGen.AdrVarLocFromString("R0_2_0")) = 0.0; + + *(mCamGen.AdrVarLocFromString("R0_0_1")) = 0.0; + *(mCamGen.AdrVarLocFromString("R0_1_1")) = 1.0; + *(mCamGen.AdrVarLocFromString("R0_2_1")) = 0.0; + + *(mCamGen.AdrVarLocFromString("R0_0_2")) = 0.0; + *(mCamGen.AdrVarLocFromString("R0_1_2")) = 0.0; + *(mCamGen.AdrVarLocFromString("R0_2_2")) = 1.0; + +} + +cMMV1_TestCam::cMMV1_TestCam () +{ + mGenerator.Init(mCamGen); +} + +void cMMV1_TestCam::Compute(std::vector & aVals,std::vector > & aDeriv) +{ + mCamGen.ComputeValDeriv(); + aVals = mCamGen.ValSsVerif(); + aDeriv = mCamGen.CompDerSsVerif(); +} + +void cMMV1_TestCam::Compute(int aNb) +{ + for (int aK=0 ; aK aPCam = mRot0.Mat() * (mPTer.FPt()-mCCam.FPt()); + aPCam = aPCam + (mOmega.FPt() ^ aPCam); + + Pt2d aPi (aPCam.x/aPCam.z,aPCam.y/aPCam.z); + Pt2d aCdPi = aPi-mCDist.FPt(); + Fonc_Num aRho2 = Square(aCdPi.x) + Square(aCdPi.y); + Fonc_Num aRho4 = Square(aRho2); + Fonc_Num aRho6 = Cube(aRho2); + + Fonc_Num aCoeffDist = mK2.FVal()*aRho2 + mK4.FVal()*aRho4 + mK6.FVal()*aRho6; + Pt2d aPDist = aPi + Pt2d(aCdPi.x*aCoeffDist,aCdPi.y*aCoeffDist); + Pt2d aPProj = mPP.FPt() + Pt2d(aPDist.x*mFoc.FVal(),aPDist.y*mFoc.FVal()); + Pt2d aResidu = aPProj-mMesIm.PtF(); + + std::string aDirApp = cMMVII_Appli::CurrentAppli().TopDirMMVII() ; + cElCompileFN::DoEverything + ( + aDirApp + "src/MMV1/", // Directory ou est localise le code genere + "cGeneratedCodeTestCam", // donne les noms de .cpp et .h de classe + // std::vector ({aPi.x,aPi.y}), // expressions formelles + std::vector ({aResidu.x,aResidu.y}), // expressions formelles + mLInterv // intervalle de reference + ); + + +} + + +void MMV1_GenerateCodeTestCam() +{ + if (1) + { + cGenCodeTestCam aGCTC; + aGCTC.Generate(); + } + if (0) + { + double aVVals[30]; + cGenCodeTestCam aGen; + cGeneratedCodeTestCam aCamGen; + aGen.Init(aCamGen); + aCamGen.SetCoordCur(aVVals); + aCamGen.ComputeValDeriv(); + + } +} + + + +}; diff --git a/MMVII/src/MMV1/XmlMMV1.cpp b/MMVII/src/MMV1/XmlMMV1.cpp index 2c7568e35e..2898c51019 100644 --- a/MMVII/src/MMV1/XmlMMV1.cpp +++ b/MMVII/src/MMV1/XmlMMV1.cpp @@ -200,6 +200,16 @@ template mMMV1_XmlPts.TypePt() = int(ATypePt); mMMV1_XmlPts.NameTypePt() = aNameType; + if (mFPC.LPS_CensusMode()) + { + mSetAPC.Census() = true; + mSetAPC.Ampl2N() = cSetAimePCAR::TheCensusMult; + } + else + { + mSetAPC.Census() = false; + mSetAPC.Ampl2N() = mFPC.LPS_Mult(); + } } template cImplem_ExportAimeTiep::~cImplem_ExportAimeTiep() { diff --git a/MMVII/src/MMV1/cGeneratedCodeTestCam.cpp b/MMVII/src/MMV1/cGeneratedCodeTestCam.cpp new file mode 100644 index 0000000000..43478da79f --- /dev/null +++ b/MMVII/src/MMV1/cGeneratedCodeTestCam.cpp @@ -0,0 +1,542 @@ +// File Automatically generated by eLiSe +#include "StdAfx.h" +#include "cGeneratedCodeTestCam.h" + + +cGeneratedCodeTestCam::cGeneratedCodeTestCam(): + cElCompiledFonc(2) +{ + AddIntRef (cIncIntervale("CCam",3,6)); + AddIntRef (cIncIntervale("CD",9,11)); + AddIntRef (cIncIntervale("F",16,17)); + AddIntRef (cIncIntervale("K2",11,12)); + AddIntRef (cIncIntervale("K4",12,13)); + AddIntRef (cIncIntervale("K6",13,14)); + AddIntRef (cIncIntervale("PGr",0,3)); + AddIntRef (cIncIntervale("PP",14,16)); + AddIntRef (cIncIntervale("W",6,9)); + Close(false); +} + + + +void cGeneratedCodeTestCam::ComputeVal() +{ + double tmp0_ = mCompCoord[0]; + double tmp1_ = mCompCoord[3]; + double tmp2_ = tmp0_ - tmp1_; + double tmp3_ = mCompCoord[1]; + double tmp4_ = mCompCoord[4]; + double tmp5_ = tmp3_ - tmp4_; + double tmp6_ = mCompCoord[2]; + double tmp7_ = mCompCoord[5]; + double tmp8_ = tmp6_ - tmp7_; + double tmp9_ = mLocR0_0_2 * (tmp2_); + double tmp10_ = mLocR0_1_2 * (tmp5_); + double tmp11_ = tmp9_ + tmp10_; + double tmp12_ = mLocR0_2_2 * (tmp8_); + double tmp13_ = tmp11_ + tmp12_; + double tmp14_ = mLocR0_0_1 * (tmp2_); + double tmp15_ = mLocR0_1_1 * (tmp5_); + double tmp16_ = tmp14_ + tmp15_; + double tmp17_ = mLocR0_2_1 * (tmp8_); + double tmp18_ = tmp16_ + tmp17_; + double tmp19_ = mCompCoord[7]; + double tmp20_ = mLocR0_0_0 * (tmp2_); + double tmp21_ = mLocR0_1_0 * (tmp5_); + double tmp22_ = tmp20_ + tmp21_; + double tmp23_ = mLocR0_2_0 * (tmp8_); + double tmp24_ = tmp22_ + tmp23_; + double tmp25_ = tmp19_ * (tmp13_); + double tmp26_ = mCompCoord[8]; + double tmp27_ = tmp26_ * (tmp18_); + double tmp28_ = tmp25_ - tmp27_; + double tmp29_ = tmp24_ + tmp28_; + double tmp30_ = mCompCoord[6]; + double tmp31_ = tmp30_ * (tmp18_); + double tmp32_ = tmp19_ * (tmp24_); + double tmp33_ = tmp31_ - tmp32_; + double tmp34_ = tmp13_ + tmp33_; + double tmp35_ = (tmp29_) / (tmp34_); + double tmp36_ = mCompCoord[9]; + double tmp37_ = tmp35_ - tmp36_; + double tmp38_ = ElSquare(tmp37_); + double tmp39_ = tmp26_ * (tmp24_); + double tmp40_ = tmp30_ * (tmp13_); + double tmp41_ = tmp39_ - tmp40_; + double tmp42_ = tmp18_ + tmp41_; + double tmp43_ = (tmp42_) / (tmp34_); + double tmp44_ = mCompCoord[10]; + double tmp45_ = tmp43_ - tmp44_; + double tmp46_ = ElSquare(tmp45_); + double tmp47_ = tmp38_ + tmp46_; + double tmp48_ = mCompCoord[11]; + double tmp49_ = tmp48_ * (tmp47_); + double tmp50_ = mCompCoord[12]; + double tmp51_ = ElSquare(tmp47_); + double tmp52_ = tmp50_ * tmp51_; + double tmp53_ = tmp49_ + tmp52_; + double tmp54_ = mCompCoord[13]; + double tmp55_ = VCube(tmp47_); + double tmp56_ = tmp54_ * tmp55_; + double tmp57_ = tmp53_ + tmp56_; + double tmp58_ = mCompCoord[16]; + + mVal[0] = (mCompCoord[14] + (tmp35_ + (tmp37_) * (tmp57_)) * tmp58_) - mLocMesIm_x; + + mVal[1] = (mCompCoord[15] + (tmp43_ + (tmp45_) * (tmp57_)) * tmp58_) - mLocMesIm_y; + +} + + +void cGeneratedCodeTestCam::ComputeValDeriv() +{ + double tmp0_ = mCompCoord[0]; + double tmp1_ = mCompCoord[3]; + double tmp2_ = tmp0_ - tmp1_; + double tmp3_ = mCompCoord[1]; + double tmp4_ = mCompCoord[4]; + double tmp5_ = tmp3_ - tmp4_; + double tmp6_ = mCompCoord[2]; + double tmp7_ = mCompCoord[5]; + double tmp8_ = tmp6_ - tmp7_; + double tmp9_ = mLocR0_0_2 * (tmp2_); + double tmp10_ = mLocR0_1_2 * (tmp5_); + double tmp11_ = tmp9_ + tmp10_; + double tmp12_ = mLocR0_2_2 * (tmp8_); + double tmp13_ = tmp11_ + tmp12_; + double tmp14_ = mLocR0_0_1 * (tmp2_); + double tmp15_ = mLocR0_1_1 * (tmp5_); + double tmp16_ = tmp14_ + tmp15_; + double tmp17_ = mLocR0_2_1 * (tmp8_); + double tmp18_ = tmp16_ + tmp17_; + double tmp19_ = mCompCoord[7]; + double tmp20_ = mLocR0_0_0 * (tmp2_); + double tmp21_ = mLocR0_1_0 * (tmp5_); + double tmp22_ = tmp20_ + tmp21_; + double tmp23_ = mLocR0_2_0 * (tmp8_); + double tmp24_ = tmp22_ + tmp23_; + double tmp25_ = tmp19_ * (tmp13_); + double tmp26_ = mCompCoord[8]; + double tmp27_ = tmp26_ * (tmp18_); + double tmp28_ = tmp25_ - tmp27_; + double tmp29_ = tmp24_ + tmp28_; + double tmp30_ = mCompCoord[6]; + double tmp31_ = tmp30_ * (tmp18_); + double tmp32_ = tmp19_ * (tmp24_); + double tmp33_ = tmp31_ - tmp32_; + double tmp34_ = tmp13_ + tmp33_; + double tmp35_ = (tmp29_) / (tmp34_); + double tmp36_ = mCompCoord[9]; + double tmp37_ = tmp35_ - tmp36_; + double tmp38_ = ElSquare(tmp37_); + double tmp39_ = tmp26_ * (tmp24_); + double tmp40_ = tmp30_ * (tmp13_); + double tmp41_ = tmp39_ - tmp40_; + double tmp42_ = tmp18_ + tmp41_; + double tmp43_ = (tmp42_) / (tmp34_); + double tmp44_ = mCompCoord[10]; + double tmp45_ = tmp43_ - tmp44_; + double tmp46_ = ElSquare(tmp45_); + double tmp47_ = tmp38_ + tmp46_; + double tmp48_ = mLocR0_0_2 * tmp19_; + double tmp49_ = mLocR0_0_1 * tmp26_; + double tmp50_ = tmp48_ - tmp49_; + double tmp51_ = mLocR0_0_0 + tmp50_; + double tmp52_ = (tmp51_) * (tmp34_); + double tmp53_ = mLocR0_0_1 * tmp30_; + double tmp54_ = mLocR0_0_0 * tmp19_; + double tmp55_ = tmp53_ - tmp54_; + double tmp56_ = mLocR0_0_2 + tmp55_; + double tmp57_ = (tmp29_) * (tmp56_); + double tmp58_ = tmp52_ - tmp57_; + double tmp59_ = ElSquare(tmp34_); + double tmp60_ = (tmp58_) / tmp59_; + double tmp61_ = mCompCoord[11]; + double tmp62_ = tmp61_ * (tmp47_); + double tmp63_ = mCompCoord[12]; + double tmp64_ = ElSquare(tmp47_); + double tmp65_ = tmp63_ * tmp64_; + double tmp66_ = tmp62_ + tmp65_; + double tmp67_ = mCompCoord[13]; + double tmp68_ = VCube(tmp47_); + double tmp69_ = tmp67_ * tmp68_; + double tmp70_ = tmp66_ + tmp69_; + double tmp71_ = 2 * (tmp60_); + double tmp72_ = tmp71_ * (tmp37_); + double tmp73_ = mLocR0_0_0 * tmp26_; + double tmp74_ = mLocR0_0_2 * tmp30_; + double tmp75_ = tmp73_ - tmp74_; + double tmp76_ = mLocR0_0_1 + tmp75_; + double tmp77_ = (tmp76_) * (tmp34_); + double tmp78_ = (tmp42_) * (tmp56_); + double tmp79_ = tmp77_ - tmp78_; + double tmp80_ = (tmp79_) / tmp59_; + double tmp81_ = 2 * (tmp80_); + double tmp82_ = tmp81_ * (tmp45_); + double tmp83_ = tmp72_ + tmp82_; + double tmp84_ = mCompCoord[16]; + double tmp85_ = mLocR0_1_2 * tmp19_; + double tmp86_ = mLocR0_1_1 * tmp26_; + double tmp87_ = tmp85_ - tmp86_; + double tmp88_ = mLocR0_1_0 + tmp87_; + double tmp89_ = (tmp88_) * (tmp34_); + double tmp90_ = mLocR0_1_1 * tmp30_; + double tmp91_ = mLocR0_1_0 * tmp19_; + double tmp92_ = tmp90_ - tmp91_; + double tmp93_ = mLocR0_1_2 + tmp92_; + double tmp94_ = (tmp29_) * (tmp93_); + double tmp95_ = tmp89_ - tmp94_; + double tmp96_ = (tmp95_) / tmp59_; + double tmp97_ = 2 * (tmp96_); + double tmp98_ = tmp97_ * (tmp37_); + double tmp99_ = mLocR0_1_0 * tmp26_; + double tmp100_ = mLocR0_1_2 * tmp30_; + double tmp101_ = tmp99_ - tmp100_; + double tmp102_ = mLocR0_1_1 + tmp101_; + double tmp103_ = (tmp102_) * (tmp34_); + double tmp104_ = (tmp42_) * (tmp93_); + double tmp105_ = tmp103_ - tmp104_; + double tmp106_ = (tmp105_) / tmp59_; + double tmp107_ = 2 * (tmp106_); + double tmp108_ = tmp107_ * (tmp45_); + double tmp109_ = tmp98_ + tmp108_; + double tmp110_ = mLocR0_2_2 * tmp19_; + double tmp111_ = mLocR0_2_1 * tmp26_; + double tmp112_ = tmp110_ - tmp111_; + double tmp113_ = mLocR0_2_0 + tmp112_; + double tmp114_ = (tmp113_) * (tmp34_); + double tmp115_ = mLocR0_2_1 * tmp30_; + double tmp116_ = mLocR0_2_0 * tmp19_; + double tmp117_ = tmp115_ - tmp116_; + double tmp118_ = mLocR0_2_2 + tmp117_; + double tmp119_ = (tmp29_) * (tmp118_); + double tmp120_ = tmp114_ - tmp119_; + double tmp121_ = (tmp120_) / tmp59_; + double tmp122_ = 2 * (tmp121_); + double tmp123_ = tmp122_ * (tmp37_); + double tmp124_ = mLocR0_2_0 * tmp26_; + double tmp125_ = mLocR0_2_2 * tmp30_; + double tmp126_ = tmp124_ - tmp125_; + double tmp127_ = mLocR0_2_1 + tmp126_; + double tmp128_ = (tmp127_) * (tmp34_); + double tmp129_ = (tmp42_) * (tmp118_); + double tmp130_ = tmp128_ - tmp129_; + double tmp131_ = (tmp130_) / tmp59_; + double tmp132_ = 2 * (tmp131_); + double tmp133_ = tmp132_ * (tmp45_); + double tmp134_ = tmp123_ + tmp133_; + double tmp135_ = -(1); + double tmp136_ = tmp135_ * mLocR0_0_2; + double tmp137_ = tmp135_ * mLocR0_0_1; + double tmp138_ = tmp135_ * mLocR0_0_0; + double tmp139_ = tmp136_ * tmp19_; + double tmp140_ = tmp137_ * tmp26_; + double tmp141_ = tmp139_ - tmp140_; + double tmp142_ = tmp138_ + tmp141_; + double tmp143_ = (tmp142_) * (tmp34_); + double tmp144_ = tmp137_ * tmp30_; + double tmp145_ = tmp138_ * tmp19_; + double tmp146_ = tmp144_ - tmp145_; + double tmp147_ = tmp136_ + tmp146_; + double tmp148_ = (tmp29_) * (tmp147_); + double tmp149_ = tmp143_ - tmp148_; + double tmp150_ = (tmp149_) / tmp59_; + double tmp151_ = 2 * (tmp150_); + double tmp152_ = tmp151_ * (tmp37_); + double tmp153_ = tmp138_ * tmp26_; + double tmp154_ = tmp136_ * tmp30_; + double tmp155_ = tmp153_ - tmp154_; + double tmp156_ = tmp137_ + tmp155_; + double tmp157_ = (tmp156_) * (tmp34_); + double tmp158_ = (tmp42_) * (tmp147_); + double tmp159_ = tmp157_ - tmp158_; + double tmp160_ = (tmp159_) / tmp59_; + double tmp161_ = 2 * (tmp160_); + double tmp162_ = tmp161_ * (tmp45_); + double tmp163_ = tmp152_ + tmp162_; + double tmp164_ = tmp135_ * mLocR0_1_2; + double tmp165_ = tmp135_ * mLocR0_1_1; + double tmp166_ = tmp135_ * mLocR0_1_0; + double tmp167_ = tmp164_ * tmp19_; + double tmp168_ = tmp165_ * tmp26_; + double tmp169_ = tmp167_ - tmp168_; + double tmp170_ = tmp166_ + tmp169_; + double tmp171_ = (tmp170_) * (tmp34_); + double tmp172_ = tmp165_ * tmp30_; + double tmp173_ = tmp166_ * tmp19_; + double tmp174_ = tmp172_ - tmp173_; + double tmp175_ = tmp164_ + tmp174_; + double tmp176_ = (tmp29_) * (tmp175_); + double tmp177_ = tmp171_ - tmp176_; + double tmp178_ = (tmp177_) / tmp59_; + double tmp179_ = 2 * (tmp178_); + double tmp180_ = tmp179_ * (tmp37_); + double tmp181_ = tmp166_ * tmp26_; + double tmp182_ = tmp164_ * tmp30_; + double tmp183_ = tmp181_ - tmp182_; + double tmp184_ = tmp165_ + tmp183_; + double tmp185_ = (tmp184_) * (tmp34_); + double tmp186_ = (tmp42_) * (tmp175_); + double tmp187_ = tmp185_ - tmp186_; + double tmp188_ = (tmp187_) / tmp59_; + double tmp189_ = 2 * (tmp188_); + double tmp190_ = tmp189_ * (tmp45_); + double tmp191_ = tmp180_ + tmp190_; + double tmp192_ = tmp135_ * mLocR0_2_2; + double tmp193_ = tmp135_ * mLocR0_2_1; + double tmp194_ = tmp135_ * mLocR0_2_0; + double tmp195_ = tmp192_ * tmp19_; + double tmp196_ = tmp193_ * tmp26_; + double tmp197_ = tmp195_ - tmp196_; + double tmp198_ = tmp194_ + tmp197_; + double tmp199_ = (tmp198_) * (tmp34_); + double tmp200_ = tmp193_ * tmp30_; + double tmp201_ = tmp194_ * tmp19_; + double tmp202_ = tmp200_ - tmp201_; + double tmp203_ = tmp192_ + tmp202_; + double tmp204_ = (tmp29_) * (tmp203_); + double tmp205_ = tmp199_ - tmp204_; + double tmp206_ = (tmp205_) / tmp59_; + double tmp207_ = 2 * (tmp206_); + double tmp208_ = tmp207_ * (tmp37_); + double tmp209_ = tmp194_ * tmp26_; + double tmp210_ = tmp192_ * tmp30_; + double tmp211_ = tmp209_ - tmp210_; + double tmp212_ = tmp193_ + tmp211_; + double tmp213_ = (tmp212_) * (tmp34_); + double tmp214_ = (tmp42_) * (tmp203_); + double tmp215_ = tmp213_ - tmp214_; + double tmp216_ = (tmp215_) / tmp59_; + double tmp217_ = 2 * (tmp216_); + double tmp218_ = tmp217_ * (tmp45_); + double tmp219_ = tmp208_ + tmp218_; + double tmp220_ = (tmp29_) * (tmp18_); + double tmp221_ = -(tmp220_); + double tmp222_ = tmp221_ / tmp59_; + double tmp223_ = 2 * (tmp222_); + double tmp224_ = tmp223_ * (tmp37_); + double tmp225_ = -(tmp13_); + double tmp226_ = tmp225_ * (tmp34_); + double tmp227_ = (tmp42_) * (tmp18_); + double tmp228_ = tmp226_ - tmp227_; + double tmp229_ = (tmp228_) / tmp59_; + double tmp230_ = 2 * (tmp229_); + double tmp231_ = tmp230_ * (tmp45_); + double tmp232_ = tmp224_ + tmp231_; + double tmp233_ = (tmp13_) * (tmp34_); + double tmp234_ = -(tmp24_); + double tmp235_ = (tmp29_) * tmp234_; + double tmp236_ = tmp233_ - tmp235_; + double tmp237_ = (tmp236_) / tmp59_; + double tmp238_ = 2 * (tmp237_); + double tmp239_ = tmp238_ * (tmp37_); + double tmp240_ = (tmp42_) * tmp234_; + double tmp241_ = -(tmp240_); + double tmp242_ = tmp241_ / tmp59_; + double tmp243_ = 2 * (tmp242_); + double tmp244_ = tmp243_ * (tmp45_); + double tmp245_ = tmp239_ + tmp244_; + double tmp246_ = -(tmp18_); + double tmp247_ = tmp246_ * (tmp34_); + double tmp248_ = (tmp247_) / tmp59_; + double tmp249_ = 2 * (tmp248_); + double tmp250_ = tmp249_ * (tmp37_); + double tmp251_ = (tmp24_) * (tmp34_); + double tmp252_ = (tmp251_) / tmp59_; + double tmp253_ = 2 * (tmp252_); + double tmp254_ = tmp253_ * (tmp45_); + double tmp255_ = tmp250_ + tmp254_; + double tmp256_ = 2 * tmp135_; + double tmp257_ = tmp256_ * (tmp37_); + double tmp258_ = tmp256_ * (tmp45_); + double tmp259_ = (tmp37_) * (tmp70_); + double tmp260_ = tmp35_ + tmp259_; + double tmp261_ = (tmp83_) * tmp61_; + double tmp262_ = 2 * (tmp83_); + double tmp263_ = tmp262_ * (tmp47_); + double tmp264_ = tmp263_ * tmp63_; + double tmp265_ = tmp261_ + tmp264_; + double tmp266_ = 3 * (tmp83_); + double tmp267_ = tmp266_ * tmp64_; + double tmp268_ = tmp267_ * tmp67_; + double tmp269_ = tmp265_ + tmp268_; + double tmp270_ = (tmp109_) * tmp61_; + double tmp271_ = 2 * (tmp109_); + double tmp272_ = tmp271_ * (tmp47_); + double tmp273_ = tmp272_ * tmp63_; + double tmp274_ = tmp270_ + tmp273_; + double tmp275_ = 3 * (tmp109_); + double tmp276_ = tmp275_ * tmp64_; + double tmp277_ = tmp276_ * tmp67_; + double tmp278_ = tmp274_ + tmp277_; + double tmp279_ = (tmp134_) * tmp61_; + double tmp280_ = 2 * (tmp134_); + double tmp281_ = tmp280_ * (tmp47_); + double tmp282_ = tmp281_ * tmp63_; + double tmp283_ = tmp279_ + tmp282_; + double tmp284_ = 3 * (tmp134_); + double tmp285_ = tmp284_ * tmp64_; + double tmp286_ = tmp285_ * tmp67_; + double tmp287_ = tmp283_ + tmp286_; + double tmp288_ = (tmp163_) * tmp61_; + double tmp289_ = 2 * (tmp163_); + double tmp290_ = tmp289_ * (tmp47_); + double tmp291_ = tmp290_ * tmp63_; + double tmp292_ = tmp288_ + tmp291_; + double tmp293_ = 3 * (tmp163_); + double tmp294_ = tmp293_ * tmp64_; + double tmp295_ = tmp294_ * tmp67_; + double tmp296_ = tmp292_ + tmp295_; + double tmp297_ = (tmp191_) * tmp61_; + double tmp298_ = 2 * (tmp191_); + double tmp299_ = tmp298_ * (tmp47_); + double tmp300_ = tmp299_ * tmp63_; + double tmp301_ = tmp297_ + tmp300_; + double tmp302_ = 3 * (tmp191_); + double tmp303_ = tmp302_ * tmp64_; + double tmp304_ = tmp303_ * tmp67_; + double tmp305_ = tmp301_ + tmp304_; + double tmp306_ = (tmp219_) * tmp61_; + double tmp307_ = 2 * (tmp219_); + double tmp308_ = tmp307_ * (tmp47_); + double tmp309_ = tmp308_ * tmp63_; + double tmp310_ = tmp306_ + tmp309_; + double tmp311_ = 3 * (tmp219_); + double tmp312_ = tmp311_ * tmp64_; + double tmp313_ = tmp312_ * tmp67_; + double tmp314_ = tmp310_ + tmp313_; + double tmp315_ = (tmp232_) * tmp61_; + double tmp316_ = 2 * (tmp232_); + double tmp317_ = tmp316_ * (tmp47_); + double tmp318_ = tmp317_ * tmp63_; + double tmp319_ = tmp315_ + tmp318_; + double tmp320_ = 3 * (tmp232_); + double tmp321_ = tmp320_ * tmp64_; + double tmp322_ = tmp321_ * tmp67_; + double tmp323_ = tmp319_ + tmp322_; + double tmp324_ = (tmp245_) * tmp61_; + double tmp325_ = 2 * (tmp245_); + double tmp326_ = tmp325_ * (tmp47_); + double tmp327_ = tmp326_ * tmp63_; + double tmp328_ = tmp324_ + tmp327_; + double tmp329_ = 3 * (tmp245_); + double tmp330_ = tmp329_ * tmp64_; + double tmp331_ = tmp330_ * tmp67_; + double tmp332_ = tmp328_ + tmp331_; + double tmp333_ = (tmp255_) * tmp61_; + double tmp334_ = 2 * (tmp255_); + double tmp335_ = tmp334_ * (tmp47_); + double tmp336_ = tmp335_ * tmp63_; + double tmp337_ = tmp333_ + tmp336_; + double tmp338_ = 3 * (tmp255_); + double tmp339_ = tmp338_ * tmp64_; + double tmp340_ = tmp339_ * tmp67_; + double tmp341_ = tmp337_ + tmp340_; + double tmp342_ = tmp257_ * tmp61_; + double tmp343_ = 2 * tmp257_; + double tmp344_ = tmp343_ * (tmp47_); + double tmp345_ = tmp344_ * tmp63_; + double tmp346_ = tmp342_ + tmp345_; + double tmp347_ = 3 * tmp257_; + double tmp348_ = tmp347_ * tmp64_; + double tmp349_ = tmp348_ * tmp67_; + double tmp350_ = tmp346_ + tmp349_; + double tmp351_ = tmp135_ * (tmp70_); + double tmp352_ = tmp258_ * tmp61_; + double tmp353_ = 2 * tmp258_; + double tmp354_ = tmp353_ * (tmp47_); + double tmp355_ = tmp354_ * tmp63_; + double tmp356_ = tmp352_ + tmp355_; + double tmp357_ = 3 * tmp258_; + double tmp358_ = tmp357_ * tmp64_; + double tmp359_ = tmp358_ * tmp67_; + double tmp360_ = tmp356_ + tmp359_; + double tmp361_ = (tmp45_) * (tmp70_); + double tmp362_ = tmp43_ + tmp361_; + + mVal[0] = (mCompCoord[14] + (tmp260_) * tmp84_) - mLocMesIm_x; + + mCompDer[0][0] = (tmp60_ + (tmp60_) * (tmp70_) + (tmp269_) * (tmp37_)) * tmp84_; + mCompDer[0][1] = (tmp96_ + (tmp96_) * (tmp70_) + (tmp278_) * (tmp37_)) * tmp84_; + mCompDer[0][2] = (tmp121_ + (tmp121_) * (tmp70_) + (tmp287_) * (tmp37_)) * tmp84_; + mCompDer[0][3] = (tmp150_ + (tmp150_) * (tmp70_) + (tmp296_) * (tmp37_)) * tmp84_; + mCompDer[0][4] = (tmp178_ + (tmp178_) * (tmp70_) + (tmp305_) * (tmp37_)) * tmp84_; + mCompDer[0][5] = (tmp206_ + (tmp206_) * (tmp70_) + (tmp314_) * (tmp37_)) * tmp84_; + mCompDer[0][6] = (tmp222_ + (tmp222_) * (tmp70_) + (tmp323_) * (tmp37_)) * tmp84_; + mCompDer[0][7] = (tmp237_ + (tmp237_) * (tmp70_) + (tmp332_) * (tmp37_)) * tmp84_; + mCompDer[0][8] = (tmp248_ + (tmp248_) * (tmp70_) + (tmp341_) * (tmp37_)) * tmp84_; + mCompDer[0][9] = (tmp351_ + (tmp350_) * (tmp37_)) * tmp84_; + mCompDer[0][10] = (tmp360_) * (tmp37_) * tmp84_; + mCompDer[0][11] = (tmp47_) * (tmp37_) * tmp84_; + mCompDer[0][12] = tmp64_ * (tmp37_) * tmp84_; + mCompDer[0][13] = tmp68_ * (tmp37_) * tmp84_; + mCompDer[0][14] = 1; + mCompDer[0][15] = 0; + mCompDer[0][16] = tmp260_; + mVal[1] = (mCompCoord[15] + (tmp362_) * tmp84_) - mLocMesIm_y; + + mCompDer[1][0] = (tmp80_ + (tmp80_) * (tmp70_) + (tmp269_) * (tmp45_)) * tmp84_; + mCompDer[1][1] = (tmp106_ + (tmp106_) * (tmp70_) + (tmp278_) * (tmp45_)) * tmp84_; + mCompDer[1][2] = (tmp131_ + (tmp131_) * (tmp70_) + (tmp287_) * (tmp45_)) * tmp84_; + mCompDer[1][3] = (tmp160_ + (tmp160_) * (tmp70_) + (tmp296_) * (tmp45_)) * tmp84_; + mCompDer[1][4] = (tmp188_ + (tmp188_) * (tmp70_) + (tmp305_) * (tmp45_)) * tmp84_; + mCompDer[1][5] = (tmp216_ + (tmp216_) * (tmp70_) + (tmp314_) * (tmp45_)) * tmp84_; + mCompDer[1][6] = (tmp229_ + (tmp229_) * (tmp70_) + (tmp323_) * (tmp45_)) * tmp84_; + mCompDer[1][7] = (tmp242_ + (tmp242_) * (tmp70_) + (tmp332_) * (tmp45_)) * tmp84_; + mCompDer[1][8] = (tmp252_ + (tmp252_) * (tmp70_) + (tmp341_) * (tmp45_)) * tmp84_; + mCompDer[1][9] = (tmp350_) * (tmp45_) * tmp84_; + mCompDer[1][10] = (tmp351_ + (tmp360_) * (tmp45_)) * tmp84_; + mCompDer[1][11] = (tmp47_) * (tmp45_) * tmp84_; + mCompDer[1][12] = tmp64_ * (tmp45_) * tmp84_; + mCompDer[1][13] = tmp68_ * (tmp45_) * tmp84_; + mCompDer[1][14] = 0; + mCompDer[1][15] = 1; + mCompDer[1][16] = tmp362_; +} + + +void cGeneratedCodeTestCam::ComputeValDerivHessian() +{ + ELISE_ASSERT(false,"Foncteur cGeneratedCodeTestCam Has no Der Sec"); +} + +void cGeneratedCodeTestCam::SetMesIm_x(double aVal){ mLocMesIm_x = aVal;} +void cGeneratedCodeTestCam::SetMesIm_y(double aVal){ mLocMesIm_y = aVal;} +void cGeneratedCodeTestCam::SetR0_0_0(double aVal){ mLocR0_0_0 = aVal;} +void cGeneratedCodeTestCam::SetR0_0_1(double aVal){ mLocR0_0_1 = aVal;} +void cGeneratedCodeTestCam::SetR0_0_2(double aVal){ mLocR0_0_2 = aVal;} +void cGeneratedCodeTestCam::SetR0_1_0(double aVal){ mLocR0_1_0 = aVal;} +void cGeneratedCodeTestCam::SetR0_1_1(double aVal){ mLocR0_1_1 = aVal;} +void cGeneratedCodeTestCam::SetR0_1_2(double aVal){ mLocR0_1_2 = aVal;} +void cGeneratedCodeTestCam::SetR0_2_0(double aVal){ mLocR0_2_0 = aVal;} +void cGeneratedCodeTestCam::SetR0_2_1(double aVal){ mLocR0_2_1 = aVal;} +void cGeneratedCodeTestCam::SetR0_2_2(double aVal){ mLocR0_2_2 = aVal;} + + + +double * cGeneratedCodeTestCam::AdrVarLocFromString(const std::string & aName) +{ + if (aName == "MesIm_x") return & mLocMesIm_x; + if (aName == "MesIm_y") return & mLocMesIm_y; + if (aName == "R0_0_0") return & mLocR0_0_0; + if (aName == "R0_0_1") return & mLocR0_0_1; + if (aName == "R0_0_2") return & mLocR0_0_2; + if (aName == "R0_1_0") return & mLocR0_1_0; + if (aName == "R0_1_1") return & mLocR0_1_1; + if (aName == "R0_1_2") return & mLocR0_1_2; + if (aName == "R0_2_0") return & mLocR0_2_0; + if (aName == "R0_2_1") return & mLocR0_2_1; + if (aName == "R0_2_2") return & mLocR0_2_2; + return 0; +} + + +cElCompiledFonc::cAutoAddEntry cGeneratedCodeTestCam::mTheAuto("cGeneratedCodeTestCam",cGeneratedCodeTestCam::Alloc); + + +cElCompiledFonc * cGeneratedCodeTestCam::Alloc() +{ return new cGeneratedCodeTestCam(); +} + + diff --git a/MMVII/src/MMV1/cGeneratedCodeTestCam.h b/MMVII/src/MMV1/cGeneratedCodeTestCam.h new file mode 100644 index 0000000000..1f803d250e --- /dev/null +++ b/MMVII/src/MMV1/cGeneratedCodeTestCam.h @@ -0,0 +1,42 @@ +// File Automatically generated by eLiSe +#include "StdAfx.h" + + +class cGeneratedCodeTestCam: public cElCompiledFonc +{ + public : + + cGeneratedCodeTestCam(); + void ComputeVal(); + void ComputeValDeriv(); + void ComputeValDerivHessian(); + double * AdrVarLocFromString(const std::string &); + void SetMesIm_x(double); + void SetMesIm_y(double); + void SetR0_0_0(double); + void SetR0_0_1(double); + void SetR0_0_2(double); + void SetR0_1_0(double); + void SetR0_1_1(double); + void SetR0_1_2(double); + void SetR0_2_0(double); + void SetR0_2_1(double); + void SetR0_2_2(double); + + + static cAutoAddEntry mTheAuto; + static cElCompiledFonc * Alloc(); + private : + + double mLocMesIm_x; + double mLocMesIm_y; + double mLocR0_0_0; + double mLocR0_0_1; + double mLocR0_0_2; + double mLocR0_1_0; + double mLocR0_1_1; + double mLocR0_1_2; + double mLocR0_2_0; + double mLocR0_2_1; + double mLocR0_2_2; +}; diff --git a/MMVII/src/MatchTieP/MatchTieP.h b/MMVII/src/MatchTieP/MatchTieP.h new file mode 100644 index 0000000000..6e3fcf3c8e --- /dev/null +++ b/MMVII/src/MatchTieP/MatchTieP.h @@ -0,0 +1,30 @@ +#ifndef _cAPPLI_MATCH_TIEP_H_ +#define _cAPPLI_MATCH_TIEP_H_ + +namespace MMVII +{ + +/** + This class implement some services common to applications doing tie-points matching +*/ +class cBaseMatchTieP : public cMMVII_Appli +{ + public : + + cBaseMatchTieP(const std::vector & aVArgs,const cSpecMMVII_Appli & aSpec); + // int Exe() override; + cCollecSpecArg2007 & ArgObl(cCollecSpecArg2007 & anArgObl) override ; + cCollecSpecArg2007 & ArgOpt(cCollecSpecArg2007 & anArgOpt) override ; + void PostInit(); ///< Initialisation not in constructor (need ArgObl/ArgOpt have been executed) + protected : + std::string mNameIm1; ///< First image + std::string mNameIm2; ///< Second image + std::vector mVSAPc1; ///< Aime Carac Point of Im1 + std::vector mVSAPc2; ///< Aime Carac Point of Im2 +}; + + +}; + +#endif // _cAPPLI_MATCH_TIEP_H_ + diff --git a/MMVII/src/MatchTieP/cAppliMatchTiePBasic.cpp b/MMVII/src/MatchTieP/cAppliMatchTiePBasic.cpp new file mode 100644 index 0000000000..07fed753a5 --- /dev/null +++ b/MMVII/src/MatchTieP/cAppliMatchTiePBasic.cpp @@ -0,0 +1,233 @@ +#include "include/MMVII_all.h" +#include "MatchTieP.h" + +namespace MMVII +{ + +class cCdtBasic; // Store a Aime PC + other stuff necessary for match +class cHypMatchCdtBasic; // An hypothesis of match between 2 candidate +class cSetCdtBasic; // All the Cdt of one type in on image +class cCpleSetCdtBasic ; // The two corresponding sets in two images +class cAppliMatchTiePBasic; // The application + +/** A class to store one hypothesi of match , contain 2 candidate and a cost, + The two candidate will share the same cHypMatchCdtBasic +*/ + + +class cHypMatchCdtBasic : public cMemCheck +{ + public : + const double & Cost() const; ///< Accessor to cost + /** We need to know for a given Hyp who is the other candidate */ + cCdtBasic & Other(const cCdtBasic & MySelf); + cHypMatchCdtBasic(double aCost,cCdtBasic & aCd1,cCdtBasic & aCd2,int aIndexOr); + /// Std Comparison, the best hyp is the lowest cost + bool operator < (const cHypMatchCdtBasic & aH2) const {return mCost tSPHypM; + +/** Descripor (Aime) + Hypothesis of match +*/ +class cCdtBasic : public cMemCheck +{ + public : + cCdtBasic(cAimePCar *); + /// Make a firt level of match by computing the NbSel best match + void MatchInit(cSetCdtBasic&,int NbSel); + cAimePCar & PC(); // Accessor + private : + cAimePCar * mPC; /// Aime descriptor + std::vector mHypMatch; /// Hypothesis of match +}; + +class cSetCdtBasic : public cMemCheck +{ + public : + cSetCdtBasic(cSetAimePCAR *); + cSetAimePCAR & SetPC(); // Accessor + std::vector& VCdt(); // Accessor + private : + cSetAimePCAR * mSetPC; // The initial set of Aime Points + std::vector mVCdt; // The structure that containt all the candidtes +}; + +class cCpleSetCdtBasic : public cMemCheck +{ + public : + cCpleSetCdtBasic(cSetAimePCAR * aS1,cSetAimePCAR * aS2); + void MakeCost(); + private : + cSetCdtBasic mS1; + cSetCdtBasic mS2; +}; + +/* ******************************************************** */ +/* */ +/* cCdtBasic */ +/* */ +/* ******************************************************** */ + +cCdtBasic:: cCdtBasic(cAimePCar * aPC) : + mPC (aPC) +{ +} + +void cCdtBasic::MatchInit(cSetCdtBasic& aSet,int NbSel) +{ + static int aCpt=0; + aCpt++; + + std::vector aVH; + for (auto & aCd2 : aSet.VCdt()) + { + cWhitchMin aWM= mPC->Desc().DistanceFromBestPeek(aCd2.mPC->Desc(),aSet.SetPC()); + aVH.push_back(cHypMatchCdtBasic(aWM.Val(),*this,aCd2,aWM.Index())); + } + std::sort(aVH.begin(),aVH.end()); + StdOut() << "BEST COST " << aVH[0].Cost() << " " << aVH.back().Cost() << " Cpt " << aCpt << "\n"; + +} + + +/* ******************************************************** */ +/* */ +/* cHypMatchCdtBasic */ +/* */ +/* ******************************************************** */ + +cHypMatchCdtBasic::cHypMatchCdtBasic(double aCost,cCdtBasic & aCd1,cCdtBasic & aCd2,int aIndexOr): + mCost (aCost), + mIndexOr (aIndexOr), + mCd1 (&aCd1), + mCd2 (&aCd2) +{ +} + +const double & cHypMatchCdtBasic::Cost() const {return mCost;} + +/* ******************************************************** */ +/* */ +/* cSetCdtBasic */ +/* */ +/* ******************************************************** */ + +cSetCdtBasic::cSetCdtBasic(cSetAimePCAR * aSet) : + mSetPC (aSet) +{ + for (auto & aPC : mSetPC->VPC()) + mVCdt.push_back(cCdtBasic(&aPC)); +} + +std::vector& cSetCdtBasic::VCdt() {return mVCdt;} +cSetAimePCAR & cSetCdtBasic::SetPC() {return *mSetPC;} + +/* ******************************************************** */ +/* */ +/* cCpleSetCdtBasic */ +/* */ +/* ******************************************************** */ + +cCpleSetCdtBasic::cCpleSetCdtBasic(cSetAimePCAR * aS1,cSetAimePCAR * aS2) : + mS1 (aS1), + mS2 (aS2) +{ +} + +void cCpleSetCdtBasic::MakeCost() +{ + for (auto & aCd1 : mS1.VCdt()) + { + aCd1.MatchInit(mS2,20); + } +} + + +/** + This class implement basic match +*/ +class cAppliMatchTiePBasic : public cBaseMatchTieP +{ + public : + + cAppliMatchTiePBasic(const std::vector & aVArgs,const cSpecMMVII_Appli & aSpec); + int Exe() override; + cCollecSpecArg2007 & ArgObl(cCollecSpecArg2007 & anArgObl) override ; + cCollecSpecArg2007 & ArgOpt(cCollecSpecArg2007 & anArgOpt) override ; + private : + std::string mTestObl; ///< temporary + std::string mTestOPt; ///< temporary + std::vector mVSCB; // Pair of set of Aime/cdt +}; + +/* =============================================== */ +/* */ +/* cAppliMatchTiePBasic */ +/* */ +/* =============================================== */ + +cAppliMatchTiePBasic::cAppliMatchTiePBasic(const std::vector & aVArgs,const cSpecMMVII_Appli & aSpec) : + cBaseMatchTieP(aVArgs,aSpec) +{ +} + +cCollecSpecArg2007 & cAppliMatchTiePBasic::ArgObl(cCollecSpecArg2007 & anArgObl) +{ + cBaseMatchTieP::ArgObl(anArgObl); + + return anArgObl + << Arg2007(mTestObl,"Test Obl"); + +} + +cCollecSpecArg2007 & cAppliMatchTiePBasic::ArgOpt(cCollecSpecArg2007 & anArgOpt) +{ + cBaseMatchTieP::ArgOpt(anArgOpt); + return anArgOpt + << AOpt2007(mTestOPt,"TOpt","Test Optionnal local",{eTA2007::HDV}) + ; +} + +int cAppliMatchTiePBasic::Exe() +{ + PostInit(); + for (int aKSet=0 ; aKSet & aVArgs,const cSpecMMVII_Appli & aSpec) +{ + return tMMVII_UnikPApli(new cAppliMatchTiePBasic(aVArgs,aSpec)); +} + +cSpecMMVII_Appli TheSpecMatchTieP +( + "TieP-AimeBasicMatch", + Alloc_MatchTieP, + "Match caracteristic points and descriptors computed with Aime method", + {eApF::TieP}, + {eApDT::PCar}, + {eApDT::TieP}, + __FILE__ +); + + + + +}; diff --git a/MMVII/src/MatchTieP/cBaseMatchTieP.cpp b/MMVII/src/MatchTieP/cBaseMatchTieP.cpp new file mode 100644 index 0000000000..ea3b76f25c --- /dev/null +++ b/MMVII/src/MatchTieP/cBaseMatchTieP.cpp @@ -0,0 +1,71 @@ +#include "include/MMVII_all.h" +#include "MatchTieP.h" + +namespace MMVII +{ + + +/* =============================================== */ +/* */ +/* cBaseMatchTieP */ +/* */ +/* =============================================== */ + +cBaseMatchTieP::cBaseMatchTieP(const std::vector & aVArgs,const cSpecMMVII_Appli & aSpec) : + cMMVII_Appli (aVArgs,aSpec,{eSharedPO::eSPO_CarPI}) +{ +} + +/// Im1 and Im2 are the only mandatory args +cCollecSpecArg2007 & cBaseMatchTieP::ArgObl(cCollecSpecArg2007 & anArgObl) +{ + return + anArgObl + << Arg2007(mNameIm1,"Name of input file") + << Arg2007(mNameIm2,"Name of input file") + ; +} + +/// This was a test to check that optional args are "inherited" +cCollecSpecArg2007 & cBaseMatchTieP::ArgOpt(cCollecSpecArg2007 & anArgOpt) +{ + return anArgOpt + // << AOpt2007(mTestOPtBase,"TOBase","Test Optionnal Base",{eTA2007::HDV}) + ; +} + +/** Once the args have been initiazed by virtual method (not in constrtuctor !) ArgObl-ArgOpt + we can read the +*/ +void cBaseMatchTieP::PostInit() +{ + // Parse all the possible labels + for (int aKTy=0 ; aKTy inline void AssertMnxn(cDenseMatrix & aM) +{ + MMVII_INTERNAL_ASSERT_tiny(aM.Sz()==cPt2di(aSz,aSz),"Bad size for matrix"); +} + +template inline void AssertM3x3(cDenseMatrix & aM) +{ + AssertMnxn(aM); +} + + +}; + + + diff --git a/MMVII/src/Matrix/cDM_Orthog.cpp b/MMVII/src/Matrix/cDM_Orthog.cpp index 221f925957..1a611a5377 100644 --- a/MMVII/src/Matrix/cDM_Orthog.cpp +++ b/MMVII/src/Matrix/cDM_Orthog.cpp @@ -45,7 +45,7 @@ template void cResulSymEigenValue::SetKthEigenValue(int aK,c template Type cResulSymEigenValue::Cond(Type aDef) const { - cWitchMinMax aIMM(0,std::abs(mEigenValues(0))); + cWhitchMinMax aIMM(0,std::abs(mEigenValues(0))); for (int aK=1 ; aK cDenseMatrix cDenseMatrix::RandomSquareRegMat // Set conditionning { - cWitchMinMax aIMM(0,std::abs(aVEV(0))); + cWhitchMinMax aIMM(0,std::abs(aVEV(0))); for (int aK=0 ; aK + +/** \file cMMVII_CatVideo.cpp + \brief Command for concat video + + This command is basic interface to ffmpeg functionnality +of concatenating video (in fact media mp4, mp3 ...). + +*/ + + +namespace MMVII +{ + + +/* ==================================================== */ +/* */ +/* cAppli_CatVideo */ +/* */ +/* ==================================================== */ + + +/** Application for concatenating videos */ + +class cAppli_CatVideo : public cMMVII_Appli +{ + public : + cAppli_CatVideo(const std::vector & aVArgs,const cSpecMMVII_Appli &); + int Exe() override; + cCollecSpecArg2007 & ArgObl(cCollecSpecArg2007 & anArgObl) override; + cCollecSpecArg2007 & ArgOpt(cCollecSpecArg2007 & anArgOpt) override; + private : + std::string mPat; ///< Pattern of input file + bool mExec; ///< Execute cat and remove file (else just create file) + bool mAppend; ///< Do we append to file + std::string mNameFoF; ///< name of file of files + std::string mNameResult; ///< name of Resulting media + bool mVideoMode; ///< is it video, change def options + std::string mOptions; ///< is it video, change options +}; + + + +cCollecSpecArg2007 & cAppli_CatVideo::ArgObl(cCollecSpecArg2007 & anArgObl) +{ + return + anArgObl + << Arg2007(mPat,"Pattern for input files",{{eTA2007::MPatIm,"0"},eTA2007::FileDirProj}) + + ; +} + +cCollecSpecArg2007 & cAppli_CatVideo::ArgOpt(cCollecSpecArg2007 & anArgOpt) +{ + return + anArgOpt + << AOpt2007(mExec,"Exec","Execute concat (vs only create file)",{eTA2007::HDV}) + << AOpt2007(mNameResult,CurOP_Out,"Resulting video") + << AOpt2007(mVideoMode,"Video","Is it video, if not set computed from post if possible") + << AOpt2007(mOptions,"Options","Options to add to ffmpeg") + ; +} + + +cAppli_CatVideo::cAppli_CatVideo +( + const std::vector & aVArgs, + const cSpecMMVII_Appli & aSpec +) : + cMMVII_Appli (aVArgs,aSpec), + mExec (true), + mAppend (false), + mNameFoF ("FileCatVideo.txt"), + mNameResult ("CatVideo") +{ +} + +int cAppli_CatVideo::Exe() +{ + tNameSet aSetPostfix; + // Sometime computing postfix fails, so dont do it when you dont need it + bool ComputePost = (! IsInit(&mNameResult)); + + cMMVII_Ofs aFileOfFile(mNameFoF,mAppend); + for (const auto & aStr : ToVect(MainSet0())) + { + aFileOfFile.Ofs() << "file '" << aStr << "'" << std::endl; + if (ComputePost) + { + aSetPostfix.Add(LastPostfix(aStr)); + } + StdOut() << " STR=" << aStr << "\n"; + } + aFileOfFile.Ofs().close(); + + if (ComputePost) + { + std::vector aVP = ToVect(aSetPostfix); + MMVII_INTERNAL_ASSERT_User + ( + aVP.size()==1, + eTyUEr::eMultiplePostifx, + "Unspecified out and non unique (or empty) postfix" + ); + mNameResult = mNameResult + "." + aVP[0]; + } + std::string aPost = Postfix(mNameResult); + if (!IsInit(&mVideoMode)) + { + if (UCaseEqual(aPost,"mp3")) + mVideoMode = false; + else if (UCaseEqual(aPost,"mp4")||UCaseEqual(aPost,"avi")) + mVideoMode = true; + else + { + MMVII_UnclasseUsEr("Uncataloged media extension, cannot detemine video mode"); + } + } + + if (! IsInit(&mOptions)) + { + if (mVideoMode) + mOptions = " -vcodec mpeg4 -b 15000k "; + } + + std::string aCom = "ffmpeg -safe 0 -f concat -i "+ mNameFoF + mOptions+ " " + mNameResult; + int aRes = EXIT_SUCCESS ; + if (mExec) + { + aRes = ExtSysCall(aCom,false); + } + StdOut() << "Com=[" << aCom << "]\n"; + + return aRes; +} + + +tMMVII_UnikPApli Alloc_CatVideo(const std::vector & aVArgs,const cSpecMMVII_Appli & aSpec) +{ + return tMMVII_UnikPApli(new cAppli_CatVideo(aVArgs,aSpec)); +} + +cSpecMMVII_Appli TheSpecCatVideo +( + "MediaCat", + Alloc_CatVideo, + "This command is used for concatening medias (interface to ffmpeg)", + {eApF::Perso}, + {eApDT::Media}, + {eApDT::Media}, + __FILE__ +); + +}; + diff --git a/MMVII/src/Perso/cMMVII_DaisyFormat.cpp b/MMVII/src/Perso/cMMVII_DaisyFormat.cpp index eab1ce756c..18f68b09c9 100644 --- a/MMVII/src/Perso/cMMVII_DaisyFormat.cpp +++ b/MMVII/src/Perso/cMMVII_DaisyFormat.cpp @@ -407,7 +407,7 @@ tMMVII_UnikPApli Alloc_Daisy(const std::vector & aVArgs,const cSpe cSpecMMVII_Appli TheSpecDaisy ( - "Daisy", + "MediaDaisy", Alloc_Daisy, "This command is used to generate audio book to daisy format from mp3 files", {eApF::Perso}, diff --git a/MMVII/src/Perso/cMMVII_Walkman.cpp b/MMVII/src/Perso/cMMVII_Walkman.cpp index c33b49f920..dca6a7f46a 100644 --- a/MMVII/src/Perso/cMMVII_Walkman.cpp +++ b/MMVII/src/Perso/cMMVII_Walkman.cpp @@ -129,7 +129,7 @@ cCollecSpecArg2007 & cAppli_Walkman::ArgOpt(cCollecSpecArg2007 & anArgOpt) { return anArgOpt - << AOpt2007(mPat,"Pat","Pattern (regex), def=.*\\.mp3",{}) + << AOpt2007(mPat,"Pat","Pattern (regex), def=.*\\.mp3",{eTA2007::HDV}) ; } @@ -223,12 +223,12 @@ tMMVII_UnikPApli Alloc_Walkman(const std::vector & aVArgs,const cS cSpecMMVII_Appli TheSpecWalkman ( - "Walkman", + "MediaWalkman", Alloc_Walkman, "This command is used to make a random selection of music", {eApF::Perso}, - {eApDT::FileSys}, - {eApDT::Xml}, + {eApDT::FileSys,eApDT::Media}, + {eApDT::Xml,eApDT::Media}, __FILE__ ); diff --git a/MMVII/src/Serial/cStrIO.cpp b/MMVII/src/Serial/cStrIO.cpp index df933a5898..ca567f2fb2 100644 --- a/MMVII/src/Serial/cStrIO.cpp +++ b/MMVII/src/Serial/cStrIO.cpp @@ -159,7 +159,7 @@ template <> bool cStrIO::FromStr(const std::string & aStr) if ((aStr=="1") || UCaseEqual(aStr,"true")) return true; if ((aStr=="0") || UCaseEqual(aStr,"false")) return false; - MMVII_INTERNAL_ASSERT_user(eTyUEr::eBadBool,"Bad value for boolean :["+aStr+"]"); + MMVII_UsersErrror(eTyUEr::eBadBool,"Bad value for boolean :["+aStr+"]"); return false; } diff --git a/MMVII/src/Serial/uti_e2string.cpp b/MMVII/src/Serial/uti_e2string.cpp index a0d94ea949..0db702f421 100644 --- a/MMVII/src/Serial/uti_e2string.cpp +++ b/MMVII/src/Serial/uti_e2string.cpp @@ -48,7 +48,7 @@ template class cE2Str // String to enum is probably a user error (programm create enum) if (anIt == mS2E->end()) { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eBadEnum,"Str2E for : " + aStr + " ; valid are : " + StrAllVal() ); + MMVII_UsersErrror(eTyUEr::eBadEnum,"Str2E for : "+aStr+" ; valids are : "+ StrAllVal() ); } return anIt->second; } @@ -192,6 +192,7 @@ template<> cE2Str::tMapE2Str cE2Str::mE2S {eTyUEr::eParseError,"ParseError"}, {eTyUEr::eBadDimForPt,"BadDimension4Pts"}, {eTyUEr::eBadSize4Vect,"BadSize4Vector"}, + {eTyUEr::eMultiplePostifx,"MultiplePostifx"}, {eTyUEr::eUnClassedError,"UnClassedError"} }; TPL_ENUM_2_STRING(eTyUEr); diff --git a/MMVII/src/TestLibsExtern/TestCmpOpVect.cpp b/MMVII/src/TestLibsExtern/TestCmpOpVect.cpp new file mode 100644 index 0000000000..3cc73f6af4 --- /dev/null +++ b/MMVII/src/TestLibsExtern/TestCmpOpVect.cpp @@ -0,0 +1,162 @@ +#include "include/MMVII_all.h" +// #include "ExternalInclude/Eigen/Dense" +#include "/usr/local/include/Eigen/Dense" +#include "ceres/jet.h" + +using ceres::Jet; + + + +namespace MMVII +{ + +template class cTestOperationVector +{ + public : + typedef float tTEigen; + typedef Eigen::Array tEigenSubArray; + typedef Eigen::Map tEigenWrap; + + static void DoIt(); +}; + + +template void cTestOperationVector::DoIt() +{ + Eigen::Array aAFix ; // = Eigen::Array::Random(); + + Eigen::Array aADyn(SzTEigen); + Eigen::Array aADyn1(1,1); + Eigen::Array aADyn2(1,SzTEigen); + + + int aNb= 1e7 * (90.0/SzTEigen) ; + double aT0 = cMMVII_Appli::CurrentAppli().SecFromT0(); + + // Eigen vecteur fix + for (int aK=0 ; aK aBloc = aADyn.head(SzTEigen-1); + aBloc(0,0) = aADyn(0,0) + 1; + + for (int aK=0 ; aK aJet; + for (int aK=0 ; aK::DoIt(); + cTestOperationVector::DoIt(); + cTestOperationVector::DoIt(); +} + +};// namespace MMVII + + diff --git a/MMVII/src/TestLibsExtern/TestDynCompDerivatives.cpp b/MMVII/src/TestLibsExtern/TestDynCompDerivatives.cpp new file mode 100644 index 0000000000..983d6b46b7 --- /dev/null +++ b/MMVII/src/TestLibsExtern/TestDynCompDerivatives.cpp @@ -0,0 +1,1101 @@ +#include "include/MMVII_FormalDerivatives.h" +#include "ceres/jet.h" + + +namespace FD = NS_MMVII_FormalDerivative; +using ceres::Jet; + + +// ========= Define on Jets some function that make them work like formula and nums +// and also may optimize the computation so that comparison is fair + + +template inline Jet square(const Jet& f) +{ + return Jet(FD::square(f.a), (2.0*f.a) * f.v); +} + +template inline Jet cube(const Jet& f) +{ + T a2 = FD::square(f.a); + return Jet(f.a*a2, (3.0*a2) * f.v); +} + + +template inline Jet powI(const Jet& aJ,const int & aExp) +{ + // In this case avoid compute 1/x and multiply by x + if (aExp==0) return Jet(1.0); + + // make a single computation of pow + T aPm1 = FD::powI(aJ.a,aExp-1); + return Jet(aJ.a*aPm1,(aExp*aPm1)*aJ.v); +} + +template Jet CreateCste(const T & aV,const Jet&) +{ + return Jet(aV); +} + + + +//========================================= + +//========================================= + +double TimeElapsFromT0() +{ + static auto BeginOfTime = std::chrono::steady_clock::now(); + auto now = std::chrono::steady_clock::now(); + return std::chrono::duration_cast(now - BeginOfTime).count() / 1e6; +} + + +/** \file TestDynCompDerivatives.cpp + \brief Illustration and test of formal derivative + + {I} A detailled example of use, and test of correctness => for the final user + + {II} An example on basic function to get some insight in the way it works + + {III} A realistic example to make performance test on different methods + +*/ + + + +/* The library is in the namespace NS_MMVII_FormalDerivative, we want to +use it conveniently without the "using" directive, so create an alias FD */ + + + +/* {I} ======================== EXAMPLE OF USE : Ratkoswky ========================================== + + In this first basic example, we take the same model than Ceres jet, the ratkoswky + function. + + We want to fit a curve y= F(x) with the parametric model [Ratko] , where b1,..,b4 are the unknown and + x,y the observations : + + y = b1 / (1+exp(b2-b3*x)) ^ 1/b4 [Ratko] + + we have a set of value (x1,y1), (x2,y2) ..., an initial guess of the parameter b(i) and want + to compute optimal value. Typically we want to use non linear least-square for that, and + need to compute differential of equation [Ratko] . The MMVII_FormalDerivative + offers service for fast differentiation. The weighted least-square is another story that we dont study here. + +*/ + + +/** RatkoswkyResidual : residual of the Ratkoswky equation as a function of unknowns and observation. + + We return a vector because this is the general case to have a N-dimentional return value + (i.e. multiple residual like in photogrametic colinear equation). + + This template function can work on numerical type, formula, jets .... +*/ + +template +std::vector RatkoswkyResidual + ( + const std::vector & aVUk, + const std::vector & aVObs + ) +{ + const Type & b1 = aVUk[0]; + const Type & b2 = aVUk[1]; + const Type & b3 = aVUk[2]; + const Type & b4 = aVUk[3]; + + const Type & x = aVObs[1]; // Warn the data I got were in order y,x .. + const Type & y = aVObs[0]; + + pow(b1,2.7); + + // Model : y = b1 / (1+exp(b2-b3*x)) ^ 1/b4 + Error() [Ratko] + return { b1 / pow(1.0+exp(b2-b3*x),1.0/b4) - y } ; +} + + +/** For test Declare a literal vector of pair Y,X corresponding to observations + (not elagant but to avoid parse file in this tutorial) +*/ +typedef std::vector> tVRatkoswkyData; +static tVRatkoswkyData TheVRatkoswkyData +{ + {16.08E0,1.0E0}, {33.83E0,2.0E0}, {65.80E0,3.0E0}, {97.20E0,4.0E0}, {191.55E0,5.0E0}, + {326.20E0,6.0E0}, {386.87E0,7.0E0}, {520.53E0,8.0E0}, {590.03E0,9.0E0}, {651.92E0,10.0E0}, + {724.93E0,11.0E0}, {699.56E0,12.0E0}, {689.96E0,13.0E0}, {637.56E0,14.0E0}, {717.41E0,15.0E0} +}; + + +/** Use RatkoswkyResidual on Formulas to computes its derivatives +*/ + +void TestRatkoswky(const tVRatkoswkyData & aVData,const std::vector & aInitialGuess) +{ + size_t aNbUk = 4; + size_t aNbObs = 2; + assert(aInitialGuess.size()==aNbUk); // consitency test + + //-[1] ========= Create/Init the coordinator ================= + //- This part [1] would be executed only one time + // Create a coordinator/context where values are stored on double and : + // 4 unknown (b1-b4), 2 observations, a buffer of size 100 + FD::cCoordinatorF aCFD(100,aNbUk,aNbObs); + + // Create formulas of residuals, VUk and VObs are vector of formulas for unkown and observation + auto aFormulaRes = RatkoswkyResidual(aCFD.VUk(),aCFD.VObs()); + + // Set the formula that will be computed + aCFD.SetCurFormulasWithDerivative(aFormulaRes); + + //-[2] ========= Now Use the coordinator to compute vals & derivatives ================= + // "Push" the data , this does not make the computation, data are memporized + // In real case, you should be care to flush with EvalAndClear before you exceed buffe (100) + for (const auto & aVYX : aVData) + { + assert(aVYX.size()==aNbObs); // consitency test + aCFD.PushNewEvals(aInitialGuess,aVYX); + } + // Now run the computation on "pushed" data, we have the derivative + const std::vector *> & aVEvals = aCFD.EvalAndClear(); + assert(aVEvals.size()==aVData.size()); // Check we get the number of computation we inserted + + //-[3] ========= Now we can use the derivatives ========================== + // directly on aVEvals, or with interface : DerComp(), ValComp() + // here the "use" we do is to check coherence with numerical values and derivatives + + + for (size_t aKObs=0; aKObs result correspond to 1 obs + // storing order : V0 dV0/dX0 dV0/dX1 .... V1 dV1/dX1 .... (here only one val) + const std::vector & aLineRes = *(aVEvals.at(aKObs)); + + // [3.1] Check the value + double aValFLine = aLineRes[0]; // we access via the vector + double aValInterface = aCFD.ValComp(aKObs,0); // via the interface, 0=> first value (unique here) + double aValStd = RatkoswkyResidual(aInitialGuess,aVData[aKObs]).at(0); // Numerical value + assert(aValFLine==aValInterface); // exactly the same + assert(std::abs(aValFLine-aValStd)<1e-10); // may exist some numericall effect + + // [3.2] Check the derivate + for (size_t aKUnk=0 ; aKUnk is the "standard" function operating on numbers + // see NumericalDerivate in "MMVII_FormalDerivatives.h" + double aDerNum = FD::NumericalDerivate + (RatkoswkyResidual,aInitialGuess,aVData[aKObs],aKUnk,1e-5).at(0); + + // Check but with pessimistic majoration of error in finite difference + assert(std::abs(aDerFLine-aDerNum)<1e-4); + } + } + std::cout << "OK TestRatkoswky \n"; +} + + +/* {II} ======================== ========================================== + + This second example, we take a very basic example to analyse some part of the +*/ +template +std::vector FitCube + ( + const std::vector & aVUk, + const std::vector & aVObs + ) +{ + const Type & a = aVUk[0]; + const Type & b = aVUk[1]; + + const Type & x = aVObs[0]; + const Type & y = aVObs[1]; + + // Naturally the user would write that + if (false) + { + return {cube(a+b *x)- y}; + Type F = (a+b *x); + return {F*F*F - y}; + } + + + // but here we want to test the reduction process + return {(a+b *x)*(x*b+a)*(a+b *x) - y}; +} + +void InspectCube() +{ + std::cout << "===================== TestFoncCube ===================\n"; + + // Create a context where values are stored on double and : + // 2 unknown, 2 observations, a buffer of size 100 + // aCFD(100,2,2) would have the same effect for the computation + // The variant with vector of string, will fix the name of variables, it + // will be usefull when will generate code and will want to analyse it + FD::cCoordinatorF aCFD(100,{"a","b"},{"x","y"}); + + // Inspect vector of unknown and vector of observations + { + for (const auto & aF : aCFD.VUk()) + std::cout << "Unknowns : "<< aF->Name() << "\n"; + for (const auto & aF : aCFD.VObs()) + std::cout << "Observation : "<< aF->Name() << "\n"; + } + + // Create the formula corresponding to residual + std::vector> aVResidu = FitCube(aCFD.VUk(),aCFD.VObs()); + FD::cFormula aResidu = aVResidu[0]; + + // Inspect the formula + std::cout << "RESIDU FORMULA, Num=" << aResidu->NumGlob() << " Name=" << aResidu->Name() <<"\n"; + std::cout << " PP=[" << aResidu->InfixPPrint() <<"]\n"; + + // Inspect the derivative relatively to b + auto aDerb = aResidu->Derivate(1); + std::cout << "DERIVATE FORMULA , Num=" << aDerb->NumGlob() << " Name=" << aDerb->Name() <<"\n"; + std::cout << " PP=[" << aDerb->InfixPPrint() <<"]\n"; + + // Set the formula that will be computed + aCFD.SetCurFormulasWithDerivative(aVResidu); + + // Print stack of formula + std::cout << "====== Stack === \n"; + aCFD.ShowStackFunc(); + + getchar(); +} + +/* {III} ======================== Test perf on colinearit equation ========================== + + On this example we use the colinearity equation which is central in bundle adjustment. We + use it with different type of camera : + + * a Fraser camera, which a very current as it modelize physically the + main distorsion with a relatively low number of parameters + + * a polynomial model that is more mathemitcall that can be used to approximate any + function; the degree is parametrizable inside a template + +Now we make a macro description of the main classes : + + class cEqCoLinearity : implement the colinarity equation; + + It is parametrized by the type of distortion TypeDist; the TypeDist + will define the mathematicall function of distorsion + the TypeDist will also define the types of "scalars" for unknowns + and observation. Scalar can be jet,cFormula, num. + See class cTplFraserDist for a detailled example of requirement to + be a valid dist. + + Fundamental static method : Residual , for a given value of unknown and obs, + return the vector of residual (x,y). + + cCountDist a Class for centralizing the counting of unknown and obs + + class cTplFraserDist : public cCountDist<7> + a class implemanting fraser distorsion + + class cTplPolDist + a class implemanting polynomial distorsion of degre "Deg" +*/ + +/* + ================ Mathematical formalization =============== + + The unknown are : + + * Pg = PGround + * C = Center of camera + * R = Orientation of camera Rotation Matrix + * F,PP = Principal point and focal + * Distortion + + Then, without distorsion, we have alreay 12 unkwnown + + We write the rotation as R = A * R0 , were R0 is the current value of the + rotation. Because : + * it avoid the the classical guimbal-lock problem + * as A is a rotation close to identity, we ca, write A = I + ^W were W + is a small vector , and ^W is the vector product matrix + + Then we have 11 obsevation : + + * 9 for matrix R0 + * 2 for image point PIm + + The equation is + + * Pc = (I +^W) R0 (Pg-C) for Pc= coordinate in camera repair + * PPi = Pp + F*(Pc.x,Pc.y) / Pc.z for projection without distorsion + + => PIm = Dist(Proj) +*/ + +/** + A class for sharing the number of unknown & observations. One template parameter + the number of unknown of the distortion +*/ + +template class cCountDist +{ + public : + static const int TheNbDist = NbParamD; + static const int TheNbCommonUk = 12 ; + static const int TheNbUk = TheNbCommonUk + TheNbDist; + static const int TheNbObs = 11; + + typedef Jet tJets; + typedef FD::cCoordinatorF tCoord; + typedef typename tCoord::tFormula tFormula; + + static const std::vector & VNamesObs() + { + static std::vector TheVObs + { + "oR00","oR01","oR02","oR10","oR11","oR12","oR20","oR21","oR22", // Rotation + "oXIm","oYIm" // Image point + }; + return TheVObs; + }; + static const std::vector & VUnkGlob () + { + static std::vector TheVUk + { + "XGround","YGround","ZGround", // Unknown 3D Point + "XCam","YCam","ZCam", "Wx","Wy","Wz", // External Parameters + "ppX","ppY","ppZ" // Internal : principal point + focal + }; + return TheVUk; + } + +}; + +/** Class implementing the fraser model distortion. + + It contains the 4 prerequirement to be a Valid distorsion class usable in + cEqCoLinearity : + + * definition of type of unknown tUk + * definition of type of obs tObs + * definition of the vector of names of unknown VNamesUnknowns(), + this vector contain the 12 global unknown + those specific to dist + * method Dist for computing the distortion + + The method Dist take as parameters : + + * xPi, yPi + * the vector of unknown , the 12 first value are those describes above + * the vector of observation, it is not used for now, but maybe + will be later for some dist ? + +*/ + +template class cTplFraserDist : public cCountDist<7> +{ + public : + typedef TypeUk tUk; + typedef TypeObs tObs; + static const std::vector& VNamesUnknowns() + { + static std::vector TheV; + // Add name of distorsion to others unkonw + if (TheV.empty()) + { + TheV = VUnkGlob(); + // k2,k4,k6 Distorsion radiale; p1 p2 Decentric ; b1 b2 Affine + for (auto aS :{"k2","k4","k6", "p1","p2","b1","b2"}) + TheV.push_back(aS); + } + + return TheV; + } + + static std::vector Dist ( + const tUk & xPi,const tUk & yPi, + const std::vector & aVUk, const std::vector & + ) + { + // In this model we confond Principal point and distorsion center, + const auto & xCD = aVUk[ 9]; + const auto & yCD = aVUk[10]; + + // Radial distortions coefficients + const auto & k2D = aVUk[12]; + const auto & k4D = aVUk[13]; + const auto & k6D = aVUk[14]; + + // Decentric distorstion + const auto & p1 = aVUk[15]; + const auto & p2 = aVUk[16]; + + // Affine distorsion + const auto & b1 = aVUk[17]; + const auto & b2 = aVUk[18]; + + // Coordinate relative to distorsion center + auto xC = xPi-xCD; + auto yC = yPi-yCD; + auto x2C = square(xC); // Use the indermediar value to (probably) optimize Jet + auto y2C = square(yC); + auto xyC = xC * yC; + auto Rho2C = x2C + y2C; + + // Compute the distorsion + auto rDist = k2D*Rho2C + k4D * square(Rho2C) + k6D*cube(Rho2C); + auto affDist = b1 * xC + b2 * yC; + auto decX = p1*(3.0*x2C + y2C) + p2*(2.0*xyC); + auto decY = p2*(3.0*y2C + x2C) + p1*(2.0*xyC); + + + auto xDist = xPi + xC * rDist + decX + affDist; + auto yDist = yPi + yC * rDist + decY ; + + return {xDist,yDist}; + } + private : +}; + + + + +/* + Class for implementing a polynomial distorsion. The maximal degree + is the last parameter of this template class. + + In this model, we want to be abble to approximat any smooth function, + so a priori we will use all the monome under a given degree. + Let D be the degree the distortion will be : + + Distx = Som (dx_ij X^i Y^j) i+j<=D + Disty = Som (dy_ij X^i Y^j) i+j<=D + + + But it we want to avoid sur parametrization, we have to be cautious and avoid + certain monoms because they redundant, or highly correlated, with some external + parameter (rotation) or other internal parameter ( PP,focal). So we avoid : + + - Degre 0 => all because principal point + + - Degre 1 => + * we note (dx_10 dx_01 dy_10 dy_01) the degree 1 parameter + * (1 0 0 1) is focal, so avoid it + * (0 -1 1 0) is a pure rotation and redundant with rotation around axe, avoid it + * so we have to select a complementary base, + * (1 0 0 0) (0 1 0 0) is a complementary base + + So we avoid degree 1 in Y + + - Degre 2 : + + * Rotation arround X + linear are highly correlated to X2 + affine, so we muste + so avoid X2 in X + * Idem avoid Y2 in Y + + + Finnaly we have : + + * (D+1) (D+2) /2 monome in X, same for Y + * 6 monome to avoid + + ---------------------------------------------------------------- + + In this class we have the 4 requirement as in Fraser. We have also two + facility function : + + * bool OkMonome(bool isX,int aDegX,int aDegY) indicate if a monome of + degree Dx,Dy is not to avoid (the bool isX means if it for Dx or Dy as + the rule is not the same) + + * void InitDegreeMonomes(xDx,xDy,yDx,yDy); + The 4 parameters are & of vector of int, as a result they contain the + degrees of the monomes : + DistX = Som ( X ^ xDx[K] Y ^ yDy[k]) + +*/ + + +/** Class implementing a polynomial distorsion of degree Deg +*/ + + +template class cTplPolDist : + public cCountDist<(Deg+1)*(Deg+2) -6> +{ + public : + typedef TypeUk tUk; + typedef TypeObs tObs; + typedef cCountDist<(Deg+1)*(Deg+2) -6> tCountDist; + + + // Vectors of names of unknowns + static const std::vector& VNamesUnknowns() + { + static std::vector TheV; + if (TheV.empty()) // First call + { + // Get the common unknowns + TheV = tCountDist::VUnkGlob(); + + // Get the degrees of monomes + std::vector aXDx,aXDy,aYDx,aYDy; + InitDegreeMonomes(aXDx,aXDy,aYDx,aYDy); + + // Add the name of monomes for X Dist + for (size_t aK=0 ; aK Dist ( + const tUk & xPi,const tUk & yPi, + const std::vector & aVUk, const std::vector & + ) + { + static std::vector aXDx,aXDy,aYDx,aYDy; + if (aXDx.empty()) // first call compute degree of monomes + InitDegreeMonomes(aXDx,aXDy,aYDx,aYDy); + + // We compute here the Value of monomes : X^i and Y^j , + // this is an optimisation for jets, probably not usefull for formula, but does not hurt either + std::vector aVMonX; + std::vector aVMonY; + + // We can compute it using powI optimized functionc, or using a recurence formula + // According to type, the optimal computation may not be the same + // On tests it seems more or less equivalent .... + if (0) + { + // Case using powI + for (int aD=0 ;aD<=Deg ; aD++) + { + aVMonX.push_back(powI(xPi,aD)); + aVMonY.push_back(powI(yPi,aD)); + } + } + else + { + // Case using recurence X^(k+1) = X^k *X + aVMonX.push_back(CreateCste(1.0,xPi)); + aVMonY.push_back(CreateCste(1.0,xPi)); + for (int aD=1 ;aD<=Deg ; aD++) + { + aVMonX.push_back(aVMonX.back()*xPi); + aVMonY.push_back(aVMonY.back()*yPi); + } + } + // Initialisze with identity + auto xDist = xPi; + auto yDist = yPi; + + int anInd = tCountDist::TheNbCommonUk; // Unkown on dist are stored after common + // Be carefull to be coherent with VNamesUnknowns + for (size_t aK=0; aK & aXDx, // Degre in x of X component + std::vector & aXDy, // Degre in y of X component + std::vector & aYDx, // Degre in x of Y component + std::vector & aYDy // Degre in y of Y component + ) + { + for (int aDx=0 ; aDx<=Deg ; aDx++) + { + for (int aDy=0 ; (aDx+aDy)<=Deg ; aDy++) + { + if (OkMonome(true,aDx,aDy)) + { + aXDx.push_back(aDx); + aXDy.push_back(aDy); + } + + if (OkMonome(false,aDx,aDy)) + { + aYDx.push_back(aDx); + aYDy.push_back(aDy); + } + } + } + } +}; + + + + + +// template class cEqCoLinearity +template class cEqCoLinearity +{ + public : + typedef typename TypeDist::tUk tUk; + typedef typename TypeDist::tObs tObs; + + typedef typename TypeDist::tJets tJets; + static const int TheNbUk = TypeDist::TheNbUk; + static const int TheNbObs = TypeDist::TheNbObs; + + /* Capital letter for 3D variable/formulas and small for 2D */ + static std::vector Residual + ( + const std::vector & aVUk, + const std::vector & aVObs + ) + { + assert (aVUk.size() ==TheNbUk) ; // FD::UserSError("Bad size for unknown"); + assert (aVObs.size()==TheNbObs) ;// FD::UserSError("Bad size for observations"); + + // 0 - Ground Coordinates of projected point + const auto & XGround = aVUk[0]; + const auto & YGround = aVUk[1]; + const auto & ZGround = aVUk[2]; + + // 1 - Pose / External parameter + // 1.1 Coordinate of camera center + const auto & C_XCam = aVUk[3]; + const auto & C_YCam = aVUk[4]; + const auto & C_ZCam = aVUk[5]; + + // 1.2 Coordinate of Omega vector coding the unknown "tiny" rotation + const auto & Wx = aVUk[6]; + const auto & Wy = aVUk[7]; + const auto & Wz = aVUk[8]; + + // 2 - Intrinsic parameters + // 2.1 Principal point and Focal + const auto & xPP = aVUk[ 9]; + const auto & yPP = aVUk[10]; + const auto & zPP = aVUk[11]; // also named as focal + + // Vector P->Cam + auto XPC = XGround-C_XCam; + auto YPC = YGround-C_YCam; + auto ZPC = ZGround-C_ZCam; + + + // Coordinate of points in camera coordinate system, do not integrate "tiny" rotation + + auto XCam0 = aVObs[0] * XPC + aVObs[1]* YPC + aVObs[2]*ZPC; + auto YCam0 = aVObs[3] * XPC + aVObs[4]* YPC + aVObs[5]*ZPC; + auto ZCam0 = aVObs[6] * XPC + aVObs[7]* YPC + aVObs[8]*ZPC; + + // Now "tiny" rotation + // Wx X Wy * Z - Wz * Y + // Wy ^ Y = Wz * X - Wx * Z + // Wz Z Wx * Y - Wy * X + + // P = P0 + W ^ P0 + + auto XCam = XCam0 + Wy * ZCam0 - Wz * YCam0; + auto YCam = YCam0 + Wz * XCam0 - Wx * ZCam0; + auto ZCam = ZCam0 + Wx * YCam0 - Wy * XCam0; + + // Projection : (xPi,yPi,1) is the bundle direction in camera coordinates + + auto xPi = XCam/ZCam; + auto yPi = YCam/ZCam; + + // Now compute the distorsion + auto aVDist = TypeDist::Dist(xPi,yPi,aVUk,aVObs); + const auto & xDist = aVDist[0]; + const auto & yDist = aVDist[1]; + + // Use principal point and focal to compute image projection + auto xIm = xPP + zPP * xDist; + auto yIm = yPP + zPP * yDist; + + + // substract image observations to have a residual + auto x_Residual = xIm - aVObs[ 9]; + auto y_Residual = yIm - aVObs[10]; + + + return {x_Residual,y_Residual}; + } +}; + + +// TJD : type jets dist , TFD : type formal dist +template class cTestEqCoL +{ + public : + cTestEqCoL(int aSzBuf,bool Show); + + private : + static const int TheNbUk = TJD::TheNbUk; + static const int TheNbObs = TJD::TheNbObs; + + typedef typename TJD::tJets tJets; + typedef FD::cCoordinatorF tCoord; + typedef typename tCoord::tFormula tFormula; + + // static const std::vector TheVNamesUnknowns; + // static const std::vector TheVNamesObs; + + /// Return unknowns vect after fixing XYZ (ground point) + const std::vector & VUk(double X,double Y,double Z) + { + mVUk[0] = X; + mVUk[1] = Y; + mVUk[2] = Z; + + return mVUk; + } + /// Return observation vect after fixing I,J (pixel projection) + const std::vector & VObs(double I,double J) + { + mVObs[ 9] = I; + mVObs[10] = J; + + return mVObs; + } + + + tCoord mCFD; ///< Coordinator for formal derivative + std::vector mVUk; ///< Buffer for computing the unknown + std::vector mVObs; ///< Buffer for computing the unknown +}; + + + + +template +cTestEqCoL::cTestEqCoL(int aSzBuf,bool Show) : + // mCFD (aSzBuf,TheNbUk,TheNbObs), // would have the same effect, but future generated code will be less readable + mCFD (aSzBuf,TJD::VNamesUnknowns(),TJD::VNamesObs()), + mVUk (TheNbUk,0.0), + mVObs (TheNbObs,0.0) +{ + // As I was not able to make automatic computation of size Jets, we check that user + // did not mistake + + static_assert(TJD::tUk::DIMENSION==TheNbUk,"Incoherent size Jets/Number Unknonws"); + + + // In unknown, we set everything to zero exepct focal to 1 + mVUk[11] = 1.0; + // In obs, we set the current matrix to Id + mVObs[0] = mVObs[4] = mVObs[8] = 1; + + double aT0 = TimeElapsFromT0(); + +// auto aVFormula = FraserFuncCamColinearEq(mCFD.VUk(),mCFD.VObs()); + auto aVFormula = cEqCoLinearity::Residual (mCFD.VUk(),mCFD.VObs()); + if (Show) + { + mCFD.SetCurFormulas({aVFormula[0]}); + int aNbRx = mCFD.VReached().size() ; + mCFD.SetCurFormulas(aVFormula); + int aNbRxy = mCFD.VReached().size() ; + + std::cout << "NbReached x:" << aNbRx << " xy:" << aNbRxy << "\n"; + + mCFD.SetCurFormulas({aVFormula[0]}); + mCFD.ShowStackFunc(); + } + mCFD.SetCurFormulasWithDerivative(aVFormula); + if (Show) + { + const std::vector& aVR =mCFD.VReached(); + int aNbTot=0; + int aNbPl=0; + for (const auto & aF : aVR) + { + aNbTot++; + std::string anOp = aF->NameOperator() ; + std::cout << "Opp= " << anOp << "\n"; + if ((anOp=="+") || (anOp=="*")) + { + aNbPl++; + } + } + std::cout + << " Tot=" << aNbTot + << " Pl=" << aNbPl + << "\n"; + } + + double aT1 = TimeElapsFromT0(); + + std::cout << "TestFraser " + << ", SzBuf=" << aSzBuf + << ", NbEq=" << mCFD.VReached().size() + << ", TimeInit=" << (aT1-aT0) << "\n"; + + + // mCFD.ShowStackFunc(); + + int aNbTestTotal = 1e5; ///< Approximative number of Test + int aNbTestWithBuf = aNbTestTotal/aSzBuf; ///< Number of time we will fill the buffer + aNbTestTotal = aNbTestWithBuf * aSzBuf; ///< Number of test with one equation + + // Here we initiate with "peferct" projection, to check something + const std::vector & aVUk = VUk(1.0,2.0,10.0); + const std::vector & aVObs = VObs(0.101,0.2); + + // Make the computation with jets + double TimeJets = TimeElapsFromT0(); + std::vector aJetRes; + { + std::vector aVJetUk; + for (int aK=0 ; aK::Residual (aVJetUk,aVObs); + } + TimeJets = TimeElapsFromT0() - TimeJets; + } + + // Make the computation with formal deriv buffered + double TimeBuf = TimeElapsFromT0(); + { + for (int aK=0 ; aK,double> tFraserJ; +typedef cTplFraserDist,FD::cFormula> tFraserF; + + +typedef cTplPolDist,double,7> tPolJD7; +typedef cTplPolDist,FD::cFormula,7> tPolFD7; + +typedef cTplPolDist,double,2> tPolJD2; +typedef cTplPolDist,FD::cFormula,2> tPolFD2; + +void TestFraserCamColinearEq() +{ + { + FD::cCoordinatorF aCoord(100,4,2); + FD::cFormula aFPi = aCoord.CsteOfVal(3.14); + FD::cFormula aFE = aCoord.CsteOfVal(exp(1)); + FD::cFormula aFCste = aFE+aFPi; + std::cout << " CSTE=[" << aFCste->InfixPPrint() <<"]\n"; + + FD::cFormula aX = aCoord.VUk()[0]; + FD::cFormula aY = aCoord.VUk()[1]; + FD::cFormula aZ = aCoord.VUk()[2]; + FD::cFormula aT = aCoord.VUk()[3]; + FD::cFormula aMX = - aX; + FD::cFormula aMMX = - aMX; + std::cout << " -X, --X=[" << aMX->InfixPPrint() << " " << aMMX->InfixPPrint() <<"]\n"; + + FD::cFormula aPipX = aFPi - aMX; + std::cout << " piPx= [" << aPipX->InfixPPrint() << "," << aPipX->Name() <<"]\n"; + + + FD::cFormula XpX = aX + aX; + std::cout << " XpX= [" << XpX->InfixPPrint() <<"]\n"; + + + FD::cFormula XpPiX = aZ+ aX + aY + aX * aFPi + aT; + + std::cout << " XpPiX= [" << XpPiX->InfixPPrint() <<"]\n"; + aCoord.ShowStackFunc(); + } + getchar(); + + + for (auto SzBuf : {1000,1}) + { + cTestEqCoL (SzBuf,false); + + cTestEqCoL (SzBuf,false); + cTestEqCoL (SzBuf,false); + + std::cout << "======================\n"; + } + + + getchar(); +} + + +/* -------------------------------------------------- */ + +namespace MMVII +{ + void BenchCmpOpVect(); +}; + +void Bench_powI() +{ + // Test that function powI gives the same results than pow + // Test alsp for jets, the value and the derivatives + for (int aK=-4 ; aK<44 ; aK++) + { + double aV= 1.35; + double aP1= pow(aV,double(aK)); + double aP2= FD::powI(aV,aK); + FD::AssertAlmostEqual(aP1,aP2,1e-8); + + Jet aJ0= powI(Jet (aV,0),aK); + FD::AssertAlmostEqual(aP1,aJ0.a,1e-8); + + double aEps = 1e-7; + double aP1Minus = pow(aV-aEps,double(aK)); + double aP1Plus = pow(aV+aEps,double(aK)); + double aNumDer = (aP1Plus-aP1Minus) / (2.0*aEps); + FD::AssertAlmostEqual(aNumDer,aJ0.v[0],1e-8); + } + + // Bench on time performance + int aNb=1e8; + + // Using std::pow + double aT0 = TimeElapsFromT0(); + double aS=0; + for (int aK=0 ; aK supress the switch + double aT2 = TimeElapsFromT0(); + for (int aK=0 ; aK::DoIt(); + // cTestOperationVector::DoIt(); + // cTestOperationVector::DoIt(); + getchar(); +} + + +/* +--- Form[0] => C0 ; Val=0 +--- Form[1] => C1 ; Val=1 +--- Form[2] => C2 ; Val=2 +-0- Form[3] => a +-0- Form[4] => b +-0- Form[5] => x +-0- Form[6] => y +-1- Form[7] => F4*F5 // bx +-2- Form[8] => F7+F3 // a+bx +-3- Form[9] => F8*F8 // (a+bx) ^2 +-4- Form[10] => F8*F9 // (a+bx) ^ 3 +-5- Form[11] => F10-F6 // (a+bx)^3-y +-3- Form[12] => F8*F5 // x(a+bx) +-4- Form[13] => F12+F12 // 2x(a+bx) +-5- Form[14] => F13*F8 // 2x(a+bx)^2 +-4- Form[15] => F9*F5 // x (a+bx)^2 +-6- Form[16] => F14+F15 // 3 x(a+bx)^2 +-3- Form[17] => F8+F8 // 2 (a+bx) +-4- Form[18] => F8*F17 // 2 (a+bx) ^2 +-5- Form[19] => F18+F9 // 3 (a+bx) ^2 + +(a+bx)^3 +3 (a+bx)^2 +3 x (a+bx)^2 + +REACHED 5 3 6 4 7 8 9 17 12 10 18 15 13 11 14 19 16 // Reached formula in their computation order +CUR 11 19 16 // Computed formula +*/ + + + diff --git a/MMVII/src/TestLibsExtern/TestJetsCam.cpp b/MMVII/src/TestLibsExtern/TestJetsCam.cpp new file mode 100644 index 0000000000..7996b9b06d --- /dev/null +++ b/MMVII/src/TestLibsExtern/TestJetsCam.cpp @@ -0,0 +1,334 @@ +#include "include/MMVII_all.h" +#include "include/MMVII_Derivatives.h" + + +namespace MMVII +{ +static const int SzJetCam=17; + +/** \file TestJetsCam.cpp + \brief Make benchmark on jets vs with camera projection + + This file contain test on efficiency of jets , sparse and dense, + compared to generated code. Ceres implementation is still to add. + +*/ + +/* ************************************** */ +/* */ +/* cVarEpsNum */ +/* */ +/* ************************************** */ + +double cVarEpsNum::BufEps[SzBuf]; +bool cVarEpsNum::IsInit = false; + + + +/* ************************************** */ +/* */ +/* cProjCamRad */ +/* */ +/* ************************************** */ + +/** Template class for implementing the projection formula, + can be used with any type having the 4 operation "+*-/" + (i.e double, jets, sparse jets ...) +*/ +template class cProjCamRad +{ + public : + void Compute (Type * Residual); + + cProjCamRad(); + cDenseMatrix mRotCur; + cPt2dr mPix; + + Type mParameter[SzJetCam]; +}; + +template cProjCamRad::cProjCamRad() : + mRotCur(3,3,eModeInitImage::eMIA_MatrixId), + mPix (0,0) +{ +} + +template void cProjCamRad::Compute(Type * Residu) +{ + // Ground Coordinates of projected point + Type & XTer = mParameter[0]; + Type & YTer = mParameter[1]; + Type & ZTer = mParameter[2]; + + // Coordinate of camera center + Type & C_XCam = mParameter[3]; + Type & C_YCam = mParameter[4]; + Type & C_ZCam = mParameter[5]; + + // Coordinate of Omega vector coding the unknown "tiny" rotation + Type & Wx = mParameter[6]; + Type & Wy = mParameter[7]; + Type & Wz = mParameter[8]; + + // Coordinate Center of distorstion + Type & xCD = mParameter[9]; + Type & yCD = mParameter[10]; + + // Distortions coefficients + Type & k2D = mParameter[11]; + Type & k4D = mParameter[12]; + Type & k6D = mParameter[13]; + + // PP and Focal + Type & xPP = mParameter[14]; + Type & yPP = mParameter[15]; + Type & zPP = mParameter[16]; // also named as focal + + // Vector P->Cam + Type XPC = XTer-C_XCam; + Type YPC = YTer-C_YCam; + Type ZPC = ZTer-C_ZCam; + + + // Coordinate of points in camera coordinate system, do not integrate "tiny" rotation + + Type XCam0 = mRotCur(0,0)*XPC + mRotCur(1,0)*YPC + mRotCur(2,0)*ZPC; + Type YCam0 = mRotCur(0,1)*XPC + mRotCur(1,1)*YPC + mRotCur(2,1)*ZPC; + Type ZCam0 = mRotCur(0,2)*XPC + mRotCur(1,2)*YPC + mRotCur(2,2)*ZPC; + + // Now "tiny" rotation + // Wx X Wy * Z - Wz * Y + // Wy ^ Y = Wz * X - Wx * Z + // Wz Z Wx * Y - Wy * X + + // P = P0 + W ^ P0 + + Type XCam = XCam0 + Wy * ZCam0 - Wz * YCam0; + Type YCam = YCam0 + Wz * XCam0 - Wx * ZCam0; + Type ZCam = ZCam0 + Wx * YCam0 - Wy * XCam0; + + // Projection + + Type xPi = XCam/ZCam; + Type yPi = YCam/ZCam; + + + // Coordinate relative to distorsion center + Type xC = xPi-xCD; + Type yC = yPi-yCD; + Type Rho2C = Square(xC) + Square(yC); + + // Compute the distorsion + Type Dist = k2D*Rho2C + k4D * Square(Rho2C) + k6D*Cube(Rho2C); + + Type xDist = xPi + xC * Dist; + Type yDist = yPi + yC * Dist; + + // Use principal point and focal + Type xIm = xPP + zPP * xDist; + Type yIm = yPP + zPP * yDist; + + Residu[0] = xIm - mPix.x(); + Residu[1] = yIm - mPix.y(); +} + +/* ************************************** */ +/* */ +/* cVarJetsTestCam */ +/* */ +/* ************************************** */ + +/** Class using sparse jets to implement camera projection & derivatives */ + +class cVarJetsTestCam : public cInterfaceTestCam +{ + public : + void InitFromParams(const std::vector &) override; + void Compute(std::vector & Vals,std::vector > & ) override; + void Compute(int aNb) override; + private : + cProjCamRad mVarJetsCam; +}; + +void cVarJetsTestCam::InitFromParams(const std::vector & aVParam) +{ + for (int aK=0 ; aK & Vals,std::vector > & aDer) +{ + Vals = std::vector(2); + aDer.clear(); + + cVarEpsNum aResidu[2]; + mVarJetsCam.Compute(aResidu); + for (int aDimXY=0 ; aDimXY<2 ; aDimXY++) + { + const cVarEpsNum & aR= aResidu[aDimXY]; + Vals[aDimXY] = aR.mNum; + aDer.push_back(std::vector(SzJetCam,0.0)); + for (int aKParam=0 ; aKParam &) override; + void Compute(std::vector & Vals,std::vector > & ) override; + void Compute(int aNb) override; + private : + cProjCamRad > mJetsCam; + +}; + +void cJetsTestCam::InitFromParams(const std::vector & aVParam) +{ + for (int aK=0 ; aK(aVParam[aK],aK); +} + +void cJetsTestCam::Compute(std::vector & Vals,std::vector > & aDer) +{ + Vals = std::vector(2); + aDer.clear(); + + cEpsNum aResidu[2]; + mJetsCam.Compute(aResidu); + for (int aDimXY=0 ; aDimXY<2 ; aDimXY++) + { + Vals[aDimXY] = aResidu[aDimXY].mNum; + aDer.push_back(std::vector(SzJetCam)); + for (int aKParam=0 ; aKParam aResidu[2]; + for (int aK=0 ; aK StdParamTestCam(double AmplNoise) +{ + std::vector aRes; + + aRes.push_back(0.0+0.01*RandUnif_C()*AmplNoise); //X-Gr + aRes.push_back(0.0+0.01*RandUnif_C()*AmplNoise); //Y-Gr + aRes.push_back(1.0+0.01*RandUnif_C()*AmplNoise); //Z-Gr + + aRes.push_back(0.0+0.01*RandUnif_C()*AmplNoise); //X-Cam + aRes.push_back(0.0+0.01*RandUnif_C()*AmplNoise); //Y-Cam + aRes.push_back(0.0+0.01*RandUnif_C()*AmplNoise); //Z-Cam + + aRes.push_back(0.0); // W-x Mandotary 000 as it is the complementary rotation + aRes.push_back(0.0); // W-y + aRes.push_back(0.0); // W-z + + aRes.push_back(0.01 *RandUnif_C()*AmplNoise); // Centre dist X + aRes.push_back(0.02 *RandUnif_C()*AmplNoise); // Centre dist Y + + + aRes.push_back(0.01 *RandUnif_C()*AmplNoise); // K1 + aRes.push_back(0.01 *RandUnif_C()*AmplNoise); // K2 + aRes.push_back(0.01 *RandUnif_C()*AmplNoise); // K3 + + + aRes.push_back(3000 * (1+ 0.01 *RandUnif_C()*AmplNoise)); // PPx + aRes.push_back(2000 * (1+ 0.01 *RandUnif_C()*AmplNoise)); // PPy + aRes.push_back(6000 * (1+ 0.01 *RandUnif_C()*AmplNoise)); // PPz / Focale + + return aRes; + +} + +void BenchJetsCam() +{ + for (int aK=0 ; aK<10 ; aK++) + { + std::vector aVParam = StdParamTestCam(1.0); + std::vector aValJet,aValV1,aVarValJet; + std::vector > aDerJet,aDerV1,aVarDerJet; + + cJetsTestCam aCamJet; + aCamJet.InitFromParams(aVParam); + aCamJet.Compute(aValJet,aDerJet); + + cVarJetsTestCam aVarCamJet; + aVarCamJet.InitFromParams(aVParam); + aVarCamJet.Compute(aVarValJet,aVarDerJet); + + + std::shared_ptr aCamV1 (cInterfaceTestCam::AllocMMV1()); + aCamV1->InitFromParams(aVParam); + aCamV1->Compute(aValV1,aDerV1); + + for (int aKXY=0 ; aKXY<2 ; aKXY++) + { + double aDif = aValJet[aKXY]-aValV1[aKXY]; + MMVII_INTERNAL_ASSERT_bench(std::abs(aDif)<1e-5,"Jets/V1 vals"); + + aDif = aVarValJet[aKXY]-aValV1[aKXY]; + + // StdOut() << "DDD=" << aDif<< " " << aValJet[aKXY] << " " << aValV1[aKXY] << "\n"; + for (int aKD=0 ; aKDCompute(aNbTest); + double aT2 = cMMVII_Appli::CurrentAppli().SecFromT0(); + // Now we now that sparse jets are slow save some time + double aT3 = aT2; + if (aK==0) + { + aVarCamJet.Compute(aNbTest); + aT3 = cMMVII_Appli::CurrentAppli().SecFromT0(); + } + + StdOut() << "TimeJets=" << (aT1-aT0) << " TimeV1=" << (aT2-aT1) << " TVar=" << (aT3-aT2) << "\n"; + } +} + + +}; diff --git a/MMVII/src/TestLibsExtern/TestMyJets.cpp b/MMVII/src/TestLibsExtern/TestMyJets.cpp new file mode 100644 index 0000000000..323b2f59f4 --- /dev/null +++ b/MMVII/src/TestLibsExtern/TestMyJets.cpp @@ -0,0 +1,183 @@ +#include "include/MMVII_all.h" +#include "include/MMVII_Derivatives.h" + +extern void BenchFormalDer(); + +namespace MMVII +{ + +/* +class cXMMVII_Ofs : public cMemCheck +{ +}; +*/ + + + +/* ************************************** */ +/* */ +/* cTestJets */ +/* */ +/* ************************************** */ + +#if (0) + +#endif + +// Test coherence between cEpsNum and cVarEpsNum + +template void TplBenchDifJets() +{ + { + static int aCpt=0,aNbTot=0,aNbNot0=0; aCpt++; + + // Generate an EpsNum with a random density of non 0 + cEpsNum anEps1 = cEpsNum::Random(RandUnif_0_1()); + // Convert to var + cVarEpsNum aVEps1 = anEps1.ToVEN(); + // Compute differnce + double aDif1 = EpsDifference(anEps1,aVEps1); + aNbTot+= Nb; + aNbNot0 += aVEps1.mVInd.size(); + + // Need a minimum number before we can compare experimental to theoreticall density + if (aCpt>100) + { + double aProp = aNbNot0/double(aNbTot); + // Verif que les proportion sont respectees pour que test soit probants + MMVII_INTERNAL_ASSERT_bench((aProp>0.25) && (aProp<0.75),"TplBenchDifJets"); + } + // Verif conversion, + MMVII_INTERNAL_ASSERT_bench(aDif1<1e-5,"TplBenchDifJets"); + + + // Generate five cEpsNum and their conversion in cVarEpsNum + cEpsNum anEps2 = cEpsNum::Random(RandUnif_0_1()); + cVarEpsNum aVEps2 = anEps2.ToVEN(); + + cEpsNum anEps3 = cEpsNum::Random(RandUnif_0_1()); + cVarEpsNum aVEps3 = anEps3.ToVEN(); + + cEpsNum anEps4 = cEpsNum::Random(RandUnif_0_1()); + cVarEpsNum aVEps4 = anEps4.ToVEN(); + + cEpsNum anEps5 = cEpsNum::Random(RandUnif_0_1()); + cVarEpsNum aVEps5 = anEps5.ToVEN(); + + // Make some calculus + cEpsNum anEpsCmp = 2.7+ 1.2*anEps1*1.3 + anEps2*COS(anEps3)+3.14 -(anEps4-1)/anEps5; + cVarEpsNum aVEpsCmp = 2.7+ 1.3*aVEps1*1.2 + aVEps2*COS(aVEps3)+3.14 -(aVEps4-1)/aVEps5; + + // Cheks the values are identical + double aDifCmp = EpsDifference(anEpsCmp,aVEpsCmp); + MMVII_INTERNAL_ASSERT_bench(aDifCmp<1e-5,"TplBenchDifJets"); + } + + // Construct tow equivalent cVarEpsNum and cEpsNum + double aVNum = RandUnif_C(); // Constant "Num" Val + // Create two numbers with no epsilon 4 Now + cVarEpsNum aVE(aVNum); + cEpsNum aE(aVNum); + int aNbCoeff = RandUnif_N(Nb); + for (int aTime=0 ; aTime aVec; + double * aD0 = & aVec(0); + double * aD1 = & aVec(1); + + MMVII_INTERNAL_ASSERT_bench((aD1-aD0)==1,"Assertion on Eigen memory organization"); + if (0) + { + StdOut() << "TEsEigenMEm " << aD0 << " " << aD1 << " " << (aD1-aD0) << "\n"; + getchar(); + } + } + + BenchJetsCam(); + + for (int aK=0 ; aK<1000 ; aK++) + { + TplBenchDifJets<10>(); + TplBenchDifJets<60>(); + } + + + //===== + +/* + TplTestJet<2>(1e-5); + TplTestJet<6>(1e-5); + TplTestJet<12>(1e-5); + TplTestJet<18>(1e-5); + TplTestJet<24>(1e-5); + TplTestJet<48>(1e-5); + TplTestJet<96>(1e-5); + TplTestJet<192>(1e-5); + TplTestJet<484>(1e-5); +*/ + + // Test that we can compile with, for example, points on jets + cEpsNum<20> aEps(3.0,1); + cPtxd,3> aP1(aEps,aEps,aEps); + cPtxd,3> aP2; + cPtxd,3> aP3 = aP1+aP2; + + IgnoreUnused(aP3); + +} +bool NEVER=false; + + +}; diff --git a/MMVII/src/UtiMaths/uti_nums.cpp b/MMVII/src/UtiMaths/uti_nums.cpp index 684cb71637..5eba04a2f5 100644 --- a/MMVII/src/UtiMaths/uti_nums.cpp +++ b/MMVII/src/UtiMaths/uti_nums.cpp @@ -187,7 +187,7 @@ template void TplBenchMinMax(int aNb) std::vector aVVals; Type aV0 = tNumTrait::RandomValueCenter(); - cWitchMinMax aWMM(0,aV0); + cWhitchMinMax aWMM(0,aV0); aVVals.push_back(aV0); for (int aK=0 ; aK std::unique_ptr NNfs(const std::string & aNameFile,c { std::unique_ptr aRes (new Type(aNameFile)); - if (!aRes->good()) - { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eOpenFile,"Cannot open file : " + aNameFile + " ,Mode=" + aMode+ " ,context=" + aMes); - } + MMVII_INTERNAL_ASSERT_User + ( + aRes->good(), + eTyUEr::eOpenFile, + "Cannot open file : " + aNameFile + " ,Mode=" + aMode+ " ,context=" + aMes + ); return aRes; } @@ -36,10 +38,12 @@ cMMVII_Ofs::cMMVII_Ofs(const std::string & aName,bool ModeAppend) : mOfs (aName,ModeAppend ? std::ios_base::app : std::ios_base::out), mName (aName) { - if (!mOfs.good()) - { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eOpenFile,"Cannot open file : " + mName + " in mode write"); - } + MMVII_INTERNAL_ASSERT_User + ( + mOfs.good(), + eTyUEr::eOpenFile, + "Cannot open file : " + mName + " in mode write" + ); } const std::string & cMMVII_Ofs::Name() const @@ -52,7 +56,7 @@ std::ofstream & cMMVII_Ofs::Ofs() #if (The_MMVII_DebugLevel>=The_MMVII_DebugLevel_InternalError_tiny) if (!mOfs.good()) { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eWriteFile,"Bad file for "+mName); + MMVII_UsersErrror(eTyUEr::eWriteFile,"Bad file for "+mName); } #endif return mOfs; @@ -101,10 +105,12 @@ cMMVII_Ifs::cMMVII_Ifs(const std::string & aName) : mIfs (aName), mName (aName) { - if (!mIfs.good()) - { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eOpenFile,"Cannot open file : " + mName + " in mode read"); - } + MMVII_INTERNAL_ASSERT_User + ( + mIfs.good(), + eTyUEr::eOpenFile, + "Cannot open file : " + mName + " in mode read" + ); } const std::string & cMMVII_Ifs::Name() const @@ -117,7 +123,7 @@ std::ifstream & cMMVII_Ifs::Ifs() #if (The_MMVII_DebugLevel>=The_MMVII_DebugLevel_InternalError_tiny) if (!mIfs.good()) { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eReadFile,"Bad file for "+mName); + MMVII_UsersErrror(eTyUEr::eReadFile,"Bad file for "+mName); } #endif return mIfs; diff --git a/MMVII/src/Utils/uti_memory.cpp b/MMVII/src/Utils/uti_memory.cpp index ae8b4a49d7..0f2a4a3d32 100644 --- a/MMVII/src/Utils/uti_memory.cpp +++ b/MMVII/src/Utils/uti_memory.cpp @@ -9,6 +9,12 @@ void mem_raz(void * adr,int64_t nb) memset(adr,0,nb); } +void DoNothingWithIt(void *) +{ + // As expected ;-) +} + + //================ cMemState ======= cMemState::cMemState() : diff --git a/MMVII/src/Utils/uti_set_sel.cpp b/MMVII/src/Utils/uti_set_sel.cpp index b0a0fc42c3..b8af325b0c 100644 --- a/MMVII/src/Utils/uti_set_sel.cpp +++ b/MMVII/src/Utils/uti_set_sel.cpp @@ -963,10 +963,10 @@ tNameSet SetNameFromString(const std::string & aName,bool AllowPat) { return SetNameFromPat(aName); } - // If we are here, we accept no file as empty set, but not file of bad format + // If we are here, we accept file as empty set, but not file of bad format if (ExistFile(aName)) { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eBadFileSetName,"Set from string, file has bad format for :" +aName); + MMVII_UsersErrror(eTyUEr::eBadFileSetName,"Set from string, file has bad format for :" +aName); } return tNameSet(); // emty set mode US } @@ -1028,9 +1028,9 @@ tNameRel RelNameFromFile (const std::string& aNameFile) if (ExistFile(aNameFile)) { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eBadFileRelName,"Rel from string, file has bad format for :" +aNameFile); + MMVII_UsersErrror(eTyUEr::eBadFileRelName,"Rel from string, file has bad format for :" +aNameFile); } - return tNameRel(); // emty set mode US + return tNameRel(); // emty rel mode US } diff --git a/MMVII/src/Utils/uti_string.cpp b/MMVII/src/Utils/uti_string.cpp index aba5f375ce..19c301b5f6 100644 --- a/MMVII/src/Utils/uti_string.cpp +++ b/MMVII/src/Utils/uti_string.cpp @@ -146,6 +146,12 @@ std::string Postfix(const std::string & aStr,char aSep,bool SVP,bool PrivPref) return aAfter; } +std::string LastPostfix(const std::string & aStr,char aSep) +{ + return Postfix(aStr,aSep,true,true); +} + + bool UCaseEqual(const std::string & aStr1 ,const std::string & aStr2) { @@ -361,7 +367,7 @@ bool CreateDirectories(const std::string & aDir,bool SVP) } else { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eCreateDir,"Cannot create directory for arg " + aDir); + MMVII_UsersErrror(eTyUEr::eCreateDir,"Cannot create directory for arg " + aDir); } } return Ok; @@ -381,10 +387,7 @@ bool RemoveRecurs(const std::string & aDir,bool ReMkDir,bool SVP) bool RemoveFile(const std::string & aFile,bool SVP) { bool Ok = boost::filesystem::remove(aFile); - if ((! Ok) && (!SVP)) - { - MMVII_INTERNAL_ASSERT_user(eTyUEr::eRemoveFile,"Cannot remove file for arg " + aFile); - } + MMVII_INTERNAL_ASSERT_User( Ok||SVP , eTyUEr::eRemoveFile,"Cannot remove file for arg " + aFile); return Ok; } diff --git a/MMVII/src/Utils/uti_sysdep.cpp b/MMVII/src/Utils/uti_sysdep.cpp index 706cfb9e0c..fb211148e9 100644 --- a/MMVII/src/Utils/uti_sysdep.cpp +++ b/MMVII/src/Utils/uti_sysdep.cpp @@ -3,7 +3,7 @@ namespace MMVII { -int SysCall(const std::string & aCom, bool SVP) +int GlobSysCall(const std::string & aCom, bool SVP) { int aResult = system(aCom.c_str()); if (aResult != EXIT_SUCCESS) diff --git a/README.md b/README.md index c6b706df5b..3bae6e77c8 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,17 @@ Instead of makefiles, *Cmake* generates a Visual C++ solution, named `micmac.sln Be sure to be in *Release* configuration, for Micmac is much faster built this way than in *Debug* mode. Again, do not compile the entire solution but just the `INSTALL` project, otherwise compiled binaries won't be copied in the `bin` directory and this will prevent Micmac from working. +## Docker image +A precompiled docker image is available and ready to use: + +`docker pull rupnike/micmac` + +or build your own image from scratch using the existing Dockerfile: + +`docker image build -t micmac:1.0 -f Dockerfile` + +[![Docker Status](https://dockeri.co/image/rupnike/micmac)](https://hub.docker.com/r/rupnike/micmac/) + # Installation test The website [logiciels.ign.fr](http://logiciels.ign.fr/?Telechargement,20) also provides a test dataset called `Boudha_dataset.zip`. diff --git a/applis/OLD-MICMAC-OLD/cStatNDistrib.cpp b/applis/OLD-MICMAC-OLD/cStatNDistrib.cpp index 824376b511..dad6799b94 100644 --- a/applis/OLD-MICMAC-OLD/cStatNDistrib.cpp +++ b/applis/OLD-MICMAC-OLD/cStatNDistrib.cpp @@ -631,33 +631,33 @@ void cStatGlob::SetSomsMade(bool aSSM) /*Footer-MicMac-eLiSe-25/06/2007 -Ce logiciel est un programme informatique servant à la mise en +Ce logiciel est un programme informatique servant a la mise en correspondances d'images pour la reconstruction du relief. -Ce logiciel est régi par la licence CeCILL-B soumise au droit français et +Ce logiciel est regi par la licence CeCILL-B soumise au droit francais et respectant les principes de diffusion des logiciels libres. Vous pouvez utiliser, modifier et/ou redistribuer ce programme sous les conditions -de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA +de la licence CeCILL-B telle que diffusee par le CEA, le CNRS et l'INRIA sur le site "http://www.cecill.info". -En contrepartie de l'accessibilité au code source et des droits de copie, -de modification et de redistribution accordés par cette licence, il n'est -offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, -seule une responsabilité restreinte pèse sur l'auteur du programme, le -titulaire des droits patrimoniaux et les concédants successifs. - -A cet égard l'attention de l'utilisateur est attirée sur les risques -associés au chargement, à l'utilisation, à la modification et/ou au -développement et à la reproduction du logiciel par l'utilisateur étant -donné sa spécificité de logiciel libre, qui peut le rendre complexe à -manipuler et qui le réserve donc à des développeurs et des professionnels -avertis possédant des connaissances informatiques approfondies. Les -utilisateurs sont donc invités à charger et tester l'adéquation du -logiciel à leurs besoins dans des conditions permettant d'assurer la -sécurité de leurs systèmes et ou de leurs données et, plus généralement, -à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. - -Le fait que vous puissiez accéder à cet en-tête signifie que vous avez -pris connaissance de la licence CeCILL-B, et que vous en avez accepté les +En contrepartie de l'accessibilite au code source et des droits de copie, +de modification et de redistribution accordes par cette licence, il n'est +offert aux utilisateurs qu'une garantie limitee. Pour les memes raisons, +seule une responsabilite restreinte pese sur l'auteur du programme, le +titulaire des droits patrimoniaux et les concedants successifs. + +A cet egard l'attention de l'utilisateur est attiree sur les risques +associes au chargement, a l'utilisation, a la modification et/ou au +developpement et a la reproduction du logiciel par l'utilisateur etant +donne sa specificite de logiciel libre, qui peut le rendre complexe a +manipuler et qui le reserve donc a des developpeurs et des professionnels +avertis possedant des connaissances informatiques approfondies. Les +utilisateurs sont donc invites a charger et tester l'adequation du +logiciel a leurs besoins dans des conditions permettant d'assurer la +securite de leurs systemes et ou de leurs donnees et, plus generalement, +a l'utiliser et l'exploiter dans les memes conditions de securite. + +Le fait que vous puissiez acceder a cet en-tete signifie que vous avez +pris connaissance de la licence CeCILL-B, et que vous en avez accepte les termes. Footer-MicMac-eLiSe-25/06/2007*/ diff --git a/binaire-aux/linux/siftpp_tgi.LINUX b/binaire-aux/linux/siftpp_tgi.LINUX index f20ad8638b..49e880df7b 100755 Binary files a/binaire-aux/linux/siftpp_tgi.LINUX and b/binaire-aux/linux/siftpp_tgi.LINUX differ diff --git a/include/XML_GEN/ParamApero.xml b/include/XML_GEN/ParamApero.xml index 6ae9d2e996..c5b5332046 100644 --- a/include/XML_GEN/ParamApero.xml +++ b/include/XML_GEN/ParamApero.xml @@ -973,6 +973,16 @@ se limite a tester les 2 algo et a selectionner le meilleur. A priori peut pas f + + + + + + + + + + + @@ -1768,6 +1770,7 @@ --> + @@ -2109,6 +2112,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // }; diff --git a/include/XML_GEN/ParamSaisiePts.xml b/include/XML_GEN/ParamSaisiePts.xml index 3b93e4aa6a..57dba4a20c 100644 --- a/include/XML_GEN/ParamSaisiePts.xml +++ b/include/XML_GEN/ParamSaisiePts.xml @@ -44,6 +44,8 @@ + + @@ -147,6 +149,8 @@ pas interfere avec format utilisateur basique, on separe --> + + diff --git a/include/XML_GEN/all.h b/include/XML_GEN/all.h index 6fb6493dc0..9f57281426 100644 --- a/include/XML_GEN/all.h +++ b/include/XML_GEN/all.h @@ -1117,6 +1117,16 @@ cXml_ParamBascRigide EL2Xml(const cSolBasculeRig &); cTypeCodageMatr ExportMatr(const ElMatrix & aMat); ElMatrix ImportMat(const cTypeCodageMatr & aCM); +// Return the cParamOrientSHC of a given name +cParamOrientSHC * POriFromBloc(cStructBlockCam & aBloc,const std::string & aName,bool SVP); +// Return the Rotation that transformate from Cam Coord to Block coordinates (in fact coord of "first" cam) +ElRotation3D RotCamToBlock(const cParamOrientSHC & aPOS); +// Return the Rotation that transformate from Cam1 Coord to Cam2 Coord +ElRotation3D RotCam1ToCam2(const cParamOrientSHC & aPOS1,const cParamOrientSHC & aPOS2); + + + + cXml_Rotation El2Xml(const ElRotation3D & aRot); ElRotation3D Xml2El(const cXml_Rotation & aXml); ElRotation3D Xml2ElRot(const cXml_O2IRotation & aXml); diff --git a/include/XML_MicMac/Apero-Compense.xml b/include/XML_MicMac/Apero-Compense.xml index 798b2da4d7..b63cd5c10d 100644 --- a/include/XML_MicMac/Apero-Compense.xml +++ b/include/XML_MicMac/Apero-Compense.xml @@ -51,7 +51,7 @@ AffineFree=false LibCD=false LibDec=false - + AllFreePattern=".*" PoseFigee=false @@ -223,6 +223,14 @@ RatioMaxDistCS=30.0 ExportMatrixMarket=false + NumAttrPdsNewF=-1 + + + WithROP=false + ROPSigmaC=-11.0 + ROPSigmaR=-11.0 + ROPOrient="XXX_RopOrient" + ROPPattern="XXX_RopPattern" @@ -260,6 +268,7 @@ NKS-Set-Orient@${AeroIn} NKS-Assoc-Im2Orient@${AeroIn} + <#WHEN VTEST=${WithGCP}> @@ -468,6 +477,15 @@ + <#WHEN VTEST=${WithROP}> + + ${ROPOrient} + ${ROPSigmaC} + ${ROPSigmaR} + ${ROPPattern} + + + ${NumAttrPdsNewF} ${ExportMatrixMarket} ${RatioMaxDistCS} ${StrDebugVecElimTieP} @@ -808,8 +826,9 @@ <#WHEN VTEST=${AllFree}> - + + ${AllFreePattern} eAllParamLibres diff --git a/include/XML_MicMac/Apero-Glob-New.xml b/include/XML_MicMac/Apero-Glob-New.xml index 38dc641c2e..50ed423301 100644 --- a/include/XML_MicMac/Apero-Glob-New.xml +++ b/include/XML_MicMac/Apero-Glob-New.xml @@ -8,8 +8,8 @@ HasSinglePoseCalibEstim=false - PatSinglePose=XXXXX - PatSingleCalib=XXXXX + PatSinglePose=PSPXXXXX + PatSingleCalib=PSCXXXXX - SetImInit="XXXX" + SetImInit="SIIXXXX" FileCamInit=InitCamCenter.xml AeroIn=XXXXXX diff --git a/include/XML_MicMac/DicoCamera.xml b/include/XML_MicMac/DicoCamera.xml index 8210fea46a..b850cba161 100644 --- a/include/XML_MicMac/DicoCamera.xml +++ b/include/XML_MicMac/DicoCamera.xml @@ -20,6 +20,13 @@ See https://en.wikipedia.org/wiki/Image_sensor_format#Table_of_sensor_formats_an --> + + LadyBug + 7.23 8.67 + LadyBug + + + OV8865 3.4 4.67 diff --git a/include/XML_MicMac/MM-Malt-Spatial.xml b/include/XML_MicMac/MM-Malt-Spatial.xml new file mode 100644 index 0000000000..f94fbd1b8f --- /dev/null +++ b/include/XML_MicMac/MM-Malt-Spatial.xml @@ -0,0 +1,795 @@ + + + + + + + + Dir="XXXX" + ImPat="XXX" + Ori=XXXX + + + ZRegul=0.12 + SzW=2 + ZoomFinal=2 + ResolRelOrhto=0.5 + ZoomInit=32 + + + + DefCor=0.3 + CostTrans=4.0 + NbMinIV=2 + Repere="NO-REPERE" + FileAnam=EmptyXML.xml + FileZMoy=EmptyXML.xml + UseGpu=false + NotUseGpu=! ${UseGpu} + + + FileMasqT=MM-MasqTerrain.xml + FileZ4PC=MM-Zoom4-PC.xml + FileZ2PC=EmptyXML.xml + + FileZ1Raff=MM-Zoom1Raffin.xml + + FileZ64=EmptyXML.xml + FileZ32=EmptyXML.xml + FileZ16PC=MM-Zoom16-PC.xml + FileOthoF=MM-Malt-OrthoFinal.xml + FileOthoQ=MM-Malt-OrthoQuick.xml + FileUnAnam=EmptyXML.xml + + ZPas=1.0 + + DbleZPas=2.0 + DemiZPas=0.5 + + + DirQO=Qk-ORTHO + DirMEC=MEC-Malt/ + Chantier=STD-MALT + DirTA=TA + Purge=true + + MkFPC=true + DoMEC=true + + DirOrthoF=ORTHO + + NbEtapeQuant=-1 + + NameMaskOrtho=../${DirMEC}AutoMask_STD-MALT_Num_${NbEtapeQuant}.tif + NameMTDMaskOrtho=../${DirMEC}Z_Num${NbEtapeQuant}_DeZoom${ZoomFinal}_STD-MALT.xml + + Geom=eGeomMNTFaisceauIm1ZTerrain_Px1D + + + ImageMaster=XXXX + ImageMasterSsPost=XXXX + FileIm1=EmptyXML.xml + ZIncIsProp=true + FullIm1=false + PasInPixel=true + + + ImMNT=".*" + ImOrtho=".*" + + ButDoOrtho=false + + FileDoNothing=EmptyXML.xml + UseImSec=false + CorMS=true + eAggregSymetrique=eAggregSymetrique + + + + AddZoom64=Sup ${ZoomInit} 64 + AddZoom32=Sup ${ZoomInit} 32 + AddZoom16=Sup ${ZoomInit} 16 + AddZoom8=Sup ${ZoomInit} 8 + AddZoom4=Sup ${ZoomInit} 4 + AddZoom2=Sup ${ZoomInit} 2 + + DoNotMEC=! ${DoMEC} + ButDoOrtho=true + + + UseMasqPerIm=false + MasqPerIm="XXXXXX" + UseGlobMasqPerIm=false + GlobMasqPerIm="XXXXXX" + + + + UseImMaxMin="false" + ImMin="XXXXXX" + ImMax="XXXXXX" + + + DoAnam=false + ParamAnam=XXXXX + IncidMax= 0.75 + DoIncid=false + DoMaskNadir=false + + + NotZoom8="Neq 8 ${ZoomFinal}" + UseClip=false + X0Clip=0 + Y0Clip=0 + X1Clip=1 + Y1Clip=1 + + + UseBoxTerrain=false + X0Terrain=0 + Y0Terrain=0 + X1Terrain=1 + Y1Terrain=1 + + UseRR=false + RoundResol=XXXX + GCC=false + + + NotCorMS=! ${CorMS} + + + + UseEqui=false + UseClas1=false + Clas1=.* + UseClas2=false + Clas2=.* + UseClas3=false + Clas3=.* + UseClas4=false + Clas4=.* + UseClas5=false + Clas5=.* + UseClas6=false + Clas6=.* + EZA=false + SzRec=50 + AlgoMaxFlow=false + + UseMasq3D=false + NameMasq3D=XXXX + + UseResolTerrain=false + ResolTerrain=0 + UseRatioResolImage=false + RatioResolImage=1 + + UseDEMInit=false + DEMInitXML="XXXXXX" + DEMInitIMG="XXXXXX" + + + + + ZIncCalc=0.3 + Conik=true + NonConik=! ${Conik} + PxIsProp=${Conik} + ModeOriIm=eGeomImageOri + ModeOrientStd=${Conik} + MSDense=true + + SpecDirFaisc="false" + DirFaisX="XXXXX" + DirFaisY="XXXXX" + DirFaisZ="XXXXX" + + UseMasqImGlobOrLoc= Or ${UseMasqPerIm} ${UseGlobMasqPerIm} + + InParal= Neq 0 ${NbProc} + + + UsePtDebug=false + PtDebugX=-10000000 + PtDebugY=-10000000 + RSRT=false + + UseGenBundle=false + ForDeform=false + UsePC=true + UseVSNI=false + VSNI=0 + NbDirPrgDyn=8 + ModeAgregPrgDyn=ePrgDAgrSomme + + + + + + + ${ZIncCalc} + ${ZIncIsProp} + ${FileZMoy} + <#WHEN VTEST=${UseDEMInit}> + + ${DEMInitIMG} + ${DEMInitXML} + + + + + + 0.5 + 3 + + + + <#WHEN VTEST=${UseResolTerrain}> + ${ResolTerrain} + + <#WHEN VTEST=${UseRatioResolImage}> + ${RatioResolImage} + + + + + ${RSRT} + ${FileMasqT} + ${ImMNT} + + + <#WHEN VTEST=${UseBoxTerrain}> + ${X0Terrain} ${Y0Terrain} ${X1Terrain} ${Y1Terrain} + + + + + <#WHEN VTEST=${UseRR}> + ${RoundResol} + + + + + + + true + ${ModeOriIm} + + <#WHEN VTEST=${UseVSNI}> + ${VSNI} + + + + ${FileIm1} + ${ImPat} + <#WHEN VTEST=${UseImMaxMin}> + + ${ImMin} + ${ImMax} + + + <#WHEN VTEST=${UseImSec}> + + NKS-Assoc-ImSec@-${Ori} + + + + + <#IF VTEST=${UseGenBundle}> + + + ${Ori} + .* + + + <#IF VTEST=${ModeOrientStd}> + + + NKS-Assoc-Im2Orient@-${Ori} + + + + (.*)\.[0-9,a-z,A-Z,_]{3,4} + $1.${Ori} + + + + + + <#WHEN VTEST=${UseGlobMasqPerIm}> + + + .* + ${GlobMasqPerIm} + + + + + <#WHEN VTEST=${UseMasqPerIm}> + + + (.*)\.(.*) + $1${MasqPerIm}.tif + + true + + + + <#WHEN VTEST=${UseEqui}> + + + <#WHEN VTEST=${UseClas1}> + + ${Clas1} + Classe1 + + + <#WHEN VTEST=${UseClas2}> + + ${Clas2} + Classe2 + + + <#WHEN VTEST=${UseClas3}> + + ${Clas3} + Classe3 + + + <#WHEN VTEST=${UseClas4}> + + ${Clas4} + Classe4 + + + <#WHEN VTEST=${UseClas5}> + + ${Clas5} + Classe5 + + + <#WHEN VTEST=${UseClas6}> + + ${Clas6} + Classe6 + + + + .* + ClasseDef + + + + + + + + + + <#WHEN VTEST=${UseClip}> + ${X0Clip} ${Y0Clip} ${X1Clip} ${Y1Clip} + + + ${PasInPixel} + ${NbMinIV} + ${FullIm1} + <#WHEN VTEST=${UseMasq3D}> + + ${NameMasq3D} + 16 + 2 + + + + + + -1 + ${SzW} + + <#WHEN VTEST=${NotUseGpu}> + <#IF VTEST=${AlgoMaxFlow}> + eAlgoCoxRoy + eAlgo2PrgDyn + + + + + true + false + + <#WHEN VTEST=${UseGpu}> + eAlgoTestGPU + + + true + ${GCC} + + ${ZPas} + eInterpolBiCub + + 5 + 2 + ${ZRegul} + + + + ${ModeAgregPrgDyn} + ${NbDirPrgDyn} + + 20.0 + + + + + false + ${ImMNT} + + + eCoeffAngle + ${ModeAgrCor} + + <#WHEN VTEST=${UseGpu}> + + 128 + + true + + + + + + + + + ${ZoomInit} + + + <#WHEN VTEST=${AddZoom64}> + + 64 + eInterpolBiLin + ${DbleZPas} + + + + + <#WHEN VTEST=${AddZoom32}> + + 32 + ${DbleZPas} + + + + <#WHEN VTEST=${AddZoom16}> + + 16 + ${DbleZPas} + + + + + + <#WHEN VTEST=${AddZoom8}> + + + + 8 + ${DbleZPas} + 10 + + + + + + <#WHEN VTEST=${AddZoom4}> + + 4 + 10 + ${ZPas} + + + + <#WHEN VTEST=${AddZoom2}> + + 2 + 4 + + + + + <#WHEN VTEST=${NotZoom8}> + + ${ZoomFinal} + + 0 + 0 + 40 + + false + false + false + false + + 2 2 + 0 + 1 + false + + + 3 3 + 1 + 0.5 + false + + + 4 4 + 2 + 0.25 + false + + + + + + + 2 + 4 + + + ePrgDAgrSomme + 8 + + 10 + + 0.3 + 4.0 + false + + + + + + ${ZoomFinal} + ${DemiZPas} + 4 + 1 + + + + + + ${ZoomFinal} + 1.0 + eAlgoDequant + ${EZA} + + + + false + .* + + + + ${FileOthoF} + ${FileUnAnam} + + + + + + + + <#WHEN VTEST=${SpecDirFaisc}> + ${DirFaisX} + ${DirFaisY} + ${DirFaisZ} + + + ${Geom} + ${Repere} + ${FileAnam} + + ${DoMEC} + + 8 + true + + ${FileDoNothing} + <#WHEN VTEST=${DoNotMEC}> + + ${ButDoOrtho} + true + true + + + + + <#WHEN VTEST=${DoIncid}> + + ${IncidMax} + 16 + <#WHEN VTEST=${DoAnam}> + + ${ParamAnam} + TheSurf + + + <#WHEN VTEST=${DoMaskNadir}> + + 1e4 + true + 1 + 0.1 + 6 + 3 + + + + + + + + + + + + + + + + ${Dir} + ${DirMEC} + ${DirMEC} + Pyram/ + + ${NbProc} + ${Chantier} + + ${Purge} + + ${SzRec} + + + + 40000 + + + + + + <#WHEN VTEST=${UsePtDebug}> + ${PtDebugX} ${PtDebugY} + + + + + + + + diff --git a/include/XML_MicMac/MM-Malt.xml b/include/XML_MicMac/MM-Malt.xml index bf3b491bfb..9b19dda99e 100644 --- a/include/XML_MicMac/MM-Malt.xml +++ b/include/XML_MicMac/MM-Malt.xml @@ -196,6 +196,12 @@ MICMAC /home/marc/micmac/include/XML_MicMac/Param-MNS-Ortho.xml WorkDir=/home/m Clas2=.* UseClas3=false Clas3=.* + UseClas4=false + Clas4=.* + UseClas5=false + Clas5=.* + UseClas6=false + Clas6=.* EZA=false SzRec=50 AlgoMaxFlow=false @@ -400,6 +406,24 @@ MICMAC /home/marc/micmac/include/XML_MicMac/Param-MNS-Ortho.xml WorkDir=/home/m Classe3 + <#WHEN VTEST=${UseClas4}> + + ${Clas4} + Classe4 + + + <#WHEN VTEST=${UseClas5}> + + ${Clas5} + Classe5 + + + <#WHEN VTEST=${UseClas6}> + + ${Clas6} + Classe6 + + .* ClasseDef diff --git a/include/XML_MicMac/MM-PostSism.xml b/include/XML_MicMac/MM-PostSism.xml index 48d5f7b2bd..4fae414a83 100644 --- a/include/XML_MicMac/MM-PostSism.xml +++ b/include/XML_MicMac/MM-PostSism.xml @@ -47,6 +47,8 @@ Px1Moy=0 Px2Moy=0 + Interpolateur=eInterpolSinCard + SurEchWCor=1 ZoomInit=1 WithZ4= SupEq ${ZoomInit} 4 @@ -162,7 +164,9 @@ L'ordre des resolutions : les plus basses aux plus grandes. true - eInterpolSinCard + ${Interpolateur} + ${SurEchWCor} + 5.0 5.0 diff --git a/include/XML_MicMac/SaisieAppuisPredic.xml b/include/XML_MicMac/SaisieAppuisPredic.xml index b3c302bb93..1deaa4c1c9 100644 --- a/include/XML_MicMac/SaisieAppuisPredic.xml +++ b/include/XML_MicMac/SaisieAppuisPredic.xml @@ -19,6 +19,10 @@ WithInputSec=false InputSec=XXXX UseMinMaxPt=false + WithDmax=false + WithPatFilt=false + DistMax=1e10 + PatFilt=.* @@ -78,6 +82,13 @@ ${PIMsFilter} + <#WHEN VTEST=${WithDmax}> + ${DistMax} + + <#WHEN VTEST=${WithPatFilt}> + ${PatFilt} + + ThisDir diff --git a/include/ext_stl/numeric.h b/include/ext_stl/numeric.h index a1b7d29cc1..4856942b31 100644 --- a/include/ext_stl/numeric.h +++ b/include/ext_stl/numeric.h @@ -449,6 +449,22 @@ template TVal KthValProp(std::vector & aV,double aProp) double MedianPond(std::vector & aV,int * aKMed=0); +template Pt3dr P3DMed(const Type & aCont,const TFctr & aFctr) +{ + std::vector mCX; + std::vector mCY; + std::vector mCZ; + + for (const auto & anObj : aCont) + { + Pt3dr aP = aFctr(anObj); + mCX.push_back(aP.x); + mCY.push_back(aP.y); + mCZ.push_back(aP.z); + } + return Pt3dr(MedianeSup(mCX),MedianeSup(mCY),MedianeSup(mCZ)); +} + #endif // _ELISE_EXT_STL_NUMERICS_H diff --git a/include/general/bitm.h b/include/general/bitm.h index 77c12e06f7..1d44cb4c52 100644 --- a/include/general/bitm.h +++ b/include/general/bitm.h @@ -1321,6 +1321,8 @@ ElRotation3D RotationOfInvariantPoint(const Pt3dr & ,const ElMatrix &); ElMatrix VecKern ( const ElMatrix & aMat); ElMatrix VecOfValP(const ElMatrix & aMat,REAL aVP); Pt3dr AxeRot(const ElMatrix & aMat); +double TetaOfAxeRot(const ElMatrix & aMat, Pt3dr & aP1); + double LongBase(const ElRotation3D &); ElRotation3D ScaleBase(const ElRotation3D &,const double & aScale); // Passer 1/LongBase pour faire base unit @@ -1328,6 +1330,7 @@ ElRotation3D ScaleBase(const ElRotation3D &,const double & aScale); // Passer 1/ double ProfFromCam(const ElRotation3D & anOr,const Pt3dr & aP); // anOr M->C +ElRotation3D AverRotation(const std::vector & aVRot,const std::vector & aVWeights); void SauvFile(const ElRotation3D &,const std::string &); void XML_SauvFile(const ElRotation3D &,const std::string &,const std::string & aNameEngl,bool aModeMatr); diff --git a/include/general/exemple_phgr_formel.h b/include/general/exemple_phgr_formel.h index dd493b334b..1671313bf5 100644 --- a/include/general/exemple_phgr_formel.h +++ b/include/general/exemple_phgr_formel.h @@ -1220,6 +1220,43 @@ template class cStructMergeTieP }; +class cP3dFormel : public cElemEqFormelle +{ + public : + cP3dFormel(const Pt3dr &,const std::string & aName,cSetEqFormelles &,cIncListInterv & aLI); + const Pt3dr & Pt() const {return mPt;} + const Pt3d & FPt() const {return mFPt;} + + private : + Pt3dr mPt; + Pt3d mFPt; +}; + +class cP2dFormel : public cElemEqFormelle +{ + public : + cP2dFormel(const Pt2dr &,const std::string & aName,cSetEqFormelles &,cIncListInterv & aLInterv); + const Pt2dr & Pt() const {return mPt;} + const Pt2d & FPt() const {return mFPt;} + + private : + Pt2dr mPt; + Pt2d mFPt; +}; + +class cValFormel : public cElemEqFormelle +{ + public : + cValFormel(const double &,const std::string & aName,cSetEqFormelles &,cIncListInterv & aLI); + const double & Val() const {return mVal;} + const Fonc_Num & FVal() const {return mFVal;} + + private : + double mVal; + Fonc_Num mFVal; +}; + + diff --git a/include/general/phgr_formel.h b/include/general/phgr_formel.h index 6c94df8ba7..dc939fbe8b 100644 --- a/include/general/phgr_formel.h +++ b/include/general/phgr_formel.h @@ -453,7 +453,8 @@ class cElemEqFormelle : public cNameSpaceEqF const cIncIntervale & IncInterv() const; cIncIntervale & IncInterv() ; tContFcteur & AllFonct(); - void AddFoncRappInit(cMultiContEQF &,INT i0,INT i1,double aTol); + // Is aVals given, its not on init value but on vals, then its size must be equal to i1-i0 + void AddFoncRappInit(cMultiContEQF &,INT i0,INT i1,double aTol,std::vector* aVals=nullptr); REAL AddRappViscosite ( const std::string & aContexte, @@ -1516,7 +1517,9 @@ class cRotationFormelle : public cElemEqFormelle, Pt3d ImVect(Pt3d,int aKForceGL=-1); Pt3d COpt(); ElRotation3D CurRot(); - void SetCurRot(const ElRotation3D & aR2CM); + // Si on veut forcer une valeur de rotation, on le fait avec MForce * DRot et une contraintye Drot =0 + // du cout cela se fait en utilisant le codage guimbal et en separant la rotation courrante de la veleur guimbal + void SetCurRot(const ElRotation3D & aCurR2CM,const ElRotation3D & aGuimbCurR2CM); ElRotation3D CurRot(REAL aT); ~cRotationFormelle(); @@ -1537,10 +1540,12 @@ class cRotationFormelle : public cElemEqFormelle, void SetTolCentre(double); Pt3dr AddRappOnCentre(const Pt3dr & aVal,const Pt3dr & aPds,bool WithDerSec); + void AddRappOnRot(const ElRotation3D & aRot,const Pt3dr & aPdsC,const Pt3dr & aPdsRot); + void ReactuFcteurRapCoU(); // cMatr_Etat_PhgrF & MatGL(bool) ; // Mode Gimbal Lock - void SetGL(bool aModeGL); + void SetGL(bool aModeGL,const ElRotation3D & aGuimb2CM); const ElMatrix & MatFGL(int ForceGL); ElMatrix MatFGLComplete(int ForceGL); const ElMatrix & MGL() const; @@ -1660,7 +1665,7 @@ class cCameraFormelle : public cGenPDVFormelle ElAffin2D & ResiduM2C(); - void SetCurRot(const ElRotation3D & aR2CM); + void SetCurRot(const ElRotation3D & aR2CM,const ElRotation3D & aGuimbC2M); friend class cParamIntrinsequeFormel; Pt3d DirRayonF(Pt2d,int aKCam); @@ -1706,7 +1711,7 @@ class cCameraFormelle : public cGenPDVFormelle Pt2dr AddEqAppuisInc(const Pt2dr & aPIm,double aPds, cParamPtProj &,bool IsEqDroite,cParamCalcVarUnkEl*); virtual void Update_0F2D(); void TestVB10(const std::string& aMes) const; - void SetGL(bool aModeGL); + void SetGL(bool aModeGL,const ElRotation3D & aGuimb2CM); // cMatr_Etat_PhgrF & MatRGL(bool isP) ; // Mode Gimbal Lock bool IsGL() const; diff --git a/include/general/photogram.h b/include/general/photogram.h index 4f54eea248..80af0bce31 100644 --- a/include/general/photogram.h +++ b/include/general/photogram.h @@ -1362,7 +1362,8 @@ class CpleEpipolaireCoord const ElPackHomologue &, INT aDegre, Pt2dr aDir1, - Pt2dr aDir2 + Pt2dr aDir2, + int aDeltaDeg=2 ); static CpleEpipolaireCoord * PolynomialFromHomologue ( @@ -1371,7 +1372,8 @@ class CpleEpipolaireCoord const ElPackHomologue & lHL2, INT aDegreL2, Pt2dr aDir1, - Pt2dr aDir2 + Pt2dr aDir2, + int aDeltaDeg=2 ); static CpleEpipolaireCoord * PolynomialFromHomologue @@ -1382,7 +1384,8 @@ class CpleEpipolaireCoord const ElPackHomologue &, INT aDegre, Pt2dr aDir1, - Pt2dr aDir2 + Pt2dr aDir2, + int aDeltaDeg=2 ); @@ -1684,7 +1687,7 @@ class ElCamera : public cCapture3D cVerifOrient MakeVerif( int aNbVerif,double aProf,const char *,const Pt3di * aNbDeterm=0) const; cOrientationConique StdExportCalibGlob(bool Matr) const; cOrientationConique StdExportCalibGlob() const; - std::string StdExport2File(cInterfChantierNameManipulateur *,const std::string & aDirOri,const std::string & aNameIm); // Test -> Ori-R + std::string StdExport2File(cInterfChantierNameManipulateur *,const std::string & aDirOri,const std::string & aNameIm,const std::string & aFileInterne = ""); // Test -> Ori-R virtual Pt3dr ImEtProf2Terrain(const Pt2dr & aP,double aZ) const = 0; virtual Pt3dr NoDistImEtProf2Terrain(const Pt2dr & aP,double aZ) const = 0; diff --git a/include/private/cElNuage3DMaille.h b/include/private/cElNuage3DMaille.h index 0215160f32..b87a7833ce 100644 --- a/include/private/cElNuage3DMaille.h +++ b/include/private/cElNuage3DMaille.h @@ -238,7 +238,7 @@ class cElNuage3DMaille : public cCapture3D Pt3dr PtOfIndex(const tIndex2D & aP) const ; Pt3dr PtOfIndexInterpol(const Pt2dr & aP) const; // [2] - Pt3dr NormaleOfIndex(const tIndex2D&, int) const; + Pt3dr NormaleOfIndex(const tIndex2D&, int, const Pt3dr&) const; virtual Pt3dr Loc_PtOfIndex(const tIndex2D & aP) const = 0; diff --git a/include/private/fonc_num.h b/include/private/fonc_num.h index 6480fd6a1b..54f0d2c38e 100644 --- a/include/private/fonc_num.h +++ b/include/private/fonc_num.h @@ -124,7 +124,7 @@ class cElCompiledFonc void SetMappingCur(const cIncListInterv &,cSetEqFormelles *); const cIncListInterv & MapRef() const; - void SetCoordCur(double * aRealCoord); + void SetCoordCur(const double * aRealCoord); void ComputeValAndSetIVC(); @@ -135,6 +135,11 @@ class cElCompiledFonc REAL Deriv(INT aD,INT aK) const; REAL DerSec(INT aD,INT aK1,INT aK2) const; const std::vector & Vals() const; + const std::vector & CompCoord() const; + const std::vector > & CompDer() const; + const std::vector & ValSsVerif() const; + const std::vector > & CompDerSsVerif() const; + void SVD_And_AddEqSysSurResol diff --git a/src/CBinaires/CMakeLists.txt b/src/CBinaires/CMakeLists.txt index 66521662af..fb040a0ed6 100644 --- a/src/CBinaires/CMakeLists.txt +++ b/src/CBinaires/CMakeLists.txt @@ -50,6 +50,10 @@ if(Boost_FOUND) target_link_libraries(mm3d ${Boost_LIBRARIES} ${Boost_THREADAPI}) endif() +if(WITH_GRAPHVIZ) + target_link_libraries(mm3d "${gvc_LIBRARIES}" -lcgraph) +endif() + install(TARGETS mm3d RUNTIME DESTINATION ${Install_Dir}) include(InstallRequiredSystemLibraries) diff --git a/src/CBinaires/mm3d.cpp b/src/CBinaires/mm3d.cpp index 673471d47c..7997ccc644 100644 --- a/src/CBinaires/mm3d.cpp +++ b/src/CBinaires/mm3d.cpp @@ -41,6 +41,8 @@ Header-MicMac-eLiSe-25/06/2007*/ #define DEF_OFSET -12349876 +int Recover_Main(int argc, char ** argv); + int XLib_Main(int argc, char ** argv); const cArgLogCom cArgLogCom::NoLog(-1); @@ -210,6 +212,7 @@ int TestDistM2C_main(int argc, char ** argv); int TestDistortion_main(int argc, char ** argv); int Blinis_main(int argc, char ** argv); +int OrientFromBlock_main(int argc, char ** argv); int Contrast_main(int argc, char ** argv); int Nikrup_main(int argc, char ** argv); int TournIm_main(int argc,char ** argv); @@ -255,6 +258,12 @@ int ConvertOriCalib_main(int argc, char ** argv); int DroneFootPrint(int argc,char ** argv); int Image_Vide(int argc,char ** argv); +int PPMD_MatEss2Orient(int argc,char ** argv); + +int GrapheStereopolis_main(int argc,char ** argv); +int CheckGCPStereopolis_main(int argc,char ** argv); +int AnalyseTrajStereopolis_main(int argc,char ** argv); + std::vector& AddLib(std::vector & aVC, const std::string & aLib) @@ -280,12 +289,20 @@ int HomolFromProfEtPx_main(int argc,char ** argv); int Line2Line_main(int argc,char ** argv); int CoronaRessample_main(int argc,char ** argv); int DivFilters_main(int argc,char ** argv); +int AnalysePxFrac_Main(int argc,char ** argv); +int CPP_YannEstimHomog(int argc,char ** argv); +int CPP_YannApplyHomog(int argc,char ** argv); +int CPP_YannInvHomolHomog(int argc,char ** argv); const std::vector & getAvailableCommands() { static std::vector aRes; if (aRes.empty()) { + aRes.push_back(cMMCom("EstimHomog",CPP_YannEstimHomog, "Homographie estimation from GCPs and image measurements ")); + aRes.push_back(cMMCom("ApplyHomog",CPP_YannApplyHomog, "Homographie application on images ")); + aRes.push_back(cMMCom("InvHomolHomog",CPP_YannInvHomolHomog, "Homographie application on images ")); + aRes.push_back(cMMCom("PPMD_MatEss2Orient", PPMD_MatEss2Orient, "transform essential matrix as list of orient ")); aRes.push_back(cMMCom("Help", CPP_MMHelp, "Help on existing MicMac commands ")); aRes.push_back(cMMCom("BAR", BasculeRobuste_main, "Bascule robutse ")); @@ -302,6 +319,7 @@ const std::vector & getAvailableCommands() aRes.push_back(cMMCom("TestPbRPC", TestCamRPC, "Test possible Problems on RPC ", cArgLogCom(2))); aRes.push_back(cMMCom("TestBundleInter", TestBundleInter_main, "Block Initialisation ")); aRes.push_back(cMMCom("Blinis", Blinis_main, "Block Initialisation ", cArgLogCom(2))); + aRes.push_back(cMMCom("OriFromBlock", OrientFromBlock_main, "Use Rigid Block to complete orientation ", cArgLogCom(2))); aRes.push_back(cMMCom("ContrastFilter", Contrast_main, "Some contrast filtering ")); aRes.push_back(cMMCom("Nikrup", Nikrup_main,/*(*/ "Generik image filter, using invert polish like notation ;-) ",cArgLogCom(3))); aRes.push_back(cMMCom("Turn90Im", TournIm_main, "Turn image of 90 degre")); @@ -369,6 +387,12 @@ const std::vector & getAvailableCommands() aRes.push_back(cMMCom("CenterBascule", CentreBascule_main, " Relative to absolute using embedded GPS", cArgLogCom(2))); aRes.push_back(cMMCom("GrapheHom", GrapheHom_main, "Compute XML-Visibility graph from approximate orientation", cArgLogCom(3))); + aRes.push_back(cMMCom("GrapheStereopolis", GrapheStereopolis_main,"Compute Pair of Image for Stereopolis", cArgLogCom(2))); + aRes.push_back(cMMCom("CheckGCPStereopolis", CheckGCPStereopolis_main,"Check GCP with strategy optimized for Stereopolis-like acquisition", cArgLogCom(2))); + + + aRes.push_back(cMMCom("AnalyseTrajStereopolis", AnalyseTrajStereopolis_main,"Analyse trajectory of Stereopolis-like acquisition", cArgLogCom(2))); + aRes.push_back(cMMCom("GCPConvert", GCP_Txt2Xml_main, "Convert GCP from Txt 2 XML", cArgLogCom(3))); aRes.push_back(cMMCom("OriConvert", Ori_Txt2Xml_main, "Convert Orientation from Txt 2 XML", cArgLogCom(3))); aRes.push_back(cMMCom("OriExport", OriExport_main, "Export orientation from XML to XML or TXT with specified convention", cArgLogCom(3))); @@ -414,6 +438,7 @@ const std::vector & getAvailableCommands() aRes.push_back(cMMCom("MMInitialModel", MMInitialModel_main, " Initial Model for MicMac ")); // ,cArgLogCom(2))); aRes.push_back(cMMCom("MMTestAllAuto", MMAllAuto_main, " Full automatic version for 1 view point, test mode ", cArgLogCom(2))); aRes.push_back(cMMCom("MM2DPosSism", MM2DPostSism_Main, " Simplified interface for post 2D post sismic deformation ", cArgLogCom(2))); + aRes.push_back(cMMCom("DistPxFrac", AnalysePxFrac_Main, "Compute distribution of fractional part of paralax ", cArgLogCom(2))); aRes.push_back(cMMCom("MMMergeCloud", MM_FusionNuage_main, " Merging of low resol cloud, in preparation 2 MicMac ", cArgLogCom(2))); aRes.push_back(cMMCom("MergeDepthMap", FusionCarteProf_main, " Merging of individual, stackable, depth maps ")); @@ -475,6 +500,7 @@ const std::vector & getAvailableCommands() aRes.push_back(cMMCom("TestChantier", TestChantier_main, " Test global acquisition")); aRes.push_back(cMMCom("TestKey", TestSet_main, " Test Keys for Sets and Assoc")); + aRes.push_back(cMMCom("Recover", Recover_Main, " Basic tool for recover files")); aRes.push_back(cMMCom("TestNameCalib", TestNameCalib_main, " Test Name of calibration")); aRes.push_back(cMMCom("TestMTD", TestMTD_main, " Test meta data of image")); aRes.push_back(cMMCom("TestCmds", TestCmds_main, " Test MM3D commands on micmac_data sets")); @@ -668,6 +694,7 @@ extern int TD_Exo6(int argc, char ** argv); extern int TD_Exo7(int argc, char ** argv); extern int TD_Exo8(int argc, char ** argv); extern int TD_Exo9(int argc, char ** argv); +extern int PPMD_Appariement_main(int argc, char ** argv); extern int TD_Match1_main(int argc, char ** argv); extern int TD_Match2_main(int argc, char ** argv); @@ -685,6 +712,7 @@ extern int CPP_NewOriReadFromSfmInit(int argc, char ** argv); extern int CPP_Bundler2MM_main(int argc, char ** argv); extern int CPP_MM2Bundler_main(int argc, char ** argv); extern int CPP_Strecha2MM(int argc, char ** argv); +extern int CPP_MM2OpenMVG_main(int argc, char ** argv); extern int ImPts2Dir_main(int argc, char ** argv); extern int FictiveObstest_main(int argc, char ** argv); extern int TestPush(int argc, char ** argv); @@ -792,6 +820,8 @@ int CPP_GenAllImP3(int argc, char ** argv); int CPP_OptimTriplet_main(int argc, char ** argv); int CPP_AllOptimTriplet_main(int argc, char ** argv); int CPP_NewSolGolInit_main(int argc, char ** argv); +int CPP_SolGlobInit_RandomDFS_main(int argc, char ** argv); +int CPP_GenOptTriplets(int argc, char ** argv); int CPP_NewOriImage2G2O_main(int argc, char ** argv); int CPP_FictiveObsFin_main(int argc, char ** argv); int CPP_XmlOriRel2OriAbs_main(int argc, char ** argv); @@ -886,6 +916,8 @@ int UnionFiltragePHom_Main(int argc, char ** argv); int TestYZ_main(int argc, char ** argv); +extern int TestLulin_main(int argc, char ** argv); + extern int ReechHomol_main(int argc, char ** argv); extern int DeformAnalyse_main(int argc, char ** argv); extern int ExtraitHomol_main(int argc, char ** argv); @@ -938,6 +970,8 @@ const std::vector & TestLibAvailableCommands() if (aRes.empty()) { + aRes.push_back(cMMCom("TestLulin", TestLulin_main, "Explaination: TestLulin ")); + aRes.push_back(cMMCom("Exo0", TD_Exo0, "Some stuff ")); aRes.push_back(cMMCom("Exo1", TD_Exo1, "Some stuff ")); aRes.push_back(cMMCom("Exo2", TD_Exo2, "Some stuff ")); @@ -948,6 +982,7 @@ const std::vector & TestLibAvailableCommands() aRes.push_back(cMMCom("Exo7", TD_Exo7, "Some stuff ")); aRes.push_back(cMMCom("Exo8", TD_Exo8, "Some stuff ")); aRes.push_back(cMMCom("Exo9", TD_Exo9, "Some stuff ")); + aRes.push_back(cMMCom("ExoMatch", PPMD_Appariement_main, "Some stuff ")); aRes.push_back(cMMCom("NoBill", UnWindows, "Supress the big shit in file resulting from (f**king) Windows editing")); @@ -987,6 +1022,7 @@ const std::vector & TestLibAvailableCommands() aRes.push_back(cMMCom("Bundler2MM", CPP_Bundler2MM_main, "Convert the Bundler solution to MicMac")); aRes.push_back(cMMCom("MM2Bundler", CPP_MM2Bundler_main, "Convert the MicMac solution to Bundler")); aRes.push_back(cMMCom("Str2MM", CPP_Strecha2MM, "Convert the Strecha solution to MicMac")); + aRes.push_back(cMMCom("MM2OMVG", CPP_MM2OpenMVG_main, "Convert Homol (PMul) to OpenMVG features / matches")); aRes.push_back(cMMCom("Im2Dir", ImPts2Dir_main, "Extract directions from images")); aRes.push_back(cMMCom("FictObs", FictiveObstest_main, "someee stuff")); aRes.push_back(cMMCom("CamTOFExp", TestCamTOF_main, "Export TOF camera pcd file to MicMac formats (e.g. tif, xml, ply)")); @@ -1141,6 +1177,8 @@ const std::vector & TestLibAvailableCommands() aRes.push_back(cMMCom("NO_OneImOptTrip",CPP_OptimTriplet_main,"New Orientation : otimize triplet")); aRes.push_back(cMMCom("NO_AllImOptTrip",CPP_AllOptimTriplet_main,"New Orientation : otimize triplet")); aRes.push_back(cMMCom("NO_SolInit3",CPP_NewSolGolInit_main,"New Orientation : sol init from triplet")); + aRes.push_back(cMMCom("NO_SolInit_RndDFS",CPP_SolGlobInit_RandomDFS_main,"New Orientation : sol init by random DFS")); + aRes.push_back(cMMCom("NO_GenPerfTripl",CPP_GenOptTriplets,"New Orientation : generate perfect triplets from InOri")); aRes.push_back(cMMCom("NO_ExportG2O",CPP_NewOriImage2G2O_main,"New Orientation : export triplets to g2o")); aRes.push_back(cMMCom("NO_GenTriOfCple",CPP_NewGenTriOfCple,"New Orientation : select triple of one edge")); @@ -1252,36 +1290,38 @@ int SampleLibElise_main(int argc, char ** argv) } //SateLib declarations -extern int RecalRPC_main(int argc, char** argv); -extern int CropRPC_main(int argc, char** argv); -extern int Grid2RPC_main(int argc, char** argv); -extern int RPC_main(int argc, char** argv); -extern int NewRefineModel_main(int argc, char** argv); -extern int RefineModel_main(int argc, char** argv); -extern int RefineJitter_main(int argc, char** argv); -extern int ApplyParralaxCor_main(int argc, char** argv); -extern int Dimap2Grid_main(int argc, char** argv); -extern int DimapUseRPC_main(int argc, char** argv); -extern int DigitalGlobe2Grid_main(int argc, char** argv); -extern int Aster2Grid_main(int argc, char** argv); -extern int AsterDestrip_main(int argc, char** argv); -extern int SATtoBundle_main(int argc, char** argv); -extern int SATvalid_main(int argc, char** argv); -extern int SATTrajectory_main(int argc, char** argv); -extern int SatEmpriseSol_main(int argc, char** argv); -extern int CalcBsurH_main(int argc, char** argv); -extern int CalcBsurHGrille_main(int argc, char** argv); -extern int CPP_SATDef2D_main(int argc, char** argv); -extern int CPP_TestRPCDirectGen(int argc, char** argv); -extern int CPP_TestRPCBackProj(int argc, char** argv); -extern int CPP_TestSystematicResiduals(int argc, char** argv); -extern int DoTile_main(int argc, char** argv); -extern int ASTERGT2MM_main(int argc, char** argv); -extern int ASTERGT_strip_2_MM_main(int argc, char** argv); -extern int ASTERProjAngle_main(int argc, char** argv); -extern int ASTERProjAngle2OtherBand_main(int argc, char** argv); - -const std::vector& SateLibAvailableCommands() +extern int RecalRPC_main(int argc, char ** argv); +extern int CropRPC_main(int argc, char ** argv); +extern int Grid2RPC_main(int argc, char ** argv); +extern int RPC_main(int argc, char ** argv); +extern int NewRefineModel_main(int argc, char **argv); +extern int RefineModel_main(int argc, char **argv); +extern int RefineJitter_main(int argc, char **argv); +extern int ApplyParralaxCor_main(int argc, char **argv); +extern int Dimap2Grid_main(int argc, char **argv); +extern int DimapUseRPC_main(int argc, char **argv); +extern int DigitalGlobe2Grid_main(int argc, char **argv); +extern int Aster2Grid_main(int argc, char **argv); +extern int AsterDestrip_main(int argc, char **argv); +extern int SATtoBundle_main(int argc, char ** argv); +extern int SATvalid_main(int argc, char ** argv); +extern int SATTrajectory_main(int argc, char ** argv); +extern int SatEmpriseSol_main(int argc, char ** argv); +extern int SatBBox_main(int argc, char ** argv); +extern int SatPosition_main(int argc, char ** argv); +extern int CalcBsurH_main(int argc, char ** argv); +extern int CalcBsurHGrille_main(int argc, char ** argv); +extern int CPP_SATDef2D_main(int argc, char ** argv); +extern int CPP_TestRPCDirectGen(int argc, char ** argv); +extern int CPP_TestRPCBackProj(int argc, char ** argv); +extern int CPP_TestSystematicResiduals(int argc, char ** argv); +extern int DoTile_main(int argc, char ** argv); +extern int ASTERGT2MM_main(int argc, char ** argv); +extern int ASTERGT_strip_2_MM_main(int argc, char ** argv); +extern int ASTERProjAngle_main(int argc, char ** argv); +extern int ASTERProjAngle2OtherBand_main(int argc, char ** argv); + +const std::vector & SateLibAvailableCommands() { static std::vector aRes; if (aRes.size()) return aRes; @@ -1305,9 +1345,11 @@ const std::vector& SateLibAvailableCommands() aRes.push_back(cMMCom("AsterDestrip", AsterDestrip_main, "Destrip Aster Images ")); aRes.push_back(cMMCom("SATtoBundle", SATtoBundle_main, "Export a satellite image to a grid of bundles")); aRes.push_back(cMMCom("SATValid", SATvalid_main, "Validate the prj function by either retrieving the line of optical centers or the provided GCPs")); - aRes.push_back(cMMCom("SatFootprint", SatEmpriseSol_main, "Satellite foortprints in ply")); - aRes.push_back(cMMCom("SatTrajectory", SATTrajectory_main, "Satellite trajectories in ply")); - aRes.push_back(cMMCom("BsurH", CalcBsurH_main, "Calculate the b/h ratio for a pattern of images")); + aRes.push_back(cMMCom("SatFootprint", SatEmpriseSol_main, "Satellite foortprints in ply")); + aRes.push_back(cMMCom("SatBBox", SatBBox_main, "Get satellite's footprint (in txt) BBox (from GRID)")); + aRes.push_back(cMMCom("SatTrajectory", SATTrajectory_main, "Satellite trajectories in ply")); + aRes.push_back(cMMCom("SatPosition", SatPosition_main, "Satellite position")); + aRes.push_back(cMMCom("BsurH", CalcBsurH_main, "Calculate the b/h ratio for a pattern of images")); aRes.push_back(cMMCom("BsurHGRI", CalcBsurHGrille_main, "Calculate the b/h ratio for a pattern of images")); aRes.push_back(cMMCom("SATD2D", CPP_SATDef2D_main, "Visualize 2D deformation fields of a pushbroom image")); aRes.push_back(cMMCom("TestRPC", CPP_TestRPCDirectGen, "Test the calculation of direct RPCs")); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2a874203ba..7aabf2ffae 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -47,6 +47,8 @@ set(UTI_ETAPOLY_DIR "EtalonnagePolygone") set(SATELIB_DIR "SateLib") set(POST_PROCESSING_DIR "PostProcessing") +set(YANN_DIR "Yann") + include(${AMD_DIR}/Sources.cmake) include(${XERES_DIR}/Sources.cmake) include(${HASSA_DIR}/Sources.cmake) @@ -74,6 +76,7 @@ include(${OPTIM_DIR}/Sources.cmake) include(${UTI_FILES_DIR}/Sources.cmake) include(${SAMPLESLIBELISE_DIR}/Sources.cmake) include(${UTI_IMAGE_DIR}/Sources.cmake) +include(${YANN_DIR}/Sources.cmake) include(${UTI_PHGRM_DIR}/Sources.cmake) include(${SATELIB_DIR}/Sources.cmake) include(${ORIPHO_DIR}/Sources.cmake) diff --git a/src/GIMMI/CMakeLists.txt b/src/GIMMI/CMakeLists.txt index d0da7a11c6..b600b2ccff 100644 --- a/src/GIMMI/CMakeLists.txt +++ b/src/GIMMI/CMakeLists.txt @@ -54,8 +54,8 @@ set(GIMM_HEADER QT5_WRAP_CPP(GIMM_HEADER_MOC ${GIMM_HEADER} ) -ADD_EXECUTABLE(GIMMI ${GIMM_SRC} ${GIMM_HEADER_MOC}) +ADD_EXECUTABLE(GIMMI_ ${GIMM_SRC} ${GIMM_HEADER_MOC}) -TARGET_LINK_LIBRARIES(GIMMI elise ${OPENGL_gl_LIBRARY} ${OPENGL_LIBRARIES} ${QT_LIBRARIES} ${X11_LIBRARIES} ${KAKADU_LIBRARIES} ANN) +TARGET_LINK_LIBRARIES(GIMMI_ elise ${OPENGL_gl_LIBRARY} ${OPENGL_LIBRARIES} ${QT_LIBRARIES} ${X11_LIBRARIES} ${KAKADU_LIBRARIES} ANN) -INSTALL(TARGETS GIMMI RUNTIME DESTINATION ${Install_Dir}) +INSTALL(TARGETS GIMMI_ RUNTIME DESTINATION ${Install_Dir}) diff --git a/src/SamplesLibElise/CPP_TestLulin.cpp b/src/SamplesLibElise/CPP_TestLulin.cpp new file mode 100644 index 0000000000..b3734a96dd --- /dev/null +++ b/src/SamplesLibElise/CPP_TestLulin.cpp @@ -0,0 +1,97 @@ +#include "../uti_image/Sift/Sift.h" +#include "../uti_image/NewRechPH/cParamNewRechPH.h" +#include "../uti_image/NewRechPH/ExternNewRechPH.h" +#include "../TpMMPD/TpPPMD.h" + + +int ExtractSiftPt(std::string aNameIm, int aSzSift) +{ + + std::string aOri; + + std::string aDir = DirOfFile(aNameIm); + std::string afileName = NameWithoutDir(aNameIm); + std::string aNameSift; + + getPastisGrayscaleFilename(aDir,afileName,aSzSift,aNameSift); + + if (aSzSift>0) + aNameSift = DirOfFile(aNameSift) +"Pastis/" + "LBPp" + NameWithoutDir(aNameSift) + ".dat"; + else + { + aNameSift = "LBPp" + afileName + ".dat"; + aNameSift = "Pastis/" + aNameSift; + } + + + std::cout << aNameSift << "\n"; + + + //read the file to know its original size + Tiff_Im aFileInit = PastisTif(aNameIm); + Pt2di imageSize = aFileInit.sz(); + + //calculate the scaling factor + double aSSF = (aSzSift<0) ? 1.0 : double( ElMax( imageSize.x, imageSize.y ) ) / double( aSzSift ) ; + + //read key-pts + std::vector aVSift; + bool Ok = read_siftPoint_list(aNameSift,aVSift); + if(Ok == false) + { + std::cout << "something went wrong" << "\n"; + return 0; + } + + std::string aNewDir = aDir + "unzip/"; + ELISE_fp::MkDir(aNewDir); + aNewDir = aDir + "unzip/" + afileName + ".sift/"; + ELISE_fp::MkDir(aNewDir); + + + //std::string aNameFile = aNameIm+".sift/keypoints.txt"; + std::string aNameFile = aDir + "unzip/" + afileName + ".sift/keypoints.txt"; + FILE * fpKeypoints = fopen(aNameFile.c_str(), "w"); + aNameFile = aDir + "unzip/" + afileName + ".sift/descriptors.txt"; + FILE * fpDescriptor = fopen(aNameFile.c_str(), "w"); + aNameFile = aDir + "unzip/" + afileName + ".sift/scores.txt"; + FILE * fpScores = fopen(aNameFile.c_str(), "w"); + aNameFile = aDir + "unzip/" + afileName + ".sift/otherInfo.txt"; + FILE * fpOther = fopen(aNameFile.c_str(), "w"); + int nSize = aVSift.size(); + for(int i=0; i* > createVTIm2DFromFile(std::string const &aName, int mFlagLoadedIms=0; std::vector > vSLLI; - for(size_t i=0;iNbCanaux();++i) + for(int i=0;iNbCanaux();++i) { TIm2D * ptr = new TIm2D(SzCrop); vPtr.push_back(ptr); diff --git a/src/TpMMPD/SimuBBA/SimuRolShut.cpp b/src/TpMMPD/SimuBBA/SimuRolShut.cpp index 7c77679a21..2572f484ed 100644 --- a/src/TpMMPD/SimuBBA/SimuRolShut.cpp +++ b/src/TpMMPD/SimuBBA/SimuRolShut.cpp @@ -842,15 +842,16 @@ int ReechRolShutV1_main(int argc, char ** argv) for(auto & aMAF : aLMAF) { std::string aNameIm = aMAF.NameIm(); - std::list & aMes = aMAF.OneMesureAF1I(); + //std::list & aMes = aMAF.OneMesureAF1I(); std::cout << aNameIm << endl; - for(auto & aOneMes : aMes) + for(auto & aOneMes : aMAF.OneMesureAF1I()) { Pt2dr aPt = aOneMes.PtIm(); std::cout << aOneMes.NamePt() << " before:" << aOneMes.PtIm(); Pt2dr aNewPt = Pt2dr(aPt.x,aPt.y*aMapReechScale[aNameIm]); - aOneMes.SetPtIm(aNewPt); + // aOneMes.SetPtIm(aNewPt); ==> MPD D'OU VIENT CETTE FONCTION ??? COMPILE PAS + aOneMes.PtIm() = aNewPt; std::cout << " after:" << aOneMes.PtIm() << endl; } } diff --git a/src/TpMMPD/Sources.cmake b/src/TpMMPD/Sources.cmake index aa38e949eb..1ea3e4dfd4 100644 --- a/src/TpMMPD/Sources.cmake +++ b/src/TpMMPD/Sources.cmake @@ -129,6 +129,7 @@ set(Src_TD_PPMD ${TDPPMD_DIR}/TiePByMesh/TiepTriFar/TiepTriFar_method.cpp ${TDPPMD_DIR}/MosaicTFWImg/mosaictfwimg.cpp + ${TDPPMD_DIR}/cTD_PPMD_Appariement.cpp ) #SOURCE_GROUP(Util FILES ${Util_Src_Files}) diff --git a/src/TpMMPD/cTD_PPMD_Appariement.cpp b/src/TpMMPD/cTD_PPMD_Appariement.cpp new file mode 100644 index 0000000000..41df4093f9 --- /dev/null +++ b/src/TpMMPD/cTD_PPMD_Appariement.cpp @@ -0,0 +1,251 @@ +#include "StdAfx.h" +#include "TpPPMD.h" + +/************************************* + * + * Creation d'une class image : cImg + * +*************************************/ +class cImg +{ + public : + cImg(int aX,int aY); + cImg(const cImg &); + + static cImg Read(const std::string& aName); + void Save(const std::string& aName); + + double Get(const Pt2di aP) {return mTIm.get(aP);} + void Set(const Pt2di aP,double aVal) {mTIm.oset(aP,aVal);} + + Pt2di Sz() {return mSz;} + + + + cImg & operator = (const cImg&); + private : + Im2D mIm; //lib MicMac + TIm2D mTIm; //lib + + Pt2di mSz; +}; + +enum eCorMode +{ + eSSD, + eCORR, + eCENSUS +}; + +eCorMode Str2Enum(std::string& aMode) +{ + eCorMode aRes; + + if (aMode=="SSD") + aRes = eSSD; + else if (aMode=="CORR") + aRes = eCORR; + else if (aMode=="CENSUS") + aRes = eCENSUS; + else + aRes = eSSD; + + return aRes; +} + +/***************************** + * + * The matching class + * + * ***************************/ + +class cMEC +{ + public : + + //class constructor + cMEC(const cImg& aI1,const cImg& aI2, + int aSzW,int aPxMax, eCorMode aMode); + + // perform matching of all pixels in mI1 + void DoAll(); + + // different functions to calculate the correlation + // between two windows + double Cost(int X,int Y,int X2); + double CostSSD(int X,int Y,int X2); + double CostCORR(int X,int Y,int X2); + double CostCENSUS(int X,int Y,int X2); + + // getter function of the parallax image + cImg Px() {return mPxIm;} + + private: + // correlation mode + eCorMode mMode; + + // the images that you want to match + cImg mI1; + cImg mI2; + + // image sizes + Pt2di mSz1; + Pt2di mSz2; + + // correlation window + int mSzW; + // the tested parallax + int mPxMax; + + // the correlation image (result) + cImg mCorIm; + // the parallax/surface image (result) + cImg mPxIm; + +}; + +cMEC::cMEC(const cImg& aI1,const cImg& aI2, + int aSzW,int aPxMax, eCorMode aMode) : + mMode(aMode), + mI1(aI1), + mI2(aI2), + mSz1(mI1.Sz()), + mSz2(mI2.Sz()), + mSzW(aSzW), + mPxMax(aPxMax), + mCorIm(mSz1.x,mSz1.y), + mPxIm(mSz1.x,mSz1.y) +{ + DoAll(); +} + +/* TO DO */ +void cMEC::DoAll() +{ + + +} + +double cMEC::Cost(int X,int Y,int X2) +{ + switch (mMode) + { + case eSSD : return CostSSD(X,Y,X2); + case eCORR : return CostCORR(X,Y,X2); + case eCENSUS : return CostCENSUS(X,Y,X2); + } + + return 0.0; +} + + +/* TO DO */ +double cMEC::CostSSD(int X,int Y,int X2) +{ + + return 1.0; + +} + +/* TO DO */ +double cMEC::CostCORR(int X,int Y,int X2) +{ + return 1.0; +} + +/* TO DO */ +double cMEC::CostCENSUS(int X,int Y,int X2) +{ + return 1.0; +} + +void cImg::Save(const std::string& aName) +{ + Tiff_Im aTif(aName.c_str(), + mSz, + GenIm::real4, + Tiff_Im::No_Compr, + Tiff_Im::BlackIsZero); + ELISE_COPY(aTif.all_pts(),mIm.in(),aTif.out()); +} + +cImg cImg::Read(const std::string& aName) +{ + Tiff_Im aTif = Tiff_Im::StdConvGen(aName,-1,true); + cImg aRes (aTif.sz().x,aTif.sz().y); + + ELISE_COPY(aTif.all_pts(),aTif.in_proj(),aRes.mIm.out()); + + return aRes; + +} + +cImg::cImg(int aX,int aY) : + mIm(aX,aY), + mTIm(mIm), + mSz(aX,aY) +{ +} + +cImg::cImg(const cImg &aIm) : + mIm(aIm.mIm), + mTIm(aIm.mTIm), + mSz(aIm.mSz) +{ +} + + +/************************************ + * + * The starting point of the program + * + * *********************************/ +int PPMD_Appariement_main(int argc,char** argv) +{ + std::cout << "TP appariement dense" << "\n"; + + std::string aIm1Name, aIm2Name; + int aSzW(2); + int aPx(50); + std::string aModeStr="SSD"; + + // program's menu when called from terminal + ElInitArgMain + ( + argc,argv, + LArgMain() << EAMC(aIm1Name,"First image name") + << EAMC(aIm2Name,"Second image name"), + LArgMain() << EAM(aSzW,"Sz",true,"Window size") + << EAM(aPx,"Px",true,"Max Dispiarity") + << EAM(aModeStr,"Mode",true,"Correlation mode (SSD, CORR, CENSUS)") + ); + eCorMode aMode = Str2Enum(aModeStr); + std::cout << aMode << "\n"; + + + // Read the images + + // Do the matching + + // Save the result to images + + + + return EXIT_SUCCESS; +} + + + + + + + + + + + + + + + + diff --git a/src/XML_GEN/ParamChantierPhotogram.cpp b/src/XML_GEN/ParamChantierPhotogram.cpp index 1238f467db..3792ac2c28 100644 --- a/src/XML_GEN/ParamChantierPhotogram.cpp +++ b/src/XML_GEN/ParamChantierPhotogram.cpp @@ -6427,6 +6427,28 @@ const cTplValGesInit< bool > & cOneAppuisDAF::UseForRTA()const return mUseForRTA; } + +cTplValGesInit< Pt3dr > & cOneAppuisDAF::Norm2Surf() +{ + return mNorm2Surf; +} + +const cTplValGesInit< Pt3dr > & cOneAppuisDAF::Norm2Surf()const +{ + return mNorm2Surf; +} + + +cTplValGesInit< double > & cOneAppuisDAF::TetaN2SHor() +{ + return mTetaN2SHor; +} + +const cTplValGesInit< double > & cOneAppuisDAF::TetaN2SHor()const +{ + return mTetaN2SHor; +} + void BinaryUnDumpFromFile(cOneAppuisDAF & anObj,ELISE_fp & aFp) { BinaryUnDumpFromFile(anObj.Pt(),aFp); @@ -6440,6 +6462,22 @@ void BinaryUnDumpFromFile(cOneAppuisDAF & anObj,ELISE_fp & aFp) } else anObj.UseForRTA().SetNoInit(); } ; + { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.Norm2Surf().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.Norm2Surf().ValForcedForUnUmp(),aFp); + } + else anObj.Norm2Surf().SetNoInit(); + } ; + { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.TetaN2SHor().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.TetaN2SHor().ValForcedForUnUmp(),aFp); + } + else anObj.TetaN2SHor().SetNoInit(); + } ; } void BinaryDumpInFile(ELISE_fp & aFp,const cOneAppuisDAF & anObj) @@ -6449,6 +6487,10 @@ void BinaryDumpInFile(ELISE_fp & aFp,const cOneAppuisDAF & anObj) BinaryDumpInFile(aFp,anObj.Incertitude()); BinaryDumpInFile(aFp,anObj.UseForRTA().IsInit()); if (anObj.UseForRTA().IsInit()) BinaryDumpInFile(aFp,anObj.UseForRTA().Val()); + BinaryDumpInFile(aFp,anObj.Norm2Surf().IsInit()); + if (anObj.Norm2Surf().IsInit()) BinaryDumpInFile(aFp,anObj.Norm2Surf().Val()); + BinaryDumpInFile(aFp,anObj.TetaN2SHor().IsInit()); + if (anObj.TetaN2SHor().IsInit()) BinaryDumpInFile(aFp,anObj.TetaN2SHor().Val()); } cElXMLTree * ToXMLTree(const cOneAppuisDAF & anObj) @@ -6460,6 +6502,10 @@ cElXMLTree * ToXMLTree(const cOneAppuisDAF & anObj) aRes->AddFils(ToXMLTree(std::string("Incertitude"),anObj.Incertitude())->ReTagThis("Incertitude")); if (anObj.UseForRTA().IsInit()) aRes->AddFils(::ToXMLTree(std::string("UseForRTA"),anObj.UseForRTA().Val())->ReTagThis("UseForRTA")); + if (anObj.Norm2Surf().IsInit()) + aRes->AddFils(ToXMLTree(std::string("Norm2Surf"),anObj.Norm2Surf().Val())->ReTagThis("Norm2Surf")); + if (anObj.TetaN2SHor().IsInit()) + aRes->AddFils(::ToXMLTree(std::string("TetaN2SHor"),anObj.TetaN2SHor().Val())->ReTagThis("TetaN2SHor")); aRes->mGXml = anObj.mGXml; XMLPopContext(anObj.mGXml); return aRes; @@ -6477,9 +6523,13 @@ void xml_init(cOneAppuisDAF & anObj,cElXMLTree * aTree) xml_init(anObj.Incertitude(),aTree->Get("Incertitude",1)); //tototo xml_init(anObj.UseForRTA(),aTree->Get("UseForRTA",1),bool(true)); //tototo + + xml_init(anObj.Norm2Surf(),aTree->Get("Norm2Surf",1)); //tototo + + xml_init(anObj.TetaN2SHor(),aTree->Get("TetaN2SHor",1)); //tototo } -std::string Mangling( cOneAppuisDAF *) {return "B6347A05E335B2BFFD3F";}; +std::string Mangling( cOneAppuisDAF *) {return "2FF4CBF525D2929EFF3F";}; std::list< cOneAppuisDAF > & cDicoAppuisFlottant::OneAppuisDAF() @@ -6538,7 +6588,7 @@ void xml_init(cDicoAppuisFlottant & anObj,cElXMLTree * aTree) xml_init(anObj.OneAppuisDAF(),aTree->GetAll("OneAppuisDAF",false,1)); } -std::string Mangling( cDicoAppuisFlottant *) {return "19E38C257C947DA2FE3F";}; +std::string Mangling( cDicoAppuisFlottant *) {return "96C4234B620110DFFD3F";}; std::string & cCpleImgTime::NameIm() @@ -6994,11 +7044,6 @@ const Pt2dr & cOneMesureAF1I::PtIm()const return mPtIm; } -void cOneMesureAF1I::SetPtIm(Pt2dr & aPt) -{ - mPtIm = aPt; -} - void BinaryUnDumpFromFile(cOneMesureAF1I & anObj,ELISE_fp & aFp) { { bool IsInit; @@ -20465,6 +20510,17 @@ const std::string & cStructBlockCam::KeyIm2TimeCam()const } +cTplValGesInit< std::string > & cStructBlockCam::MasterGrp() +{ + return mMasterGrp; +} + +const cTplValGesInit< std::string > & cStructBlockCam::MasterGrp()const +{ + return mMasterGrp; +} + + std::list< cParamOrientSHC > & cStructBlockCam::ParamOrientSHC() { return LiaisonsSHC().Val().ParamOrientSHC(); @@ -20489,6 +20545,14 @@ const cTplValGesInit< cLiaisonsSHC > & cStructBlockCam::LiaisonsSHC()const void BinaryUnDumpFromFile(cStructBlockCam & anObj,ELISE_fp & aFp) { BinaryUnDumpFromFile(anObj.KeyIm2TimeCam(),aFp); + { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.MasterGrp().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.MasterGrp().ValForcedForUnUmp(),aFp); + } + else anObj.MasterGrp().SetNoInit(); + } ; { bool IsInit; BinaryUnDumpFromFile(IsInit,aFp); if (IsInit) { @@ -20502,6 +20566,8 @@ void BinaryUnDumpFromFile(cStructBlockCam & anObj,ELISE_fp & aFp) void BinaryDumpInFile(ELISE_fp & aFp,const cStructBlockCam & anObj) { BinaryDumpInFile(aFp,anObj.KeyIm2TimeCam()); + BinaryDumpInFile(aFp,anObj.MasterGrp().IsInit()); + if (anObj.MasterGrp().IsInit()) BinaryDumpInFile(aFp,anObj.MasterGrp().Val()); BinaryDumpInFile(aFp,anObj.LiaisonsSHC().IsInit()); if (anObj.LiaisonsSHC().IsInit()) BinaryDumpInFile(aFp,anObj.LiaisonsSHC().Val()); } @@ -20511,6 +20577,8 @@ cElXMLTree * ToXMLTree(const cStructBlockCam & anObj) XMLPushContext(anObj.mGXml); cElXMLTree * aRes = new cElXMLTree((cElXMLTree *)0,"StructBlockCam",eXMLBranche); aRes->AddFils(::ToXMLTree(std::string("KeyIm2TimeCam"),anObj.KeyIm2TimeCam())->ReTagThis("KeyIm2TimeCam")); + if (anObj.MasterGrp().IsInit()) + aRes->AddFils(::ToXMLTree(std::string("MasterGrp"),anObj.MasterGrp().Val())->ReTagThis("MasterGrp")); if (anObj.LiaisonsSHC().IsInit()) aRes->AddFils(ToXMLTree(anObj.LiaisonsSHC().Val())->ReTagThis("LiaisonsSHC")); aRes->mGXml = anObj.mGXml; @@ -20525,10 +20593,12 @@ void xml_init(cStructBlockCam & anObj,cElXMLTree * aTree) xml_init(anObj.KeyIm2TimeCam(),aTree->Get("KeyIm2TimeCam",1)); //tototo + xml_init(anObj.MasterGrp(),aTree->Get("MasterGrp",1)); //tototo + xml_init(anObj.LiaisonsSHC(),aTree->Get("LiaisonsSHC",1)); //tototo } -std::string Mangling( cStructBlockCam *) {return "B06598583EB111DCFE3F";}; +std::string Mangling( cStructBlockCam *) {return "9231968F03FA00A5FF3F";}; std::list< std::string > & cXmlExivEntry::Names() @@ -24419,4 +24489,683 @@ void xml_init(cXml_SpecifAllMMCmd & anObj,cElXMLTree * aTree) std::string Mangling( cXml_SpecifAllMMCmd *) {return "20390C65F56AF2DEFB3F";}; + +cTplValGesInit< int > & cGS_OneLinear::Period() +{ + return mPeriod; +} + +const cTplValGesInit< int > & cGS_OneLinear::Period()const +{ + return mPeriod; +} + + +int & cGS_OneLinear::DeltaMin() +{ + return mDeltaMin; +} + +const int & cGS_OneLinear::DeltaMin()const +{ + return mDeltaMin; +} + + +int & cGS_OneLinear::DeltaMax() +{ + return mDeltaMax; +} + +const int & cGS_OneLinear::DeltaMax()const +{ + return mDeltaMax; +} + + +std::list< cCpleString > & cGS_OneLinear::CpleGrp() +{ + return mCpleGrp; +} + +const std::list< cCpleString > & cGS_OneLinear::CpleGrp()const +{ + return mCpleGrp; +} + +void BinaryUnDumpFromFile(cGS_OneLinear & anObj,ELISE_fp & aFp) +{ + { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.Period().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.Period().ValForcedForUnUmp(),aFp); + } + else anObj.Period().SetNoInit(); + } ; + BinaryUnDumpFromFile(anObj.DeltaMin(),aFp); + BinaryUnDumpFromFile(anObj.DeltaMax(),aFp); + { int aNb; + BinaryUnDumpFromFile(aNb,aFp); + for( int aK=0 ; aK::const_iterator iT=anObj.CpleGrp().begin(); + iT!=anObj.CpleGrp().end(); + iT++ + ) + BinaryDumpInFile(aFp,*iT); +} + +cElXMLTree * ToXMLTree(const cGS_OneLinear & anObj) +{ + XMLPushContext(anObj.mGXml); + cElXMLTree * aRes = new cElXMLTree((cElXMLTree *)0,"GS_OneLinear",eXMLBranche); + if (anObj.Period().IsInit()) + aRes->AddFils(::ToXMLTree(std::string("Period"),anObj.Period().Val())->ReTagThis("Period")); + aRes->AddFils(::ToXMLTree(std::string("DeltaMin"),anObj.DeltaMin())->ReTagThis("DeltaMin")); + aRes->AddFils(::ToXMLTree(std::string("DeltaMax"),anObj.DeltaMax())->ReTagThis("DeltaMax")); + for + ( std::list< cCpleString >::const_iterator it=anObj.CpleGrp().begin(); + it !=anObj.CpleGrp().end(); + it++ + ) + aRes->AddFils(::ToXMLTree(std::string("CpleGrp"),(*it))->ReTagThis("CpleGrp")); + aRes->mGXml = anObj.mGXml; + XMLPopContext(anObj.mGXml); + return aRes; +} + +void xml_init(cGS_OneLinear & anObj,cElXMLTree * aTree) +{ + if (aTree==0) return; + anObj.mGXml = aTree->mGXml; + + xml_init(anObj.Period(),aTree->Get("Period",1),int(1)); //tototo + + xml_init(anObj.DeltaMin(),aTree->Get("DeltaMin",1)); //tototo + + xml_init(anObj.DeltaMax(),aTree->Get("DeltaMax",1)); //tototo + + xml_init(anObj.CpleGrp(),aTree->GetAll("CpleGrp",false,1)); +} + +std::string Mangling( cGS_OneLinear *) {return "58A1E21FDC4D6BC8FDBF";}; + + +std::list< cGS_OneLinear > & cGS_SectionLinear::GS_OneLinear() +{ + return mGS_OneLinear; +} + +const std::list< cGS_OneLinear > & cGS_SectionLinear::GS_OneLinear()const +{ + return mGS_OneLinear; +} + +void BinaryUnDumpFromFile(cGS_SectionLinear & anObj,ELISE_fp & aFp) +{ + { int aNb; + BinaryUnDumpFromFile(aNb,aFp); + for( int aK=0 ; aK::const_iterator iT=anObj.GS_OneLinear().begin(); + iT!=anObj.GS_OneLinear().end(); + iT++ + ) + BinaryDumpInFile(aFp,*iT); +} + +cElXMLTree * ToXMLTree(const cGS_SectionLinear & anObj) +{ + XMLPushContext(anObj.mGXml); + cElXMLTree * aRes = new cElXMLTree((cElXMLTree *)0,"GS_SectionLinear",eXMLBranche); + for + ( std::list< cGS_OneLinear >::const_iterator it=anObj.GS_OneLinear().begin(); + it !=anObj.GS_OneLinear().end(); + it++ + ) + aRes->AddFils(ToXMLTree((*it))->ReTagThis("GS_OneLinear")); + aRes->mGXml = anObj.mGXml; + XMLPopContext(anObj.mGXml); + return aRes; +} + +void xml_init(cGS_SectionLinear & anObj,cElXMLTree * aTree) +{ + if (aTree==0) return; + anObj.mGXml = aTree->mGXml; + + xml_init(anObj.GS_OneLinear(),aTree->GetAll("GS_OneLinear",false,1)); +} + +std::string Mangling( cGS_SectionLinear *) {return "5AD3092E3A64FEC0FE3F";}; + + +double & cGS_SectionCross::DistMax() +{ + return mDistMax; +} + +const double & cGS_SectionCross::DistMax()const +{ + return mDistMax; +} + + +double & cGS_SectionCross::DistCurvMin() +{ + return mDistCurvMin; +} + +const double & cGS_SectionCross::DistCurvMin()const +{ + return mDistCurvMin; +} + + +double & cGS_SectionCross::AngleMinSpeed() +{ + return mAngleMinSpeed; +} + +const double & cGS_SectionCross::AngleMinSpeed()const +{ + return mAngleMinSpeed; +} + + +double & cGS_SectionCross::DistMinTraj() +{ + return mDistMinTraj; +} + +const double & cGS_SectionCross::DistMinTraj()const +{ + return mDistMinTraj; +} + + +std::list< std::string > & cGS_SectionCross::ListCam() +{ + return mListCam; +} + +const std::list< std::string > & cGS_SectionCross::ListCam()const +{ + return mListCam; +} + +void BinaryUnDumpFromFile(cGS_SectionCross & anObj,ELISE_fp & aFp) +{ + BinaryUnDumpFromFile(anObj.DistMax(),aFp); + BinaryUnDumpFromFile(anObj.DistCurvMin(),aFp); + BinaryUnDumpFromFile(anObj.AngleMinSpeed(),aFp); + BinaryUnDumpFromFile(anObj.DistMinTraj(),aFp); + { int aNb; + BinaryUnDumpFromFile(aNb,aFp); + for( int aK=0 ; aK::const_iterator iT=anObj.ListCam().begin(); + iT!=anObj.ListCam().end(); + iT++ + ) + BinaryDumpInFile(aFp,*iT); +} + +cElXMLTree * ToXMLTree(const cGS_SectionCross & anObj) +{ + XMLPushContext(anObj.mGXml); + cElXMLTree * aRes = new cElXMLTree((cElXMLTree *)0,"GS_SectionCross",eXMLBranche); + aRes->AddFils(::ToXMLTree(std::string("DistMax"),anObj.DistMax())->ReTagThis("DistMax")); + aRes->AddFils(::ToXMLTree(std::string("DistCurvMin"),anObj.DistCurvMin())->ReTagThis("DistCurvMin")); + aRes->AddFils(::ToXMLTree(std::string("AngleMinSpeed"),anObj.AngleMinSpeed())->ReTagThis("AngleMinSpeed")); + aRes->AddFils(::ToXMLTree(std::string("DistMinTraj"),anObj.DistMinTraj())->ReTagThis("DistMinTraj")); + for + ( std::list< std::string >::const_iterator it=anObj.ListCam().begin(); + it !=anObj.ListCam().end(); + it++ + ) + aRes->AddFils(::ToXMLTree(std::string("ListCam"),(*it))->ReTagThis("ListCam")); + aRes->mGXml = anObj.mGXml; + XMLPopContext(anObj.mGXml); + return aRes; +} + +void xml_init(cGS_SectionCross & anObj,cElXMLTree * aTree) +{ + if (aTree==0) return; + anObj.mGXml = aTree->mGXml; + + xml_init(anObj.DistMax(),aTree->Get("DistMax",1)); //tototo + + xml_init(anObj.DistCurvMin(),aTree->Get("DistCurvMin",1)); //tototo + + xml_init(anObj.AngleMinSpeed(),aTree->Get("AngleMinSpeed",1)); //tototo + + xml_init(anObj.DistMinTraj(),aTree->Get("DistMinTraj",1)); //tototo + + xml_init(anObj.ListCam(),aTree->GetAll("ListCam",false,1)); +} + +std::string Mangling( cGS_SectionCross *) {return "1722A5927232D4EEFC3F";}; + + +double & cOneInterv_OT::DistMax() +{ + return mDistMax; +} + +const double & cOneInterv_OT::DistMax()const +{ + return mDistMax; +} + + +std::list< cCpleString > & cOneInterv_OT::CpleGrp() +{ + return mCpleGrp; +} + +const std::list< cCpleString > & cOneInterv_OT::CpleGrp()const +{ + return mCpleGrp; +} + +void BinaryUnDumpFromFile(cOneInterv_OT & anObj,ELISE_fp & aFp) +{ + BinaryUnDumpFromFile(anObj.DistMax(),aFp); + { int aNb; + BinaryUnDumpFromFile(aNb,aFp); + for( int aK=0 ; aK::const_iterator iT=anObj.CpleGrp().begin(); + iT!=anObj.CpleGrp().end(); + iT++ + ) + BinaryDumpInFile(aFp,*iT); +} + +cElXMLTree * ToXMLTree(const cOneInterv_OT & anObj) +{ + XMLPushContext(anObj.mGXml); + cElXMLTree * aRes = new cElXMLTree((cElXMLTree *)0,"OneInterv_OT",eXMLBranche); + aRes->AddFils(::ToXMLTree(std::string("DistMax"),anObj.DistMax())->ReTagThis("DistMax")); + for + ( std::list< cCpleString >::const_iterator it=anObj.CpleGrp().begin(); + it !=anObj.CpleGrp().end(); + it++ + ) + aRes->AddFils(::ToXMLTree(std::string("CpleGrp"),(*it))->ReTagThis("CpleGrp")); + aRes->mGXml = anObj.mGXml; + XMLPopContext(anObj.mGXml); + return aRes; +} + +void xml_init(cOneInterv_OT & anObj,cElXMLTree * aTree) +{ + if (aTree==0) return; + anObj.mGXml = aTree->mGXml; + + xml_init(anObj.DistMax(),aTree->Get("DistMax",1)); //tototo + + xml_init(anObj.CpleGrp(),aTree->GetAll("CpleGrp",false,1)); +} + +std::string Mangling( cOneInterv_OT *) {return "58C0CB36EE31F8ABFA3F";}; + + +double & cGS_SectionOverlapingTraj::AngleMaxSpeed() +{ + return mAngleMaxSpeed; +} + +const double & cGS_SectionOverlapingTraj::AngleMaxSpeed()const +{ + return mAngleMaxSpeed; +} + + +double & cGS_SectionOverlapingTraj::DistMaxTraj() +{ + return mDistMaxTraj; +} + +const double & cGS_SectionOverlapingTraj::DistMaxTraj()const +{ + return mDistMaxTraj; +} + + +std::list< cOneInterv_OT > & cGS_SectionOverlapingTraj::OneInterv_OT() +{ + return mOneInterv_OT; +} + +const std::list< cOneInterv_OT > & cGS_SectionOverlapingTraj::OneInterv_OT()const +{ + return mOneInterv_OT; +} + +void BinaryUnDumpFromFile(cGS_SectionOverlapingTraj & anObj,ELISE_fp & aFp) +{ + BinaryUnDumpFromFile(anObj.AngleMaxSpeed(),aFp); + BinaryUnDumpFromFile(anObj.DistMaxTraj(),aFp); + { int aNb; + BinaryUnDumpFromFile(aNb,aFp); + for( int aK=0 ; aK::const_iterator iT=anObj.OneInterv_OT().begin(); + iT!=anObj.OneInterv_OT().end(); + iT++ + ) + BinaryDumpInFile(aFp,*iT); +} + +cElXMLTree * ToXMLTree(const cGS_SectionOverlapingTraj & anObj) +{ + XMLPushContext(anObj.mGXml); + cElXMLTree * aRes = new cElXMLTree((cElXMLTree *)0,"GS_SectionOverlapingTraj",eXMLBranche); + aRes->AddFils(::ToXMLTree(std::string("AngleMaxSpeed"),anObj.AngleMaxSpeed())->ReTagThis("AngleMaxSpeed")); + aRes->AddFils(::ToXMLTree(std::string("DistMaxTraj"),anObj.DistMaxTraj())->ReTagThis("DistMaxTraj")); + for + ( std::list< cOneInterv_OT >::const_iterator it=anObj.OneInterv_OT().begin(); + it !=anObj.OneInterv_OT().end(); + it++ + ) + aRes->AddFils(ToXMLTree((*it))->ReTagThis("OneInterv_OT")); + aRes->mGXml = anObj.mGXml; + XMLPopContext(anObj.mGXml); + return aRes; +} + +void xml_init(cGS_SectionOverlapingTraj & anObj,cElXMLTree * aTree) +{ + if (aTree==0) return; + anObj.mGXml = aTree->mGXml; + + xml_init(anObj.AngleMaxSpeed(),aTree->Get("AngleMaxSpeed",1)); //tototo + + xml_init(anObj.DistMaxTraj(),aTree->Get("DistMaxTraj",1)); //tototo + + xml_init(anObj.OneInterv_OT(),aTree->GetAll("OneInterv_OT",false,1)); +} + +std::string Mangling( cGS_SectionOverlapingTraj *) {return "DB47F3DDFF7A7AEDFD3F";}; + + +std::string & cXml_ParamGraphStereopolis::NameGrpC() +{ + return mNameGrpC; +} + +const std::string & cXml_ParamGraphStereopolis::NameGrpC()const +{ + return mNameGrpC; +} + + +std::list< cGS_OneLinear > & cXml_ParamGraphStereopolis::GS_OneLinear() +{ + return GS_SectionLinear().Val().GS_OneLinear(); +} + +const std::list< cGS_OneLinear > & cXml_ParamGraphStereopolis::GS_OneLinear()const +{ + return GS_SectionLinear().Val().GS_OneLinear(); +} + + +cTplValGesInit< cGS_SectionLinear > & cXml_ParamGraphStereopolis::GS_SectionLinear() +{ + return mGS_SectionLinear; +} + +const cTplValGesInit< cGS_SectionLinear > & cXml_ParamGraphStereopolis::GS_SectionLinear()const +{ + return mGS_SectionLinear; +} + + +double & cXml_ParamGraphStereopolis::DistMax() +{ + return GS_SectionCross().Val().DistMax(); +} + +const double & cXml_ParamGraphStereopolis::DistMax()const +{ + return GS_SectionCross().Val().DistMax(); +} + + +double & cXml_ParamGraphStereopolis::DistCurvMin() +{ + return GS_SectionCross().Val().DistCurvMin(); +} + +const double & cXml_ParamGraphStereopolis::DistCurvMin()const +{ + return GS_SectionCross().Val().DistCurvMin(); +} + + +double & cXml_ParamGraphStereopolis::AngleMinSpeed() +{ + return GS_SectionCross().Val().AngleMinSpeed(); +} + +const double & cXml_ParamGraphStereopolis::AngleMinSpeed()const +{ + return GS_SectionCross().Val().AngleMinSpeed(); +} + + +double & cXml_ParamGraphStereopolis::DistMinTraj() +{ + return GS_SectionCross().Val().DistMinTraj(); +} + +const double & cXml_ParamGraphStereopolis::DistMinTraj()const +{ + return GS_SectionCross().Val().DistMinTraj(); +} + + +std::list< std::string > & cXml_ParamGraphStereopolis::ListCam() +{ + return GS_SectionCross().Val().ListCam(); +} + +const std::list< std::string > & cXml_ParamGraphStereopolis::ListCam()const +{ + return GS_SectionCross().Val().ListCam(); +} + + +cTplValGesInit< cGS_SectionCross > & cXml_ParamGraphStereopolis::GS_SectionCross() +{ + return mGS_SectionCross; +} + +const cTplValGesInit< cGS_SectionCross > & cXml_ParamGraphStereopolis::GS_SectionCross()const +{ + return mGS_SectionCross; +} + + +double & cXml_ParamGraphStereopolis::AngleMaxSpeed() +{ + return GS_SectionOverlapingTraj().Val().AngleMaxSpeed(); +} + +const double & cXml_ParamGraphStereopolis::AngleMaxSpeed()const +{ + return GS_SectionOverlapingTraj().Val().AngleMaxSpeed(); +} + + +double & cXml_ParamGraphStereopolis::DistMaxTraj() +{ + return GS_SectionOverlapingTraj().Val().DistMaxTraj(); +} + +const double & cXml_ParamGraphStereopolis::DistMaxTraj()const +{ + return GS_SectionOverlapingTraj().Val().DistMaxTraj(); +} + + +std::list< cOneInterv_OT > & cXml_ParamGraphStereopolis::OneInterv_OT() +{ + return GS_SectionOverlapingTraj().Val().OneInterv_OT(); +} + +const std::list< cOneInterv_OT > & cXml_ParamGraphStereopolis::OneInterv_OT()const +{ + return GS_SectionOverlapingTraj().Val().OneInterv_OT(); +} + + +cTplValGesInit< cGS_SectionOverlapingTraj > & cXml_ParamGraphStereopolis::GS_SectionOverlapingTraj() +{ + return mGS_SectionOverlapingTraj; +} + +const cTplValGesInit< cGS_SectionOverlapingTraj > & cXml_ParamGraphStereopolis::GS_SectionOverlapingTraj()const +{ + return mGS_SectionOverlapingTraj; +} + +void BinaryUnDumpFromFile(cXml_ParamGraphStereopolis & anObj,ELISE_fp & aFp) +{ + BinaryUnDumpFromFile(anObj.NameGrpC(),aFp); + { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.GS_SectionLinear().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.GS_SectionLinear().ValForcedForUnUmp(),aFp); + } + else anObj.GS_SectionLinear().SetNoInit(); + } ; + { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.GS_SectionCross().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.GS_SectionCross().ValForcedForUnUmp(),aFp); + } + else anObj.GS_SectionCross().SetNoInit(); + } ; + { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.GS_SectionOverlapingTraj().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.GS_SectionOverlapingTraj().ValForcedForUnUmp(),aFp); + } + else anObj.GS_SectionOverlapingTraj().SetNoInit(); + } ; +} + +void BinaryDumpInFile(ELISE_fp & aFp,const cXml_ParamGraphStereopolis & anObj) +{ + BinaryDumpInFile(aFp,anObj.NameGrpC()); + BinaryDumpInFile(aFp,anObj.GS_SectionLinear().IsInit()); + if (anObj.GS_SectionLinear().IsInit()) BinaryDumpInFile(aFp,anObj.GS_SectionLinear().Val()); + BinaryDumpInFile(aFp,anObj.GS_SectionCross().IsInit()); + if (anObj.GS_SectionCross().IsInit()) BinaryDumpInFile(aFp,anObj.GS_SectionCross().Val()); + BinaryDumpInFile(aFp,anObj.GS_SectionOverlapingTraj().IsInit()); + if (anObj.GS_SectionOverlapingTraj().IsInit()) BinaryDumpInFile(aFp,anObj.GS_SectionOverlapingTraj().Val()); +} + +cElXMLTree * ToXMLTree(const cXml_ParamGraphStereopolis & anObj) +{ + XMLPushContext(anObj.mGXml); + cElXMLTree * aRes = new cElXMLTree((cElXMLTree *)0,"Xml_ParamGraphStereopolis",eXMLBranche); + aRes->AddFils(::ToXMLTree(std::string("NameGrpC"),anObj.NameGrpC())->ReTagThis("NameGrpC")); + if (anObj.GS_SectionLinear().IsInit()) + aRes->AddFils(ToXMLTree(anObj.GS_SectionLinear().Val())->ReTagThis("GS_SectionLinear")); + if (anObj.GS_SectionCross().IsInit()) + aRes->AddFils(ToXMLTree(anObj.GS_SectionCross().Val())->ReTagThis("GS_SectionCross")); + if (anObj.GS_SectionOverlapingTraj().IsInit()) + aRes->AddFils(ToXMLTree(anObj.GS_SectionOverlapingTraj().Val())->ReTagThis("GS_SectionOverlapingTraj")); + aRes->mGXml = anObj.mGXml; + XMLPopContext(anObj.mGXml); + return aRes; +} + +void xml_init(cXml_ParamGraphStereopolis & anObj,cElXMLTree * aTree) +{ + if (aTree==0) return; + anObj.mGXml = aTree->mGXml; + + xml_init(anObj.NameGrpC(),aTree->Get("NameGrpC",1)); //tototo + + xml_init(anObj.GS_SectionLinear(),aTree->Get("GS_SectionLinear",1)); //tototo + + xml_init(anObj.GS_SectionCross(),aTree->Get("GS_SectionCross",1)); //tototo + + xml_init(anObj.GS_SectionOverlapingTraj(),aTree->Get("GS_SectionOverlapingTraj",1)); //tototo +} + +std::string Mangling( cXml_ParamGraphStereopolis *) {return "C81DA2EEDFC08691FB3F";}; + // }; diff --git a/src/Yann/EstimHomogr.cpp b/src/Yann/EstimHomogr.cpp new file mode 100644 index 0000000000..f7f2ec69a8 --- /dev/null +++ b/src/Yann/EstimHomogr.cpp @@ -0,0 +1,1011 @@ + + + +/*Header-MicMac-eLiSe-25/06/2007 + + MicMac : Multi Image Correspondances par Methodes Automatiques de Correlation + eLiSe : ELements of an Image Software Environnement + + www.micmac.ign.fr + + + Copyright : Institut Geographique National + Author : Marc Pierrot Deseilligny + Contributors : Gregoire Maillet, Didier Boldo. + +[1] M. Pierrot-Deseilligny, N. Paparoditis. + "A multiresolution and optimization-based image matching approach: + An application to surface reconstruction from SPOT5-HRS stereo imagery." + In IAPRS vol XXXVI-1/W41 in ISPRS Workshop On Topographic Mapping From Space + (With Special Emphasis on Small Satellites), Ankara, Turquie, 02-2006. + +[2] M. Pierrot-Deseilligny, "MicMac, un lociel de mise en correspondance + d'images, adapte au contexte geograhique" to appears in + Bulletin d'information de l'Institut Geographique National, 2007. + +Francais : + + MicMac est un logiciel de mise en correspondance d'image adapte + au contexte de recherche en information geographique. Il s'appuie sur + la bibliotheque de manipulation d'image eLiSe. Il est distibue sous la + licences Cecill-B. Voir en bas de fichier et http://www.cecill.info. + + +English : + + MicMac is an open source software specialized in image matching + for research in geographic information. MicMac is built on the + eLiSe image library. MicMac is governed by the "Cecill-B licence". + See below and http://www.cecill.info. + +Header-MicMac-eLiSe-25/06/2007*/ + + +#include "StdAfx.h" +#include "hassan/reechantillonnage.h" + +// -------------------------------------------------------------------------------------- +// Classes permettant d'estimer, d'appliquer et d'inverser les points de liaison d'un +// homographie (calculée à partir d'un jeu de points terrain <-> image). +// -------------------------------------------------------------------------------------- +class cAppli_YannEstimHomog{ + + public : + cAppli_YannEstimHomog(int argc, char ** argv); + + std::string mName3D; // Fichier des mesures 3D + std::string mName2D; // fichier des mesures 2D + std::string mNameImRef; // Image référence (optionnelle) + std::string mDirOri; // Direction d'orientation + std::string mResolution; // Resolution images de sortie + std::string mMargeRel; // Marge relative des bords + std::string aNameCam; // Chemin calibration interne + bool mCamRot; // Camera frame rotation + cElemAppliSetFile mEASF; // Pour gerer un ensemble d'images + cInterfChantierNameManipulateur * mICNM; // Name manipulateur + std::string mDir; // Directory of data + cDicoAppuisFlottant mDAF3D; // All 3D + cSetOfMesureAppuisFlottants mDAF2D; // All 2D +}; +// -------------------------------------------------------------------------------------- +class cAppli_YannApplyHomog{ + + public : + cAppli_YannApplyHomog(int argc, char ** argv); + + std::string mNameIm; // Images à convertir + std::string mNameHomog; // Fichier d'homographie + std::string mDir; // Répertoire d'images + std::string mDirOut; // Répertoire de sortie + cElemAppliSetFile mEASF; // Pour gerer un ensemble d'images + cInterfChantierNameManipulateur * mICNM; // Name manipulateur +}; +// -------------------------------------------------------------------------------------- +class cAppli_YannInvHomolHomog{ + + public : + cAppli_YannInvHomolHomog(int argc, char ** argv); + + std::string ImPattern; // Images redressées + std::string ImPatternInit; // Images initiales + std::string mFolderIn; // Dossier input + std::string mFolderOut; // Dossier output + std::string mHomogFile; // Fichier d'homographie + std::string mExt; // Extension d'image cible + std::string exportTxtIn; // Entrée en binaire ou txt + std::string exportTxtOut; // Sortie en binaire ou txt + std::string mDir; // Directory of data + std::string mDirOri; // Répertoire d'orientation + std::string mRawFolder; // Dossier des images bruts + cElemAppliSetFile mEASF; // Pour gerer un ensemble d'images + cInterfChantierNameManipulateur * mICNM; // Name manipulateur + +}; + + +// -------------------------------------------------------------------------------------- +// Fonction de lecture du fichier d'homographie +// -------------------------------------------------------------------------------------- +// Inputs : +// - nom du fichier à lire +// - matrice des paramètres d'homographie +// - emprise xmin, ymin, xmax, ymax +// - nombre de pixels en x de l'image +// -------------------------------------------------------------------------------------- +void readHomogFile(std::string mHomogFile, ElMatrix &H, double &xmin, double &ymin, double &xmax, + double &ymax, int &Nx_org, int &Ny_org, int &Nx, int &Ny, std::string &dirOri){ + + std::string line; + std::ifstream infile(mHomogFile); + + // Test existence du fichier + std::string message = "ERROR: can't find homography file [" + std::string(mHomogFile) + "]"; + ELISE_ASSERT(infile.good(), message.c_str()); + + std::getline(infile, line); + + for (int i=0; i<3; i++){ + + std::getline(infile, line); + + for (int j=0; j<3; j++){ + std::getline(infile, line); + line = line.substr(10,30); + line = line.substr(0, line.size()-5); + H(0,3*i+j) = std::stof(line); + } + + std::getline(infile, line); + } + + std::getline(infile, line); + std::getline(infile, line); + + std::getline(infile, line); + line = line.substr(6,line.size()-10); + xmin = std::stof(line); + + std::getline(infile, line); + line = line.substr(6,line.size()-10); + ymin = std::stof(line); + + std::getline(infile, line); + std::getline(infile, line); + + std::getline(infile, line); + line = line.substr(6,line.size()-10); + xmax = std::stof(line); + + std::getline(infile, line); + line = line.substr(6,line.size()-10); + ymax = std::stof(line); + + std::getline(infile, line); + std::getline(infile, line); + + std::getline(infile, line); + Nx_org = std::stof(line.substr(6,line.size()-10)); + std::getline(infile, line); + Ny_org = std::stof(line.substr(6,line.size()-10)); + + std::getline(infile, line); + std::getline(infile, line); + + std::getline(infile, line); + Nx = std::stof(line.substr(6,line.size()-10)); + std::getline(infile, line); + Ny = std::stof(line.substr(6,line.size()-10)); + + std::getline(infile, line); + std::getline(infile, line); + dirOri = line.substr(7,line.size()-15); + + infile.close(); + +} + +// -------------------------------------------------------------------------------------- +// Fonction d'inversion de l'homographie +// -------------------------------------------------------------------------------------- +// Inputs : +// - pattern des images homographiées +// - pattern des images initiales +// - fichier des paramètres d'homographie +// - dossier d'orientation des images initiales +// - dossier des points homologues transformés (defaut : nom_input + "InvHomog") +// - arguments de types de points (binaire ou txt) et d'images produites +// -------------------------------------------------------------------------------------- +// Outputs : +// - points homologues dans l'espace image de depart +// -------------------------------------------------------------------------------------- +cAppli_YannInvHomolHomog::cAppli_YannInvHomolHomog(int argc, char ** argv){ + + ElInitArgMain(argc,argv, + LArgMain() << EAMC(ImPattern,"Rectified images pattern") + << EAMC(mRawFolder,"Raw images folder") + << EAMC(mHomogFile,"Homography parameters file"), + LArgMain() << EAM(mFolderOut,"Out", "NONE", "Homol output folder") + << EAM(exportTxtIn, "ExpTxtIn", "0", "Input in txt") + << EAM(exportTxtOut, "ExpTxtOut", "0", "Output in txt") + << EAM(mExt, "Ext", "NONE", "Target image extension")); + + + std::string sep = "-----------------------------------------------------------------------"; + + std::cout << "-----------------------------------------------------------------------" << std::endl; + std::cout << " HOMOGRAPHIE INVERSE TRANSFORMATION " << std::endl; + std::cout << "-----------------------------------------------------------------------" << std::endl; + + + // --------------------------------------------------------------- + // Lecture des paramètres d'homographie + // --------------------------------------------------------------- + ElMatrix H(1,9,0.0); + + int Nx; int Ny; + int Nx_org; int Ny_org; + double xmin; double ymin; + double xmax; double ymax; + std::string aNameCam; + + readHomogFile(mHomogFile, H, xmin, ymin, xmax, ymax, Nx_org, Ny_org, Nx, Ny, aNameCam); + + double resolution = (xmax-xmin)/(Nx-1); + + // --------------------------------------------------------------- + // Correction éventuelle de la distorsion + // --------------------------------------------------------------- + + CamStenope * aCam = 0; + + if (aNameCam.size() > 0){ + cInterfChantierNameManipulateur * anICNM = cInterfChantierNameManipulateur::BasicAlloc("./"); + aCam = CamOrientGenFromFile(mRawFolder+"/"+aNameCam,anICNM); + } + + // --------------------------------------------------------------- + // Gestion du répertoire de sortie + // --------------------------------------------------------------- + std::string output_folder = "InvHomog"; + if (EAMIsInit(&mFolderOut)){ + output_folder = mFolderOut; + } + + + // --------------------------------------------------------------- + // Impression console pour confirmation des paramètres + // --------------------------------------------------------------- + printf ("H = %10.3f %10.3f %10.3f BBOX = %7.2f %7.2f \n", H(0,0), H(0,1), H(0,2), xmin, xmax); + printf (" %10.3f %10.3f %10.3f %7.2f %7.2f \n", H(0,3), H(0,4), H(0,5), ymin, ymax); + printf (" %10.3f %10.3f %10.3f \n", H(0,6), H(0,7), 1.0); + printf ("GENERATED IMAGE SIZE: [%i x %i] RAW IMAGE SIZE: [%i x %i] \n", Nx, Ny, Nx_org, Ny_org); + + std::cout << sep << std::endl; + + cInterfChantierNameManipulateur * anICNM = cInterfChantierNameManipulateur::BasicAlloc("./"); + + bool ExpTxtIn = false; + bool ExpTxtOut = false; + + if (EAMIsInit(&exportTxtIn)){ + ExpTxtIn = ((exportTxtIn == "1") || (exportTxtIn == "true") || (exportTxtIn == "T")); + } + if (EAMIsInit(&exportTxtOut)){ + ExpTxtOut = ((exportTxtOut == "1") || (exportTxtOut == "true") || (exportTxtOut == "T")); + } + + std::string aPostIn= ""; + + std::string anExtIn = ExpTxtIn ? "txt" : "dat"; + std::string anExtOut = ExpTxtOut ? "txt" : "dat"; + + std::string aKHIn = std::string("NKS-Assoc-CplIm2Hom@") + + std::string(aPostIn) + + std::string("@") + + std::string(anExtIn); + std::string aKHOut = std::string("NKS-Assoc-CplIm2Hom@") + + std::string(output_folder) + + std::string("@") + + std::string(anExtOut); + + double x1, y1, x1h, y1h, d1; + double x2, y2, x2h, y2h, d2; + + int count = 0; + int count_warning_domain_error = 0; + + const std::vector * aVN = anICNM->Get(ImPattern); + for (int aKN1=0; aKN1size()); aKN1++){ + + std::string aNameIm1 = (*aVN)[aKN1]; + std::cout << aNameIm1 << ":" << std::endl; + + for (int aKN2=0; aKN2size()); aKN2++){ + + std::string aNameIm2 = (*aVN)[aKN2]; + + // Récupération des fichiers homologues + std::string aNameIn = "./" + anICNM->Assoc1To2(aKHIn,aNameIm1,aNameIm2,true); + std::string aNameOut = "./" + anICNM->Assoc1To2(aKHOut,aNameIm1,aNameIm2,true); + + if (EAMIsInit(&mExt)){ + aNameOut = "./" + anICNM->Assoc1To2(aKHOut,StdPrefix(aNameIm1)+"."+mExt,StdPrefix(aNameIm2)+"."+mExt,true); + } + + bool ExistFileIn = ELISE_fp::exist_file(aNameIn); + + if (ExistFileIn){ + + ElPackHomologue aPackIn = ElPackHomologue::FromFile(aNameIn); + ElPackHomologue aPackOut; + + for (ElPackHomologue::const_iterator itP=aPackIn.begin(); itP!=aPackIn.end() ; itP++){ + + Pt2dr aP1 = itP->P1(); + Pt2dr aP2 = itP->P2(); + + x1 = xmin + aP1.x*resolution; y1 = ymax - aP1.y*resolution; + x2 = xmin + aP2.x*resolution; y2 = ymax - aP2.y*resolution; + + d1 = H(0,6)*x1 + H(0,7)*y1 + 1.0; + x1h = (H(0,0)*x1 + H(0,1)*y1 + H(0,2))/d1; + y1h = (H(0,3)*x1 + H(0,4)*y1 + H(0,5))/d1; + + d2 = H(0,6)*x2 + H(0,7)*y2 + 1.0; + x2h = (H(0,0)*x2 + H(0,1)*y2 + H(0,2))/d2; + y2h = (H(0,3)*x2 + H(0,4)*y2 + H(0,5))/d2; + + if ((x1h < 0) || (y1h < 0) || (x2h < 0) || (y1h < 0)){ + count_warning_domain_error ++; + continue; + } + + if ((x1h > Nx_org) || (y1h > Ny_org) || (x2h > Nx_org) || (y1h > Ny_org)){ + count_warning_domain_error ++; + continue; + } + + Pt2dr pt1 = Pt2dr(x1h,y1h); + Pt2dr pt2 = Pt2dr(x2h,y2h); + + // Distorsion + if (aNameCam.size() > 0){ + pt1 = aCam->DistDirecte(pt1); + pt2 = aCam->DistDirecte(pt2); + } + + ElCplePtsHomologues aCple(pt1, pt2, itP->Pds()); + aPackOut.Cple_Add(aCple); + + } + + count += aPackOut.size(); + aPackOut.StdPutInFile(aNameOut); + std::cout << " " << aNameIm2 << " (" << aPackOut.size() << " pts)" << std::endl; + + } + + } + + } + + std::cout << sep << std::endl; + std::cout << count << " tie points transformed into " << "[Homol" << output_folder << "]" << std::endl; + if (count_warning_domain_error > 0){ + int count_rel = (100*count_warning_domain_error)/(count + count_warning_domain_error); + std::cout << "Warning: " << count_warning_domain_error; + std::cout << " (" << count_rel <<" %) points out of image frame removed" << std::endl; + } + std::cout << sep << std::endl; + +} + + +// -------------------------------------------------------------------------------------- +// Fonction d'application de l'homographie +// -------------------------------------------------------------------------------------- +// Inputs : +// - string: Pattern d'images sur lesquelles appliquer la transformation +// - string: Fichier des paramètres d'homographie +// - string: Répertoire de sortie (optionnel) pour la création des images +// -------------------------------------------------------------------------------------- +// Outputs : +// - Les images transformées par l'homographie +// -------------------------------------------------------------------------------------- +cAppli_YannApplyHomog::cAppli_YannApplyHomog(int argc, char ** argv){ + + ElInitArgMain(argc,argv, + LArgMain() << EAMC(mNameIm,"Images pattern") + << EAMC(mNameHomog,"Homography parameters file"), + LArgMain() << EAM(mDirOut,"Out", "./", "Output folder")); + + + std::string sep = "-----------------------------------------------------------------------"; + + std::cout << "-----------------------------------------------------------------------" << std::endl; + std::cout << " HOMOGRAPHIE TRANSFORMATION " << std::endl; + std::cout << "-----------------------------------------------------------------------" << std::endl; + + // --------------------------------------------------------------- + // Lecture des images + // --------------------------------------------------------------- + if (EAMIsInit(&mNameIm)){ + mEASF.Init(mNameIm); + mICNM = mEASF.mICNM; + mDir = mEASF.mDir; + } + + unsigned N = mEASF.SetIm()->size(); + + // --------------------------------------------------------------- + // Gestion du répertoire de sortie + // --------------------------------------------------------------- + std::string output_folder = "./"; + if (EAMIsInit(&mDirOut)){ + output_folder = mDirOut; + ELISE_fp::MkDir(output_folder); + } + + // --------------------------------------------------------------- + // Lecture des paramètres d'homographie + // --------------------------------------------------------------- + ElMatrix H(1,9,0.0); + + int Nx; int Ny; + int Nx_org; int Ny_org; + double xmin; double ymin; + double xmax; double ymax; + std::string aNameCam; + + readHomogFile(mNameHomog, H, xmin, ymin, xmax, ymax, Nx_org, Ny_org, Nx, Ny, aNameCam); + + // --------------------------------------------------------------- + // Impression console pour confirmation des paramètres + // --------------------------------------------------------------- + printf ("H = %10.3f %10.3f %10.3f BBOX = %7.2f %7.2f \n", H(0,0), H(0,1), H(0,2), xmin, xmax); + printf (" %10.3f %10.3f %10.3f %7.2f %7.2f \n", H(0,3), H(0,4), H(0,5), ymin, ymax); + printf (" %10.3f %10.3f %10.3f \n", H(0,6), H(0,7), 1.0); + printf ("GENERATED IMAGE SIZE: [%i x %i] RAW IMAGE SIZE: [%i x %i] \n", Nx, Ny, Nx_org, Ny_org); + std::cout << sep << std::endl; + + // --------------------------------------------------------------- + // Liste des images a transformer + // --------------------------------------------------------------- + std::string aNameIn; + std::string aNameOut; + std::string aNameFileOut; + std::cout << "Transformation of images (" << N << ")" << std::endl; + std::cout << sep << std::endl; + + CamStenope * aCam = 0; + + // Correction éventuelle de la distorsion + if (aNameCam.size() > 0){ + cInterfChantierNameManipulateur * anICNM = cInterfChantierNameManipulateur::BasicAlloc("./"); + aCam = CamOrientGenFromFile(aNameCam,anICNM); + } + + ElMatrix PATTERN_X(Nx,Ny,0.0); + ElMatrix PATTERN_Y(Nx,Ny,0.0); + + double D; + double X; + double Y; + + for (int iy=0; iy 0){ + Pt2dr aCenterOut = aCam->DistDirecte(Pt2dr(PATTERN_X(ix,iy), PATTERN_Y(ix,iy))); + PATTERN_X(ix,iy) = aCenterOut.x; + PATTERN_Y(ix,iy) = aCenterOut.y; + } + } + } + + for (unsigned i=0; isize() == 1), "ImRef must refer to exactly 1 image"); + + } + + // --------------------------------------------------------------- + // Cohérence dossier d'orientation + // --------------------------------------------------------------- + if (EAMIsInit(&mCamRot)){ + ELISE_ASSERT(EAMIsInit(&mDirOri), "No orientation folder for camera frame rotation") + } + + + // --------------------------------------------------------------- + // Gestion de la marge + // --------------------------------------------------------------- + double marge = 0.3; + if (EAMIsInit(&mMargeRel)){ + marge = std::stof(mMargeRel); + } + + // --------------------------------------------------------------- + // Gestion de la résolution de sortie + // --------------------------------------------------------------- + int resolution = 2000; + if (EAMIsInit(&mResolution)){ + resolution = std::stoi(mResolution); + } + + + // --------------------------------------------------------------- + // Récupération des points dans le repère image (2D) + // --------------------------------------------------------------- + mDAF2D = StdGetFromPCP(mName2D, SetOfMesureAppuisFlottants); + std::cout << "Number of images in measurement file [" << mName2D; + std::cout << "]: " << mDAF2D.MesureAppuiFlottant1Im().size() << std::endl; + + + // Conversion liste -> vecteur + std::vector MESURE_IMAGES; + for (std::list::const_iterator itM= mDAF2D.MesureAppuiFlottant1Im().begin(); + itM != mDAF2D.MesureAppuiFlottant1Im().end(); + itM++){ + MESURE_IMAGES.push_back(*itM); + } + + + // --------------------------------------------------------------- + // Recherche de l'image ayant le plus de points + // --------------------------------------------------------------- + + unsigned max = 0; + unsigned val = 0; + unsigned argmax = 0; + int selected = -1; + + + for (unsigned i=0; i max){ + max = val; + argmax = i; + } + + if (EAMIsInit(&mNameImRef)){ + if (MESURE_IMAGES[i].NameIm() == mNameImRef){ + selected = i; + } + } + + if (MESURE_IMAGES[i].OneMesureAF1I().size() >= 4){ + std::cout << MESURE_IMAGES[i].NameIm() << ": "; + std::cout << MESURE_IMAGES[i].OneMesureAF1I().size(); + std::cout << " pts" << std::endl; + } + + } + + if (EAMIsInit(&mNameImRef)){ + ELISE_ASSERT(selected != -1, "ImRef is not referenced in measurement file"); + } + + + if (!EAMIsInit(&mNameImRef)){ + mNameImRef = MESURE_IMAGES[argmax].NameIm(); + selected = argmax; + } + + std::cout << "SELECTED IMAGE: " << mNameImRef << " "; + std::cout << "(" << MESURE_IMAGES[selected].OneMesureAF1I().size(); + std::cout << " pts)"<< std::endl; + + // Lecture taille de l'image + Tiff_Im aTF = Tiff_Im::StdConvGen(mNameImRef,3,false); + Pt2di im_size_origin = aTF.sz(); + int Nx_org = im_size_origin.x; + int Ny_org = im_size_origin.y; + + // Test nombre de points suffisant + const int N = MESURE_IMAGES[selected].OneMesureAF1I().size(); + std::string tmp = "ERROR: not enough points in image measurement file (" + std::to_string(N) + ")"; + + ELISE_ASSERT(N >= 4, tmp.c_str()); + + + // Récupération des points 2D + std::vector X2D; + std::vector Y2D; + std::vector NAME2D; + for (std::list::iterator i=MESURE_IMAGES[selected].OneMesureAF1I().begin(); + i != MESURE_IMAGES[selected].OneMesureAF1I().end(); i++){ + X2D.push_back(i->PtIm().x); + Y2D.push_back(i->PtIm().y); + NAME2D.push_back(i->NamePt()); + } + + std::cout << sep << std::endl; + + // --------------------------------------------------------------- + // Récupération des points dans le repère terrain (3D) + // --------------------------------------------------------------- + mDAF3D = StdGetFromPCP(mName3D, DicoAppuisFlottant); + std::cout << "Number of 3D ground points in [" << mName3D; + std::cout << "]: " << mDAF3D.OneAppuisDAF().size() << std::endl; + + // Récupération des points 3D + std::vector X3D; + std::vector Y3D; + std::vector Z3D; + std::vector NAME3D; + for (std::list::const_iterator itT= mDAF3D.OneAppuisDAF().begin(); + itT != mDAF3D.OneAppuisDAF().end(); + itT++){ + X3D.push_back(itT->Pt().x); + Y3D.push_back(itT->Pt().y); + Z3D.push_back(itT->Pt().z); + NAME3D.push_back(itT->NamePt()); + } + + + // --------------------------------------------------------------- + // Appariemment des points IMAGE <-> TERRAIN + // --------------------------------------------------------------- + std::vector P2D[2]; + std::vector P3D[3]; + + for (unsigned i=0; iDistInverse(Pt2dr(P2D[0][i], P2D[1][i])); + P2D[0][i] = aCenterOut.x; + P2D[1][i] = aCenterOut.y; + } + + + // Rotation + coplanarisation + ElMatrix ROT(3,3,0.0); + if ((!EAMIsInit(&mCamRot)) || (mCamRot)){ + cOrientationConique aOriConique=StdGetFromPCP(aNameCam,OrientationConique); + + ROT = MatFromCol( + aOriConique.Externe().ParamRotation().CodageMatr().Val().L1(), + aOriConique.Externe().ParamRotation().CodageMatr().Val().L2(), + aOriConique.Externe().ParamRotation().CodageMatr().Val().L3() + ).transpose(); + + // Rotation des points du repère terrain + for (unsigned i=0; i P(1,3,0.0); + ElMatrix P_ROT(1,3,0.0); + P(0,0) = P3D[0][i]; P(0,1) = P3D[1][i];P(0,2) = P3D[2][i]; + P_ROT = ROT*P; + P3D[0][i] = P_ROT(0,0); P3D[1][i] = P_ROT(0,1); P3D[2][i] = P_ROT(0,2); + } + + // --------------------------------------------------------------- + // "Co-planarisation" des points par moindres carrés + // --------------------------------------------------------------- + + ElMatrix Aplan(3,N,0.0); + ElMatrix Bplan(1,N,1.0); + for (int i=0; i Xplan = gaussj(Aplan.transpose()*Aplan)*(Aplan.transpose()*Bplan); + + // Calcul de la matrice de rotation + ElMatrix normale = Xplan*(-1.0/sqrt(Xplan.L2())); + Pt3dr rot_axis(-normale(0,2), 0.0, normale(0,0)); + ElMatrix VR = MatProVect(rot_axis).transpose(); + ElMatrix Id(3,3,0); Id(0,0) = Id(1,1) = Id(2,2) = 1; + ElMatrix R = Id + VR + VR*VR*(1.0/(1.0+normale(0,1))); + + // Rotation + for (unsigned i=0; i ERR_PLAN = Aplan*Xplan - Bplan; + printf ("Point planarization: RMSE = %4.2f GROUND UNITS\n", sqrt(ERR_PLAN.L2()/N)); + std::cout << sep << std::endl; + + } + + } + + + // --------------------------------------------------------------- + // Emprise de la zone + // --------------------------------------------------------------- + auto xmin = min_element(std::begin(P3D[0]), std::end(P3D[0])); + auto xmax = max_element(std::begin(P3D[0]), std::end(P3D[0])); + auto ymin = min_element(std::begin(P3D[2]), std::end(P3D[2])); + auto ymax = max_element(std::begin(P3D[2]), std::end(P3D[2])); + + std::cout << "Bounding box:" << std::endl; + printf ("xmin: %6.2f xmax: %6.2f\n", *xmin, *xmax); + printf ("ymin: %6.2f ymax: %6.2f\n", *ymin, *ymax); + + std::cout << sep << std::endl; + + // --------------------------------------------------------------- + // Calcul de l'homographie + // --------------------------------------------------------------- + + L2SysSurResol system(8); // Solveur moindres carrés + + for (int i=0; i H(1,8,0.0); + for (int i=0; i<8; i++){ + H(0,i) = HTAB[i]; + } + + // Résidu + double residu = sqrt(system.ResiduAfterSol()/(2.0*N)); + + // Sortie console + printf ("H = %10.3f %10.3f %10.3f\n", H(0,0), H(0,1), H(0,2)); + printf (" %10.3f %10.3f %10.3f\n", H(0,3), H(0,4), H(0,5)); + printf (" %10.3f %10.3f %10.3f", H(0,6), H(0,7), 1.0); + printf (" RMSE = %4.2f PX\n", residu); + + std::cout << sep << std::endl; + + // --------------------------------------------------------------- + // Sauvegarde de l'homographie + // --------------------------------------------------------------- + + cElComposHomographie aHX(H(0,0),H(0,1),H(0,2)); + cElComposHomographie aHY(H(0,3),H(0,4),H(0,5)); + cElComposHomographie aHZ(H(0,6),H(0,7), 1); + + cElHomographie homography = cElHomographie(aHX,aHY,aHZ); + + cElXMLFileIn aFileXML("homog.xml"); + aFileXML.PutElHomographie(homography,"Homographie"); + + + + // --------------------------------------------------------------- + // Prise en compte de la marge + // --------------------------------------------------------------- + double margex = abs(*xmax-*xmin)*marge; + double margey = abs(*ymax-*ymin)*marge; + *xmin = *xmin - margex; *xmax = *xmax + margex; + *ymin = *ymin - margey; *ymax = *ymax + margey; + + Pt2dr pt_min (*xmin, *ymin); + Pt2dr pt_max (*xmax, *ymax); + aFileXML.PutPt2dr(pt_min,"MinCoords"); + aFileXML.PutPt2dr(pt_max,"MaxCoords"); + + int Nx = resolution; + int Ny = (*ymax-*ymin)/(*xmax-*xmin)*Nx; + aFileXML.PutPt2dr(Pt2dr(Nx_org, Ny_org), "Input_resolution"); + aFileXML.PutPt2dr(Pt2dr(Nx, Ny), "Output_resolution"); + aFileXML.PutString(aNameCam, "Calib"); + + std::cout << "Homography parameters written in [homog.xml] file" << std::endl; + std::cout << sep << std::endl; + +} + + + +// ---------------------------------------------------------------------------- +// A chaque commande MicMac correspond une fonction ayant la signature du main +// Le lien se fait dans src/CBinaires/mm3d.cpp +// ---------------------------------------------------------------------------- + +// (1) Estimation de l'homographie +int CPP_YannEstimHomog(int argc,char ** argv){ + cAppli_YannEstimHomog(argc,argv); + return EXIT_SUCCESS; +} + +// (2) Application de l'homographie +int CPP_YannApplyHomog(int argc,char ** argv){ + cAppli_YannApplyHomog(argc,argv); + return EXIT_SUCCESS; +} + +// (3) Inversion des TP par l'homographie +int CPP_YannInvHomolHomog(int argc,char ** argv){ + cAppli_YannInvHomolHomog(argc,argv); + return EXIT_SUCCESS; +} + +/*Footer-MicMac-eLiSe-25/06/2007 + +Ce logiciel est un programme informatique servant a la mise en +correspondances d'images pour la reconstruction du relief. + +Ce logiciel est régi par la licence CeCILL-B soumise au droit français et +respectant les principes de diffusion des logiciels libres. Vous pouvez +utiliser, modifier et/ou redistribuer ce programme sous les conditions +de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA +sur le site "http://www.cecill.info". + +En contrepartie de l'accessibilité au code source et des droits de copie, +de modification et de redistribution accordés par cette licence, il n'est +offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, +seule une responsabilité restreinte pèse sur l'auteur du programme, le +titulaire des droits patrimoniaux et les concédants successifs. + +A cet égard l'attention de l'utilisateur est attirée sur les risques +associés au chargement, à l'utilisation, à la modification et/ou au +développement et à la reproduction du logiciel par l'utilisateur étant +donné sa spécificité de logiciel libre, qui peut le rendre complexe à +manipuler et qui le réserve donc à des développeurs et des professionnels +avertis possédant des connaissances informatiques approfondies. Les +utilisateurs sont donc invités à charger et tester l'adéquation du +logiciel à leurs besoins dans des conditions permettant d'assurer la +sécurité de leurs systèmes et ou de leurs données et, plus généralement, +à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. + +Le fait que vous puissiez accéder à cet en-tête signifie que vous avez +pris connaissance de la licence CeCILL-B, et que vous en avez accepté les +termes. +Footer-MicMac-eLiSe-25/06/2007*/ diff --git a/src/Yann/Sources.cmake b/src/Yann/Sources.cmake new file mode 100644 index 0000000000..4260b74408 --- /dev/null +++ b/src/Yann/Sources.cmake @@ -0,0 +1,5 @@ +list(APPEND Yann_Src_Files + ${YANN_DIR}/EstimHomogr.cpp + ) + +list(APPEND Elise_Src_Files ${Yann_Src_Files}) diff --git a/src/fonc_num/fnum_compile.cpp b/src/fonc_num/fnum_compile.cpp index 6c2af6a2f5..938add65bb 100644 --- a/src/fonc_num/fnum_compile.cpp +++ b/src/fonc_num/fnum_compile.cpp @@ -811,7 +811,7 @@ void cElCompiledFonc::InitBloc(const cSetEqFormelles & aSet) } -void cElCompiledFonc::SetCoordCur(double * aRealCoord) +void cElCompiledFonc::SetCoordCur(const double * aRealCoord) { ELISE_ASSERT(isCurMappingSet,"No Current Mapping"); @@ -823,6 +823,7 @@ void cElCompiledFonc::SetCoordCur(double * aRealCoord) { INT aIC = LIC(aK); mCompCoord[aIC] = aRealCoord[mMapComp2Real[aIC]]; + // std::cout << "FFFffFFf " << aIC << " " < & cElCompiledFonc::Vals() const { ELISE_ASSERT(isValComputed,"No Val Computed"); return mVal; } +const std::vector & cElCompiledFonc::ValSsVerif() const +{ + return mVal; +} +const std::vector > & cElCompiledFonc::CompDerSsVerif() const +{ + return mCompDer; +} + +const std::vector > & cElCompiledFonc::CompDer() const +{ + ELISE_ASSERT(isDerComputed,"No Der Computed"); + return mCompDer; +} +const std::vector & cElCompiledFonc::CompCoord() const +{ + ELISE_ASSERT(isCoordSet,"No Coord Set"); + return mCompCoord; +} + + REAL cElCompiledFonc::Deriv(INT aD,INT aK) const { diff --git a/src/geom3d/cElNuage3DMaille.cpp b/src/geom3d/cElNuage3DMaille.cpp index f2a6bb8043..ffb0aebea8 100644 --- a/src/geom3d/cElNuage3DMaille.cpp +++ b/src/geom3d/cElNuage3DMaille.cpp @@ -912,7 +912,7 @@ void cElNuage3DMaille::PlyPutDataVertex(FILE * aFP, bool aModeBin, int aAddNorma if (aAddNormale) { - Pt3dr aN = NormaleOfIndex(anI, aAddNormale); + Pt3dr aN = NormaleOfIndex(anI, aAddNormale, anOffset); if (DoublePrec) { @@ -1125,7 +1125,7 @@ double cElNuage3DMaille::DiffDeSurface } //Compute local normal on 3D points in a window (wSize x wSize) -Pt3dr cElNuage3DMaille::NormaleOfIndex(const tIndex2D& anI1, int wSize) const +Pt3dr cElNuage3DMaille::NormaleOfIndex(const tIndex2D& anI1, int wSize, const Pt3dr & anOffset) const { if (IndexHasContenu(anI1)) { @@ -1136,7 +1136,10 @@ Pt3dr cElNuage3DMaille::NormaleOfIndex(const tIndex2D& anI1, int wSize) const if (mNormByCenter==1) return aTgt * (-aFact); else if (mNormByCenter==2) - return mCam->OrigineProf(); + { + Pt3dr aCentreOptique = mCam->OrigineProf() - anOffset; + return aCentreOptique; + } std::vector aVP; std::vector aVPds; diff --git a/src/optim/opt_mat_creuse.cpp b/src/optim/opt_mat_creuse.cpp index b27c222e1c..90616d2dc9 100644 --- a/src/optim/opt_mat_creuse.cpp +++ b/src/optim/opt_mat_creuse.cpp @@ -1806,12 +1806,12 @@ void cElMatCreuseBlocSym::CalculCholesky() { if (aScal <=0) { - std::cout << "Value = " << aScal << "\n"; + std::cout << "ValueNeg = " << aScal << "\n"; static bool First = true; if (First) { std::cout << " Warn tape enter to continue" << std::endl; - if (TheExitOnWarn || MPD_MM()) + if (TheExitOnWarn) // ( || MPD_MM()) ElEXIT(1,"aScal<=0 in Cholesky"); else { diff --git a/src/photogram/OffsetGPS.cpp b/src/photogram/OffsetGPS.cpp index a5d576c1f9..9cf3bc009f 100644 --- a/src/photogram/OffsetGPS.cpp +++ b/src/photogram/OffsetGPS.cpp @@ -236,7 +236,7 @@ void GenerateCodeEqOffsetGPS(bool aGL) ElRotation3D aRot(Pt3dr(0,0,0),0,0,0); cRotationFormelle * aRF = aSet.NewRotation (cNameSpaceEqF::eRotLibre,aRot); - aRF->SetGL(aGL); + aRF->SetGL(aGL,ElRotation3D::Id); cBaseGPS * aBase = aSet.NewBaseGPS(Pt3dr(0,0,0)); aSet.NewEqOffsetGPS(*aRF,*aBase,true); diff --git a/src/photogram/phgr_basic.cpp b/src/photogram/phgr_basic.cpp index b1fd271f6c..b3b3a34638 100644 --- a/src/photogram/phgr_basic.cpp +++ b/src/photogram/phgr_basic.cpp @@ -812,8 +812,17 @@ ElPackHomologue ElPackHomologue::FromFile(const std::string & aName) if ( aFTxt.fgets( aBuf, End ) ) //if (aFTxt.fgets(aBuf,200,End)) TEST_OVERFLOW { Pt2dr aP1,aP2; + double aPds=1.0; + int aNb = sscanf(aBuf.c_str(),"%lf %lf %lf %lf %lf",&aP1.x,&aP1.y,&aP2.x,&aP2.y,&aPds); + + if ((aNb==4) || (aNb==5)) + { + aPck.Cple_Add(ElCplePtsHomologues(aP1,aP2,aPds)); + } + /* if (sscanf(aBuf.c_str(),"%lf %lf %lf %lf",&aP1.x,&aP1.y,&aP2.x,&aP2.y)==4) //sscanf(aBuf.c_str(),"%lf %lf %lf %lf",&aP1.x,&aP1.y,&aP2.x,&aP2.y); TEST_OVERFLOW aPck.Cple_Add(ElCplePtsHomologues(aP1,aP2,1.0)); +*/ } } @@ -892,7 +901,7 @@ void ElPackHomologue::StdPutInFile(const std::string & aName) const itP++ ) { - fprintf(aFP,"%f %f %f %f\n",itP->P1().x,itP->P1().y,itP->P2().x,itP->P2().y); + fprintf(aFP,"%f %f %f %f %f\n",itP->P1().x,itP->P1().y,itP->P2().x,itP->P2().y,itP->Pds()); } ElFclose(aFP); /* @@ -3486,9 +3495,15 @@ cOrientationConique ElCamera::StdExportCalibGlob() const return StdExportCalibGlob(true); } -std::string ElCamera::StdExport2File(cInterfChantierNameManipulateur *anICNM,const std::string & aDirOri,const std::string & aNameIm) +std::string ElCamera::StdExport2File(cInterfChantierNameManipulateur *anICNM,const std::string & aDirOri,const std::string & aNameIm,const std::string & aNameFileInterne) { + bool FileInterne = (aNameFileInterne != ""); cOrientationConique anOC = StdExportCalibGlob() ; + if (FileInterne) + { + anOC.Interne().SetNoInit(); + anOC.FileInterne().SetVal(aNameFileInterne); + } std::string aName = anICNM->NameOriStenope(aDirOri,aNameIm); MakeFileXML(anOC,aName); return aName; diff --git a/src/photogram/phgr_epipole.cpp b/src/photogram/phgr_epipole.cpp index 3d1533e123..18642c90e5 100644 --- a/src/photogram/phgr_epipole.cpp +++ b/src/photogram/phgr_epipole.cpp @@ -562,6 +562,18 @@ EpipolaireCoordinate & CpleEpipolaireCoord::EPI2() return *mEPI2; } +/* + On cherche a resoudre dans les reperes epipolaire (liés aux directio aDir1, + aDir2 comme axe des x) un couple de transfo en y (Y1,Y2) tel que : + + Y1(P) = Y2(P) pour tous les points hom de aPackH + + Bien sur c'est indeterminé à une fonction pres , donc on impose ausi pour lever l'arbitraire : + + Y1((0,y)) = y + + +*/ CpleEpipolaireCoord * CpleEpipolaireCoord::PolynomialFromHomologue ( @@ -571,7 +583,8 @@ CpleEpipolaireCoord * CpleEpipolaireCoord::PolynomialFromHomologue const ElPackHomologue & aPackH, INT aDegre, Pt2dr aDir1, - Pt2dr aDir2 + Pt2dr aDir2, + int aDeltaDeg ) { StatElPackH aStat(aPackH); @@ -580,6 +593,7 @@ CpleEpipolaireCoord * CpleEpipolaireCoord::PolynomialFromHomologue Polynome2dReal aPol1(aDegre,aStat.RMax1()); Polynome2dReal aPol2(aDegre,aStat.RMax2()); + // Sur Pol1 on ne retient pas les term en Y^k qui sont la fonction correspondant a X=0 INT aNbInc =0; for (INT k=0; kGSSR_AddNewEquation(itC->Pds()*aPdsResidu,aDVP,aP1.y); aSys.PushEquation(aVecPds,aP1.y,itC->Pds()*aPdsResidu); } @@ -646,22 +663,24 @@ CpleEpipolaireCoord * CpleEpipolaireCoord::PolynomialFromHomologue aNbInc=0; { - for (INT k=0; k & cRotationFormelle::MatFGL(int aKForceGL) @@ -275,6 +275,41 @@ Pt3dr cRotationFormelle::AddRappOnCentre(const Pt3dr & aPVal,const Pt3dr & aPds return aRes; } +void cRotationFormelle::AddRappOnRot(const ElRotation3D & aRot,const Pt3dr & aPdsC,const Pt3dr & aPdsRot) +{ + double aVVals[6]; + + ELISE_ASSERT(mModeGL,"RotationFormelle::AddRappOnRot no Guibal lock"); + // On veut , d'apres l'utilisation du Guimbal : + // aRot = ElRotation3D(mCurCOpt.tr(),mMGL*mCurTeta01.Mat(),true); + // Donc on impose : + // mCurTeta01 = mMGL.tranp() * aRot + ElRotation3D aTargetMat (Pt3dr(0,0,0),mMGL.transpose()*aRot.Mat(),true); + aVVals[0]= aTargetMat.teta01(); + aVVals[1]= aTargetMat.teta02(); + aVVals[2]= aTargetMat.teta12(); + + + Pt3dr aTargC = aRot.tr(); + + aVVals[3]= aTargC.x; + aVVals[4]= aTargC.y; + aVVals[5]= aTargC.z; + + tContFcteur aFRap = FoncRapp(0,6,aVVals); + mSet.AddEqFonctToSys(aFRap[0],aPdsRot.x,false); + mSet.AddEqFonctToSys(aFRap[1],aPdsRot.y,false); + mSet.AddEqFonctToSys(aFRap[2],aPdsRot.z,false); + mSet.AddEqFonctToSys(aFRap[3],aPdsC.x,false); + mSet.AddEqFonctToSys(aFRap[4],aPdsC.y,false); + mSet.AddEqFonctToSys(aFRap[5],aPdsC.z,false); +/* + + return aRes; + aRot = aPdsC; +*/ +} + void cRotationFormelle::SetTolAng(double aTol) { @@ -317,7 +352,7 @@ void cRotationFormelle::ReactuFcteurRapCoU() mFcteurRapCoU->SetNormValFtcrFixedNormEuclid(euclid(mCurCOpt-pRotAttach->mCurCOpt)); } -void cRotationFormelle::SetCurRot(const ElRotation3D & aR2CM) +void cRotationFormelle::SetCurRot(const ElRotation3D & aR2CM,const ElRotation3D & aGuimb2CM) { AssertDegre0(); @@ -326,14 +361,26 @@ void cRotationFormelle::SetCurRot(const ElRotation3D & aR2CM) mCurCOpt.z = aR2CM.tr().z; if (mModeGL) { - mMGL = aR2CM.Mat(); + // ElRotation3D cRotationFormelle::CurRot() + // aRes = ElRotation3D(aRes.tr(),mMGL*aRes.Mat(),true); + // Mat = mMGL-1 * Rot + // mCurCOpt.x = 0; // mCurCOpt.y = 0; // mCurCOpt.z = 0; + + mMGL = aGuimb2CM.Mat(); + ElRotation3D aCurDif (Pt3dr(0,0,0), mMGL.transpose()*aR2CM.Mat() ,true); + mCurTeta01 = aCurDif.teta01(); + mCurTeta02 = aCurDif.teta02(); + mCurTeta12 = aCurDif.teta12(); +/* + mMGL = aR2CM.Mat(); mCurTeta01 = 0; mCurTeta02 = 0; mCurTeta12 = 0; +*/ } else { @@ -709,7 +756,7 @@ cCameraFormelle::cEqAppui::cEqAppui { if (Code2Gen) // En mode normal, on ne modifie pas la camera { - mCam.SetGL(isGL); + mCam.SetGL(isGL,ElRotation3D::Id); } if (isProj) @@ -950,9 +997,9 @@ cMatr_Etat_PhgrF & cCameraFormelle::MatRGL(bool isP) } */ -void cCameraFormelle::SetGL(bool aModeGL) +void cCameraFormelle::SetGL(bool aModeGL,const ElRotation3D & aGuimb2CM) { - mRot->SetGL(aModeGL); + mRot->SetGL(aModeGL,aGuimb2CM); } bool cCameraFormelle::IsGL() const { @@ -1357,9 +1404,9 @@ void cCameraFormelle::Update_0F2D() mCameraCourante = CalcCameraCourante(); } -void cCameraFormelle::SetCurRot(const ElRotation3D & aR2CM) +void cCameraFormelle::SetCurRot(const ElRotation3D & aR2CM,const ElRotation3D & aGuimb2CM) { - mRot->SetCurRot(aR2CM); + mRot->SetCurRot(aR2CM,aGuimb2CM); mCameraCourante->SetOrientation(mRot->CurRot().inv()); // mCameraCourante->SetOrientation(aR2CM.inv()); Update_0F2D(); diff --git a/src/photogram/phgr_formel.cpp b/src/photogram/phgr_formel.cpp index 5d309180aa..c62649714b 100644 --- a/src/photogram/phgr_formel.cpp +++ b/src/photogram/phgr_formel.cpp @@ -268,21 +268,23 @@ void cElemEqFormelle::SetValAndInit(REAL aVal,INT anIndGlob) cElemEqFormelle::tContFcteur cElemEqFormelle::FoncRappInit(INT i0,INT i1) { - -/* -if (0) -{ - for (int i=i0 ; i* aVals + ) { - tContFcteur aPlus = FoncRappInit(i0,i1); + if (aVals) + { + ELISE_ASSERT(int(aVals->size())==(i1-i0),"AddFoncRappInit size vals incoherent "); + } + tContFcteur aPlus = aVals ? FoncRapp(i0,i1,&((*aVals)[0])-i0) : FoncRappInit(i0,i1); for (INT aK=0; aK ElPackHomologue::MepRelStd(REAL LBase,bool SysL2) // Co return MatEssToMulipleRot(aMEss,LBase); } +extern bool ShowMSG_ListRot2RotPhys; + ElRotation3D ListRot2RotPhys(const std::list & aLRot,const ElPackHomologue & aPack) { const ElRotation3D * aRes = &(aLRot.front()); INT aScMin = -20 * aPack.size(); + int aCpt=0; for ( std::list::const_iterator it=aLRot.begin(); @@ -384,6 +387,11 @@ ElRotation3D ListRot2RotPhys(const std::list & aLRot,const ElPack aScMin = aScore; aRes = &(*it); } + if (ShowMSG_ListRot2RotPhys) + { + std::cout << "Cpt " << aCpt << " SCORE " << aScore << "\n"; + } + aCpt++; } return *aRes; diff --git a/src/photogram/phgr_vrai_bundle.cpp b/src/photogram/phgr_vrai_bundle.cpp index 6c05d6cf9e..f01c7e4410 100644 --- a/src/photogram/phgr_vrai_bundle.cpp +++ b/src/photogram/phgr_vrai_bundle.cpp @@ -1157,12 +1157,14 @@ cFullBundleBase::cFullBundleBase(const ElPackHomologue & aPack,double aFoc,bool cPackInPts2d (aPack), cInterfBundle2Image ((int)mVP1.size(),aFoc), mBB (false,0,aFoc,UseAccelCoordCste), - mAddCstrDrone (MPD_MM()) + mAddCstrDrone (false && MPD_MM()) { if (mAddCstrDrone) { std::cout << "ADD CSTRE DRONE \n"; } +/* +*/ } double cFullBundleBase::VIB2I_ErrorK(const ElRotation3D &aRot,const int & aK) const diff --git a/src/recipes/rejacobi.cpp b/src/recipes/rejacobi.cpp index fb24fd3fab..46a9c51c82 100644 --- a/src/recipes/rejacobi.cpp +++ b/src/recipes/rejacobi.cpp @@ -488,6 +488,29 @@ static REAL SetToMatDirecte(ElMatrix & aMat) return -1; } + +ElRotation3D AverRotation(const std::vector & aVRot,const std::vector & aVWeights) +{ + ELISE_ASSERT(aVRot.size()==aVWeights.size(),"AverRotation dif size"); + Pt3dr aC(0,0,0); + ElMatrix aMat(3,3,0.0); + double aSomW = 0.0; + + for (int aK=0 ; aK NearestRotation ( const ElMatrix & aMat) { INT n = aMat.tx(); diff --git a/src/saisieQT/main/saisieAppuisPredicQT_main.cpp b/src/saisieQT/main/saisieAppuisPredicQT_main.cpp index 62ea0430b4..122e5cbfb1 100644 --- a/src/saisieQT/main/saisieAppuisPredicQT_main.cpp +++ b/src/saisieQT/main/saisieAppuisPredicQT_main.cpp @@ -18,7 +18,10 @@ void SaisieAppuisPredic(int argc, char ** argv, double &aZInc, std::string & aInputSec, bool & WithMaxMinPt, - double & aGama); + double & aGama, + std::string & aPatFilter, + double & aDistMax + ); using namespace std; @@ -92,7 +95,9 @@ int saisieAppuisPredicQT_main(int argc, char *argv[]) } bool WithMaxMinPt=false; - SaisieAppuisPredic(argc, argv, aSzWin, aNbFen, aFullName, aDir, aName, aNamePt, aNameOri, aModeOri, aNameMesure, aTypePts, aMasq3D,aPIMsFilter,aFlou, aForceGray, aZMoy, aZInc, aInputSec,WithMaxMinPt, aGama); + std::string aPatF; + double aDistMax; + SaisieAppuisPredic(argc, argv, aSzWin, aNbFen, aFullName, aDir, aName, aNamePt, aNameOri, aModeOri, aNameMesure, aTypePts, aMasq3D,aPIMsFilter,aFlou, aForceGray, aZMoy, aZInc, aInputSec,WithMaxMinPt, aGama,aPatF,aDistMax); if (!MMVisualMode) { diff --git a/src/tiff/tiff_header.cpp b/src/tiff/tiff_header.cpp index 1eae7dad9a..067d4f7656 100644 --- a/src/tiff/tiff_header.cpp +++ b/src/tiff/tiff_header.cpp @@ -2268,7 +2268,7 @@ L_Arg_Opt_Tiff ArgOpTiffMDP(const cMetaDataPhoto & aMDP,bool SVP) L_Arg_Opt_Tiff ArgOpTiffMDP(const std::string & aNF) { - return ArgOpTiffMDP(Tiff_Im(aNF.c_str()).MDP()); + return ArgOpTiffMDP(Tiff_Im(aNF.c_str()).MDP(),true); } diff --git a/src/uti_files/CPP_CheckChantier.cpp b/src/uti_files/CPP_CheckChantier.cpp index d92b172955..d03bd60705 100644 --- a/src/uti_files/CPP_CheckChantier.cpp +++ b/src/uti_files/CPP_CheckChantier.cpp @@ -38,6 +38,7 @@ English : Header-MicMac-eLiSe-25/06/2007*/ #include "StdAfx.h" #include +#include "../include/im_tpl/image.h" /* */ @@ -136,9 +137,54 @@ void CheckSetFile(const std::string & aDir,const std::string & aKey,const std::s int CheckOneTiff_main(int argc,char ** argv) { + // Comme c'etait comme cela, j'y touche pas, mais rajoute quand meme qqchose std::string aName = InitJunkErrorHandler(argc,argv); + + int CorrecNan = 0; + ElInitArgMain + ( + argc,argv, + LArgMain() << EAMC(aName,"Directory "), + LArgMain() << EAM(CorrecNan,"WCNan",true,"With check/correction of nan (1=check,2=correc)") + ); + Tiff_Im aTF(aName.c_str()); ELISE_COPY(aTF.all_pts(),aTF.in(),Output::onul()); + if (CorrecNan) + { + Im2D aIm = Im2D::FromFileStd(aName); + TIm2D aTIm(aIm); + + Pt2di aSz = aIm.sz(); + Pt2di aP; + Im2D_Bits<1> aMasqOk(aSz.x,aSz.y,1); + TIm2DBits<1> aTMasqOk(aMasqOk); + Im2D_Bits<1> aMasqRes(aSz.x,aSz.y,1); + int aCptNan=0; + for (aP.x=0 ; aP.x=2) + { + Im2D aImCorrec = ImpaintL2(aMasqOk,aMasqRes,aIm,4); + + std::string aNameRes = StdPrefix(aName)+"_Correc.tif"; + + Tiff_Im aTifOut(aNameRes.c_str(),aSz,aTF.type_el(),aTF.mode_compr(),aTF.phot_interp()); + ELISE_COPY(aImCorrec.all_pts(),aImCorrec.in(),aTifOut.out()); + } + } return EXIT_SUCCESS; } diff --git a/src/uti_files/CPP_GenCode.cpp b/src/uti_files/CPP_GenCode.cpp index cac0cb7e4f..f6e1599243 100644 --- a/src/uti_files/CPP_GenCode.cpp +++ b/src/uti_files/CPP_GenCode.cpp @@ -337,7 +337,7 @@ void GenCodeAppui(bool C2M,bool isFixe,bool isGL,bool isAFocal,bool wDist,const { cCameraFormelle * aCam = aPIF->NewCam(cNameSpaceEqF::eRotFigee,aRot,0,"toto",false,false); if (isGL) - aCam->SetGL(true); + aCam->SetGL(true,ElRotation3D::Id); aCam->AddForUseFctrEqAppuisInc(true,false,wDist,EqDroite); aCam->AddForUseFctrEqAppuisInc(true,true,wDist,EqDroite); } diff --git a/src/uti_files/CPP_MyRename.cpp b/src/uti_files/CPP_MyRename.cpp index e274d62f10..2ddac23f04 100644 --- a/src/uti_files/CPP_MyRename.cpp +++ b/src/uti_files/CPP_MyRename.cpp @@ -386,12 +386,14 @@ cAppliMyRename::cAppliMyRename(int argc,char ** argv) : for (int aK=0 ; aK Date(true); const cElDate & aDate0 = mVCam[0]->mMTD->Date(true); @@ -987,6 +995,8 @@ void cAppli_Ori_Txt2Xml_main::InitCamera(cTxtCam & aCam,Pt3dr aC,Pt3dr aWPK,P { aCam.mOC->Externe().Centre() = aC; aCam.mTime = (mMTDOnce | allDateUnInit) ? aCam.mNum : aCam.mMTD->Date().DifInSec(mVCam[0]->mMTD->Date()) ; + if (aTime > 0) + aCam.mTime = aTime; aCam.mOC->Externe().Time().SetVal(aCam.mTime); aCam.mC = aC; @@ -1039,6 +1049,7 @@ void cAppli_Ori_Txt2Xml_main::ParseFile() std::string aNameIm; if (aReadApp.Decode(aLine) && (aCpt>=mCptMin) && (aCptAssoc1To1(mKeyName2Image,aReadApp.mName,true); if (! ELISE_fp::exist_file(aNameIm)) { @@ -1047,6 +1058,11 @@ void cAppli_Ori_Txt2Xml_main::ParseFile() { ELISE_ASSERT(false,"This image does not exist"); } + else if (EAMIsInit(&mFileNonExist)) + { + Ok=true; + ELISE_fp::CpFile(mFileNonExist,aNameIm); + } } else { @@ -1117,8 +1133,9 @@ void cAppli_Ori_Txt2Xml_main::ParseFile() double aIx = aReadApp.IsDef(aReadApp.mInc3.x) ? aReadApp.mInc3.x : -1; double aIy = aReadApp.IsDef(aReadApp.mInc3.y) ? aReadApp.mInc3.y : -1; double aIz = aReadApp.IsDef(aReadApp.mInc3.z) ? aReadApp.mInc3.z : -1; - - InitCamera(aNewCam,aC,mHasWPK ? aReadApp.mWPK :Pt3dr(0,0,0),Pt3dr(aIx,aIy,aIz)); + double aTime = aReadApp.IsDef(aReadApp.mTime) ? aReadApp.mTime : - 1; + + InitCamera(aNewCam,aC,mHasWPK ? aReadApp.mWPK :Pt3dr(0,0,0),Pt3dr(aIx,aIy,aIz),aTime); aNewCam.mPrio = aNewCam.mTime ;// + aNewCam.mNum * 1e-7; diff --git a/src/uti_files/CPP_TestKeys.cpp b/src/uti_files/CPP_TestKeys.cpp index 27ce62b51a..6ecc0031c7 100644 --- a/src/uti_files/CPP_TestKeys.cpp +++ b/src/uti_files/CPP_TestKeys.cpp @@ -39,6 +39,38 @@ Header-MicMac-eLiSe-25/06/2007*/ #include "StdAfx.h" #include +int Recover_Main(int argc, char ** argv) +{ + std::string aNameIn,aNameOut; + ElInitArgMain + ( + argc,argv, + LArgMain() << EAMC(aNameIn, "Name of Input File") + << EAMC(aNameOut, "Name of Input File"), + LArgMain() + ); + + FILE * aFPin = FopenNN(aNameIn,"r","In recover"); + FILE * aFPOut = FopenNN(aNameOut,"w","In recover"); + + int aC; + while ( (aC= fgetc(aFPin)) != EOF) + { + if ( + ( (aC>='a') && (aC<='z')) + || ( (aC>='A') && (aC<='Z')) + || ( (aC>='0') && (aC<='9')) + || (aC=='\n') + ) + fputc(aC,aFPOut); + } + fclose(aFPin); + fclose(aFPOut); + + return EXIT_SUCCESS; +} + + /* Parametre de Tapas : diff --git a/src/uti_image/CPP_DevVideo.cpp b/src/uti_image/CPP_DevVideo.cpp index 832b1140de..6a370d6d5a 100644 --- a/src/uti_image/CPP_DevVideo.cpp +++ b/src/uti_image/CPP_DevVideo.cpp @@ -536,6 +536,39 @@ const cSolChemOptImV & cOneImageVideo::SolOfLength(int aNbL) #define TEST true +// To get output of ffmpeg's FPS request + +std::string getCmdOutput(const char* cmd) { + char buffer[128]; + std::string result = ""; + #if (ELISE_windows) + FILE* pipe = _popen(cmd, "r"); + if (!pipe) throw std::runtime_error("_popen() failed!"); + try { + while (fgets(buffer, sizeof buffer, pipe) != NULL) { + result += buffer; + } + } catch (...) { + _pclose(pipe); + throw; + } + _pclose(pipe); + #else + FILE* pipe = popen(cmd, "r"); + if (!pipe) throw std::runtime_error("popen() failed!"); + try { + while (fgets(buffer, sizeof buffer, pipe) != NULL) { + result += buffer; + } + } catch (...) { + pclose(pipe); + throw; + } + pclose(pipe); + #endif + return result; +} + cAppliDevideo::cAppliDevideo(int argc,char ** argv) : mCam ("NONE"), mPostfix ("png"), @@ -558,7 +591,7 @@ cAppliDevideo::cAppliDevideo(int argc,char ** argv) : LArgMain() << EAM(mTargetRate,"Rate",true,"Rate final Def=4") << EAM(mParamSzSift,"ParamSzSift",true,"Parameter used for sift development, def=-1 (Highest)") << EAM(mPatNumber,"PatNumber",true,"Pat number (reduce number for test)") - << EAM(mDoVideo2Im,"DoV2I",true,"Do the development of video 2 images, def true iff no image to corresp pattern") + << EAM(mDoVideo2Im,"DoV2I",true,"Do the development of video 2 images, def true if no image to corresp pattern") << EAM(mNbDigit,"NDig",true,"Nb digit for numbering out images (Def=5)") << EAM(mFoc,"Foc",true,"Set focale in xif, def=F35") << EAM(mCam,"Cam",true,"Set Cam in xif") @@ -567,7 +600,7 @@ cAppliDevideo::cAppliDevideo(int argc,char ** argv) : << EAM(mTuning,"Tuning",true,"as it says ... ") << EAM(mSzDecoup,"TheSzDecoup",true,"Sz of a priori split, \"expert\" level , Def=300 ") << EAM(mOverLap,"OverLap",true,"Target overlap between images ") - << EAM(mRateVideoInit,"RateVideo",true,"Rate image per seconde (FPS), Def=24 ") + << EAM(mRateVideoInit,"RateVideo",true,"Rate image per seconde (FPS), Def=fps value from ffmpeg ") ); // avconv -i adjudant.MOV Im_0247_%5d_Ok.png @@ -608,20 +641,29 @@ cAppliDevideo::cAppliDevideo(int argc,char ** argv) : // Extraction des images fixes + remplit les xif if (mDoVideo2Im) { - std::string aComDev = "avconv -i " + std::string aComDev = "ffmpeg -i " + mFullNameVideo + " " + mEASF.mDir + mPrefix + "%" + ToString(mNbDigit) + "d_Ok." + mPostfix; System(aComDev); // std::cout << aComDev<< "\n"; + std::string aComFPS = "ffmpeg -i " + + mFullNameVideo + " 2>&1 | sed -n \"s/.*, \\(.*\\) fp.*/\\1/p\""; + + std::string aFps = getCmdOutput(aComFPS.c_str()); + std::stringstream ss; + ss << aFps; + ss >> mRateVideoInit; + std::cout << "FPS video : " << mRateVideoInit << "\n"; + if (mF35>0) { std::string aComXif = MM3dBinFile("SetExif ") + QUOTE(mMMPatImDev) + " F=" + ToString(mFoc) + " F35=" + ToString(mF35) - + " Cam=" + mCam + + " Cam='" + mCam + "'" ; System(aComXif); diff --git a/src/uti_image/CPP_Drunk.cpp b/src/uti_image/CPP_Drunk.cpp index 308f221561..8b80614da3 100644 --- a/src/uti_image/CPP_Drunk.cpp +++ b/src/uti_image/CPP_Drunk.cpp @@ -99,8 +99,16 @@ void Drunk(string aFullPattern,string aOri,string DirOut, bool Talk, bool RGB, B //Loading the camera string aNameCam="Ori-"+aOri+"/Orientation-"+aNameIm+".xml"; cInterfChantierNameManipulateur * anICNM = cInterfChantierNameManipulateur::BasicAlloc(aNameDir); - CamStenope * aCam = CamOrientGenFromFile(aNameCam,anICNM); + // CamStenope * aCam = CamOrientGenFromFile(aNameCam,anICNM); + CamStenope * aCam = anICNM->StdCamStenOfNamesSVP (aNameIm,aOri) ; + bool WithExtern = (aCam != nullptr); + if (!WithExtern) + { + std::string aNameCal = anICNM->StdNameCalib(aOri,aNameIm); + aCam = Std_Cal_From_File(aNameCal); + // aCalibFileExtern= true; + } //Reading the image and creating the objects to be manipulated Tiff_Im aTF= Tiff_Im::StdConvGen(aNameDir + aNameIm,3,false); diff --git a/src/uti_image/CPP_Filter.cpp b/src/uti_image/CPP_Filter.cpp index 45c23a5dc0..e3d3f57d91 100644 --- a/src/uti_image/CPP_Filter.cpp +++ b/src/uti_image/CPP_Filter.cpp @@ -1163,11 +1163,13 @@ int Contrast_main(int argc,char ** argv) int TournIm_main(int argc,char ** argv) { std::string aNameIm; + int aNumGeom = 1; ElInitArgMain ( argc,argv, LArgMain() << EAMC(aNameIm,"Name of Input image", eSAM_IsExistFile), LArgMain() + << EAM(aNumGeom,"NumGeom",true,"0=>Id,1=>90(def), 2=>180,3=>270,[4-7]=>Sym", eSAM_NoInit) ); Tiff_Im aTif = Tiff_Im::StdConvGen(aNameIm,-1,true); @@ -1175,20 +1177,52 @@ int TournIm_main(int argc,char ** argv) Pt2di aSz = aVIm[0]->sz(); std::cout << "SZ IN " << aSz << "\n"; - std::string aNameOut ="T90-"+ aNameIm; + Fonc_Num aFTrans = Virgule(FY,aSz.y-1-FX); + std::string aPref = "T90-"; + + if (aNumGeom==0) + { + aPref = "T0-"; + aFTrans = Virgule(FX,FY); + } + else if (aNumGeom==1) + { + aFTrans = Virgule(FY,aSz.y-1-FX); + } + else if (aNumGeom==2) + { + aPref = "T180-"; + aFTrans = Virgule(aSz.x-1-FX,aSz.y-1-FY); + } + else if (aNumGeom==3) + { + aPref = "T270-"; + aFTrans = Virgule(aSz.x-1-FY,FX); + } + else + { + ELISE_ASSERT(false,"Unhandled value for ²"); + } + + std::string aNameOut = DirOfFile(aNameIm) + aPref+ StdPrefix(NameWithoutDir(aNameIm))+".tif"; + L_Arg_Opt_Tiff aLarg; + aLarg = aLarg+ Arg_Tiff(Tiff_Im::ANoStrip()); Tiff_Im aTifOut ( aNameOut.c_str(), - Pt2di(aSz.y,aSz.x), + ((aNumGeom%2)==1) ? Pt2di(aSz.y,aSz.x) : Pt2di(aSz.x,aSz.y), aTif.type_el(), Tiff_Im::No_Compr, - aTif.phot_interp() + aTif.phot_interp(), + aLarg ); std::cout << "SZ OUT " << aTifOut.sz() << "\n"; Fonc_Num aF; int aKIm=0; - Fonc_Num aFTrans = Virgule(FY,aSz.y-1-FX); + + + // aFTrans = Virgule(FY,aSz.y-1-FX); for (auto aI : aVIm) { @@ -1197,6 +1231,7 @@ int TournIm_main(int argc,char ** argv) aF = (aKIm) ? Virgule(aF,aNewF) : aNewF; aKIm++; } +/* int aX0,aX1,aY0,aY1; ELISE_COPY( aTifOut.all_pts(), @@ -1204,6 +1239,7 @@ int TournIm_main(int argc,char ** argv) Virgule(VMin(aX0)|VMax(aX1),VMin(aY0)|VMax(aY1)) ); std::cout << "XXX " << aX0 << " " << aX1 << ";; Y " << aY0 << " " << aY1 << "\n"; +*/ ELISE_COPY(aTifOut.all_pts(),aF,aTifOut.out()); return EXIT_SUCCESS; diff --git a/src/uti_image/CPP_ScaleIm.cpp b/src/uti_image/CPP_ScaleIm.cpp index f35d2f9d39..2bcf7900f3 100644 --- a/src/uti_image/CPP_ScaleIm.cpp +++ b/src/uti_image/CPP_ScaleIm.cpp @@ -67,7 +67,8 @@ int ScaleIm_main(int argc,char ** argv) bool aForceGray = false; bool aForce8B = false; - bool aModeMasq=false; + bool aModeMasq = false; + bool Arg2IsWidth = false; ElInitArgMain @@ -90,6 +91,7 @@ int ScaleIm_main(int argc,char ** argv) << EAM(aForce8B,"F8B",true,"Force 8 bits (Def=false)") << EAM(aModeMasq,"ModMasq",true,"Mode Masq => binarize at 0.9999 threshlod ") << EAM(aNameDepl,"NameDepl",true,"Image of displacement ") + << EAM(Arg2IsWidth ,"Arg2IsW",true,"If 2nd Arg is Witdh") ); if (!MMVisualMode) { @@ -100,13 +102,15 @@ int ScaleIm_main(int argc,char ** argv) if (aDilXY.x<0) aDilXY = Pt2dr(aDilate,aDilate); - if (aScY==0) - aScY= aScX; - std::string aNameTif = NameFileStd(aNameIn,aForceGray ? 1 :-1,!aForce8B ,true,true); - Tiff_Im tiff = Tiff_Im::StdConvGen(aNameIn.c_str(),aForceGray ? 1 :-1,!aForce8B ,true); + if (Arg2IsWidth) + { + aScX = tiff.sz().x / double(aScX); + } + if (aScY==0) + aScY= aScX; aP0.SetSup(Pt2dr(0,0)); Pt2di aSzG = tiff.sz(); diff --git a/src/uti_phgrm/Apero/AFaire.txt b/src/uti_phgrm/Apero/AFaire.txt index 6744253789..2ddd1a31f0 100644 --- a/src/uti_phgrm/Apero/AFaire.txt +++ b/src/uti_phgrm/Apero/AFaire.txt @@ -1,4 +1,7 @@ + + +====================================================================== -1- Terminer l'optimisation par descente sur la ligne des moindres carres (traquer LAMBDA MIN pour voir le fichier). 99% du boulot est fait (= calcul du score f(Lambda)) , reste une minim par diff --git a/src/uti_phgrm/Apero/Apero.h b/src/uti_phgrm/Apero/Apero.h index 22641067d7..2902306d2e 100644 --- a/src/uti_phgrm/Apero/Apero.h +++ b/src/uti_phgrm/Apero/Apero.h @@ -414,6 +414,7 @@ class cGenPoseCam tGrApero::TSom * Som(); virtual Pt2di SzCalib() const = 0; protected : + virtual void UseRappelOnPose() const; cGenPoseCam(cAppliApero & anAppli,const std::string & aName); cAppliApero & mAppli; @@ -581,7 +582,7 @@ class cPoseCam : public cGenPoseCam ElRotation3D CurRot() const; Pt3dr CurCentre() const; Pt3dr CurCentreOfPt(const Pt2dr & ) const; - void SetCurRot(const ElRotation3D & aRot); + void PCSetCurRot(const ElRotation3D & aRot); void SetBascRig(const cSolBasculeRig & aSBR); @@ -638,6 +639,10 @@ class cPoseCam : public cGenPoseCam void SetPreCompBloc(cPreCompBloc *); cPreCB1Pose * GetPreCB1Pose(bool SVP) const; // SVP => can be 0 void SetPreCB1Pose(cPreCB1Pose *); + void UseRappelOnPose() const override; + int DifBlocInf1(const cPoseCam &) const; // Return "Many" if not initialized + void SetNumTimeBloc(int aNum); + private : void AssertHasObsCentre() const; @@ -727,7 +732,10 @@ class cPoseCam : public cGenPoseCam cEqOffsetGPS * mEqOffsetGPS; cStructRigidInit * mSRI; cPreCompBloc * mBlocCam; + int mNumTimeBloc; cPreCB1Pose * mPoseInBlocCam; + bool mUseRappelPose; // Do we use a "rappel" to a given value + ElRotation3D mRotURP; // Rotation use Rappel Pose }; @@ -1063,7 +1071,7 @@ class cOnePtsMult const Pt2dr& P0() const; const Pt2dr& PK(int ) const ; - void AddPt2PMul(int aNum,const Pt2dr & aP,bool IsFirstSet); + void AddPt2PMul(int aNum,const Pt2dr & aP,bool IsFirstSet,double aPds); cOnePtsMult(); const tFixedSetInt & Flag() const; void SetCombin(cOneCombinMult *); @@ -1332,7 +1340,7 @@ class cObsLiaisonMultiple bool packMustBeSwapped=false // file aNamePack contains the couples in inverse order (the first point belongs to aName2 and the second to aName1) ); - void AddCple(int anI1,int anI2,const ElCplePtsHomologues&,bool IsFirstSet); + void AddCple(int anI1,int anI2,const ElCplePtsHomologues&,bool IsFirstSet,double aPds); cAppliApero & mAppli; @@ -2318,6 +2326,7 @@ class cAppliApero : public NROptF1vND return CalcDebugEliminateNumTieP(aNum); } + const cRappelPose * PtrRP() const; private : @@ -2806,6 +2815,7 @@ class cAppliApero : public NROptF1vND bool mUseVDETp; std::vector mNumsVDETp; int mDebugNumPts; + const cRappelPose * mRappelPose; }; #define ADDALLMAJ(aMes) AddAllMajick(__LINE__,__FILE__,aMes) diff --git a/src/uti_phgrm/Apero/Basculement.cpp b/src/uti_phgrm/Apero/Basculement.cpp index 0f1d736c4f..0b98704832 100644 --- a/src/uti_phgrm/Apero/Basculement.cpp +++ b/src/uti_phgrm/Apero/Basculement.cpp @@ -890,7 +890,7 @@ cSolBasculeRig cAppliApero::BasculePoints ElCamera::ChangeSys(aVC,*aPtrBNL,FTR,!aBonC); if (FTR) { - aPC->SetCurRot(aCS->Orient().inv()); + aPC->PCSetCurRot(aCS->Orient().inv()); } else { @@ -901,7 +901,6 @@ cSolBasculeRig cAppliApero::BasculePoints /* */ } - // aPC->SetCurRot ( aSBR.TransformOriC2M(aPC->CurRot())); if (aPC->HasObsOnCentre() && ((!CalcV) || (aPC->HasObsOnVitesse()))) { @@ -1281,7 +1280,6 @@ void cAppliApero::BasculePlan // {RP2E * Rc}(Cam) = Plan // // std::cout << euclid(aPC->CurRot().tr()) << " " << aPC->CurRot().tr() << "\n"; - // aPC->SetCurRot(aRP2E.inv()*(aPC->CurRot())); // std::cout << "BASCULE PLAN DONE FOR " << aPC->Name() << "\n"; // std::cout << euclid(aPC->CurRot().tr()) << " " << aPC->CurRot().tr() << "\n\n"; aPC->SetBascRig(aSBR); @@ -1395,7 +1393,7 @@ void cAppliApero::FixeEchelle(const cFixeEchelle & aFE) if ( aPC->RotIsInit()) { ElRotation3D aR = aPC->CurRot(); - aPC->SetCurRot(ElRotation3D(aR.tr()*aMult,aR.Mat(),true)); + aPC->PCSetCurRot(ElRotation3D(aR.tr()*aMult,aR.Mat(),true)); } } @@ -1626,8 +1624,7 @@ void cAppliApero::FixeOrientPlane(const cFixeOrientPlane & aFOP) { // std::cout << aR.Mat() * (Pt3dr(0,0,1)) << "\n"; // std::cout << aPC->CurRot().Mat() * (Pt3dr(0,0,1)) << "\n"; - aPC->SetCurRot(aR*aPC->CurRot()); -// std::cout << aPC->CurRot().Mat() * (Pt3dr(0,0,1)) << "\n\n"; + aPC->PCSetCurRot(aR*aPC->CurRot()); } } } diff --git a/src/uti_phgrm/Apero/GraphePose.cpp b/src/uti_phgrm/Apero/GraphePose.cpp index 01204d0bdf..c5b12a35a6 100644 --- a/src/uti_phgrm/Apero/GraphePose.cpp +++ b/src/uti_phgrm/Apero/GraphePose.cpp @@ -76,6 +76,9 @@ void cAppliApero::ConstructMST const cPoseCameraInc & aPCI ) { +bool MST_DEBUG = false && MPD_MM(); + + if (mNbRotPreInit==0) { @@ -91,7 +94,7 @@ void cAppliApero::ConstructMST const cMEP_SPEC_MST & aMST = aPCI.MEP_SPEC_MST().Val(); - bool Show = aMST.Show().Val(); + bool Show = aMST.Show().Val() ; int aNbPtsMin = aMST.MinNbPtsInit().Val(); double anExpDist = aMST.ExpDist().Val(); double anExpNb = aMST.ExpNb().Val(); @@ -99,6 +102,11 @@ void cAppliApero::ConstructMST { std::cout << "MST " << aLNew.size() << "\n"; } + if (MST_DEBUG) + { + for (const auto & aN : aLNew ) + std::cout << " --- NNeew " << aN<< "\n"; + } bool OnInit = aMST.MontageOnInit().Val(); @@ -113,6 +121,10 @@ void cAppliApero::ConstructMST { if (mVecPose[aK]->PreInit()) { +if (MST_DEBUG) +{ + std::cout << "IIIIIII " << mVecPose[aK]->Name() << "\n"; +} ELISE_ASSERT ( !BoolFind(aLNew,mVecPose[aK]->Name()), @@ -140,10 +152,16 @@ void cAppliApero::ConstructMST UseBloc = true; PreInitBloc(aMST.MSTBlockRigid().Val()); } +if (MST_DEBUG) +{ + std::cout << "MM " << MPD_MM() << " BLoc=" << UseBloc << "\n"; + getchar(); +} // A chaque iteration on va affecter un sommet for (int aTimes=0 ; aTimes aVBestC; @@ -165,6 +183,11 @@ void cAppliApero::ConstructMST bool GotPMul; double aPds = anOLM->StdQualityZone(ZuUseInInit(),OnInit,aNbPtsMin,anExpDist,anExpNb,GotPMul); +if (MST_DEBUG&& (aTimes==0)) +{ + std::cout << "MSTPDs " << aPds << " " << aPcK->Name() << " " << anOLM->NbRotPreInit() << "\n"; +} + if (aPds> 0) { if (aPds>aPdsMax) @@ -177,6 +200,11 @@ void cAppliApero::ConstructMST } } } +if (MST_DEBUG && aBestCam) +{ + std::cout << "aBestCamwwww " << aBestCam->Name() << " Time " << aTimes << "\n"; + if (aTimes==0) getchar(); +} // On calcule les pere-mere if (aBestCam != 0) @@ -309,6 +337,7 @@ void cAppliApero::ConstructMST } +if (MST_DEBUG) { std::cout << "ENDDDDDDDD MST \n"; getchar(); } // aSInit.pushlast(anAppli.PoseFromName(*itI)->Som()); } diff --git a/src/uti_phgrm/Apero/NewPtsLiaison.cpp b/src/uti_phgrm/Apero/NewPtsLiaison.cpp index 81874b7454..fc7f380d5c 100644 --- a/src/uti_phgrm/Apero/NewPtsLiaison.cpp +++ b/src/uti_phgrm/Apero/NewPtsLiaison.cpp @@ -348,6 +348,8 @@ void cAppliApero::CDNP_Compense double aLimBsHRefut = Param().LimBsHRefut().Val(); cArg_UPL anArgUPL = ArgUPL(); + int aNAWNF = Param().NumAttrPdsNewF().Val(); + for (int aKp=0 ; aKp=0) + { + aPdsIm = aConf->Attr(aKp,aNAWNF); + } + double aResidu = 0; int aNbEtape = 2; diff --git a/src/uti_phgrm/Apero/PowelOptimize.cpp b/src/uti_phgrm/Apero/PowelOptimize.cpp index f47b690078..ce5b1a02b1 100644 --- a/src/uti_phgrm/Apero/PowelOptimize.cpp +++ b/src/uti_phgrm/Apero/PowelOptimize.cpp @@ -346,7 +346,7 @@ std::cout << "\n"; void cOneRotPowelOptimize::AvantEval(const double * aP) { - mCam->SetCurRot(Param2Rot(aP)); + mCam->PCSetCurRot(Param2Rot(aP)); } double cOneRotPowelOptimize::ResiduLiaison() diff --git a/src/uti_phgrm/Apero/cAA_Compensation.cpp b/src/uti_phgrm/Apero/cAA_Compensation.cpp index 3b03b9c51e..bded975c19 100644 --- a/src/uti_phgrm/Apero/cAA_Compensation.cpp +++ b/src/uti_phgrm/Apero/cAA_Compensation.cpp @@ -162,6 +162,12 @@ for (int aK=0 ; aKUseRappelOnPose(); + } + } { AddObservationsContrCamGenInc(anSO.ContrCamGenInc(),IsLastIter,aSO); @@ -524,6 +530,112 @@ const std::string & TheNameFileTxtConvName() static std::string TMC="Sensib-ConvName.txt"; return TMC; } + +const std::string & TheNameFileXmlConvNameIm() +{ + static std::string TMC="Sensib-ConvName-Im.xml"; + return TMC; +} + +std::map LecSensibName(const std::string & aNameFile,const std::string & aPref) +{ + std::map aRes; + ELISE_fp aFile(aNameFile.c_str(),ELISE_fp::READ); + + std::string aPat = std::string(" (") + aPref + ".*) => (.*)"; + cElRegex anAutom(aPat,10); + bool endof=false; + std::string aLine; + + while (!endof) + { + if (aFile.fgets(aLine,endof)) + { + if (anAutom.Match(aLine)) + { + std::string anId = anAutom.KIemeExprPar(1); + std::string aVal = anAutom.KIemeExprPar(2); + aRes[anId] = aVal; + } + } + } + return aRes; +} + +std::map > + LecSensibDicIm(const std::string & aNameConv,const std::string & aNameXml) +{ + std::map > aRes; + + std::map aConv = LecSensibName ( aNameConv,"Ima"); + cXmlNameSensibs aXmlSN = StdGetFromAp(aNameXml,XmlNameSensibs); + + for (const auto & aS1I : aXmlSN.SensibDateOneInc()) + { + auto anIter = aConv.find(aS1I.NameBloc()); + if (anIter != aConv.end()) + { + aRes[anIter->second].push_back(aS1I); + } + } + + return aRes; +} + +const cSensibDateOneInc * GetSensib(const std::vector & aVec,const std::string & anId,bool SVP=false) +{ + auto anIter = std::find_if + ( + aVec.begin(), + aVec.end(), + [anId](const cSensibDateOneInc & aS1) {return aS1.NameInc() == anId;} + ); + if (anIter == aVec.end()) + { + ELISE_ASSERT(SVP,"Cannot find in GetSensib"); + return nullptr; + } + + return &(*anIter); +} + + +std::map> GetSCenterOPK(const std::string & aNameConv,const std::string & aNameXml) +{ + std::map > aRes; + + for (const auto & aVec : LecSensibDicIm(aNameConv,aNameXml)) + { + Pt3dr aSCenter + ( + GetSensib(aVec.second,"Cx")->SensibParamInv(), + GetSensib(aVec.second,"Cy")->SensibParamInv(), + GetSensib(aVec.second,"Cz")->SensibParamInv() + ); + Pt3dr aSOPK + ( + GetSensib(aVec.second,"T12")->SensibParamInv(), + GetSensib(aVec.second,"T02")->SensibParamInv(), + GetSensib(aVec.second,"T01")->SensibParamInv() + ); + if (0) + { + std::cout << "SSSss " << aVec.first << aSCenter << aSOPK << "\n"; + } + aRes[aVec.first] = std::pair(aSCenter,aSOPK); + } + + return aRes; +} +std::map> StdGetSCenterOPK(const std::string & aDir) +{ + return GetSCenterOPK(aDir+"/Sensib-ConvName.txt",aDir+"/Sensib-Data.dmp"); +} + + + + + std::string TheNameFileExpSens(bool Bin) { return "Sensib-Data" + std::string(Bin ? ".dmp" : ".xml"); @@ -664,6 +776,7 @@ std::cout << "DONNNNE AOAF : NonO ============================================== std::string aNameConv = aPrefESPA + TheNameFileTxtConvName(); ofstream aStdConvTxt (aNameConv.c_str()); + cSauvegardeNamedRel aRelIm; if (! aStdConvTxt.is_open()) { std::cout << "FILE=" << aNameConv << "\n"; @@ -683,6 +796,7 @@ std::cout << "DONNNNE AOAF : NonO ============================================== for (int aK=0 ; aK " << mNamesIdIm[aK] << "\n"; + aRelIm.Cple().push_back(cCpleString(IdOfIma(aK), mNamesIdIm[aK])); } Im2D_REAL4 aMCov(aNbV,aNbV); @@ -720,6 +834,7 @@ std::cout << "DONNNNE AOAF : NonO ============================================== //fclose(aFConvTxt); aStdConvTxt.close(); + MakeFileXML(aRelIm,aPrefESPA+ TheNameFileXmlConvNameIm()); } bool ExportMMF = mParam.SectionChantier().ExportMatrixMarket().Val() ; diff --git a/src/uti_phgrm/Apero/cAppliApero.cpp b/src/uti_phgrm/Apero/cAppliApero.cpp index 82f9948727..8a0f457922 100644 --- a/src/uti_phgrm/Apero/cAppliApero.cpp +++ b/src/uti_phgrm/Apero/cAppliApero.cpp @@ -103,7 +103,8 @@ cAppliApero::cAppliApero (cResultSubstAndStdGetFile aParam) : mNumCalib (0), mNumImage (0), mLevStaB (mParam.SectionChantier().DoStatElimBundle().ValWithDef(0)), - mUseVDETp (false) + mUseVDETp (false), + mRappelPose (mParam.SectionChantier().RappelPose().PtrVal()) // mGlobManiP3TI (0) { @@ -1162,6 +1163,9 @@ bool cAppliApero::ExportTiePEliminated() const return (mLevStaB>=3) && IsLastEtapeOfLastIter(); } +const cRappelPose * cAppliApero::PtrRP() const {return mRappelPose;} + + /* int LevStaB() const; bool MemoSingleTieP() const; diff --git a/src/uti_phgrm/Apero/cCameraRPC.cpp b/src/uti_phgrm/Apero/cCameraRPC.cpp index 62ea29b53f..53e8296e5c 100644 --- a/src/uti_phgrm/Apero/cCameraRPC.cpp +++ b/src/uti_phgrm/Apero/cCameraRPC.cpp @@ -4292,6 +4292,30 @@ bool CalcCentreOptiqueGrille(const OrientationGrille & aOri, Pt3dr & aCentre) } +int SatPosition_main(int argc,char ** argv) +{ + std::string aGRIName; + + ElInitArgMain + ( + argc, argv, + LArgMain() << EAMC(aGRIName,"Grid"), + LArgMain() + ); + + OrientationGrille aGRI(aGRIName); + + Pt3dr aCentre; + if (! CalcCentreOptiqueGrille(aGRI,aCentre)) + return EXIT_FAILURE; + + std::cout << aCentre.x << " " << aCentre.y << " " << aCentre.z << "\n"; + + return EXIT_SUCCESS; + +} + + int CalcBsurHGrille_main(int argc,char ** argv) { std::string aGRIName1,aGRIName2; @@ -4325,6 +4349,7 @@ int CalcBsurHGrille_main(int argc,char ** argv) std::cout << "B=" << aB << ", H=" << aCentre1.z << ", B/H=" << aB/aCentre1.z << "\n"; + return(1); @@ -4860,33 +4885,33 @@ void cRPCVerf::Compare3D(std::vector &aGrid3d) const /*Footer-MicMac-eLiSe-25/06/2007 -Ce logiciel est un programme informatique servant à la mise en +Ce logiciel est un programme informatique servant a la mise en correspondances d'images pour la reconstruction du relief. -Ce logiciel est régi par la licence CeCILL-B soumise au droit français et +Ce logiciel est regi par la licence CeCILL-B soumise au droit francais et respectant les principes de diffusion des logiciels libres. Vous pouvez utiliser, modifier et/ou redistribuer ce programme sous les conditions -de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA +de la licence CeCILL-B telle que diffusee par le CEA, le CNRS et l'INRIA sur le site "http://www.cecill.info". -En contrepartie de l'accessibilité au code source et des droits de copie, -de modification et de redistribution accordés par cette licence, il n'est -offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, -seule une responsabilité restreinte pèse sur l'auteur du programme, le -titulaire des droits patrimoniaux et les concédants successifs. - -A cet égard l'attention de l'utilisateur est attirée sur les risques -associés au chargement, à l'utilisation, à la modification et/ou au -développement et à la reproduction du logiciel par l'utilisateur étant -donné sa spécificité de logiciel libre, qui peut le rendre complexe à -manipuler et qui le réserve donc à des développeurs et des professionnels -avertis possédant des connaissances informatiques approfondies. Les -utilisateurs sont donc invités à charger et tester l'adéquation du -logiciel à leurs besoins dans des conditions permettant d'assurer la -sécurité de leurs systèmes et ou de leurs données et, plus généralement, -à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. - -Le fait que vous puissiez accéder à cet en-tête signifie que vous avez -pris connaissance de la licence CeCILL-B, et que vous en avez accepté les +En contrepartie de l'accessibilite au code source et des droits de copie, +de modification et de redistribution accordes par cette licence, il n'est +offert aux utilisateurs qu'une garantie limitee. Pour les memes raisons, +seule une responsabilite restreinte pese sur l'auteur du programme, le +titulaire des droits patrimoniaux et les concedants successifs. + +A cet egard l'attention de l'utilisateur est attiree sur les risques +associes au chargement, a l'utilisation, a la modification et/ou au +developpement et a la reproduction du logiciel par l'utilisateur etant +donne sa specificite de logiciel libre, qui peut le rendre complexe a +manipuler et qui le reserve donc a des developpeurs et des professionnels +avertis possedant des connaissances informatiques approfondies. Les +utilisateurs sont donc invites a charger et tester l'adequation du +logiciel a leurs besoins dans des conditions permettant d'assurer la +securite de leurs systemes et ou de leurs donnees et, plus generalement, +a l'utiliser et l'exploiter dans les memes conditions de securite. + +Le fait que vous puissiez acceder a cet en-tete signifie que vous avez +pris connaissance de la licence CeCILL-B, et que vous en avez accepte les termes. Footer-MicMac-eLiSe-25/06/2007*/ diff --git a/src/uti_phgrm/Apero/cImplemBlockCam.cpp b/src/uti_phgrm/Apero/cImplemBlockCam.cpp index 0b95169d32..7662bbb53a 100644 --- a/src/uti_phgrm/Apero/cImplemBlockCam.cpp +++ b/src/uti_phgrm/Apero/cImplemBlockCam.cpp @@ -41,6 +41,33 @@ Header-MicMac-eLiSe-25/06/2007*/ // ModifDIST ==> Tag Provisoire des modifs a rajouter si dist +// Return the cParamOrientSHC of a given name +cParamOrientSHC * POriFromBloc(cStructBlockCam & aBloc,const std::string & aName,bool SVP) +{ + for ( auto & aPOS : aBloc.ParamOrientSHC()) + { + if (aPOS.IdGrp() == aName) + return & aPOS; + } + if (!SVP) + { + ELISE_ASSERT(false ,"Cannot get POriFromBloc"); + } + return nullptr; +} + +// Return the Rotation that transformate from Cam Coord to Block coordinates (in fact coord of "first" cam) +ElRotation3D RotCamToBlock(const cParamOrientSHC & aPOS) +{ + return ElRotation3D(aPOS.Vecteur(),ImportMat(aPOS.Rot()),true); +} + +// Return the Rotation that transformate from Cam1 Coord to Cam2 Coord +ElRotation3D RotCam1ToCam2(const cParamOrientSHC & aPOS1,const cParamOrientSHC & aPOS2) +{ + return RotCamToBlock(aPOS2).inv() * RotCamToBlock(aPOS1); +} + /****************************************************************************/ /* */ /* Rigid Block, distance equation */ @@ -475,12 +502,14 @@ class cIBC_ImsOneTime cIBC_ImsOneTime(int aNbCam,const std::string& aNameTime) ; void AddPose(cPoseCam *, int aNum); cPoseCam * Pose(int aKP); + void SetNum(int aNum); const std::string & NameTime() const {return mNameTime;} private : - std::vector mCams; + std::vector mVCams; std::string mNameTime; + int mNums; }; @@ -587,27 +616,36 @@ static cCmp_IOT_Ptr TheIOTCmp; cIBC_ImsOneTime::cIBC_ImsOneTime(int aNb,const std::string & aNameTime) : - mCams (aNb), + mVCams (aNb), mNameTime (aNameTime) { } +void cIBC_ImsOneTime::SetNum(int aNum) +{ + for (auto & aPCam : mVCams) + { + if (aPCam) + aPCam->SetNumTimeBloc(aNum); + } +} + void cIBC_ImsOneTime::AddPose(cPoseCam * aPC, int aNum) { - cPoseCam * aPC0 = mCams.at(aNum); + cPoseCam * aPC0 = mVCams.at(aNum); if (aPC0 != 0) { std::cout << "For cameras " << aPC->Name() << " and " << aPC0->Name() << "\n"; ELISE_ASSERT(false,"Conflicting name from KeyIm2TimeCam "); } - mCams[aNum] = aPC; + mVCams[aNum] = aPC; } cPoseCam * cIBC_ImsOneTime::Pose(int aKP) { - return mCams.at(aKP); + return mVCams.at(aKP); } // ================================= // cIBC_OneCam @@ -756,19 +794,26 @@ cImplemBlockCam::cImplemBlockCam mGlobDistTB (false) { const std::vector & aVP = mAppli.VecAllPose(); + std::string aMasterGrp = aSBC.MasterGrp().ValWithDef(""); // On initialise les camera - for (int aKP=0 ; aKPName(); - std::pair aPair = mAppli.ICNM()->Assoc2To1(mSBC.KeyIm2TimeCam(),aNamePose,true); - std::string aNameCam = aPair.second; - if (! DicBoolFind(mName2Cam,aNameCam)) // si aNameCam se trouve dans mName2Cam + + for (int aKP=0 ; aKPName(); + std::pair aPair = mAppli.ICNM()->Assoc2To1(mSBC.KeyIm2TimeCam(),aNamePose,true); + std::string aNameCam = aPair.second; + // At first iter, we do it if master, at second if not master + bool Doit = (anIter==0) == (aNameCam==aMasterGrp); + if (Doit && (! DicBoolFind(mName2Cam,aNameCam))) // si aNameCam se trouve dans mName2Cam + { + cIBC_OneCam * aCam = new cIBC_OneCam(aNameCam, (int)mNum2Cam.size()); // (name & index dans mNum2Cam) + mName2Cam[aNameCam] = aCam; + mNum2Cam.push_back(aCam); + } } } mNbCam = (int)mNum2Cam.size(); @@ -811,6 +856,8 @@ cImplemBlockCam::cImplemBlockCam } mNbTime = (int)mNum2ITime.size(); std::sort(mNum2ITime.begin(),mNum2ITime.end(),TheIOTCmp); // sort by time stamp + for (int aK=0 ; aKSetNum(aK); // ## diff --git a/src/uti_phgrm/Apero/cPackMultipleLiaison.cpp b/src/uti_phgrm/Apero/cPackMultipleLiaison.cpp index dadc342b93..5a98ca697e 100644 --- a/src/uti_phgrm/Apero/cPackMultipleLiaison.cpp +++ b/src/uti_phgrm/Apero/cPackMultipleLiaison.cpp @@ -365,7 +365,7 @@ const Pt2dr& cOnePtsMult::PK(int aK ) const } -void cOnePtsMult::AddPt2PMul(int aNum,const Pt2dr & aP,bool IsFirstSet) +void cOnePtsMult::AddPt2PMul(int aNum,const Pt2dr & aP,bool IsFirstSet,double aNewPds) { if (mFlagI.IsIn(aNum)) { @@ -381,8 +381,22 @@ void cOnePtsMult::AddPt2PMul(int aNum,const Pt2dr & aP,bool IsFirstSet) #endif } mFlagI.Add(aNum); - mNPts.AddPts(aP); + + int aNbPts = mNPts.NbPts(); + // Update the weithgint of mNPts so that is is the average of weigth of pairs + if (aNbPts==0) + { + // First case is speciall, weight should not be re-used + mNPts.Pds() = aNewPds; + } + else + { + double aSomPds = mNPts.Pds() * (aNbPts-1) + aNewPds; // Transform avergae in som + mNPts.Pds() = aSomPds / aNbPts; // Back an average + } + + mNPts.AddPts(aP); } const tFixedSetInt & cOnePtsMult::Flag() const @@ -810,7 +824,7 @@ void cObsLiaisonMultiple::AddPack if (aC1->AcceptPoint(itP->P1()) && aC2->AcceptPoint(itP->P2())) { - aNewPack.Cple_Add(ElCplePtsHomologues(itP->P1(),itP->P2())); + aNewPack.Cple_Add(ElCplePtsHomologues(itP->P1(),itP->P2(),itP->Pds())); } } aPack = aNewPack; @@ -823,12 +837,13 @@ void cObsLiaisonMultiple::AddPack for (ElPackHomologue::const_iterator itP=aPack.begin();itP!=aPack.end();itP++) { - AddCple(anInd1,anInd2,itP->ToCple(),IsFirstSet); +/// std::cout << "PppPpppp " << itP->Pds() << "\n"; + AddCple(anInd1,anInd2,itP->ToCple(),IsFirstSet,itP->Pds()); } } -void cObsLiaisonMultiple::AddCple(int aK1,int aK2,const ElCplePtsHomologues& aCpl,bool IsFirstSet) +void cObsLiaisonMultiple::AddCple(int aK1,int aK2,const ElCplePtsHomologues& aCpl,bool IsFirstSet,double aPds) { std::list aLPM = mIndPMul->KPPVois @@ -846,7 +861,8 @@ void cObsLiaisonMultiple::AddCple(int aK1,int aK2,const ElCplePtsHomologues& aCp if (aLPM.empty()) { aPM = new cOnePtsMult; - aPM->AddPt2PMul(aK1,aCpl.P1(),IsFirstSet); + // Weitght doent matter for creation + aPM->AddPt2PMul(aK1,aCpl.P1(),IsFirstSet,aPds); mVPMul.push_back(aPM); if (! mBox.Include(aCpl.P1())) { @@ -861,7 +877,7 @@ void cObsLiaisonMultiple::AddCple(int aK1,int aK2,const ElCplePtsHomologues& aCp { aPM = *(aLPM.begin()); } - aPM->AddPt2PMul(aK2,aCpl.P2(),IsFirstSet); + aPM->AddPt2PMul(aK2,aCpl.P2(),IsFirstSet,aPds); if (mAppli.MemoSingleTieP()) // TestSTP { @@ -1324,9 +1340,10 @@ double cObsLiaisonMultiple::AddObsLM const std::vector & aVP = aCOM->GenVP(); std::vector aVpds; - double aPds = aNupl.Pds() * mMultPds; + double aPdsGlob = aNupl.Pds() * mMultPds; + int NbRRI; - int aNbRInit= aPM->InitPdsPMul(aPds,aVpds,&NbRRI); + int aNbRInit= aPM->InitPdsPMul(aPdsGlob,aVpds,&NbRRI); if (aNbRInit>=2) { aNbNN++; @@ -1552,7 +1569,7 @@ for (int aK=0 ; aKLiaisTer()->SetTerrainInit(true); diff --git a/src/uti_phgrm/Apero/cParamApero.cpp b/src/uti_phgrm/Apero/cParamApero.cpp index 1e96a8f723..9876c7137f 100644 --- a/src/uti_phgrm/Apero/cParamApero.cpp +++ b/src/uti_phgrm/Apero/cParamApero.cpp @@ -10593,6 +10593,95 @@ void xml_init(cSectionInconnues & anObj,cElXMLTree * aTree) std::string Mangling( cSectionInconnues *) {return "4CECE2192C59959DFE3F";}; +std::string & cRappelPose::IdOrient() +{ + return mIdOrient; +} + +const std::string & cRappelPose::IdOrient()const +{ + return mIdOrient; +} + + +double & cRappelPose::SigmaC() +{ + return mSigmaC; +} + +const double & cRappelPose::SigmaC()const +{ + return mSigmaC; +} + + +double & cRappelPose::SigmaR() +{ + return mSigmaR; +} + +const double & cRappelPose::SigmaR()const +{ + return mSigmaR; +} + + +cElRegex_Ptr & cRappelPose::PatternApply() +{ + return mPatternApply; +} + +const cElRegex_Ptr & cRappelPose::PatternApply()const +{ + return mPatternApply; +} + +void BinaryUnDumpFromFile(cRappelPose & anObj,ELISE_fp & aFp) +{ + BinaryUnDumpFromFile(anObj.IdOrient(),aFp); + BinaryUnDumpFromFile(anObj.SigmaC(),aFp); + BinaryUnDumpFromFile(anObj.SigmaR(),aFp); + BinaryUnDumpFromFile(anObj.PatternApply(),aFp); +} + +void BinaryDumpInFile(ELISE_fp & aFp,const cRappelPose & anObj) +{ + BinaryDumpInFile(aFp,anObj.IdOrient()); + BinaryDumpInFile(aFp,anObj.SigmaC()); + BinaryDumpInFile(aFp,anObj.SigmaR()); + BinaryDumpInFile(aFp,anObj.PatternApply()); +} + +cElXMLTree * ToXMLTree(const cRappelPose & anObj) +{ + XMLPushContext(anObj.mGXml); + cElXMLTree * aRes = new cElXMLTree((cElXMLTree *)0,"RappelPose",eXMLBranche); + aRes->AddFils(::ToXMLTree(std::string("IdOrient"),anObj.IdOrient())->ReTagThis("IdOrient")); + aRes->AddFils(::ToXMLTree(std::string("SigmaC"),anObj.SigmaC())->ReTagThis("SigmaC")); + aRes->AddFils(::ToXMLTree(std::string("SigmaR"),anObj.SigmaR())->ReTagThis("SigmaR")); + aRes->AddFils(::ToXMLTree(std::string("PatternApply"),anObj.PatternApply())->ReTagThis("PatternApply")); + aRes->mGXml = anObj.mGXml; + XMLPopContext(anObj.mGXml); + return aRes; +} + +void xml_init(cRappelPose & anObj,cElXMLTree * aTree) +{ + if (aTree==0) return; + anObj.mGXml = aTree->mGXml; + + xml_init(anObj.IdOrient(),aTree->Get("IdOrient",1)); //tototo + + xml_init(anObj.SigmaC(),aTree->Get("SigmaC",1)); //tototo + + xml_init(anObj.SigmaR(),aTree->Get("SigmaR",1)); //tototo + + xml_init(anObj.PatternApply(),aTree->Get("PatternApply",1)); //tototo +} + +std::string Mangling( cRappelPose *) {return "B7342D8BF89C60F2FE3F";}; + + cTplValGesInit< double > & cUseExportImageResidu::SzByPair() { return mSzByPair; @@ -10825,6 +10914,72 @@ void xml_init(cTimeLinkage & anObj,cElXMLTree * aTree) std::string Mangling( cTimeLinkage *) {return "BEB337D7A41F8CD1FD3F";}; +std::string & cSectionChantier::IdOrient() +{ + return RappelPose().Val().IdOrient(); +} + +const std::string & cSectionChantier::IdOrient()const +{ + return RappelPose().Val().IdOrient(); +} + + +double & cSectionChantier::SigmaC() +{ + return RappelPose().Val().SigmaC(); +} + +const double & cSectionChantier::SigmaC()const +{ + return RappelPose().Val().SigmaC(); +} + + +double & cSectionChantier::SigmaR() +{ + return RappelPose().Val().SigmaR(); +} + +const double & cSectionChantier::SigmaR()const +{ + return RappelPose().Val().SigmaR(); +} + + +cElRegex_Ptr & cSectionChantier::PatternApply() +{ + return RappelPose().Val().PatternApply(); +} + +const cElRegex_Ptr & cSectionChantier::PatternApply()const +{ + return RappelPose().Val().PatternApply(); +} + + +cTplValGesInit< cRappelPose > & cSectionChantier::RappelPose() +{ + return mRappelPose; +} + +const cTplValGesInit< cRappelPose > & cSectionChantier::RappelPose()const +{ + return mRappelPose; +} + + +cTplValGesInit< int > & cSectionChantier::NumAttrPdsNewF() +{ + return mNumAttrPdsNewF; +} + +const cTplValGesInit< int > & cSectionChantier::NumAttrPdsNewF()const +{ + return mNumAttrPdsNewF; +} + + cTplValGesInit< double > & cSectionChantier::RatioMaxDistCS() { return mRatioMaxDistCS; @@ -11212,6 +11367,22 @@ const cTplValGesInit< bool > & cSectionChantier::ExportMatrixMarket()const void BinaryUnDumpFromFile(cSectionChantier & anObj,ELISE_fp & aFp) { { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.RappelPose().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.RappelPose().ValForcedForUnUmp(),aFp); + } + else anObj.RappelPose().SetNoInit(); + } ; + { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.NumAttrPdsNewF().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.NumAttrPdsNewF().ValForcedForUnUmp(),aFp); + } + else anObj.NumAttrPdsNewF().SetNoInit(); + } ; + { bool IsInit; BinaryUnDumpFromFile(IsInit,aFp); if (IsInit) { anObj.RatioMaxDistCS().SetInitForUnUmp(); @@ -11431,6 +11602,10 @@ void BinaryUnDumpFromFile(cSectionChantier & anObj,ELISE_fp & aFp) void BinaryDumpInFile(ELISE_fp & aFp,const cSectionChantier & anObj) { + BinaryDumpInFile(aFp,anObj.RappelPose().IsInit()); + if (anObj.RappelPose().IsInit()) BinaryDumpInFile(aFp,anObj.RappelPose().Val()); + BinaryDumpInFile(aFp,anObj.NumAttrPdsNewF().IsInit()); + if (anObj.NumAttrPdsNewF().IsInit()) BinaryDumpInFile(aFp,anObj.NumAttrPdsNewF().Val()); BinaryDumpInFile(aFp,anObj.RatioMaxDistCS().IsInit()); if (anObj.RatioMaxDistCS().IsInit()) BinaryDumpInFile(aFp,anObj.RatioMaxDistCS().Val()); BinaryDumpInFile(aFp,anObj.DebugVecElimTieP().IsInit()); @@ -11491,6 +11666,10 @@ cElXMLTree * ToXMLTree(const cSectionChantier & anObj) { XMLPushContext(anObj.mGXml); cElXMLTree * aRes = new cElXMLTree((cElXMLTree *)0,"SectionChantier",eXMLBranche); + if (anObj.RappelPose().IsInit()) + aRes->AddFils(ToXMLTree(anObj.RappelPose().Val())->ReTagThis("RappelPose")); + if (anObj.NumAttrPdsNewF().IsInit()) + aRes->AddFils(::ToXMLTree(std::string("NumAttrPdsNewF"),anObj.NumAttrPdsNewF().Val())->ReTagThis("NumAttrPdsNewF")); if (anObj.RatioMaxDistCS().IsInit()) aRes->AddFils(::ToXMLTree(std::string("RatioMaxDistCS"),anObj.RatioMaxDistCS().Val())->ReTagThis("RatioMaxDistCS")); if (anObj.DebugVecElimTieP().IsInit()) @@ -11555,6 +11734,10 @@ void xml_init(cSectionChantier & anObj,cElXMLTree * aTree) if (aTree==0) return; anObj.mGXml = aTree->mGXml; + xml_init(anObj.RappelPose(),aTree->Get("RappelPose",1)); //tototo + + xml_init(anObj.NumAttrPdsNewF(),aTree->Get("NumAttrPdsNewF",1),int(-1)); //tototo + xml_init(anObj.RatioMaxDistCS(),aTree->Get("RatioMaxDistCS",1),double(30.0)); //tototo xml_init(anObj.DebugVecElimTieP(),aTree->Get("DebugVecElimTieP",1)); //tototo @@ -11610,7 +11793,7 @@ void xml_init(cSectionChantier & anObj,cElXMLTree * aTree) xml_init(anObj.ExportMatrixMarket(),aTree->Get("ExportMatrixMarket",1),bool(false)); //tototo } -std::string Mangling( cSectionChantier *) {return "64F2B4F850271D90FCBF";}; +std::string Mangling( cSectionChantier *) {return "4CE89E5872B0B5CFFC3F";}; cTplValGesInit< bool > & cSectionSolveur::AllMatSym() @@ -26461,6 +26644,72 @@ const cSectionInconnues & cParamApero::SectionInconnues()const } +std::string & cParamApero::IdOrient() +{ + return SectionChantier().RappelPose().Val().IdOrient(); +} + +const std::string & cParamApero::IdOrient()const +{ + return SectionChantier().RappelPose().Val().IdOrient(); +} + + +double & cParamApero::SigmaC() +{ + return SectionChantier().RappelPose().Val().SigmaC(); +} + +const double & cParamApero::SigmaC()const +{ + return SectionChantier().RappelPose().Val().SigmaC(); +} + + +double & cParamApero::SigmaR() +{ + return SectionChantier().RappelPose().Val().SigmaR(); +} + +const double & cParamApero::SigmaR()const +{ + return SectionChantier().RappelPose().Val().SigmaR(); +} + + +cElRegex_Ptr & cParamApero::PatternApply() +{ + return SectionChantier().RappelPose().Val().PatternApply(); +} + +const cElRegex_Ptr & cParamApero::PatternApply()const +{ + return SectionChantier().RappelPose().Val().PatternApply(); +} + + +cTplValGesInit< cRappelPose > & cParamApero::RappelPose() +{ + return SectionChantier().RappelPose(); +} + +const cTplValGesInit< cRappelPose > & cParamApero::RappelPose()const +{ + return SectionChantier().RappelPose(); +} + + +cTplValGesInit< int > & cParamApero::NumAttrPdsNewF() +{ + return SectionChantier().NumAttrPdsNewF(); +} + +const cTplValGesInit< int > & cParamApero::NumAttrPdsNewF()const +{ + return SectionChantier().NumAttrPdsNewF(); +} + + cTplValGesInit< double > & cParamApero::RatioMaxDistCS() { return SectionChantier().RatioMaxDistCS(); @@ -27238,7 +27487,7 @@ void xml_init(cParamApero & anObj,cElXMLTree * aTree) xml_init(anObj.SectionCompensation(),aTree->Get("SectionCompensation",1)); //tototo } -std::string Mangling( cParamApero *) {return "769625359E0142E3FE3F";}; +std::string Mangling( cParamApero *) {return "E5FC97C9FD44E1D0FE3F";}; std::string & cXmlSauvExportAperoOneIm::Name() diff --git a/src/uti_phgrm/Apero/cParamApero.h b/src/uti_phgrm/Apero/cParamApero.h index 65cfcafc54..47e2c4d447 100644 --- a/src/uti_phgrm/Apero/cParamApero.h +++ b/src/uti_phgrm/Apero/cParamApero.h @@ -3020,6 +3020,39 @@ std::string Mangling( cSectionInconnues *); /******************************************************/ /******************************************************/ /******************************************************/ +class cRappelPose +{ + public: + cGlobXmlGen mGXml; + + friend void xml_init(cRappelPose & anObj,cElXMLTree * aTree); + + + std::string & IdOrient(); + const std::string & IdOrient()const ; + + double & SigmaC(); + const double & SigmaC()const ; + + double & SigmaR(); + const double & SigmaR()const ; + + cElRegex_Ptr & PatternApply(); + const cElRegex_Ptr & PatternApply()const ; + private: + std::string mIdOrient; + double mSigmaC; + double mSigmaR; + cElRegex_Ptr mPatternApply; +}; +cElXMLTree * ToXMLTree(const cRappelPose &); + +void BinaryDumpInFile(ELISE_fp &,const cRappelPose &); + +void BinaryUnDumpFromFile(cRappelPose &,ELISE_fp &); + +std::string Mangling( cRappelPose *); + class cUseExportImageResidu { public: @@ -3094,6 +3127,24 @@ class cSectionChantier friend void xml_init(cSectionChantier & anObj,cElXMLTree * aTree); + std::string & IdOrient(); + const std::string & IdOrient()const ; + + double & SigmaC(); + const double & SigmaC()const ; + + double & SigmaR(); + const double & SigmaR()const ; + + cElRegex_Ptr & PatternApply(); + const cElRegex_Ptr & PatternApply()const ; + + cTplValGesInit< cRappelPose > & RappelPose(); + const cTplValGesInit< cRappelPose > & RappelPose()const ; + + cTplValGesInit< int > & NumAttrPdsNewF(); + const cTplValGesInit< int > & NumAttrPdsNewF()const ; + cTplValGesInit< double > & RatioMaxDistCS(); const cTplValGesInit< double > & RatioMaxDistCS()const ; @@ -3199,6 +3250,8 @@ class cSectionChantier cTplValGesInit< bool > & ExportMatrixMarket(); const cTplValGesInit< bool > & ExportMatrixMarket()const ; private: + cTplValGesInit< cRappelPose > mRappelPose; + cTplValGesInit< int > mNumAttrPdsNewF; cTplValGesInit< double > mRatioMaxDistCS; cTplValGesInit< std::string > mDebugVecElimTieP; cTplValGesInit< int > mDoStatElimBundle; @@ -7118,6 +7171,24 @@ class cParamApero cSectionInconnues & SectionInconnues(); const cSectionInconnues & SectionInconnues()const ; + std::string & IdOrient(); + const std::string & IdOrient()const ; + + double & SigmaC(); + const double & SigmaC()const ; + + double & SigmaR(); + const double & SigmaR()const ; + + cElRegex_Ptr & PatternApply(); + const cElRegex_Ptr & PatternApply()const ; + + cTplValGesInit< cRappelPose > & RappelPose(); + const cTplValGesInit< cRappelPose > & RappelPose()const ; + + cTplValGesInit< int > & NumAttrPdsNewF(); + const cTplValGesInit< int > & NumAttrPdsNewF()const ; + cTplValGesInit< double > & RatioMaxDistCS(); const cTplValGesInit< double > & RatioMaxDistCS()const ; diff --git a/src/uti_phgrm/Apero/cPose.cpp b/src/uti_phgrm/Apero/cPose.cpp index 075c0ebb1e..132035dd24 100644 --- a/src/uti_phgrm/Apero/cPose.cpp +++ b/src/uti_phgrm/Apero/cPose.cpp @@ -43,7 +43,7 @@ Header-MicMac-eLiSe-25/06/2007*/ -#include "Apero.h" +#include "cPose.h" /* ========== cStructRigidInit ============*/ @@ -56,20 +56,13 @@ cStructRigidInit::cStructRigidInit(cPoseCam * RigidMere,const ElRotation3D & aR) static const int NbMinCreateIm = 200; -class cPtAVGR; -class cAperoVisuGlobRes; +//class cPtAVGR; +//class cAperoVisuGlobRes; + +/***************** classes moved to cPose.h *******************/ /*=========== cPtAVGR ===========*/ -class cPtAVGR -{ - public : - cPtAVGR (const Pt3dr & aP,double aRes); - Pt3df mPt; - float mRes; - float mResFiltr; - bool mInQt; -}; cPtAVGR::cPtAVGR(const Pt3dr & aP,double aRes) : @@ -78,15 +71,15 @@ cPtAVGR::cPtAVGR(const Pt3dr & aP,double aRes) : { } -class cFoncPtOfPtAVGR +/*class cFoncPtOfPtAVGR { public : Pt2dr operator () (cPtAVGR * aP) {return Pt2dr(aP->mPt.x,aP->mPt.y);} -}; +};*/ /*=========== cAperoVisuGlobRes ===========*/ -typedef enum +/*typedef enum { eBAVGR_X, eBAVGR_Y, @@ -122,7 +115,7 @@ class cAperoVisuGlobRes cPlyCloud mPC; cPlyCloud mPCLeg; // Legende double mVMilZ; -}; +};*/ cAperoVisuGlobRes::cAperoVisuGlobRes() : @@ -356,7 +349,7 @@ static cAperoVisuGlobRes mAVGR; //============================================ -class cInfoAccumRes +/*class cInfoAccumRes { public : cInfoAccumRes(const Pt2dr & aPt,double aPds,double aResidu,const Pt2dr & aDir); @@ -365,7 +358,7 @@ class cInfoAccumRes double mPds; double mResidu; Pt2dr mDir; -}; +};*/ cInfoAccumRes::cInfoAccumRes(const Pt2dr & aPt,double aPds,double aResidu,const Pt2dr & aDir) : @@ -376,7 +369,7 @@ cInfoAccumRes::cInfoAccumRes(const Pt2dr & aPt,double aPds,double aResidu,const { } -class cAccumResidu +/*class cAccumResidu { public : void Accum(const cInfoAccumRes &); @@ -407,7 +400,7 @@ class cAccumResidu bool mInit; int mDegPol; L2SysSurResol * mSys; -}; +};*/ cAccumResidu::cAccumResidu(Pt2di aSz,double aResol,bool OnlySign,int aDegPol) : mNbInfo (0), @@ -1005,7 +998,10 @@ cPoseCam::cPoseCam mEqOffsetGPS (0), mSRI (nullptr), mBlocCam (nullptr), - mPoseInBlocCam (nullptr) + mNumTimeBloc (-1), + mPoseInBlocCam (nullptr), + mUseRappelPose (false), + mRotURP (ElRotation3D::Id) { mPrec = this; mNext = this; @@ -1105,6 +1101,17 @@ bool cPoseCam::FidExist() const } +void cPoseCam::SetNumTimeBloc(int aNum) +{ + mNumTimeBloc = aNum; +} + +int cPoseCam::DifBlocInf1(const cPoseCam & aPC) const +{ + if ((mNumTimeBloc==-1) || (aPC.mNumTimeBloc==-1)) return 1000; + return ElAbs(mNumTimeBloc-aPC.mNumTimeBloc); +} + bool cPoseCam::IsInZoneU(const Pt2dr & aP) const @@ -1532,15 +1539,19 @@ void cPoseCam::AddLink(cPoseCam * aPC) -void cPoseCam::SetCurRot(const ElRotation3D & aRot) +void cPoseCam::PCSetCurRot(const ElRotation3D & aRot) { + ELISE_ASSERT(!mUseRappelPose,"Internam Error, probaly bascule + UseRappelPose"); + + AssertHasNotCamNonOrtho(); - mCF->SetCurRot(aRot); + mCF->SetCurRot(aRot,aRot); } void cPoseCam::SetBascRig(const cSolBasculeRig & aSBR) { + PCSetCurRot(aSBR.TransformOriC2M(CurRot())); Pt3dr aP; if (mSomPM) @@ -1551,13 +1562,17 @@ void cPoseCam::SetBascRig(const cSolBasculeRig & aSBR) else { const CamStenope * aCS = CurCam() ; - ELISE_ASSERT( (mProfondeur != PROF_UNDEF()),"No Profondeur in cPoseCam::SetBascRig"); + if (mProfondeur == PROF_UNDEF()) + { + std::cout << "Warn : NoProfInBasc For camera =" << mName << "\n"; + // ELISE_ASSERT( false,"No Profondeur in cPoseCam::SetBascRig"); + return ; + } aP = aCS->ImEtProf2Terrain(aCS->Sz()/2.0,mProfondeur); aP = aSBR(aP); } - SetCurRot(aSBR.TransformOriC2M(CurRot())); const CamStenope * aCS = CurCam() ; @@ -1684,12 +1699,12 @@ double DistanceMatr(const ElRotation3D & aR1,const ElRotation3D & aR2) return aId.L2(aMatr); } -class cTransfo3DIdent : public cTransfo3D +/*class cTransfo3DIdent : public cTransfo3D { public : std::vector Src2Cibl(const std::vector & aSrc) const {return aSrc;} -}; +};*/ extern bool DebugOFPA; @@ -2291,7 +2306,6 @@ if (mSRI && MPD_MM()) ElCamera::ChangeSys(aVCam,aTransfo,true,true); ElRotation3D aRMod = aCS->Orient(); - // mCF->SetCurRot(aRMod.inv()); aRot = aRMod.inv(); // ShowMatr("Entree",aRot.Mat()); @@ -2300,19 +2314,27 @@ if (mSRI && MPD_MM()) } + mRotURP = aRot; + mUseRappelPose = mAppli.PtrRP() && mAppli.PtrRP()->PatternApply()->Match(mName); + if (mUseRappelPose) + { + CamStenope * aCS = mAppli.ICNM()->StdCamStenOfNames(mName,mAppli.PtrRP()->IdOrient()); + mRotURP = aCS->Orient().inv(); + } + double aLMG = mAppli.Param().LimModeGL().Val(); double aGVal = GuimbalAnalyse(aRot,false); - if ((aLMG>0) && (aGVal0) && (aGValSetGL(true); + mCF->SetGL(true,mRotURP); } else { std::cout << "NO GUIMBAL " << mName << " " << aGVal<< "\n"; } - mCF->SetCurRot(aRot); + mCF->SetCurRot(aRot,mRotURP); @@ -2367,6 +2389,21 @@ if (mSRI && MPD_MM()) } } + +void cPoseCam::UseRappelOnPose() const +{ + if (! mUseRappelPose) return; + + double aPdsC = 1/ElSquare(mAppli.PtrRP()->SigmaC()); + Pt3dr aPtPdsC(aPdsC,aPdsC,aPdsC); + double aPdsR = 1/ElSquare(mAppli.PtrRP()->SigmaR()); + Pt3dr aPtPdsR (aPdsR,aPdsR,aPdsR); + mRF->AddRappOnRot(mRotURP,aPtPdsC,aPtPdsR); + + // std::cout << "NAME RAPPELE ON POSE =" << mName << "\n"; +} + + void cPoseCam::AffineRot() { for (int aK=0 ; aKmPats.size()) ; aK++) diff --git a/src/uti_phgrm/Apero/cPose.h b/src/uti_phgrm/Apero/cPose.h new file mode 100644 index 0000000000..00aa2e12c8 --- /dev/null +++ b/src/uti_phgrm/Apero/cPose.h @@ -0,0 +1,199 @@ +/*Header-MicMac-eLiSe-25/06/2007 + + MicMac : Multi Image Correspondances par Methodes Automatiques de Correlation + eLiSe : ELements of an Image Software Environnement + + www.micmac.ign.fr + + + Copyright : Institut Geographique National + Author : Marc Pierrot Deseilligny + Contributors : Gregoire Maillet, Didier Boldo. + +[1] M. Pierrot-Deseilligny, N. Paparoditis. + "A multiresolution and optimization-based image matching approach: + An application to surface reconstruction from SPOT5-HRS stereo imagery." + In IAPRS vol XXXVI-1/W41 in ISPRS Workshop On Topographic Mapping From Space + (With Special Emphasis on Small Satellites), Ankara, Turquie, 02-2006. + +[2] M. Pierrot-Deseilligny, "MicMac, un lociel de mise en correspondance + d'images, adapte au contexte geograhique" to appears in + Bulletin d'information de l'Institut Geographique National, 2007. + +Francais : + + MicMac est un logiciel de mise en correspondance d'image adapte + au contexte de recherche en information geographique. Il s'appuie sur + la bibliotheque de manipulation d'image eLiSe. Il est distibue sous la + licences Cecill-B. Voir en bas de fichier et http://www.cecill.info. + + +English : + + MicMac is an open source software specialized in image matching + for research in geographic information. MicMac is built on the + eLiSe image library. MicMac is governed by the "Cecill-B licence". + See below and http://www.cecill.info. + +Header-MicMac-eLiSe-25/06/2007*/ + +#ifndef _POSE_H_ +#define _POSE_H_ + +#include "Apero.h" + +class cPtAVGR; +class cFoncPtOfPtAVGR; +class cAperoVisuGlobRes; +class cTransfo3DIdent; +class cInfoAccumRes; +class cAccumResidu; + + + +class cPtAVGR +{ + public : + cPtAVGR (const Pt3dr & aP,double aRes); + Pt3df mPt; + float mRes; + float mResFiltr; + bool mInQt; +}; + + +typedef enum +{ + eBAVGR_X, + eBAVGR_Y, + eBAVGR_Z, + eBAVGR_Res +} eBoxAVGR; + +class cFoncPtOfPtAVGR +{ + public : + Pt2dr operator () (cPtAVGR * aP) {return Pt2dr(aP->mPt.x,aP->mPt.y);} +}; + + +class cAperoVisuGlobRes +{ + public : + void AddResidu(const Pt3dr & aP,double aRes); + void DoResidu(const std::string & aDir,int aNbMes); + + cAperoVisuGlobRes(); + + private : + Interval CalculBox(double & aVMil,double & aResol,eBoxAVGR aMode,double PropElim,double Rab); + Box2dr CalculBox_XY(double PropElim,double Rab); + double ToEcartStd(double anE) const; + double FromEcartStd(double anE) const; + Pt3di ColOfEcart(double anE); + + typedef ElQT tQtTiepT; + + int mNbPts; + std::list mLpt; + tQtTiepT * mQt; + double mResol; + double mResolX; + double mResolY; + double mSigRes; + double mMoyRes; + cPlyCloud mPC; + cPlyCloud mPCLeg; // Legende + double mVMilZ; +}; + +class cTransfo3DIdent : public cTransfo3D +{ + public : + std::vector Src2Cibl(const std::vector & aSrc) const {return aSrc;} + +}; + + +class cInfoAccumRes +{ + public : + cInfoAccumRes(const Pt2dr & aPt,double aPds,double aResidu,const Pt2dr & aDir); + + Pt2dr mPt; + double mPds; + double mResidu; + Pt2dr mDir; +}; + + +class cAccumResidu +{ + public : + void Accum(const cInfoAccumRes &); + cAccumResidu(Pt2di aSz,double aRed,bool OnlySign,int aDegPol); + + const Pt2di & SzRed() {return mSzRed;} + + void Export(const std::string & aDir,const std::string & aName,const cUseExportImageResidu &,FILE * ); + void ExportResXY(TIm2D* aTResX,TIm2D* aTResY); + void ExportResXY(const Pt2di&,Pt2dr& aRes); + private : + void AccumInImage(const cInfoAccumRes &); + + std::list mLIAR; + int mNbInfo; + double mSomPds; + bool mOnlySign; + double mResol; + Pt2di mSz; + Pt2di mSzRed; + + Im2D_REAL4 mPds; + TIm2D mTPds; + Im2D_REAL4 mMoySign; + TIm2D mTMoySign; + Im2D_REAL4 mMoyAbs; + TIm2D mTMoyAbs; + bool mInit; + int mDegPol; + L2SysSurResol * mSys; +}; + +#endif // _POSE_H_ + + +/*Footer-MicMac-eLiSe-25/06/2007 + +Ce logiciel est un programme informatique servant à la mise en +correspondances d'images pour la reconstruction du relief. + +Ce logiciel est régi par la licence CeCILL-B soumise au droit français et +respectant les principes de diffusion des logiciels libres. Vous pouvez +utiliser, modifier et/ou redistribuer ce programme sous les conditions +de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA +sur le site "http://www.cecill.info". + +En contrepartie de l'accessibilité au code source et des droits de copie, +de modification et de redistribution accordés par cette licence, il n'est +offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, +seule une responsabilité restreinte pèse sur l'auteur du programme, le +titulaire des droits patrimoniaux et les concédants successifs. + +A cet égard l'attention de l'utilisateur est attirée sur les risques +associés au chargement, à l'utilisation, à la modification et/ou au +développement et à la reproduction du logiciel par l'utilisateur étant +donné sa spécificité de logiciel libre, qui peut le rendre complexe à +manipuler et qui le réserve donc à des développeurs et des professionnels +avertis possédant des connaissances informatiques approfondies. Les +utilisateurs sont donc invités à charger et tester l'adéquation du +logiciel à leurs besoins dans des conditions permettant d'assurer la +sécurité de leurs systèmes et ou de leurs données et, plus généralement, +à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. + +Le fait que vous puissiez accéder à cet en-tête signifie que vous avez +pris connaissance de la licence CeCILL-B, et que vous en avez accepté les +termes. +Footer-MicMac-eLiSe-25/06/2007*/ + + diff --git a/src/uti_phgrm/Apero/cPosePolynGenCam.cpp b/src/uti_phgrm/Apero/cPosePolynGenCam.cpp index a76bd5bf41..1c65a9d4b6 100644 --- a/src/uti_phgrm/Apero/cPosePolynGenCam.cpp +++ b/src/uti_phgrm/Apero/cPosePolynGenCam.cpp @@ -80,6 +80,10 @@ tGrApero::TSom * cGenPoseCam::Som() return mSom; } +void cGenPoseCam::UseRappelOnPose() const +{ +} + bool cGenPoseCam::PreInit() const { return mPreInit; } diff --git a/src/uti_phgrm/BlockCam.h b/src/uti_phgrm/BlockCam.h new file mode 100644 index 0000000000..92a9b72f99 --- /dev/null +++ b/src/uti_phgrm/BlockCam.h @@ -0,0 +1,143 @@ +#ifndef _ELISE_BLOCK_CAM_H_ +#define _ELISE_BLOCK_CAM_H_ + +/* + This file, who should have exist far before, contains some devlopment common to Tapas & Campari +*/ + +class cAppli_Block +{ + public : + // CamStenope * CamSOfName(const std::string & aName) {return mICNM->StdCamStenOfNames(aName,mOriIn);} + CamStenope * CamSOfName(const std::string & aName) {return mICNM->StdCamStenOfNamesSVP(aName,mOriIn);} // Corrige une possible regression qui generait une erreur si non existe + typedef std::pair t2Str; + t2Str TimGrp(const std::string & aName) + { + return mICNM->Assoc2To1(mKeyBl,aName,true); + } + protected : + void Compile(); + + // === Input parameters + std::string mPatIm; // Liste of all images + std::string mOriIn; // input orientation + std::string mNameBlock; // name of the block-blini + + // === Computed parameters + std::string mKeyBl; // key for name compute of bloc + cStructBlockCam mBlock; // structure of the rigid bloc + cElemAppliSetFile mEASF; // Structure to extract pattern + name manip + const std::vector * mVN; // list of images + std::string mDir; // Directory of data + cInterfChantierNameManipulateur * mICNM; // Name manip +}; + + +class cGS_Cam; +class cGS_1BlC; // 1 Bloc Camera +class cGS_Appli; // Application + + +class cGS_Cam // 1 Camera +{ + public : + cGS_Cam(CamStenope * aCamS, const std::string &aName, const std::string &aGrp,cGS_1BlC * aBl) : + mCamS (aCamS), + mName (aName), + mGrp (aGrp), + mBlock (aBl) + { + } + cGS_Cam(const cGS_Cam&) = delete; + CamStenope * mCamS; // Camera + std::string mName; // Name Im + std::string mGrp; // Groupe in the block + cGS_1BlC * mBlock; +}; + + +class cGS_1BlC // 1 Bloc Camera +{ + public : + double DistLine(const cGS_1BlC & aBl2) const; + double Time() const {return mCamC->mCamS->GetTime();} + cGS_Cam * CamOfGrp(const std::string & aGrp) const; + bool ValidForCross(const cGS_1BlC&,const cGS_SectionCross &) const; + + cGS_1BlC(cGS_Appli&,const std::string & aTimeId,const std::vector &); + cGS_1BlC(const cGS_1BlC&) = delete; + + cGS_Appli& mAppli; // Application + std::string mTimeId; // Identifier of timing + std::vector mVCams; // Vector of all cam/image + cGS_Cam * mCamC; // Centrale camera (generaly INS) + cGS_Cam * mCamSec; // Used for apply comparing 3 traj + Pt3dr mP3; // Center + Pt2dr mP2; // P for indextion in QT + Pt2dr mV2; // 2D speed + Seg2d mSeg; // line PCur -> Next + int mNum; // Numerotation, can be usefull ? + double mAbsCurv; // Curvilinear abscisse +}; + +// Poor desing, a huge class with several command, would be better to make some inheritance +// will see later + +class cGS_Appli : public cAppli_Block // Application +{ + public : + typedef enum + { + eGraphe, + eCheckRel, // Check Relative Orientation + eComputeBlini // Analyse Traj et Blini + } eModeAppli; + + cGS_Appli(int,char**,eModeAppli); + bool AddPair(std::string aS1,std::string aS2); + const std::string & NameGrpC() const {return mNameGrpC;} + cGS_Cam* & CamOfName(const std::string & aName) {return mDicoCam[aName];} + virtual int Exe(); + protected : + void DoGraphe(); + void DoCheckMesures(); + void SauvRel(); + void AddAllBloc(const cGS_1BlC&,const cGS_1BlC &); + double mDistStd; + typedef ElQT tQtSom; + typedef ElQT tQtArc; + + eModeAppli mMode; + cXml_ParamGraphStereopolis mParam; + int mLevelMsg; + int AdaptIndex(int aKBl) {return ElMax(0,ElMin(mNbBloc,aKBl));} + + std::vector mVBlocs; + int mNbBloc; + std::set mSetStr; + tQtSom * mQtSom; + tQtArc * mQtArc; + cPlyCloud mPlyCross; + std::string mNameSave; + int mNbPairByF; + int mNbFile; + cSauvegardeNamedRel mRel; + Pt2dr mPInf; + Pt2dr mPSup; + bool mDoPlyCros; + std::string mNameParam; + std::string mNameGrpC; + + cSetOfMesureAppuisFlottants mSMAF; + std::string mNamePointe; + std::map mDicoCam; + std::set mSetBloc; + std::string mDirInc; // Folder 4 Inc readin + std::string mNameMasq3D; // For eliminating part of trajectory + Pt2dr mSig0Incert; // Sigma to transform Inc in weight +}; + + + + +#endif // _ELISE_BLOCK_CAM_H_ diff --git a/src/uti_phgrm/CPP_Block.cpp b/src/uti_phgrm/CPP_Block.cpp index ac36f2021e..8451319246 100644 --- a/src/uti_phgrm/CPP_Block.cpp +++ b/src/uti_phgrm/CPP_Block.cpp @@ -37,7 +37,7 @@ English : Header-MicMac-eLiSe-25/06/2007*/ #include "StdAfx.h" - +#include "BlockCam.h" int Blinis_main(int argc,char ** argv) @@ -46,9 +46,10 @@ int Blinis_main(int argc,char ** argv) MMD_InitArgcArgv(argc,argv); std::string aDir,aPat,aFullDir; - std::string AeroIn; - std::string KeyIm2Bloc; - std::string aFileOut; + std::string AeroIn; + std::string KeyIm2Bloc; + std::string aFileOut; + std::string aMasterGrp; ElInitArgMain @@ -59,6 +60,7 @@ int Blinis_main(int argc,char ** argv) << EAMC(KeyIm2Bloc,"Key for computing bloc structure") << EAMC(aFileOut,"File for destination"), LArgMain() + << EAM(aMasterGrp,"MGrp",true,"Master Group if you need to fix it (as in IMU for example)") ); if (!MMVisualMode) @@ -71,6 +73,10 @@ int Blinis_main(int argc,char ** argv) cStructBlockCam aBlockName = StdGetFromPCP(Basic_XML_MM_File("Stereo-Bloc_Naming.xml"),StructBlockCam); aBlockName.KeyIm2TimeCam() = KeyIm2Bloc; + if (EAMIsInit(&aMasterGrp)) + { + aBlockName.MasterGrp().SetVal(aMasterGrp); + } ELISE_fp::MkDirSvp(aDir+"Tmp-MM-Dir/"); MakeFileXML(aBlockName,aDir+"Tmp-MM-Dir/Stereo-Bloc_Naming.xml"); std::string aCom = MM3dBinFile_quotes( "Apero" ) @@ -90,26 +96,850 @@ int Blinis_main(int argc,char ** argv) else return EXIT_SUCCESS; } - /***********************************************************************/ -class cOneImBrion + +void cAppli_Block::Compile() +{ + // =========== Naming and name stuff ==== + mEASF.Init(mPatIm); // Compute the pattern + mICNM = mEASF.mICNM; // Extract name manip + mVN = mEASF.SetIm(); // Extract list of input name + mDir = mEASF.mDir; + StdCorrecNameOrient(mOriIn,mDir); + + // =========== Block stuff ==== + mBlock = StdGetFromPCP(mNameBlock,StructBlockCam); // Init Block + mKeyBl = mBlock.KeyIm2TimeCam(); // Store key for facilitie +} + + +class cAOFB_Im +{ + public : + cAOFB_Im(const std::string & aName,CamStenope* aCamInit,const std::string& aNameCalib) : + mName (aName), + mCamInit (aCamInit), + mNameCalib (aNameCalib), + mDone (mCamInit!=nullptr), + mR_Cam2W (mDone ? mCamInit->Orient().inv() : ElRotation3D::Id), + mTime (mDone ? mCamInit->GetTime() : 0.0) + { + } + + std::string mName; // Name of image + CamStenope * mCamInit; // Possible initial camera (pose+Cal) + std::string mNameCalib; // Name of calibration + bool mDone; + ElRotation3D mR_Cam2W; // Orientation Cam -> Word + double mTime; +}; + +class cAppli_OriFromBlock : public cAppli_Block { public : + cAppli_OriFromBlock (int argc,char ** argv); private : - std::string mName; - CamStenope * mCalib; + // Extract Time Stamp and Grp from Compiled image + t2Str TimGrp(cAOFB_Im * aPtrI) {return cAppli_Block::TimGrp(aPtrI->mName);} + + std::string mNameCalib; // input calibration (required for non oriented image) + std::string mOriOut; // Output orientation + + std::vector mVecI; // list of "compiled" + std::map mMapI; // map Time+Grp -> compiled image + + bool mCPI; // Calibration Per Image + }; -class cAppli_Brion // Block Rigid Initialisation des Orientation Normale +cAppli_OriFromBlock::cAppli_OriFromBlock (int argc,char ** argv) : + mCPI (false) +{ + MMD_InitArgcArgv(argc,argv); + + ElInitArgMain + ( + argc,argv, + LArgMain() << EAMC(mPatIm,"Full name (Dir+Pat)", eSAM_IsPatFile) + << EAMC(mOriIn,"Input Orientation folder", eSAM_IsExistDirOri) + << EAMC(mNameCalib,"Calibration folder", eSAM_IsExistDirOri) + << EAMC(mNameBlock,"File for block") + << EAMC(mOriOut,"Output Orientation folder"), + LArgMain() + << EAM(mCPI,"CPI",true,"Calib Per Im") + ); + + cAppli_Block::Compile(); + + StdCorrecNameOrient(mNameCalib,mDir); + // Create structur of "compiled" cam + for (int aKIm=0 ; aKImsize()) ; aKIm++) + { + const std::string & aName = (*mVN)[aKIm]; + // CamStenope * aCamIn = mICNM->StdCamStenOfNamesSVP(aName,mOriIn); // Camera may not + CamStenope * aCamIn = CamSOfName(aName); + std::string aNameCal = mICNM->StdNameCalib(mNameCalib,aName); + mICNM->GlobCalibOfName(aName,mNameCalib,true); // Calib should exist + cAOFB_Im * aPtrI = new cAOFB_Im(aName,aCamIn,aNameCal); // Create compiled + mVecI.push_back(aPtrI); // memo all compiled + mMapI[TimGrp(aPtrI)] = aPtrI; // We will need to access to pose from Time & Group + // std::pair aPair=mICNM->Assoc2To1(mKeyBl,aPtrI->mName,true); + } + + // Try to compile pose non existing + for (const auto & aPtrI : mVecI) + { + // If cam init exits nothing to do + if (! aPtrI->mCamInit) + { + int aNbInit = 0; + double aSumTime = 0.0; + // Extract time stamp & name of this block + t2Str aPair= TimGrp(aPtrI); + std::string aNameTime = aPair.first; // get a time stamp + std::string aNameGrp = aPair.second;// get a cam name + + cParamOrientSHC * OrInBlock = POriFromBloc(mBlock,aNameGrp,false); // Extrac orientaion in block + + // In the case there is several head oriented, we store multiple solutio, + std::vector aVecOrient; + std::vector aVecPds; + + // Parse the block of camera + for (const auto & aLiaison : mBlock.LiaisonsSHC().Val().ParamOrientSHC()) + { + std::string aNeighGrp = aLiaison.IdGrp(); + if (aNameGrp != aNeighGrp) // No need to try to init on itself + { + // Extract neighboor in block from time-stamp & group + cAOFB_Im* aNeigh = mMapI[t2Str(aNameTime,aNeighGrp)]; + if (aNeigh && aNeigh->mCamInit) // If neighbooring exist and has orientation init + { + cParamOrientSHC * aOriNeigh = POriFromBloc(mBlock,aNeighGrp,false); + + ElRotation3D aOri_Neigh2World = aNeigh->mCamInit->Orient().inv(); // Monde->Neigh + ElRotation3D aOriBlock_This2Neigh = RotCam1ToCam2(*OrInBlock,*aOriNeigh); + ElRotation3D aOri_This2Word = aOri_Neigh2World * aOriBlock_This2Neigh; + aVecOrient.push_back(aOri_This2Word); + aVecPds.push_back(1.0); + aSumTime += aNeigh->mTime; + aNbInit++; + std::cout << aPtrI->mName << " From " << aNeigh->mName << "\n"; + } + } + } + if (aNbInit) + { + aPtrI->mR_Cam2W = AverRotation(aVecOrient,aVecPds); + aPtrI->mDone = true; + aPtrI->mTime = aSumTime / aNbInit; + } + else + { + } + } + } + + // Now export + for (const auto & aPtrI : mVecI) + { + if (aPtrI->mDone) + { + // Case calibration by image, we export directly the results + // std::string aNameFI = mICNM->StdNameCalib(mNameCalib,aName); + std::string aNameFI = mICNM->StdNameCalib(mOriOut,aPtrI->mName); + CamStenope * aCamCal = mICNM->GlobCalibOfName(aPtrI->mName,mNameCalib,true); + aCamCal->SetOrientation(aPtrI->mR_Cam2W.inv()); + aCamCal->SetTime(aPtrI->mTime); + aCamCal->StdExport2File(mICNM,mOriOut,aPtrI->mName,mCPI ? "" : aNameFI); + if (!mCPI) + { + std::string aNameCal = mICNM->StdNameCalib(mNameCalib,aPtrI->mName); + ELISE_fp::CpFile(aNameCal,aNameFI); + } + } + } + + // cElemAppliSetFile anEASF(mPatIm); +} + +int OrientFromBlock_main(int argc,char ** argv) +{ + cAppli_OriFromBlock anAppli(argc,argv); + + return EXIT_SUCCESS; +} + + +/***********************************************************************/ + + +/***********************************************************/ +/* */ +/* Graphe Stereopolis */ +/* */ +/***********************************************************/ + + + + // =========== cGS_1BlC ============= + +cGS_1BlC::cGS_1BlC(cGS_Appli& anAppli,const std::string& aTimeId,const std::vector & aVN) : + mAppli (anAppli), + mTimeId (aTimeId), + mCamC (nullptr), + mCamSec (nullptr) +{ + for (const auto & aName : aVN) + { + // Compute new Cam with name & grp + CamStenope * aCam = mAppli.CamSOfName(aName); + std::string aNameGrp = mAppli.TimGrp(aName).second; + cGS_Cam * aGS_Cam = new cGS_Cam(aCam,aName,aNameGrp,this); + mAppli.CamOfName(aName) = aGS_Cam; + + // save it + mVCams.push_back(aGS_Cam); + // Chek if it is the central one + if (aNameGrp==mAppli.NameGrpC()) + { + mCamC = aGS_Cam; + } + else + { + mCamSec = aGS_Cam; + } + } + if (mCamC) + { + // Compute localisation + mP3 = mCamC->mCamS->PseudoOpticalCenter(); + mP2 = Pt2dr(mP3.x,mP3.y); + } +} +cGS_Cam * cGS_1BlC::CamOfGrp(const std::string & aGrp) const +{ + for (const auto& aCam : mVCams) + if (aCam->mGrp==aGrp) + return aCam; + return nullptr; +} + +double cGS_1BlC::DistLine(const cGS_1BlC & aBl2) const +{ + SegComp aDr1(mSeg); + return ElMax + ( + aDr1.dist_droite(aBl2.mSeg.p0()) + ,aDr1.dist_droite(aBl2.mSeg.p1()) + ); +} + + +bool cGS_1BlC::ValidForCross(const cGS_1BlC& aBl2,const cGS_SectionCross & aSC) const +{ + // Handle only one way + Avoid ajacence + if (mNum>=aBl2.mNum-1) + return false; + // If absc curv too close we are just in the same trajectory, not a cross + if (ElAbs(mAbsCurv-aBl2.mAbsCurv) < aSC.DistCurvMin()) + return false; + + if (ElAbs(angle_de_droite_nor(mV2,aBl2.mV2)) < aSC.AngleMinSpeed()) + return false; + + if ( (DistLine(aBl2) aS2) ElSwap(aS1,aS2); // store only oneway + + return mSetStr.insert(t2Str(aS1,aS2)).second; +} + +void cGS_Appli::AddAllBloc(const cGS_1BlC& aBl1,const cGS_1BlC & aBl2) +{ + const cGS_SectionCross& aSC = mParam.GS_SectionCross().Val(); + for (const auto & aN1 : aSC.ListCam()) + { + for (const auto & aN2 : aSC.ListCam()) + { + cGS_Cam * aCam1 = aBl1.CamOfGrp(aN1); + cGS_Cam * aCam2 = aBl2.CamOfGrp(aN2); + if (aCam1 && aCam2) + { + AddPair(aCam1->mName,aCam2->mName); + } + } + } +} + + +void cGS_Appli::SauvRel() +{ + std::string aName = StdPrefix(mNameSave) + "_" + ToString(mNbFile) + "." + StdPostfix(mNameSave); + + MakeFileXML(mRel,mDir+aName); +} + +cGS_Appli::cGS_Appli (int argc,char ** argv,eModeAppli aMode) : + mMode (aMode), + mLevelMsg (1), + mQtSom (nullptr), + mQtArc (nullptr), + mNameSave ("GrapheStereropolis.xml"), + mNbPairByF (2000), + mNbFile (0), + mPInf (1e20,1e20), + mPSup (-1e20,-1e20), + mDoPlyCros (true) +{ + + MMD_InitArgcArgv(argc,argv); + + LArgMain anArgObl; + anArgObl << EAMC(mPatIm,"Full name (Dir+Pat)", eSAM_IsPatFile) + << EAMC(mOriIn,"Input Orientation folder", eSAM_IsExistDirOri) + << EAMC(mNameBlock,"File for block"); + LArgMain anArgOpt; + anArgOpt << EAM(mLevelMsg,"LevMsg",true,"Level of Message, def=1"); + + + if (aMode == eGraphe) + { + ElInitArgMain + ( + argc,argv, + anArgObl + << EAMC(mNameParam,"Name File Param"), + anArgOpt + << EAM(mNameSave,"Out",true,"Name 4 save, def=GrapheStereropolis.xml") + << EAM(mNbPairByF,"NbPByF",true,"Max number of pair by file") + ); + mParam = StdGetFromPCP(mNameParam,Xml_ParamGraphStereopolis); + mNameGrpC = mParam.NameGrpC(); + } + else if (aMode == eCheckRel) + { + ElInitArgMain + ( + argc,argv, + anArgObl + << EAMC(mNamePointe,"Name File Pointe"), + anArgOpt + // << EAM(mNameSave,"Out",true,"Name 4 save, def=GrapheStereropolis.xml") + ); + } + else if (aMode == eComputeBlini) + { + ElInitArgMain + ( + argc,argv, + anArgObl, + anArgOpt + << EAM(mDirInc,"DirInc",true,"Folder 4 Inc reading") + << EAM(mNameMasq3D,"Masq3D",true,"Folder 4 eliminating part of trajectory") + << EAM(mSig0Incert,"SigmaInc",true,"Sigma to transform incet in weight") + ); + } + + cAppli_Block::Compile(); + // Must be done now because + if (aMode != eGraphe) + { + mNameGrpC = mBlock.MasterGrp().ValWithDef(mBlock.ParamOrientSHC().begin()->IdGrp()); + } + + if (EAMIsInit(&mDirInc)) + StdCorrecNameOrient(mDirInc,mDir); + + if (mLevelMsg>=1) std::cout << "=== DONE READ ARGS\n"; + + // Map Name of Time => Vecteur of name images at this time + std::map > aMapBl; + + // Group name by timing + for (const auto & aName : *mVN) + { + t2Str aTimG = TimGrp(aName); + aMapBl[aTimG.first].push_back(aName); + mSetBloc.insert(aTimG.second); + } + if (mLevelMsg>=1) std::cout << "=== DONE COMPUTE Groups, NbInit=" << aMapBl.size() << "\n"; + + // Compute bloc + bool RequireCamSec = (mMode==cGS_Appli::eComputeBlini); + for (const auto & aBloc : aMapBl) + { + cGS_1BlC * aGSB = new cGS_1BlC(*this,aBloc.first,aBloc.second); + if ( (aGSB->mCamC!=nullptr) && ((!RequireCamSec)||(aGSB->mCamSec!=nullptr)) ) + { + mVBlocs.push_back(aGSB); + mPInf = Inf(mPInf,aGSB->mP2); + mPSup = Sup(mPSup,aGSB->mP2); + } + } + + mNbBloc = mVBlocs.size(); + if (mLevelMsg>=1) std::cout << "=== DONE COMPUTE READ CAMS; NbBloc=" << mNbBloc << "\n"; + // Speed computation would fail if not enough blocs + ELISE_ASSERT(mVBlocs.size()>=2,"Not enough bloc"); + + // Sort by time + std::sort + ( + mVBlocs.begin(), + mVBlocs.end(), + [](const cGS_1BlC * aBl1,const cGS_1BlC * aBl2) + { + return aBl1->Time() < aBl2->Time() ; + } + ); + if (mLevelMsg>=1) std::cout << "=== DONE SORTED BY TIME\n"; + + // Computation of speed, absic + for (int aKBl=0 ; aKBlmCamS->Capteur2RayTer(mPt)) + { + } + double Absc() const {return mCam->mBlock->mAbsCurv;} + double DProj(const Pt3dr & aPTer) {return euclid(mPt, mCam->mCamS->Ter2Capteur(aPTer));} + + Pt2dr mPt; + cGS_Cam * mCam; + ElSeg3D mSeg; }; +// Represent a list of consecutive cGS_OneP3D2Check +class cInterv_OneP3D2C +{ + public : + cInterv_OneP3D2C(int aInd0,int aInd1,cGS_OneP3D2Check * aP3); + double ScoreReproj(const Pt3dr & aP) const; + Pt3dr Inter(int aI1,int aI2,bool & Ok) const; + double ScoreReproj(int aI1,int aI2) const; + void Print(FILE * aFp) const; + + cGS_OneP3D2Check * mP3; + int mInd0; + int mInd1; + double mScoreMin; + double mScoreMax; + double mScoreSom; + Pt2di mCplMin; + bool mOk; + Pt3dr mPInter; +}; +class cGS_OneP3D2Check +{ + public : + cGS_OneP3D2Check(const std::string & aName) : + mName (aName), + mScMax (0.0), + mScSom (0.0) + { + } + + std::string mName; + double mScMax; + double mScSom; + + std::vector mVPt; + std::vector mVInt; + void Print(FILE * aFp) const; + void Compile(); +}; + +/**************** cInterv_OneP3D2C ***********/ + +double cInterv_OneP3D2C::ScoreReproj(const Pt3dr & aP) const +{ + double aRes = 0.0; + for (int aInd=mInd0 ; aIndmVPt[aInd].DProj(aP); + } + int aNbConstr = (mInd1 - mInd0) * 2; + int aDOF = aNbConstr -3 ; // degre of freedom + return aRes / double(aDOF); +} + +Pt3dr cInterv_OneP3D2C::Inter(int aI1,int aI2,bool &Ok) const +{ + std::vector aVS; + aVS.push_back(mP3->mVPt[aI1].mSeg); + aVS.push_back(mP3->mVPt[aI2].mSeg); + return InterSeg(aVS,Ok); +} + +double cInterv_OneP3D2C::ScoreReproj(int aI1,int aI2) const +{ + bool Ok; + Pt3dr aPInter = Inter(aI1,aI2,Ok); + return Ok ? ScoreReproj(aPInter) : 1e20; +} + + +cInterv_OneP3D2C::cInterv_OneP3D2C(int aInd0,int aInd1,cGS_OneP3D2Check * aP3) : + mP3 (aP3), + mInd0 (aInd0), + mInd1 (aInd1), + mScoreMin (1e10), + mScoreMax (0), + mScoreSom (0), + mCplMin (-1,-1), + mOk (false) +{ + for (int aI1 = mInd0 ; aI1mVPt[anInd].DProj(mPInter); + mScoreMax = ElMax(mScoreMax,aD); + mScoreSom += aD; + } + } +} + +void cInterv_OneP3D2C::Print(FILE * aFp) const +{ + double aPixThres = 5; + fprintf(aFp,"- - - - - - - - - - - - - - -\n"); + for (int anInd=mInd0 ; anIndmVPt[anInd].DProj(mPInter); + bool Ok = (aDistmVPt[anInd].mCam->mName.c_str() + ); + fprintf(aFp,"\n"); + } +} + +/********** cGS_OneP3D2Check **************/ + +void cGS_OneP3D2Check::Print(FILE * aFp) const +{ + fprintf(aFp,"############################################################\n"); + fprintf(aFp," Name Point : %s\n",mName.c_str()); + + for(const auto & aPtrInt : mVInt) + { + aPtrInt->Print(aFp); + } +} + + +void cGS_OneP3D2Check::Compile() +{ + std::sort + ( + mVPt.begin(), mVPt.end(), + [](const cGS_OnePointe2Check & aP1,const cGS_OnePointe2Check & aP2) {return aP1.Absc()= aBegin+2) + { + cInterv_OneP3D2C * aInterv = new cInterv_OneP3D2C(aBegin,aEnd,this); + if (aInterv->mOk) + { + mVInt.push_back(aInterv); + mScMax = ElMax(mScMax,aInterv->mScoreMax); + mScSom += aInterv->mScoreSom; + } + } + } +} + +void cGS_Appli::DoCheckMesures() +{ + mSMAF = StdGetFromPCP(mNamePointe,SetOfMesureAppuisFlottants); + std::map mDicoP3; + + int aNbPointes = 0; + for (const auto & aMes1Im : mSMAF.MesureAppuiFlottant1Im()) + { +// std::cout<<"IMMM " << aMes1Im.NameIm() << "\n"; + cGS_Cam *aCam = CamOfName(aMes1Im.NameIm()); + if (aCam!=nullptr) + { + for (auto aPointe : aMes1Im.OneMesureAF1I()) + { + aNbPointes++; + cGS_OneP3D2Check * & aP3 = mDicoP3[aPointe.NamePt()]; + if (aP3==nullptr) + { + aP3 = new cGS_OneP3D2Check(aPointe.NamePt()); + } + aP3->mVPt.push_back(cGS_OnePointe2Check(aPointe.PtIm(),aCam)); + } + } + } + const cGS_OneP3D2Check * aWorst = nullptr; + double aScMax = -1; + double aScSum = 0; + for (const auto & aPointe : mDicoP3) + { + if (aPointe.second) + { + aPointe.second->Compile(); + aScSum += aPointe.second->mScSom; + if (aPointe.second->mScMax > aScMax) + { + aScMax = aPointe.second->mScMax; + aWorst = aPointe.second; + } + } + } + FILE * aFP = FopenNN("CheckGCPStereopolis.txt","w","DoCheckMesures"); + + fprintf(aFP,"AVERAGE = %f\n",aScSum/aNbPointes); + if (aWorst) + { + fprintf(aFP,"WORT POINT = %s\n",aWorst->mName.c_str()); + } + for (const auto & aPointe : mDicoP3) + { + if (aPointe.second) + { + aPointe.second->Print(aFP); + } + } + fclose(aFP); +} + + + +void cGS_Appli::DoGraphe() +{ + + // Compute Quod Tree for spatial indexation + { + // Get a rough estimation of a standard dist using average between succesive position + mDistStd = mVBlocs.back()->mAbsCurv / (mNbBloc-1); + Pt2dr aRab(mDistStd,mDistStd); + mQtSom= new tQtSom + ( + [](cGS_1BlC *aBl){return aBl->mP2;}, + Box2dr(mPInf-aRab,mPSup+aRab), + 10, + mDistStd*5.0 + ); + mQtArc= new tQtArc + ( + [](cGS_1BlC *aBl){return aBl->mSeg;}, + Box2dr(mPInf-aRab,mPSup+aRab), + 10, + mDistStd*5.0 + ); + + // Put submit in Qt + for (auto & aBl : mVBlocs) + mQtSom->insert(aBl); + } + if (mLevelMsg>=1) std::cout << "=== DONE COMPUTED Quod-Tree\n"; + + int aNbLine = 0; + // Add successive from linear analysis, generally only same camera + block + if (mParam.GS_SectionLinear().IsInit()) + { + for (int aKBl1=0 ; aKBl1mName,aCam2->mName)) + { + aNbLine++; + } + } + } + } + } + } + } + } + if (mLevelMsg>=1) std::cout << "=== DONE Added Linear\n"; + // Process crosses, may be important to limit drift + int aNbCross = 0; + if (mParam.GS_SectionCross().IsInit()) + { + const cGS_SectionCross& aSC = mParam.GS_SectionCross().Val(); + for (auto & aBl1 : mVBlocs) + { + set aSNeigh; + mQtSom->RVoisins(aSNeigh,aBl1->mP2,aSC.DistMax()); + for (auto & aBl2 : aSNeigh) + { + if (aBl1->ValidForCross(*aBl2,aSC)) + { + AddAllBloc(*aBl1,*aBl2); + aNbCross ++; + if (mDoPlyCros) + { + Pt3di aColCr(255,128,0); + mPlyCross.AddSeg(aColCr,aBl1->mP3,aBl2->mP3,200); + } + } + } + } + } + if (mDoPlyCros) + { + mPlyCross.PutFile("Cross.ply"); + } + std::cout << "NB VAL , FOR LINE: " << aNbLine << " FOR CROSS: " << aNbCross << "\n"; + + // Save to file + + int aCptPair = 0; + for (const auto & aPair : mSetStr) + { + mRel.Cple().push_back(cCpleString(aPair.first,aPair.second)); + aCptPair ++; + // If we are at limit size, flush buffer + if (aCptPair== mNbPairByF) + { + SauvRel(); + mRel.Cple().clear(); + aCptPair=0; + mNbFile++; + } + } + // Save remaining + SauvRel(); +} + +int CheckGCPStereopolis_main(int argc,char ** argv) +{ + cGS_Appli anAppli(argc,argv,cGS_Appli::eCheckRel); + + return anAppli.Exe(); +} + +int GrapheStereopolis_main(int argc,char ** argv) +{ + cGS_Appli anAppli(argc,argv,cGS_Appli::eGraphe); + + return anAppli.Exe(); +} + /*Footer-MicMac-eLiSe-25/06/2007 Ce logiciel est un programme informatique servant à la mise en diff --git a/src/uti_phgrm/CPP_Bundler2MM.cpp b/src/uti_phgrm/CPP_Bundler2MM.cpp index c6a535c16e..441f8776b4 100644 --- a/src/uti_phgrm/CPP_Bundler2MM.cpp +++ b/src/uti_phgrm/CPP_Bundler2MM.cpp @@ -98,9 +98,9 @@ cAppliBundler::cAppliBundler(int argc, char** argv) : argc,argv, LArgMain() << EAMC(aDir,"Working dir. If inside put ./"), LArgMain() << EAM(mNameFile,"b",true,"bundler.txt, (if FromBundler or ToBundler)" ) - << EAM(mCCListAllFile,"l",true,"list.txt, (if FromBundler)") + << EAM(mCCListAllFile,"l",true,"list.txt, (if FromBundler or ToBundler)") << EAM(mCoordsFile,"c",true,"coords.txt, (if FromBundler)") - << EAM(mOri,"Ori",true,"Orientation directory, (if FromBundler or ToBundler)") + << EAM(mOri,"Ori",true,"Orientation directory withoout Ori-, (if FromBundler or ToBundler)") << EAM(mSH,"SH",true,"Homol Postfix") << EAM(aExpTxt,"ExpTxt",true,"Homol in ASCI?") << EAM(ConvHomMM2Bund,"ConvHom",true,"Convert homol to bundler format, Def=false") diff --git a/src/uti_phgrm/CPP_Campari.cpp b/src/uti_phgrm/CPP_Campari.cpp index 073813ef22..8706d53aac 100644 --- a/src/uti_phgrm/CPP_Campari.cpp +++ b/src/uti_phgrm/CPP_Campari.cpp @@ -306,22 +306,27 @@ std::string cAppli_Tapas_Campari::TimeStamp(const std::string & aName,cInterfCh std::string cAppli_Tapas_Campari::ExtendPattern ( const std::string & aPatGlob, - const std::string & aImCenter, + const std::string & aPatCenter, cInterfChantierNameManipulateur * anICNM ) { const cInterfChantierNameManipulateur::tSet * aSetGlob = anICNM->Get(aPatGlob); std::string aKey = mSBC.KeyIm2TimeCam(); - std::string aTimeC = anICNM->Assoc2To1(mSBC.KeyIm2TimeCam(),aImCenter,true).first; + const cInterfChantierNameManipulateur::tSet * aSetCenter = anICNM->Get(aPatCenter); cPatOfName aPat; - for (const auto & aName : *aSetGlob) + + for (const auto & aImCenter : *aSetCenter) { + std::string aTimeC = anICNM->Assoc2To1(mSBC.KeyIm2TimeCam(),aImCenter,true).first; + for (const auto & aName : *aSetGlob) + { std::pair aPair = anICNM->Assoc2To1(mSBC.KeyIm2TimeCam(),aName,true); if (aPair.first == aTimeC) aPat.AddName(aName); // std::cout << "PAIR " << aPair.first << " *** " << aPair.second << "\n"; + } } @@ -447,13 +452,16 @@ class cAppli_Campari : public cAppli_Tapas_Campari std::vector mPdsErrorGps; std::string mStrDebugVTP; // Debug sur les tie points + int mNumPtsAttrNewF; + std::vector mROP; }; cAppli_Campari::cAppli_Campari (int argc,char ** argv) : - AeroOut (""), - mNameRTA ("SauvRTA.xml") + AeroOut (""), + mNameRTA ("SauvRTA.xml"), + mNumPtsAttrNewF (-1) { mStr0 = MakeStrFromArgcARgv(argc,argv,true); MMD_InitArgcArgv(argc,argv); @@ -473,7 +481,8 @@ cAppli_Campari::cAppli_Campari (int argc,char ** argv) : LocLibPP = true; LocLibDec = true; LocLibCD= true; - bool AllFree = false; + bool AllFree = false; + std::string AllFreePattern; std::string CalibMod2Refine; bool AddViscInterne=false; double ViscosInterne=0.1; @@ -539,6 +548,7 @@ cAppli_Campari::cAppli_Campari (int argc,char ** argv) : << EAM(CPI1,"CPI1",true,"Calib Per Im, Firt time", eSAM_IsBool) << EAM(CPI2,"CPI2",true,"Calib Per Im, After first time, reUsing Calib Per Im As input", eSAM_IsBool) << EAM(AllFree,"AllFree",true,"Refine all calibration parameters (Def=false)", eSAM_IsBool) + << EAM(AllFreePattern,"AllFreePat",true,"Pattern of images that will be subject to AllFree (Def=.*)", eSAM_IsBool) << EAM(CalibMod2Refine,"GradualRefineCal",true,"Calibration model to refine gradually",eSAM_None) << EAM(DetailAppuis,"DetGCP",true,"Detail on GCP (Def=false)", eSAM_IsBool) << EAM(Viscos,"Visc",true,"Viscosity on external orientation in Levenberg-Marquardt like resolution (Def=1.0)") @@ -570,6 +580,9 @@ cAppli_Campari::cAppli_Campari (int argc,char ** argv) : << EAM(aVExpImRes,"ExpImRes",true,"Sz of Im Res=[Cam,Pose,Pair]") << EAM(mStrDebugVTP,"StrDebugVTP",true,"String of debug for tie points") + << EAM(mNumPtsAttrNewF,"NAWNF",true,"Num Attribute for Weigthing in New Format") + << EAM(mROP,"ROP",true,"Rappel On Pose [IdOr,SigmaC,SigmaOr,Pattern]") + ); @@ -652,6 +665,10 @@ cAppli_Campari::cAppli_Campari (int argc,char ** argv) : if (EAMIsInit(&RapTxt)) mCom += std::string(" +RapTxt=") + RapTxt + " "; if (AllPoseFigee) mCom += " +PoseFigee=true "; + if (EAMIsInit(&AllFreePattern)) + { + mCom += " +AllFreePattern=" + AllFreePattern + " "; + } if (EAMIsInit(&PatPoseFigee)) { mCom += " +WithPatPoseFigee=true +PatPoseFigee=" + PatPoseFigee + " "; @@ -697,6 +714,7 @@ cAppli_Campari::cAppli_Campari (int argc,char ** argv) : + std::string(" +UEIR_ByPose=") + ToString(aVExpImRes[1]) + std::string(" +UEIR_ByPair=") + ToString(aVExpImRes[2]) + std::string(" +UEIR_NbMesByCase=") + ToString(aNbByC) + + std::string(" ") ; } @@ -783,10 +801,28 @@ cAppli_Campari::cAppli_Campari (int argc,char ** argv) : + " +EcartMaxPlaniPondCentre=" + ToString(mPdsErrorGps[1]) + " +SigmaPlaniPondCentre=" + ToString(mPdsErrorGps[2]) + " +EcartMaxAltiPondCentre=" + ToString(mPdsErrorGps[3]) - + " +SigmaPlaniPondCentre=" + ToString(mPdsErrorGps[4]) ; + + " +SigmaPlaniPondCentre=" + ToString(mPdsErrorGps[4]) + " "; } + if (EAMIsInit(&mNumPtsAttrNewF)) + { + mCom = mCom + " +NumAttrPdsNewF=" + ToString(mNumPtsAttrNewF) + " "; + } + + if (EAMIsInit(&mROP)) + { + ELISE_ASSERT(mROP.size()==4,"Bad size for Rappel On Pose (ROP)"); + StdCorrecNameOrient(mROP.at(0),mDir); + mCom = mCom + " +WithROP=true" + + " +ROPOrient="+ mROP.at(0) + + " +ROPSigmaC="+ mROP.at(1) + + " +ROPSigmaR="+ mROP.at(2) + + " +ROPPattern="+ QUOTE(mROP.at(3)) + + " "; + } + + if (aSetHom=="NONE") { mCom = mCom + " +UseHom=false "; diff --git a/src/uti_phgrm/CPP_CenterBascule.cpp b/src/uti_phgrm/CPP_CenterBascule.cpp index db222623ba..94f2066747 100644 --- a/src/uti_phgrm/CPP_CenterBascule.cpp +++ b/src/uti_phgrm/CPP_CenterBascule.cpp @@ -117,20 +117,328 @@ int CentreBascule_main(int argc,char ** argv) /* */ /*********************************************************************/ +class cCmpOriOneSom +{ + public : + cCmpOriOneSom(const std::string& aName,CamStenope* C1,CamStenope* C2) ; + void SetPrec(const cCmpOriOneSom & aS1); + + void Show(ofstream & ofs,bool WithRel,bool DoCirc) const; + void PlyShowDiffRot(cPlyCloud & aPlyFile,double aMult,const Pt3di & aCol) const; + void PlyShowDiffCenter(cPlyCloud & aPlyFile,double aMult,const Pt3di & aCol) const; + + public : + const std::string mName; + const CamStenope * mCam1; + // mCam1.Orient() = Orientation Monde to Cam + ElRotation3D mRC1ToM; + Pt3dr mC1; + Pt2dr mP1; + const CamStenope * mCam2; + ElRotation3D mRC2ToM; + Pt3dr mC2; + Pt2dr mP2; + int mNum; + double mAbsCurv; + double mDC; + double mDMat; + double mDMatAng;//angular distance between rotation matrices + double mDMatRel; + double mDCRel; + ElRotation3D mRC1ToC2; + // For analyzing circular traj + double mDistBcl; // Ratio of "bouclage" + bool mIsPivot; + int mNumTour; + int mNumInTour; + double mAbscInTour; +}; + + +void cCmpOriOneSom::SetPrec(const cCmpOriOneSom & aSPrec) +{ + mNum = aSPrec.mNum + 1; + mAbsCurv = aSPrec.mAbsCurv+ euclid(mC1-aSPrec.mC1); + // Calcul des orientations relatives / à image prec pour 1 et 2 + ElRotation3D aCurToPrec1 = aSPrec.mRC1ToM.inv() * mRC1ToM ; + ElRotation3D aCurToPrec2 = aSPrec.mRC2ToM.inv() * mRC2ToM ; + + // Calcul des difference en rotation et centres pour ces orientations relatives + mDMatRel = sqrt(aCurToPrec1.Mat().L2(aCurToPrec2.Mat())) ; // plus ou moin homogene a des radians + mDCRel = euclid(aCurToPrec1.tr()-aCurToPrec2.tr()) ; + + // They are similar but different + // double aDD = sqrt(mRC1ToC2.Mat().L2(aSPrec.mRC1ToC2.Mat())); + // std::cout << "FFFFff " << aDD / mDMatRel << "\n"; +} + +void cCmpOriOneSom::Show(ofstream & ofs,bool WithRel,bool DoCirc) const +{ + double MultDMat = 1e5; + + ofs << mName + << "," << ToString(mC1.x) + << "," << ToString(mC1.y) + << "," << ToString(mC1.z) + << "," << ToString(abs(mC1.x - mC2.x)) + << "," << ToString(abs(mC1.y - mC2.y)) + << "," << ToString(mC1.z - mC2.z) + << "," << ToString(euclid(mP1-mP2)) + << "," << ToString(euclid(mC1-mC2)) + << "," << ToString(mDMat*MultDMat) + ; + + if (WithRel) + { + ofs + << "," << ToString(mDCRel) + << "," << ToString(mDMatRel*MultDMat) + ; + } + if (DoCirc) + { + ofs + << "," << ToString(mNumTour) + << "," << ToString(mNumInTour) + << "," << ToString(mAbscInTour) + ; + } + ofs << "\n"; + +} + +void cCmpOriOneSom::PlyShowDiffRot(cPlyCloud & aPlyFile,double aMult,const Pt3di & aCol) const +{ + // We represent the Axiator of differential orientation + Pt3dr anAxe = AxeRot(mRC1ToC2.Mat()); + double anAngle = TetaOfAxeRot(mRC1ToC2.Mat(),anAxe); + aPlyFile.AddSeg(aCol,mC1,mC1+anAxe*(anAngle*aMult),3000); +} + +void cCmpOriOneSom::PlyShowDiffCenter(cPlyCloud & aPlyFile,double aMult,const Pt3di & aCol) const +{ + aPlyFile.AddSeg(aCol,mC1,mC1+(mC2-mC1)*aMult,3000); +} + +cCmpOriOneSom::cCmpOriOneSom(const std::string& aName,CamStenope* aCam1,CamStenope* aCam2) : + mName (aName), + mCam1 (aCam1), + mRC1ToM (aCam1->Orient().inv()), + mC1 (mRC1ToM.tr()), + mP1 (mC1.x,mC1.y), + mCam2 (aCam2), + mRC2ToM (aCam2->Orient().inv()), + mC2 (mRC2ToM.tr()), + mP2 (mC2.x,mC2.y), + mNum (0.0), + mAbsCurv (0.0), + mDC (euclid(mC1-mC2)), + mDMat (sqrt(mRC1ToM.Mat().L2(mRC2ToM.Mat()))), + mDMatRel (0.0), + mDCRel (0.0), + mRC1ToC2 (mRC2ToM.inv() * mRC1ToM), + mDistBcl (0.0), + mIsPivot (false), + mNumTour (0), + mNumInTour (0), + mAbscInTour (0) +{ + ELISE_ASSERT(euclid( mCam1->VraiOpticalCenter() - mC1)<1e-5,"Verif conventions"); + // Pt3dr AxeRot(const ElMatrix & aMat); +} + class cAppli_CmpOriCam : public cAppliWithSetImage { public : cAppli_CmpOriCam(int argc, char** argv); + void ComputeCircular(); + void ComputeAngularDist(); std::string mPat,mOri1,mOri2; std::string mDirOri2; std::string mXmlG; std::string mCSV = "CSVEachPose.csv"; std::string mPly; + std::vector mVCmp; cInterfChantierNameManipulateur * mICNM2; + std::vector mSeuilsCircs; + }; +void cAppli_CmpOriCam::ComputeCircular() +{ + ELISE_ASSERT(mSeuilsCircs.size()==2,"Size Seuil Circs"); + int aI0 = round_ni(mSeuilsCircs.at(0)); + double aSeuilDist = mSeuilsCircs.at(1); + std::vector aVRatio; + cCmpOriOneSom & aS0=mVCmp[aI0]; + for (auto & aSom : mVCmp) + { + aSom.mDistBcl = euclid(aSom.mC1-aS0.mC1) ; + } + for (int aK=1 ; aK Half_R_Rt(const ElMatrix& R) +{ + ElMatrix aRes((R - R.transpose())*0.5); + + /*std::cout << aRes(0,0) << " " << aRes(0,1) << " " << aRes(0,2) << "\n" + << aRes(1,0) << " " << aRes(1,1) << " " << aRes(1,2) << "\n" + << aRes(2,0) << " " << aRes(2,1) << " " << aRes(2,2) << "\n";*/ + return aRes; +} + +std::vector R2q(const ElMatrix& R) +{ + std::vector q(4); + + q.at(0) = (R(0,0) + R(1,1) + R(2,2) -1) *0.5; + q.at(1) = (R(2,1) - R(1,2)) *0.5; + q.at(2) = (R(0,2) - R(2,0)) *0.5; + q.at(3) = (R(1,0) - R(0,1)) *0.5; + + q.at(0) = sqrt((q.at(0)+1)/2); + + for (int aK=1; aK<4; aK++) + { + q.at(aK) = q.at(aK)/2/q.at(0); + } + + //std::cout << "q " << q << "\n"; + return q; +} + + +/* Logarithm of a matrix S*R^T */ +Pt3dr LogR(const ElMatrix& SRt) +{ + Pt3dr aRes(0,0,0); + + //transform to skew matrix + ElMatrix SRtx = Half_R_Rt(SRt); + + //if euclidean norm equal to zero return zero matrix + if (SRtx.L2()==0) + return aRes; + + Pt3dr y (SRtx(2,1),SRtx(0,2),SRtx(1,0)); + double yNorm = euclid(y); + + + aRes.x = std::asin(yNorm) * y.x * 1/yNorm; + aRes.y = std::asin(yNorm) * y.y * 1/yNorm; + aRes.z = std::asin(yNorm) * y.z * 1/yNorm; + //std::cout << "LogSRtx=" << aRes << "\n"; + + + return aRes; + +} + +/* Angular distance from quaternions + * + * Teta = 2*acos (|c|) where (c,vec) = q1^-1 * q2 + * where c is the real and vec the imaginary part of the resulting quaternion + * + * Hartley, R., Trumpf, J., Dai, Y. and Li, H., 2013. Rotation averaging. International journal of computer vision, 103(3), pp.267-305. + * + * */ +double AngDistFromQ(std::vector& q1,std::vector& q2) +{ + double aRes; + + double SOM2=0; + for (int aK=0; aK<4; aK++) + SOM2 += q1.at(aK)*q1.at(aK); + + std::vector q1Inv(4); + q1Inv.at(0) = q1.at(0)/SOM2; + for (int aK=1; aK<4; aK++) + { + q1Inv.at(aK) = -q1.at(aK)/SOM2; + } + + double q1Inv_q2_dot = q1Inv.at(1)*q2.at(1) + q1Inv.at(2)*q2.at(2) + q1Inv.at(3)*q2.at(3); + double q1Inv_q2_real = q1Inv.at(0)*q2.at(0) - q1Inv_q2_dot; + + /* Computation of the real part not necessary for the angular distance + Pt3dr q1Inv_q2_cross = Pt3dr (q1Inv.at(2)*q2.at(3) - q1Inv.at(3)*q2.at(2), + q1Inv.at(3)*q2.at(1) - q1Inv.at(1)*q2.at(3), + q1Inv.at(1)*q2.at(2) - q1Inv.at(2)*q2.at(1)); + + Pt3dr q1Inv_q2_im = Pt3dr (q1Inv.at(0)*q2.at(1) + q2.at(0)*q1Inv.at(1) + q1Inv_q2_cross.x, + q1Inv.at(0)*q2.at(2) + q2.at(0)*q1Inv.at(2) + q1Inv_q2_cross.y, + q1Inv.at(0)*q2.at(3) + q2.at(0)*q1Inv.at(3) + q1Inv_q2_cross.z); */ + + aRes = 2*acos (abs(q1Inv_q2_real)); + aRes *= (180/PI); + + return aRes; +} + +/* Angular distance from Rotations in SO(3) + * + * mDMatAng = || log(S*R^t) ||_2 + * where S and R are two rotation matrices that we compare + + * Hartley, R., Trumpf, J., Dai, Y. and Li, H., 2013. Rotation averaging. International journal of computer vision, 103(3), pp.267-305. + * */ + +double AngDistFromR(ElMatrix& R1,ElMatrix& R2) +{ + Pt3dr LogSRtx = LogR(R1*R2.transpose()); + + return euclid(LogSRtx) *180/PI; +} + + + +void cAppli_CmpOriCam::ComputeAngularDist() +{ + //iterate over all cameras + for (auto & aSom : mVCmp) + { + + std::vector q1 = R2q(aSom.mRC1ToM.Mat()); + std::vector q2 = R2q(aSom.mRC2ToM.Mat()); + aSom.mDMatAng = AngDistFromQ(q1,q2); + //std::cout << "mDMatAng=" << aSom.mDMatAng << "\n"; + } +} + cAppli_CmpOriCam::cAppli_CmpOriCam(int argc, char** argv) : cAppliWithSetImage(argc-1,argv+1,0) { @@ -140,6 +448,8 @@ cAppli_CmpOriCam::cAppli_CmpOriCam(int argc, char** argv) : double aScaleC; double aScaleO; double aF; + Pt2dr SeuilMatRel; + bool DoAngDist = false; ElInitArgMain ( @@ -157,16 +467,19 @@ cAppli_CmpOriCam::cAppli_CmpOriCam(int argc, char** argv) : << EAM(aScaleC,"ScaleC",true,"Scale for camera center difference, the center diff is displayed when this option is activated") << EAM(aScaleO,"ScaleO",true,"Scale for camera orientation difference, the ori diff is displayed when this option is activated") << EAM(aF,"F",true,"approximate value of focal length in (m), Def=0.03875m for Camlight") - + << EAM(SeuilMatRel,"SMR",true,"Seuil Mat Rel [Ratio,Prop] ") + << EAM(mSeuilsCircs,"SeuilCirc",true,"Thresholds to compute circ [I0,RatBcl]") + << EAM(DoAngDist,"AngDist",true,"Calculate the angular distance, Def=false") ); + bool DoRel = true; // Do relative informatio, + bool DoCirc = EAMIsInit(&mSeuilsCircs); + mICNM2 = mEASF.mICNM; if (EAMIsInit(&mDirOri2)) { mICNM2 = cInterfChantierNameManipulateur::BasicAlloc(mDirOri2); } -/* -*/ mICNM2->CorrecNameOrient(mOri2); @@ -174,6 +487,7 @@ cAppli_CmpOriCam::cAppli_CmpOriCam(int argc, char** argv) : double aSomDC = 0; double aSomDM = 0; + double aSomDMAng = 0; bool isCSV = false; ofstream mCSVContent; @@ -181,57 +495,70 @@ cAppli_CmpOriCam::cAppli_CmpOriCam(int argc, char** argv) : { mCSVContent.open(mCSV); isCSV = true; - mCSVContent<< "Img,X1,Y1,Z1,dX,dY,dZ,dXY,dXYZ\n"; + mCSVContent<< "Img,X1,Y1,Z1,dX,dY,dZ,dXY,dXYZ,dMat"; + if (DoRel) + mCSVContent<< ",dTrRel,dMatRel"; + if (DoCirc) + mCSVContent<< ",NumTour,NumInTour,AbscInTour"; + mCSVContent<< "\n"; } cPlyCloud aPlyC, aPlyO; + // Calcul de la structure de sommets fusionnant les 2 orientations for (int aK=0 ; aKattr().mIma; CamStenope * aCam1 = anIm->CamSNN(); CamStenope * aCam2 = mICNM2->StdCamStenOfNames(anIm->mNameIm,mOri2); - Pt3dr aC1 = aCam1->VraiOpticalCenter(); - Pt3dr aC2 = aCam2->VraiOpticalCenter(); + mVCmp.push_back(cCmpOriOneSom(anIm->mNameIm,aCam1,aCam2)); + } - if (EAMIsInit(&aScaleO)) - { - ElSeg3D aRay2 = aCam2->Capteur2RayTer(aCam2->PP()); - double prof = - aCam1->Focale()/5120*32.7/1000; + // Calcul des orientation relatives, des abscisses etc ... + std::vector aVDMatRel; + for (int aK=1 ; aKTer2Capteur(aRay2.P1()-(aC2-aC1)); + if (DoAngDist) + { + ComputeAngularDist(); + } - Pt3dr aPP3D = aCam1->ImEtProf2Terrain(aCam1->PP(),prof); + for (const auto & aSom : mVCmp) + { + aSomDC += aSom.mDC; + aSomDM += aSom.mDMat; - Pt3dr aP3D = aCam1->ImEtProf2Terrain(aP,prof); + if (DoAngDist) + aSomDMAng += aSom.mDMatAng; - aPlyO.AddSeg(aColOri,aPP3D,aP3D+(aPP3D-aP3D)*1000*aScaleO,10000); + if (EAMIsInit(&aScaleO)) + { + aSom.PlyShowDiffRot(aPlyO,aScaleO,aColOri); } - ElRotation3D aR1= aCam1->Orient(); - ElRotation3D aR2= aCam2->Orient(); - - double aDC = euclid(aC1-aC2); - double aDCXY = euclid(Pt2dr(aC1.x,aC1.y)-Pt2dr(aC2.x,aC2.y)); - double aDM = aR1.Mat().L2(aR2.Mat()); - aSomDC += aDC; - aSomDM += aDM; - std::cout << anIm->mNameIm << "\n"; if (isCSV) { - mCSVContent << anIm->mNameIm <<","<< ToString(aC1.x) << "," << ToString(aC1.y) << "," << ToString(aC1.z) << "," << ToString(abs(aC1.x - aC2.x)) << "," << ToString(abs(aC1.y - aC2.y)) << "," <SeuilMatRel.x) + std::cout << aSom.mName << " " << aRatio << "\n"; + } + } } int CPP_CmpOriCam_main(int argc, char** argv) diff --git a/src/uti_phgrm/CPP_CmpCalib.cpp b/src/uti_phgrm/CPP_CmpCalib.cpp index 83d5bbd739..1839f80af4 100644 --- a/src/uti_phgrm/CPP_CmpCalib.cpp +++ b/src/uti_phgrm/CPP_CmpCalib.cpp @@ -292,6 +292,8 @@ void cAppliCmpCal::OneItere(bool First,bool Last,const std::string Out) mP0.x * aPdsX+mP1.x * (1-aPdsX), mP0.y * aPdsY+mP1.y * (1-aPdsY) ); + +// std::cout << "PIMMM " << aPIm << "\n"; InitNormales (aPIm); mEqORV->AddObservation(mN1,mN2); @@ -565,10 +567,11 @@ cLibertOfCalib GetDefDegreeOfCalib(const cCalibDistortion & aCalib ) void GenerateMesure2D3D(cBasicGeomCap3D * aCamIn,int aNbXY,int aNbProf,const std::string & aNameIm,cDicoAppuisFlottant & aDAF,cMesureAppuiFlottant1Im & aMAF) { +// std::cout << "CONVCALL " << __LINE__ << "\n"; double aProfGlob = 1.0; CamStenope * aCS = aCamIn->DownCastCS() ; - if (aCS) + if (aCS && aCS->ProfIsDef()) { aProfGlob = aCS->GetProfondeur(); } @@ -747,6 +750,7 @@ int ConvertCalib_main(int argc, char** argv) << EAM(DecFree,"DecFree",true,"Decentrik free (def=true when appliable)") ); + if (MMVisualMode) return EXIT_SUCCESS; std::string aNameImage = aCalibOut; @@ -757,7 +761,9 @@ int ConvertCalib_main(int argc, char** argv) cDicoAppuisFlottant aDAF; cMesureAppuiFlottant1Im aMAF; +std::cout << "CONVCALL " << __LINE__ << "\n"; GenerateMesure2D3D(aCamIn,aNbXY,aNbProf,aNameImage,aDAF,aMAF); +std::cout << "CONVCALL " << __LINE__ << "\n"; cCalibrationInternConique aCICOut = StdGetFromPCP(aCalibOut,CalibrationInternConique); cLibertOfCalib aLOC = GetDefDegreeOfCalib(aCICOut.CalibDistortion().back()); if (!EAMIsInit(&aDRMax) ) aDRMax = aLOC.mDegRad; @@ -787,8 +793,8 @@ int ConvertCalib_main(int argc, char** argv) ; - System(aCom); std::cout << "COM= " << aCom << "\n"; + System(aCom); // "/opt/micmac/culture3d/bin/mm3d" diff --git a/src/uti_phgrm/CPP_CreateEpip.cpp b/src/uti_phgrm/CPP_CreateEpip.cpp index 38d9fac641..a2e74d4c34 100644 --- a/src/uti_phgrm/CPP_CreateEpip.cpp +++ b/src/uti_phgrm/CPP_CreateEpip.cpp @@ -87,6 +87,8 @@ class cApply_CreateEpip_main std::string mName2; bool mWithOri; int mNbBloc; + int mDegSupInv; + double mEpsCheckInv; Pt2dr mDir1; Pt2dr mDir2; @@ -97,7 +99,14 @@ class cApply_CreateEpip_main void Ressample(cBasicGeomCap3D * aG1,EpipolaireCoordinate & E1,double aStep); }; -Pt2dr cApply_CreateEpip_main::DirEpipIm2(cBasicGeomCap3D * aG1,cBasicGeomCap3D * aG2,ElPackHomologue & aPack,bool AddToP1) +// Compute direction of epip in G2 and fill Pack, AddToP1 indicate which way it must be added +Pt2dr cApply_CreateEpip_main::DirEpipIm2 + ( + cBasicGeomCap3D * aG1, + cBasicGeomCap3D * aG2, + ElPackHomologue & aPack, + bool AddToP1 + ) { Pt2dr aSz = Pt2dr(aG1->SzBasicCapt3D()); @@ -105,6 +114,8 @@ Pt2dr cApply_CreateEpip_main::DirEpipIm2(cBasicGeomCap3D * aG1,cBasicGeomCap3D Pt2dr aSomTens2(0,0); // On le met tres petit, ce qui a priori n'est pas genant et evite // d'avoir des point hors zone + // GetVeryRoughInterProf est une proportion + double aIProf = aG1->GetVeryRoughInterProf() / 100.0; /* @@ -116,6 +127,7 @@ if (MPD_MM()) */ + // aEps avoid points to be too close to limits double aEps = 5e-4; double aLenghtSquare = ElMin(mLengthMin,sqrt((aSz.x*aSz.y) / (mNbXY*mNbXY))); @@ -125,20 +137,24 @@ if (MPD_MM()) int aNbY = ElMax(1+3*mDegre,round_up(aSz.y /aLenghtSquare)); - std::cout << "NBBBB " << aNbX << " " << aNbY << "\n"; + std::cout << "NBBBB x:" << aNbX << " y:" << aNbY << " z: " << mNbZ << "\n"; for (int aKX=0 ; aKX<= aNbX ; aKX++) { + // Barrycentrik weighting, double aPdsX = ElMax(aEps,ElMin(1-aEps,aKX /double(aNbX))); for (int aKY=0 ; aKY<= aNbY ; aKY++) { + // Barrycentrik weighting, double aPdsY = ElMax(aEps,ElMin(1-aEps,aKY/double(aNbY))); + // Point in image 1 on regular gris Pt2dr aPIm1 = aSz.mcbyc(Pt2dr(aPdsX,aPdsY)); if (aG1->CaptHasData(aPIm1)) { Pt3dr aPT1; Pt3dr aC1; + // Compute bundle with origin on pseudo center aG1->GetCenterAndPTerOnBundle(aC1,aPT1,aPIm1); // std::cout << "IPROF " << aIProf * euclid(aPT1-aC1) << " " << aPT1 << "\n"; @@ -146,16 +162,19 @@ if (MPD_MM()) std::vector aVPIm2; for (int aKZ = -mNbZ ; aKZ <= mNbZ ; aKZ++) { + // Compute P Ground on bundle Pt3dr aPT2 = aC1 + (aPT1-aC1) * (1+(aIProf*aKZ) / mNbZ); if (aG1->PIsVisibleInImage(aPT2) && aG2->PIsVisibleInImage(aPT2)) { + // Add projection aVPIm2.push_back(aG2->Ter2Capteur(aPT2)); ElCplePtsHomologues aCple(aPIm1,aVPIm2.back(),1.0); - if (! AddToP1) + if (! AddToP1) // If Im1/Im2 were swapped aCple.SelfSwap(); aPack.Cple_Add(aCple); } } + // If more than one point is Ok if (aVPIm2.size() >=2) { Pt2dr aDir2 = vunit(aVPIm2.back()-aVPIm2[0]); @@ -165,7 +184,7 @@ if (MPD_MM()) } } Pt2dr aRT = Pt2dr::polar(aSomTens2,0.0); - return Pt2dr::FromPolar(1.0,aRT.y/2.0); + return Pt2dr::FromPolar(1.0,aRT.y/2.0); // Divide angle as it was multiplied } class cTmpReechEpip @@ -183,7 +202,8 @@ class cTmpReechEpip const std::string & aPostMasq, int aNumKer, bool aDebug, - int aNbBloc + int aNbBloc, + double aEpsChekInv = 1e-2 // Check accuracy of inverse ); private : Box2dr mBoxImIn; @@ -241,7 +261,8 @@ cTmpReechEpip::cTmpReechEpip const std::string & aPostMasq, int aNumKer , bool Debug, - int aNbBloc + int aNbBloc, + double aEpsCheckInv ) : mBoxImIn(aBoxImIn), mEpi (anEpi), @@ -256,7 +277,11 @@ cTmpReechEpip::cTmpReechEpip mRedImY (mSzRed.x,mSzRed.y), mRedTImY (mRedImY) { - + std::cout << "=== RESAMPLE EPIP " << aNameOri + << " Ker=" << aNumKer + << " Step=" << mStep + << " SzRed=" << mSzRed + << "======\n"; cInterpolateurIm2D * aPtrSCI = 0; @@ -295,7 +320,7 @@ cTmpReechEpip::cTmpReechEpip if ((aPIm.x>mBoxImIn._p0.x) && (aPIm.y>mBoxImIn._p0.y) && (aPIm.xDirect(aPIm); - if (euclid(aPEpi-aPEpi2) < 1e-2) + if (euclid(aPEpi-aPEpi2) < aEpsCheckInv) { Ok= true; mRedTMasq.oset(aPInd,Ok); @@ -328,6 +353,10 @@ cTmpReechEpip::cTmpReechEpip if (ExportMasq) { std::string aNameMasq = StdPrefix(aNameOut)+ aPostMasq +".tif"; + if (Debug) + { + Tiff_Im::Create8BFromFonc("Reduc-"+aNameMasq,mRedIMasq.sz(),mRedIMasq.in()*255); + } aTifMasq = Debug ? Tiff_Im(aNameMasq.c_str()) : Tiff_Im @@ -480,11 +509,11 @@ void cApply_CreateEpip_main::DoEpipGen() mNbXY = 100; ElPackHomologue aPack; - + // Compute the direction and the set of homologous points if (mWithOri) { - mDir2 = DirEpipIm2(mGenI1,mGenI2,aPack,true); - mDir1 = DirEpipIm2(mGenI2,mGenI1,aPack,false); + mDir2 = DirEpipIm2(mGenI1,mGenI2,aPack,true); // Dont Swap + mDir1 = DirEpipIm2(mGenI2,mGenI1,aPack,false); // Swap Pt } else { @@ -496,8 +525,8 @@ void cApply_CreateEpip_main::DoEpipGen() aPack = mICNM->StdPackHomol("",mName1,mName2); } - std::cout << "Compute Epip\n"; - CpleEpipolaireCoord * aCple = CpleEpipolaireCoord::PolynomialFromHomologue(false,aPack,mDegre,mDir1,mDir2); + std::cout << "Compute Epip ; D1=" << mDir1 << " ,D2=" << mDir2 << "\n"; + CpleEpipolaireCoord * aCple = CpleEpipolaireCoord::PolynomialFromHomologue(false,aPack,mDegre,mDir1,mDir2,mDegSupInv); EpipolaireCoordinate & e1 = aCple->EPI1(); EpipolaireCoordinate & e2 = aCple->EPI2(); @@ -505,6 +534,7 @@ void cApply_CreateEpip_main::DoEpipGen() Pt2dr aInf1(1e20,1e20),aSup1(-1e20,-1e20); Pt2dr aInf2(1e20,1e20),aSup2(-1e20,-1e20); + double aBias = 0.0; double aErrMax = 0.0; double aErrMoy = 0.0; int mNbP = 0; @@ -521,21 +551,27 @@ void cApply_CreateEpip_main::DoEpipGen() double aErrMaxDir1 = 0.0; double aErrMaxInv1 = 0.0; + // Compute accuracy, bounding box for (ElPackHomologue::const_iterator itC=aPack.begin() ; itC!= aPack.end() ; itC++) { + // Images of P1 and P2 by epipolar transforms Pt2dr aP1 = e1.Direct(itC->P1()); Pt2dr aP2 = e2.Direct(itC->P2()); + // Update bounding boxes aInf1 = Inf(aInf1,aP1); aSup1 = Sup(aSup1,aP1); aInf2 = Inf(aInf2,aP2); aSup2 = Sup(aSup2,aP2); + // Average off of X aX2mX1 += aP2.x - aP1.x; - double anErr = ElAbs(aP1.y-aP2.y); + double aDifY = aP1.y-aP2.y; // Should be 0 + double anErr = ElAbs(aDifY); mNbP++; aErrMax = ElMax(anErr,aErrMax); aErrMoy += anErr; + aBias += aDifY; if (aCple3) { @@ -567,15 +603,26 @@ void cApply_CreateEpip_main::DoEpipGen() std::cout << aInf1 << " " << aSup1 << "\n"; std::cout << aInf2 << " " << aSup2 << "\n"; std::cout << "DIR " << mDir1 << " " << mDir2 << " X2-X1 " << aX2mX1<< "\n"; - std::cout << "Epip Rect Accuracy, Moy " << aErrMoy/mNbP << " Max " << aErrMax << "\n"; - bool aConsChan = true; - Pt2di aSzI1 = mWithOri ? mGenI1->SzBasicCapt3D() : Tiff_Im::StdConvGen(mName1.c_str(),aConsChan ? -1 :1 ,true).sz() ; - Pt2di aSzI2 = mWithOri ? mGenI2->SzBasicCapt3D() : Tiff_Im::StdConvGen(mName2.c_str(),aConsChan ? -1 :1 ,true).sz() ; + std::cout << "Epip Rect Accuracy:" + << " Bias " << aBias/mNbP + << " ,Moy " << aErrMoy/mNbP + << " ,Max " << aErrMax + << "\n"; + + std::cout << "Epip NbPts= " << mNbP << " Redund=" << mNbP/double(ElSquare(mDegre)) << "\n"; - cTmpReechEpip aReech1(aConsChan,mName1,Box2dr(Pt2dr(0,0),Pt2dr(aSzI1)),&e1,Box2dr(aInf1,aSup1),mStepReech,"ImEpi1"+mPostIm+".tif",mPostMasq,mNumKer,mDebug,mNbBloc); + bool aConsChan = true; + Pt2di aSzI1 = mWithOri ? + mGenI1->SzBasicCapt3D() : + Tiff_Im::StdConvGen(mName1.c_str(),aConsChan ? -1 :1 ,true).sz() ; + Pt2di aSzI2 = mWithOri ? + mGenI2->SzBasicCapt3D() : + Tiff_Im::StdConvGen(mName2.c_str(),aConsChan ? -1 :1 ,true).sz() ; + + cTmpReechEpip aReech1(aConsChan,mName1,Box2dr(Pt2dr(0,0),Pt2dr(aSzI1)),&e1,Box2dr(aInf1,aSup1),mStepReech,"ImEpi1"+mPostIm+".tif",mPostMasq,mNumKer,mDebug,mNbBloc,mEpsCheckInv); std::cout << "DONE IM1 \n"; - cTmpReechEpip aReech2(aConsChan,mName2,Box2dr(Pt2dr(0,0),Pt2dr(aSzI2)),&e2,Box2dr(aInf2,aSup2),mStepReech,"ImEpi2"+mPostIm+".tif",mPostMasq,mNumKer,mDebug,mNbBloc); + cTmpReechEpip aReech2(aConsChan,mName2,Box2dr(Pt2dr(0,0),Pt2dr(aSzI2)),&e2,Box2dr(aInf2,aSup2),mStepReech,"ImEpi2"+mPostIm+".tif",mPostMasq,mNumKer,mDebug,mNbBloc,mEpsCheckInv); std::cout << "DONE IM2 \n"; std::cout << "DONNE REECH TMP \n"; @@ -589,15 +636,17 @@ void cApply_CreateEpip_main::DoEpipGen() cApply_CreateEpip_main::cApply_CreateEpip_main(int argc,char ** argv) : - mDegre (-1), - mForceGen (false), - mNumKer (5), - mDebug (false), - mPostMasq (""), - mGenI1 (0), - mGenI2 (0), - mWithOri (true), - mNbBloc (2000) + mDegre (-1), + mForceGen (false), + mNumKer (5), + mDebug (false), + mPostMasq (""), + mGenI1 (0), + mGenI2 (0), + mWithOri (true), + mNbBloc (2000), + mDegSupInv (4), + mEpsCheckInv (1e-1) { Tiff_Im::SetDefTileFile(50000); std::string aDir= ELISE_Current_DIR; @@ -634,6 +683,9 @@ cApply_CreateEpip_main::cApply_CreateEpip_main(int argc,char ** argv) : << EAM(mDir1,"Dir1",false,"Direction of Epip one (when Ori=NONE)") << EAM(mDir2,"Dir2",false,"Direction of Epip one (when Ori=NONE)") << EAM(mNbBloc,"NbBloc",false,"Sz of Bloc (mostly tuning)") + << EAM(mDebug,"Debug",false,"Debuging") + << EAM(mDegSupInv,"SDI",false,"Supplementary degree for inverse") + << EAM(mEpsCheckInv,"ECI",false,"Espsilpn for check inverse accuracy") ); @@ -675,10 +727,12 @@ if (!MMVisualMode) if ((!mWithOri) || (mGenI1->DownCastCS()==0) || (mGenI2->DownCastCS()==0) || mForceGen) { + if (! EAMIsInit(&mDegre)) { mDegre = mWithOri ? 9 : 2; } + std::cout << "DDDDDD " << mDegre << " " << mWithOri << "\n"; DoEpipGen(); return; } @@ -930,6 +984,7 @@ class cAppliOneReechMarqFid : public ElDistortion22_Gen , bool mBySingle; int mNumKer; std::string mPostMasq; + bool ExportAffine; }; // mAffin (mm) = Pixel @@ -964,7 +1019,8 @@ cAppliOneReechMarqFid::cAppliOneReechMarqFid(int argc,char ** argv) : mAffPixIm2ChambreMm (ElAffin2D::Id()), mBySingle (true), mNumKer (5), - mPostMasq ("NONE") + mPostMasq ("NONE"), + ExportAffine (true) { ElInitArgMain ( @@ -974,6 +1030,7 @@ cAppliOneReechMarqFid::cAppliOneReechMarqFid(int argc,char ** argv) : LArgMain() << EAM(mBoxChambreMm,"BoxCh",true,"Box in Chambre (generally in mm, [xmin,ymin,xmax,ymax])") << EAM(mNumKer,"Kern",true,"Kernel of interpol,0 Bilin, 1 Bicub, other SinC (fix size of apodisation window), Def=5") << EAM(mPostMasq,"AttrMasq",true,"Atribut for masq toto-> toto_AttrMasq.tif, NONE if unused, Def=NONE") + << EAM(ExportAffine,"ExpAff","true","Export the affine transformation") ); if (mPostMasq!="NONE") @@ -1045,6 +1102,16 @@ void cAppliOneReechMarqFid::DoReech() 2000 ); std::cout << "FOR " << mNameIm << " RESIDU " << mResidu << " Time " << aChrono.uval() << " \n"; + + if (ExportAffine) + { + std::string aAffFileDir = "Ori-InterneScan/"; + ELISE_fp::MkDirSvp(aAffFileDir); + + mAffChambreMm2PixIm.SaveInFile(aAffFileDir+"OIS-Reech_"+StdPrefix(mNameIm)+"_ChambreMm2Pix.xml"); + //MakeFileXML(mAffChambreMm2PixIm,aAffFileDir+"OIS-Reech_"+StdPrefix(mNameIm)+"_ChambreMm2Pix.xml"); + + } } diff --git a/src/uti_phgrm/CPP_HomFilterMasq.cpp b/src/uti_phgrm/CPP_HomFilterMasq.cpp index e7ce41c5af..6dbd86b4c8 100644 --- a/src/uti_phgrm/CPP_HomFilterMasq.cpp +++ b/src/uti_phgrm/CPP_HomFilterMasq.cpp @@ -77,7 +77,8 @@ int HomFilterMasq_main(int argc,char ** argv) // MemoArg(argc,argv); MMD_InitArgcArgv(argc,argv); std::string aDir,aPat,aFullDir; - bool ExpTxt=false; + bool ExpTxtIn=false; + bool ExpTxtOut=false; std::string PostPlan="_Masq"; std::string KeyCalcMasq; std::string KeyEquivNoMasq; @@ -95,6 +96,8 @@ int HomFilterMasq_main(int argc,char ** argv) Pt2dr aSelecTer; + std::vector aVParam3DRel; + ElInitArgMain ( @@ -107,19 +110,30 @@ int HomFilterMasq_main(int argc,char ** argv) << EAM(KeyEquivNoMasq,"KeyEquivNoMasq",true,"When given if KENM(i1)==KENM(i2), don't masq") << EAM(aResol,"Resol",true,"Sub Resolution for masq storing, Def=10") << EAM(AcceptNoMask,"ANM",true,"Accept no mask, def = true if MasqGlob and false else") - << EAM(ExpTxt,"ExpTxt",true,"Ascii format for in and out, def=false") + << EAM(ExpTxtIn,"ExpTxt",true,"Ascii format for in and out, def=false") + << EAM(ExpTxtOut,"ExpTxtOut",true,"Ascii format for out when != in , def=ExpTxt") << EAM(aPostIn,"PostIn",true,"Post for Input dir Hom, Def=") << EAM(aPostOut,"PostOut",true,"Post for Output dir Hom, Def=MasqFiltered") << EAM(aOriMasq3D,"OriMasq3D",true,"Orientation for Masq 3D") << EAM(aNameMasq3D,"Masq3D",true,"File of Masq3D, Def=AperiCloud_${OriMasq3D}.ply") + << EAM(aVParam3DRel,"Param3DRel",true,"Relative 3D param [DZMin,DZMax,DistMax]") << EAM(aSelecTer,"SelecTer",true,"[Per,Prop] Period of tiling on ground selection, Prop=proporion of selected") << EAM(aDistId,"DistId",true,"Supress pair such that d(P1,P2) < DistId, def unused") - << EAM(aDistHom,"DistH",true,"Distance for filtering homologous point") - << EAM(DoSym,"Symetrise",true,"Symetrise masq") + << EAM(aDistHom,"DistH",true,"Distance of reprojection for filtering homologous point") + << EAM(DoSym,"Symetrise",true,"Symetrise Files when dont exist") << EAM(DoCalNb,"Nb",true,"Calculate number of homologous points") ); bool aHasOri3D = EAMIsInit(&aOriMasq3D); bool HasTerSelec = EAMIsInit(&aSelecTer); + bool HasRel3DFilter = EAMIsInit(&aVParam3DRel); + double aDZMin=0,aDZMax=0,aDistMax=0; + if (HasRel3DFilter) + { + ELISE_ASSERT(aVParam3DRel.size()==3,"aVParam3DRel bad size"); + aDZMin = aVParam3DRel.at(0); + aDZMax = aVParam3DRel.at(1); + aDistMax = aVParam3DRel.at(2); + } #if (ELISE_windows) @@ -155,7 +169,7 @@ int HomFilterMasq_main(int argc,char ** argv) } else { - ELISE_ASSERT(EAMIsInit(&aSelecTer) || (aDistHom>=0),"Unused OriMasq3D"); + ELISE_ASSERT(EAMIsInit(&aSelecTer) || (aDistHom>=0) || HasRel3DFilter ,"Unused OriMasq3D"); } aKeyOri = "NKS-Assoc-Im2Orient@" + aOriMasq3D; } @@ -221,17 +235,20 @@ int HomFilterMasq_main(int argc,char ** argv) if (aHasOri3D) aResolMoy /= aVCam.size(); - std::string anExt = ExpTxt ? "txt" : "dat"; + std::string anExtIn = ExpTxtIn ? "txt" : "dat"; + if (!EAMIsInit(&ExpTxtOut)) + ExpTxtOut = ExpTxtIn; + std::string anExtOut = ExpTxtOut ? "txt" : "dat"; std::string aKHIn = std::string("NKS-Assoc-CplIm2Hom@") + std::string(aPostIn) + std::string("@") - + std::string(anExt); + + std::string(anExtIn); std::string aKHOut = std::string("NKS-Assoc-CplIm2Hom@") + std::string(aPostOut) + std::string("@") - + std::string(anExt); + + std::string(anExtOut); double aPeriodTer=0,aSeuilDistTer=0; @@ -309,6 +326,26 @@ std::cout << aNameIm1 << " # " << aNameIm2 << "\n"; aNbTestTer ++; aNbInTer += OkTer; } + if (Ok && HasRel3DFilter) + { + CamStenope * aCam1 = aVCam[aKN1]->DownCastCS(); + CamStenope * aCam2 = aVCam[aKN2]->DownCastCS(); + Pt3dr aC1 = aCam1->PseudoOpticalCenter(); + Pt3dr aC2 = aCam2->PseudoOpticalCenter(); + + double aDZ1 = aC1.z-aPTer.z; + double aDist1 = euclid(aC1-aPTer); + double aDZ2 = aC2.z-aPTer.z; + double aDist2 = euclid(aC2-aPTer); + if ( + ((aDZ1aDZMax) && (aDZ2>aDZMax)) + || ((aDist1>aDistMax) && (aDist2>aDistMax)) + ) + { + Ok = false; + } + } if (Ok && (aDistHom >0 )) { @@ -332,7 +369,7 @@ std::cout << aNameIm1 << " # " << aNameIm2 << "\n"; if (Ok) { - ElCplePtsHomologues aCple(aP1,aP2); + ElCplePtsHomologues aCple(aP1,aP2,itP->Pds()); aPackOut.Cple_Add(aCple); if (SymThisFile) { diff --git a/src/uti_phgrm/CPP_Liquor.cpp b/src/uti_phgrm/CPP_Liquor.cpp index 1a9f6abb71..b7daeda1b9 100644 --- a/src/uti_phgrm/CPP_Liquor.cpp +++ b/src/uti_phgrm/CPP_Liquor.cpp @@ -146,7 +146,11 @@ class cAppliLiquor : public cAppli_Tapas_Campari double mOverlapProp; // entre les 2, il peut sembler logique d'avoir une raccord prop int mExe; std::string mSH; + std::string mSHTapas; + bool mExpTxt; std::string mParamCommon; + std::string mParamTapas; + std::string mParamCampari; std::string mKeyName; }; @@ -202,7 +206,8 @@ cAppliLiquor::cAppliLiquor(int argc,char ** argv) : mSzLim (40), mIntervOverlap (3,40), mOverlapProp (0.1), - mExe (2) + mExe (2), + mExpTxt (false) { @@ -216,6 +221,8 @@ cAppliLiquor::cAppliLiquor(int argc,char ** argv) : << EAM(mIntervOverlap,"IOL",true,"Interval Overlap Def(3,40) image / (4,8) Blocs") << EAM(mExe,"Exe",true,"Execute commands 2 always, 1 if dont exist, 0 never") << EAM(mSH,"SH",true,"Set of Homogue") + << EAM(mSHTapas,"SHTapas",true,"Set of Homologue special for Tapas") + << EAM(mExpTxt,"ExpTxt",true,"Homol in txt, Def=false") << EAM(mKeyName,"KeyName",true,"Key Name for print") << ArgATP() ); @@ -247,8 +254,23 @@ cAppliLiquor::cAppliLiquor(int argc,char ** argv) : } mParamCommon = StrParamBloc(); - mParamCommon += BlQUOTE(StrInitOfEAM(&mSH)); + if (EAMIsInit(&mSHTapas)) + { + if (mSHTapas!="") + { + mParamTapas += BlQUOTE(" SH="+mSHTapas); + } + } + else + { + mParamTapas += BlQUOTE(StrInitOfEAM(&mSH)); + } + mParamCampari += BlQUOTE(StrInitOfEAM(&mSH)); + + + mParamCommon += std::string(" SauvAutom=NONE "); + mParamCommon += std::string(" ExpTxt=") + ToString(mExpTxt); /* { for (const auto & aS : *mVNames) @@ -327,6 +349,7 @@ void cAppliLiquor::DoComRec(int aLevel) + anIL.NameOri() + " " // + StrImMinMax(anIL) + mParamCommon + + mParamCampari + " SigmaTieP=2.0 "; } @@ -447,6 +470,7 @@ std::string cAppliLiquor::ComTerm(const cIntervLiquor& anIL) const + std::string(" RefineAll=false ") // => dan ParamCommon + std::string(" SauvAutom=NONE ") + mParamCommon + + mParamTapas ; return aCom; diff --git a/src/uti_phgrm/CPP_MM2DPostSism.cpp b/src/uti_phgrm/CPP_MM2DPostSism.cpp index 1904eea2f9..073c5c7cfa 100644 --- a/src/uti_phgrm/CPP_MM2DPostSism.cpp +++ b/src/uti_phgrm/CPP_MM2DPostSism.cpp @@ -143,7 +143,9 @@ int MM2DPostSism_Main(int argc,char ** argv) bool useDequant=true; double aIncCalc=2.0; int aSsResolOpt=4; + int aSurEchWCor=1; std::string aDirMEC="MEC/"; + std::string anInterp = "SinCard"; Pt2dr aPxMoy(0,0); int aZoomInit = 1; @@ -164,6 +166,8 @@ int MM2DPostSism_Main(int argc,char ** argv) << EAM(aDirMEC,"DirMEC",true,"Subdirectory where the results will be stored (Def='MEC/')") << EAM(aPxMoy,"PxMoy",true,"Px-Moy , Def=(0,0)") << EAM(aZoomInit,"ZoomInit",true,"Initial Zoom, Def=1 (can be long of Inc>2)") + << EAM(anInterp,"Interp",true,"Interpolator,Def=SinCard, can be PPV,MPD,Bilin,BiCub,BicubOpt)") + << EAM(aSurEchWCor,"SEWC",true,"Over Sampling Correlation Window)") ); if (!MMVisualMode) @@ -188,6 +192,7 @@ int MM2DPostSism_Main(int argc,char ** argv) { aPxMoy = Pt2dr(DecalageFromPC(aIm1,aIm2)); } + std::string aCom = MM3dBinFile("MICMAC") + XML_MM_File("MM-PostSism.xml") @@ -203,6 +208,8 @@ int MM2DPostSism_Main(int argc,char ** argv) + " +Px1Moy=" + ToString(aPxMoy.x) + " +Px2Moy=" + ToString(aPxMoy.y) + " +ZoomInit=" + ToString(aZoomInit) + + " +Interpolateur=eInterpol" + anInterp + + " +SurEchWCor=" + ToString(aSurEchWCor) ; @@ -683,6 +690,118 @@ int FusionDepl_Main(int argc,char ** argv) } +int AnalysePxFrac_Main(int argc,char ** argv) +{ + std::string aNameIm; + int aNbStep=100; + Box2di aBox; + int aBrd; + Pt2dr aMinMax; + bool Unsigned=true; + double aMul=1.0; + + ElInitArgMain + ( + argc,argv, + LArgMain() << EAMC(aNameIm,"Name of Image"), + LArgMain() << EAM(aNbStep,"NbStep",true,"Number of step in one pixel, def=100") + << EAM(aBox,"Box",true,"Box, def=full image") + << EAM(aBrd,"Border",true,"Border to supr, def=0") + << EAM(aMinMax,"MinMax",true,"MinMax values") + << EAM(Unsigned,"USigned",true,"Unsigned frac") + << EAM(aMul,"Mul",true,"Multiplier, def=1.0") + ); + + Im2D_REAL4 aIm = Im2D_REAL4::FromFileStd(aNameIm); + + Pt2di aP0(0,0); + Pt2di aP1 = aIm.sz(); + + if (EAMIsInit(&aBox)) + { + aP0 = aBox._p0; + aP1 = aBox._p1; + } + if (EAMIsInit(&aBrd)) + { + Pt2di aPBrd(aBrd,aBrd); + aP0 = aP0 + aPBrd; + aP1 = aP1 - aPBrd; + } + + Flux_Pts aFlux = rectangle(aP0,aP1); + if (EAMIsInit(&aMinMax)) + { + Symb_FNum aSI0(aIm.in()); + aFlux = select(aFlux,(aSI0>=aMinMax.x) && (aSI0 aH(aSzHist,0.0); + double NbTot; + + ELISE_COPY + ( + aFlux, + 1, + aH.histo().chc(aFonc) + | sigma(NbTot) + ); + + ELISE_COPY(aH.all_pts(),aH.in() *(aSzHist/NbTot),aH.out()); + + for (int aK=0 ; aK aVPt; + for (int aX=0 ; aX FeatureKeypoints; +typedef std::vector> FeatureMatches; +class cAppliOMVG +{ + public: + cAppliOMVG(int argc, char** argv); + + void Save(); + + private: + cInterfChantierNameManipulateur * mICNM; + + std::string mPattern; + std::string mSH; + std::string mHomExp; + + + + template + void FileReadOK(FILE *fptr, const char *format, T *value); + + + +}; + +void cAppliOMVG::Save() +{ + cSetTiePMul * aSPM = new cSetTiePMul(0); + + cElemAppliSetFile anEASF(mPattern); + aSPM->SetFilter(*(anEASF.SetIm())); + + + const std::vector * aVFileH = cSetTiePMul::StdSetName(mICNM,mSH,(mHomExp=="dat" ) ? 1 : 0 ); + + //read the PMul files + for (auto F : *aVFileH) + { + std::cout << F << "\n"; + aSPM->AddFile(F); + } + std::vector aVSPM = aSPM->VPMul(); + + //structure that will save features + std::map aMap_Features; + + //structure that will save matches ({I,J},{FeatureId_I,FeatureId_J}) + std::map,FeatureMatches* > aMap_Matches; + + //ierate and save + for (auto aConfig : aVSPM) + { + + //vector of images in this config (track length) + std::vector aVIm = aConfig->VIdIm(); + + + //nb of Pts in this config + int NbPts = aConfig->NbPts(); + + for (int aPt=0; aPtNameFromId(ImId); + + if (aMap_Features.find(aImName) == aMap_Features.end()) + aMap_Features[aImName] = new FeatureKeypoints; + + FeatureKeypoints* aFeatures = aMap_Features[aImName]; + + Pt2dr aPtCoord = aConfig->GetPtByImgId(aPt,ImId); + + aFeatures->push_back(aPtCoord); + std::cout << "ImId " << ImId << "\n"; + + } + + //add matches + int NbMul = int(aVIm.size()); + for (int I=0; INameFromId(aVIm[I]); + int FeatureId_I = aMap_Features[aIName]->size()-1; + + for (int J=(I+1); JNameFromId(aVIm[J]); + int FeatureId_J = aMap_Features[aJName]->size()-1; + + + if (0) + std::cout << aIName << "-" << aJName << " I,J " << aVIm[I] << " " << aVIm[J] + << ", F" << FeatureId_I << " " << FeatureId_J << "\n"; + + if (aMap_Matches.find({aVIm[I],aVIm[J]}) == aMap_Matches.end()) + aMap_Matches[{aVIm[I],aVIm[J]}] = new FeatureMatches; + + FeatureMatches* aMatches = aMap_Matches[{aVIm[I],aVIm[J]}]; + aMatches->push_back(std::make_pair(FeatureId_I,FeatureId_J)); + + } + + } + + std::cout << "=====Pt " << "\n"; + } + + } + + //save to files + for (auto aImage : aMap_Features) + { + + std::string FeatureName = StdPrefix(aImage.first.c_str()) + ".feat"; + std::ofstream file(FeatureName.c_str()); + for(auto aFeature : (*aImage.second)) + { + file << aFeature.x << " " << aFeature.y << " 0 4\n"; + } + file.close(); + + } + //desc file empty + for (auto aImage : aMap_Features) + { + + std::string FeatureName = StdPrefix(aImage.first.c_str()) + ".desc"; + std::ofstream file(FeatureName.c_str()); + file.close(); + + } + + + std::ofstream match_file("match.f.txt"); + for (auto aMatch : aMap_Matches) + { + std::cout << aSPM->NameFromId(aMatch.first.first) << " " << aMatch.first.first << "\n"; + + int NbMul = aMatch.second->size(); + match_file << aSPM->NameFromId(aMatch.first.first) << " " << aSPM->NameFromId(aMatch.first.second) << "\n" + << NbMul << "\n"; + + for (int aP=0; aPat(aP).first << " " << aMatch.second->at(aP).second << "\n"; + } + + } + match_file.close(); + +} + +cAppliOMVG::cAppliOMVG(int argc, char** argv) : + mSH(""), + mHomExp("dat") +{ + + bool aExpTxt=false; + + + ElInitArgMain + ( + argc,argv, + LArgMain() << EAMC(mPattern,"Pattern of images"), + LArgMain() << EAM(mSH,"SH",true,"Homol Postfix") + << EAM(aExpTxt,"ExpTxt","Input PMul in txt format") + ); + + + aExpTxt ? mHomExp="txt" : mHomExp="dat"; + + #if (ELISE_windows) + replace( mPattern.begin(), mPattern.end(), '\\', '/' ); + #endif + + mICNM = cInterfChantierNameManipulateur::BasicAlloc(DirOfFile(mPattern)); + + +} + + + +int CPP_MM2OpenMVG_main(int argc, char** argv) +{ + cAppliOMVG anApp(argc,argv); + anApp.Save(); + + return EXIT_SUCCESS; +} + + + +/*Footer-MicMac-eLiSe-25/06/2007 + +Ce logiciel est un programme informatique servant à la mise en +correspondances d'images pour la reconstruction du relief. + +Ce logiciel est régi par la licence CeCILL-B soumise au droit français et +respectant les principes de diffusion des logiciels libres. Vous pouvez +utiliser, modifier et/ou redistribuer ce programme sous les conditions +de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA +sur le site "http://www.cecill.info". + +En contrepartie de l'accessibilité au code source et des droits de copie, +de modification et de redistribution accordés par cette licence, il n'est +offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, +seule une responsabilité restreinte pèse sur l'auteur du programme, le +titulaire des droits patrimoniaux et les concédants successifs. + +A cet égard l'attention de l'utilisateur est attirée sur les risques +associés au chargement, à l'utilisation, à la modification et/ou au +développement et à la reproduction du logiciel par l'utilisateur étant +donné sa spécificité de logiciel libre, qui peut le rendre complexe à +manipuler et qui le réserve donc à des développeurs et des professionnels +avertis possédant des connaissances informatiques approfondies. Les +utilisateurs sont donc invités à charger et tester l'adéquation du +logiciel à leurs besoins dans des conditions permettant d'assurer la +sécurité de leurs systèmes et ou de leurs données et, plus généralement, +à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. + +Le fait que vous puissiez accéder à cet en-tête signifie que vous avez +pris connaissance de la licence CeCILL-B, et que vous en avez accepté les +termes. +Footer-MicMac-eLiSe-25/06/2007*/ diff --git a/src/uti_phgrm/CPP_Malt.cpp b/src/uti_phgrm/CPP_Malt.cpp index 12f935bb81..b673f2e410 100644 --- a/src/uti_phgrm/CPP_Malt.cpp +++ b/src/uti_phgrm/CPP_Malt.cpp @@ -39,6 +39,11 @@ Header-MicMac-eLiSe-25/06/2007*/ #include "StdAfx.h" #include "XML_GEN/all_tpl.h" +#include "../uti_phgrm/MICMAC/cInterfModuleImageLoader.h" +#include "../uti_phgrm/MICMAC/Jp2ImageLoader.h" +#include "../uti_phgrm/MICMAC/cCameraModuleOrientation.h" +#include "../uti_phgrm/MICMAC/cOrientationRTO.h" + #if ELISE_QT #include "general/visual_mainwindow.h" #endif @@ -63,6 +68,95 @@ template void VerifIn(const Type & aV,const Type * aTab,int aNb, co ELISE_ASSERT(false,"Value is not in eligible set "); } +int getPlacePoint(const std::string fileName) +{ + int placePoint = -1; + for(int l=(int)(fileName.size()-1);(l>=0)&&(placePoint==-1);--l) + { + if (fileName[l]=='.') + { + placePoint = l; + } + } + return placePoint; +} + +Pt2di getImageSz(std::string const &aName) +{ + //on recupere l'extension + int placePoint = getPlacePoint(aName); + std::string ext = std::string(""); + if (placePoint!=-1) + { + ext.assign(aName.begin()+placePoint+1,aName.end()); + } + //std::cout << "Extension : "< aRes(new JP2ImageLoader(aName, false)); + if (aRes.get()) + { + return Std2Elise(aRes->Sz(1)); + } + } +#endif + + Tiff_Im aTif = Tiff_Im::StdConvGen(aName,1,true,false); + return aTif.sz(); +} + +bool getCamera(const std::string imageName, const std::string oriType, const std::string modeOri, const std::string mDir, const Pt2di ImgSz, shared_ptr& aCam, cInterfChantierNameManipulateur * mICNM) +{ + std::string orientationName; + ElAffin2D oriIntImaM2C; + + if (modeOri=="GRID") + { + int placePoint = getPlacePoint(imageName); + if (placePoint==-1) return false; + + std::string baseName; + baseName.assign(imageName.begin(),imageName.begin()+placePoint+1); + orientationName = mDir + baseName+oriType; + if (ELISE_fp::exist_file(orientationName)) + { + shared_ptr aCam2 (new cCameraModuleOrientation(new OrientationGrille(orientationName),ImgSz,oriIntImaM2C)); + aCam = aCam2; + } + } + else + { + //Soit il s'agit d'une orientation normale + if (ELISE_fp::exist_file(mDir + "Ori-" + oriType + "/Orientation-" + imageName + ".xml")) + { + orientationName = mDir + "Ori-" + oriType + "/Orientation-" + imageName + ".xml"; + + std::cout< aCam2 (Cam_Gen_From_File(orientationName,"OrientationConique", mICNM)); + aCam = aCam2; + } + //Soit d'une orientation passee par GenBundle + else if (ELISE_fp::exist_file(mDir + "Ori-" + oriType + "/GB-Orientation-" + imageName + ".xml")) + { + orientationName = mDir + "Ori-" + oriType + "/GB-Orientation-" + imageName + ".xml"; + + shared_ptr aCam2 (new cCameraModuleOrientation(new OrientationRTO(orientationName),ImgSz,oriIntImaM2C)); + aCam = aCam2; + } + else + { + orientationName = ""; + } + } + + return (ELISE_fp::exist_file(orientationName)); +} + + class cAppliMalt { public : @@ -153,6 +247,7 @@ class cAppliMalt int mVSNI; int mNbDirPrgD; bool mPrgDReInject; + bool mSpatial; }; @@ -244,7 +339,8 @@ cAppliMalt::cAppliMalt(int argc,char ** argv) : mMaxFlow (false), mSzRec (50), mNbDirPrgD (7), - mPrgDReInject (false) + mPrgDReInject (false), + mSpatial (false) { #if ELISE_QT @@ -298,7 +394,8 @@ cAppliMalt::cAppliMalt(int argc,char ** argv) : InitDefValFromType(); - Box2dr aBoxClip, aBoxTerrain; + Box2dr aBoxClip, aBoxTerrain, aBoxTerrainGeomIm; + double aZMin=-999; double aResolTerrain; double aRatioResolImage=1; @@ -373,6 +470,8 @@ cAppliMalt::cAppliMalt(int argc,char ** argv) : << EAM(mIncidMax,"IncMax",true,"Maximum incidence of image", eSAM_NoInit) << EAM(aBoxClip,"BoxClip",true,"To Clip Computation, normalized image coordinates ([0,0,1,1] means full box)", eSAM_Normalize) << EAM(aBoxTerrain,"BoxTerrain",true,"([Xmin,Ymin,Xmax,Ymax])") + << EAM(aBoxTerrainGeomIm,"BoxTerrainGeomIm",true,"For GeomImage, using orientation to project... ([Xmin,Ymin,Xmax,Ymax])") + << EAM(aZMin,"ZMin",true,"to compute BoxTerrainGeomIm projection in the image") << EAM(aResolTerrain,"ResolTerrain",true,"Ground Resol (Def automatically computed)", eSAM_NoInit) << EAM(aRatioResolImage,"RRI",true,"Ratio Resol Image (f.e. if set to 0.8 and image resol is 2.0, will be computed at 1.6)", eSAM_NoInit) << EAM(mRoundResol,"RoundResol",true,"Use rounding of resolution (def context dependent,tuning purpose)", eSAM_InternalUse) @@ -393,9 +492,10 @@ cAppliMalt::cAppliMalt(int argc,char ** argv) : << EAM(mNbDirPrgD,"NbDirPrgD",true,"Nb Dir for prog dyn, (rather for tuning)") << EAM(mPrgDReInject,"PrgDReInject",true,"Reinjection mode for Prg Dyn (experimental)") << EAM(OrthoImSupMNT,"OISM",true,"When true footprint of ortho-image=footprint of DSM") + << EAM(mSpatial,"Spatial",true,"Compute the DTM with spatial optimized parameters") << EAM(aDEMInitIMG,"DEMInitIMG",true,"img of the DEM used to initialise the depth research", eSAM_NoInit) << EAM(aDEMInitXML,"DEMInitXML",true,"xml of the DEM used to initialise the depth research", eSAM_NoInit) - ); + ); if (!MMVisualMode) { @@ -712,6 +812,18 @@ cAppliMalt::cAppliMalt(int argc,char ** argv) : std::string aFileMM = "MM-Malt.xml"; + if (mSpatial && mType==eGeomImage) + { + aFileMM="MM-Malt-Spatial.xml"; + mSzW = 2; + mZRegul = 0.12; +// mAffineLast = true; + mZPas = 1.0; + mCostTrans = 4.0; + mDefCor = 0.3; + mNbMinIV = 2; + } + if (0) { std::cout << "TTTTESSTTTTTT MALT !!!!!!!!\n";// getchar(); @@ -1228,6 +1340,78 @@ cAppliMalt::cAppliMalt(int argc,char ** argv) : + std::string(" +Y1Terrain=") + ToString(aBoxTerrain._p1.y) ; } + if (EAMIsInit(&aBoxTerrainGeomIm) && mType==eGeomImage) + { + std::cout << "Calcul d'une boxImage a partir de celle ci (Terrain): " << aBoxTerrainGeomIm << std::endl; + + Pt2di ImgSz = getImageSz(mDir + mImMaster); + std::cout << "ImgSz: " << ImgSz.x << " " << ImgSz.y << std::endl; + std::cout << "ZMin: "<< aZMin<< std::endl; + + if (aZMin==-999) + { + std::cout << "*****************************************************************************" << std::endl; + std::cout << "***** Donner le ZMin pour reprojeter la BoxTerrain en coordonnees image *****" << std::endl; + std::cout << "*****************************************************************************" << std::endl; + return; + } + shared_ptr aCam; + + if (!getCamera(mImMaster,mOri,mModeOri,mDir,ImgSz, aCam, mICNM)) + { + std::cout << "No orientation file for " << mImMaster << " - skip " << std::endl; + return; + } + + //Ecriture en pt3d pour utiliser Ter2Capteur + Pt3dr PtSO, PtSE, PtNO, PtNE; + PtSO.x = aBoxTerrainGeomIm._p0.x; PtSO.y = aBoxTerrainGeomIm._p0.y; PtSO.z = aZMin; + PtNE.x = aBoxTerrainGeomIm._p1.x; PtNE.y = aBoxTerrainGeomIm._p1.y; PtNE.z = aZMin; + PtSE.x = PtNE.x; PtSE.y = PtSO.y; PtSE.z = aZMin; + PtNO.x = PtSO.x; PtNO.y = PtNE.y; PtNO.z = aZMin; + Pt2dr ptINO = aCam->Ter2Capteur(PtNO); + Pt2dr ptINE = aCam->Ter2Capteur(PtNE); + Pt2dr ptISO = aCam->Ter2Capteur(PtSO); + Pt2dr ptISE = aCam->Ter2Capteur(PtSE); + + std::cout << "ptINO : " << ptINO.x << " " << ptINO.y << std::endl; + std::cout << "ptINE : " << ptINE.x << " " << ptINE.y << std::endl; + std::cout << "ptISO : " << ptISO.x << " " << ptISO.y << std::endl; + std::cout << "ptISE : " << ptISE.x << " " << ptISE.y << std::endl; + + int marge = 20; // en pixel + + int cmin = std::min(std::min(ptINE.x,ptISE.x), std::min(ptINO.x,ptISO.x))-marge; + cmin = std::max(cmin, 0); + + int lmin = std::min(std::min(ptINE.y,ptISE.y), std::min(ptINO.y,ptISO.y))-marge; + lmin = std::max(lmin, 0); + + int cmax = std::max(std::max(ptINE.x,ptISE.x), std::max(ptINO.x,ptISO.x))+marge; + cmax = std::min(cmax, ImgSz.x); + + int lmax = std::max(std::max(ptINE.y,ptISE.y), std::max(ptINO.y,ptISO.y))+marge; + lmax = std::min(lmax, ImgSz.y); + + std::cout << "BOX : " << cmin << " " << lmin << " " << cmax << " " << lmax << std::endl; + + if (cmin>=ImgSz.x || cmax<=0 || lmin>=ImgSz.y || lmax<=0) + { + std::cout << "**********************************************************************" << std::endl; + std::cout << "******* La BoxTerrainGeomIm est en dehors de l'image maitresse *******" << std::endl; + std::cout << "**********************************************************************" << std::endl; + return; + } + else + { + mCom = mCom + " +UseBoxTerrain=true " + + std::string(" +X0Terrain=") + ToString(cmin) + + std::string(" +Y0Terrain=") + ToString(lmin) + + std::string(" +X1Terrain=") + ToString(cmax) + + std::string(" +Y1Terrain=") + ToString(lmax) ; + } + } + if (EAMIsInit(&mMaxFlow)) mCom = mCom + " +AlgoMaxFlow=" + ToString(mMaxFlow); if (EAMIsInit(&mSzRec)) mCom = mCom + " +SzRec=" + ToString(mSzRec); @@ -1241,6 +1425,8 @@ cAppliMalt::cAppliMalt(int argc,char ** argv) : { if (mMCorPonc) mCom = mCom + " +ModeAgrCor=eAggregIm1Maitre"; + else if (mSpatial) + mCom = mCom + " +ModeAgrCor=eAggregSymetrique"; else mCom = mCom + " +ModeAgrCor=eAggregMoyMedIm1Maitre"; } @@ -1260,8 +1446,14 @@ cAppliMalt::cAppliMalt(int argc,char ** argv) : mCom= mCom + " +UseClas2=true" + " +Clas2=" +QUOTE(mEquiv[1]); if (mEquiv.size()>2) mCom= mCom + " +UseClas3=true" + " +Clas3=" +QUOTE(mEquiv[2]); - if (mEquiv.size()>3) + mCom= mCom + " +UseClas4=true" + " +Clas4=" +QUOTE(mEquiv[3]); + if (mEquiv.size()>4) + mCom= mCom + " +UseClas5=true" + " +Clas5=" +QUOTE(mEquiv[4]); + if (mEquiv.size()>5) + mCom= mCom + " +UseClas6=true" + " +Clas6=" +QUOTE(mEquiv[5]); + + if (mEquiv.size()>6) ELISE_ASSERT(false,"too many equiv class for Malt, use MicMac"); } if (mPenalSelImBestNadir>0) diff --git a/src/uti_phgrm/CPP_Morito.cpp b/src/uti_phgrm/CPP_Morito.cpp index 290d58b2b3..be325dc949 100644 --- a/src/uti_phgrm/CPP_Morito.cpp +++ b/src/uti_phgrm/CPP_Morito.cpp @@ -172,7 +172,7 @@ cAppliMorito::cAppliMorito(int argc,char ** argv) : LArgMain() << EAMC(mOri1,"First set of image", eSAM_IsPatFile) << EAMC(mOri2,"Second set of image", eSAM_IsPatFile) << EAMC(mOriOut,"Orientation Dir"), - LArgMain() << EAM(mWithOutLayer,"WithOutLayer",true,"Is robust estimation requires or simply L2 (Def=false, other not supported now)") + LArgMain() << EAM(mWithOutLayer,"WithOutLayer",true,"If robust estimation required or simply L2 (Def=false, other not supported now)") << EAM(mDir,"Dir",true,"Global directory, Def=./") << EAM(aShowSol,"Show",true,"Show the transformation, Def=false") diff --git a/src/uti_phgrm/CPP_NewTapas.cpp b/src/uti_phgrm/CPP_NewTapas.cpp index 4fc0c7fdc1..2cb341908f 100644 --- a/src/uti_phgrm/CPP_NewTapas.cpp +++ b/src/uti_phgrm/CPP_NewTapas.cpp @@ -408,6 +408,7 @@ int Tapas_main_new(int argc,char ** argv) double aLVM = 1.0; bool MultipleBlock =false; bool IsMidle= false; + bool InitBlocCam = false; ElInitArgMain ( @@ -455,6 +456,7 @@ int Tapas_main_new(int argc,char ** argv) << EAM(aVRegulDist,"RegulDist",true,"Parameter fo RegulDist [Val,Grad,Hessian,NbCase,SeuilNb]") << EAM(aLVM,"MulLVM",true,"Multipier Levenberg Markard") << EAM(MultipleBlock,"MultipleBlock",true,"Multiple block need special caution (only related to Levenberg Markard)") + << EAM(InitBlocCam,"UBR4I","Use Bloc Rigid for Init, def=context dependent") << anATP.ArgATP() ); @@ -734,13 +736,14 @@ int Tapas_main_new(int argc,char ** argv) const std::vector & aVTime = anATP.BlocTimeStamps(); std::map & aCptTime = anATP.BlocCptTime(); + // Recupere l'image la plus proche du milieu et dont le bloc est plein int aDistMax = -1; int aKMax = -1; for (int aK=0 ; aKaDistMax) { aDistMax = aDist; @@ -784,7 +787,8 @@ int Tapas_main_new(int argc,char ** argv) */ if (EAMIsInit(&ImInit)) { - aCom = aCom + " +InitCamCenter=false +InitBlocCam=true "; + InitBlocCam = true; + aCom = aCom + " +InitCamCenter=false "; ImInit= QUOTE(anATP.ExtendPattern(aPat,ImInit,aICNM)); aCom = aCom + " +SetImInit="+ImInit; } @@ -800,6 +804,10 @@ int Tapas_main_new(int argc,char ** argv) } + if (InitBlocCam) + { + aCom = aCom + " +InitBlocCam=true "; + } anATP.AddParamBloc(aCom); std::cout << "Com = " << aCom << "\n"; diff --git a/src/uti_phgrm/CPP_Nuage2Ply.cpp b/src/uti_phgrm/CPP_Nuage2Ply.cpp index 86c1b88b1f..a391a9f016 100644 --- a/src/uti_phgrm/CPP_Nuage2Ply.cpp +++ b/src/uti_phgrm/CPP_Nuage2Ply.cpp @@ -382,7 +382,7 @@ int PlyGCP_main(int argc,char ** argv) ( argc,argv, LArgMain() << EAMC(aNameGCP,"Name of GCP file", eSAM_IsExistFile) - << EAMC(aResol,"Resolution"), + << EAMC(aResol,"Resolution, use for string"), LArgMain() << EAM(aNamePly,"Out",true," Def= GCP.ply") << EAM(aNorm,"Normal",true,"Def=(0,0,1)") << EAM(aCoul,"Coul",true,"Color Def=[255,0,0]") diff --git a/src/uti_phgrm/CPP_SaisieAppuisPredic.cpp b/src/uti_phgrm/CPP_SaisieAppuisPredic.cpp index 42e3558edf..fdbbfebe94 100644 --- a/src/uti_phgrm/CPP_SaisieAppuisPredic.cpp +++ b/src/uti_phgrm/CPP_SaisieAppuisPredic.cpp @@ -60,7 +60,9 @@ void SaisieAppuisPredic(int argc, char ** argv, double &aZInc, std::string & aInputSec, bool & WithMaxMinPt, - double & aGama + double & aGama, + std::string & aPatFilter, + double & aDistMax ) { MMD_InitArgcArgv(argc,argv); @@ -85,6 +87,8 @@ void SaisieAppuisPredic(int argc, char ** argv, << EAM(PIMsFilter,"PIMsF",true,"PIMs filter used for visibility", eSAM_NoInit) << EAM(aInputSec,"InputSec",true,"For inmporting Other Inputs", eSAM_NoInit) << EAM(WithMaxMinPt,"WMM",true,"With max-min option for point seizing", eSAM_NoInit) + << EAM(aPatFilter,"PNF",true,"Pts Name Filter", eSAM_NoInit) + << EAM(aDistMax,"DMax",true,"Dist Max to center", eSAM_NoInit) ); if (!MMVisualMode) @@ -127,6 +131,8 @@ void SaisieAppuisPredic(int argc, char ** argv, #if ELISE_X11 int SaisieAppuisPredic_main(int argc,char ** argv) { + std::string aPatFilter; + double aDistMax; Pt2di aSzW(800,800); Pt2di aNbFen(-1,-1); std::string aFullName,aNamePt,anOri, aModeOri, aNameMesure, aDir, aName; @@ -141,7 +147,7 @@ int SaisieAppuisPredic_main(int argc,char ** argv) bool WithMaxMinPt=false; double aGama = 1.0; - SaisieAppuisPredic(argc, argv, aSzW, aNbFen, aFullName, aDir, aName, aNamePt, anOri, aModeOri, aNameMesure, aTypePts,aMasq3D,aPIMsFilter, aFlou, aForceGray, aZMoy, aZInc,aInputSec,WithMaxMinPt, aGama); + SaisieAppuisPredic(argc, argv, aSzW, aNbFen, aFullName, aDir, aName, aNamePt, anOri, aModeOri, aNameMesure, aTypePts,aMasq3D,aPIMsFilter, aFlou, aForceGray, aZMoy, aZInc,aInputSec,WithMaxMinPt, aGama,aPatFilter,aDistMax); if(!MMVisualMode) { @@ -194,6 +200,21 @@ int SaisieAppuisPredic_main(int argc,char ** argv) { aCom = aCom + " +Gama=" + ToString(aGama) + " "; } + if (EAMIsInit(&aPatFilter)) + { + aCom = aCom + " +WithPatFilt=true +PatFilt=" + QUOTE(aPatFilter) + " "; + } + if (EAMIsInit(&aDistMax)) + { + aCom = aCom + " +WithDmax=true +DistMax=" + ToString(aDistMax) + " "; + } +/* + if (EAMIsInit(&aDistMax)) + { + aCom = aCom + " +Gama=" + ToString(aGama) + " "; + } +*/ + std::cout << aCom << "\n"; diff --git a/src/uti_phgrm/CPP_Stereopolis.cpp b/src/uti_phgrm/CPP_Stereopolis.cpp new file mode 100644 index 0000000000..07263cfd36 --- /dev/null +++ b/src/uti_phgrm/CPP_Stereopolis.cpp @@ -0,0 +1,477 @@ +/*Header-MicMac-eLiSe-25/06/2007 + + MicMac : Multi Image Correspondances par Methodes Automatiques de Correlation + eLiSe : ELements of an Image Software Environnement + + www.micmac.ign.fr + + + Copyright : Institut Geographique National + Author : Marc Pierrot Deseilligny + Contributors : Gregoire Maillet, Didier Boldo. + +[1] M. Pierrot-Deseilligny, N. Paparoditis. + "A multiresolution and optimization-based image matching approach: + An application to surface reconstruction from SPOT5-HRS stereo imagery." + In IAPRS vol XXXVI-1/W41 in ISPRS Workshop On Topographic Mapping From Space + (With Special Emphasis on Small Satellites), Ankara, Turquie, 02-2006. + +[2] M. Pierrot-Deseilligny, "MicMac, un lociel de mise en correspondance + d'images, adapte au contexte geograhique" to appears in + Bulletin d'information de l'Institut Geographique National, 2007. + +Francais : + + MicMac est un logiciel de mise en correspondance d'image adapte + au contexte de recherche en information geographique. Il s'appuie sur + la bibliotheque de manipulation d'image eLiSe. Il est distibue sous la + licences Cecill-B. Voir en bas de fichier et http://www.cecill.info. + + +English : + + MicMac is an open source software specialized in image matching + for research in geographic information. MicMac is built on the + eLiSe image library. MicMac is governed by the "Cecill-B licence". + See below and http://www.cecill.info. + +Header-MicMac-eLiSe-25/06/2007*/ +#include "StdAfx.h" +#include "BlockCam.h" + +static const Pt3di PColRed(255,0,0); +static const Pt3di PColGreen(0,255,0); +static const Pt3di PColBlue(0,0,255); +static const Pt3di PColBlack(0,0,0); +static const Pt3di PColOrange(255,128,0); +static const Pt3di PColCyan(0,0,255); +static const Pt3di PColGrayMed(128,128,12); + +typedef std::map> tMapInc; + +// std::map> +tMapInc StdGetSCenterOPK(const std::string & aDir); + + // StdGetSCenterOPK("Ori-4MesInc/"); + +/*****************************************/ +/* */ +/* :: */ +/* */ +/*****************************************/ + + +void CreatPlyOnePt(const std::string& aName, const Pt3dr & aPt,const Pt3di aCoul,double aRay,int aNbByRay) +{ + cPlyCloud aPlyFile; + aPlyFile.AddSphere(aCoul,aPt,aRay,aNbByRay); + aPlyFile.PutFile(aName); +} + +class cBlockATS +{ + public : + cBlockATS(const cBlockATS *) = delete; + cBlockATS(cGS_1BlC *); + const ElRotation3D & OriC2S() const {return mOriC2S;} + const Pt3dr & LevA() const {return mLevA;} + const Pt3dr & Pos() const {return mOriC2W.tr();} + const ElMatrix & BoreS() const {return mBoreS;} + void CalculNext(const cBlockATS & aNext); + + // Calcul le boresight relatif + void SetEstimBoreS(const ElMatrix & aMat); + void SetInc(const tMapInc &); + + const Pt3dr & OPK_V() const {return mOPK;} // Vehicule + Pt3dr OPK_W() const {return mOriC2W.Mat() * mOPK;} // Word + const cGS_1BlC & StdBl() const {return *mStdBl;} + const std::string & NameIm() const {return mStdBl->mCamSec->mName;} + bool WithInc () const {return mWithInc;} + Pt3dr IncXYZ () const {return mIncXYZ;} + Pt3dr IncOPK () const {return mIncOPK;} + + double PdsPos() const {return mPdsPos;} + void SetPdsPos(double aPds) {mPdsPos=aPds;} + double PdsOri() const {return mPdsOri;} + void SetPdsOri(double aPds) {mPdsOri=aPds;} + Pt3di StdCoul() {return (mPdsPos >0) ? PColGreen : PColRed;} + private : + cGS_1BlC * mStdBl; + ElRotation3D mOriC2W; // Orientation Centrale 3 World + ElRotation3D mOriS2W; // Orientation Secondary = cam + ElRotation3D mOriC2S; // Orientation Centrale relatively to Cam + + // ElRotation3D mOriCNext2C; // Orientation Centrale 3 World + // ElRotation3D mOriSNext2S; // Orientation Centrale 3 World + + // Relative position of C(=central) in S (=second=camera) repair + Pt3dr mLevA; // alwo known as lever arm + ElMatrix mBoreS; // alwo known as boresight + + // Handles Boresigth As + Pt3dr mOPK; // Omega Phi Kapa as delta between Boresight and average Boresight + + // Inc on orients + bool mWithInc; + Pt3dr mIncXYZ; + Pt3dr mIncOPK; + double mPdsPos; + double mPdsOri; +}; + +void cBlockATS::CalculNext(const cBlockATS & aNext) +{ +/* + mOriCNext2C = mOriC2W.inv() * aNext.mOriC2W; + mOriSNext2S = mOriS2W.inv() * aNext.mOriS2W; + std::cout << "TTRRRRRR "<< mOriCNext2C.tr() << mOriSNext2S.tr() << "\n"; +*/ +} + +void cBlockATS::SetInc(const tMapInc & aMap) +{ + tMapInc::const_iterator anIt = aMap.find(NameIm()); + + if (anIt==aMap.end()) + { + return; + } + mWithInc = true; + mIncXYZ = anIt->second.first; + mIncOPK = anIt->second.second; + +// std::cout << "JJJJ " << (anIt==aMap.end()) << " <- " << NameIm() << mIncXYZ << mIncOPK << "\n"; +} + +cBlockATS::cBlockATS(cGS_1BlC * aBl) : + mStdBl (aBl), + mOriC2W (mStdBl->mCamC->mCamS->Orient().inv()), + mOriS2W (mStdBl->mCamSec->mCamS->Orient().inv()), + mOriC2S (mOriS2W.inv() * mOriC2W), + // mOriCNext2C (ElRotation3D::Id), + // mOriSNext2S (ElRotation3D::Id), + mLevA (mOriC2S.tr()), + mBoreS (mOriC2S.Mat()), + mWithInc (false), + mPdsPos (1.0), + mPdsOri (1.0) +{ +} + +void cBlockATS::SetEstimBoreS(const ElMatrix & aMat) +{ + if (true) + { + // BOres = RCam-1 * RIns + // RCam * BOres = RIns + // RCam * BOres = RIns * OPK + // OPK = RIns -1 * RCam * BOres + + ElMatrix aRes = mOriC2W.inv().Mat() * mOriS2W.Mat() * aMat ; + ElRotation3D aR(Pt3dr(0,0,0),aRes,true); + mOPK = Pt3dr(aR.teta12(),aR.teta02(),aR.teta01()); + + // mOPK = mOriC2W.Mat() * mOPK; + } + else + { + } + +} + + +class cAnalyseTrajStereopolis : public cGS_Appli +{ + public : + cAnalyseTrajStereopolis(int argc,char ** argv); + private : + template void Stat(const Type & Fctr,const std::string &Name); + template void StatWithSel(const Type & Fctr,const TypeSel & aSel,const std::string &Name); + + double ScoreOneLA(const Pt3dr &) const; // Score 4 One LevArm, using sum euclid dist + double ScoreOneBoreS(const ElMatrix &) const; + std::vector mVBlATS; + cPlyCloud mPly_LACloud; + cPlyCloud mPly_TrajCOpt; + cPlyCloud mPly_TrajSeg; + cPlyCloud mPly_TrajLevArm; + cPlyCloud mPly_TrajBoreS_V; + cPlyCloud mPly_TrajBoreS_W; + cPlyCloud mPly_TrajNameCam; + + cPlyCloud mPly_TrajIncPos; + cPlyCloud mPly_TrajIncOPK; + Pt3dr mLAEstim; + ElMatrix mBoresEstim; + std::map> mMapInc; + bool mWithInc; + cMasqBin3D * mMasq3D; +}; + +template + void cAnalyseTrajStereopolis::StatWithSel + ( + const Type & aFctr, + const TypeSel & aSel, + const std::string &Name + ) +{ + std::vector aVP; + Pt3dr aSomP(0,0,0); + int aNbSel = 0; + for (const auto & aBl : mVBlATS) + { + if (aSel(aBl)) + { + Pt3dr aP = aFctr(*aBl); + aP = Pt3dr(ElAbs(aP.x),ElAbs(aP.y),ElAbs(aP.z)); + aVP.push_back(aP); + aSomP = aSomP + aP; + aNbSel ++; + } + } + + ELISE_ASSERT(aNbSel!=0,"No Block in StatWithSel"); + aSomP = aSomP / aNbSel; + std::cout << "========== STAT FOR " << Name << " =================\n"; + std::cout << " MoyAbs= " << euclid(aSomP) << " " << aSomP << "\n"; + Pt3dr aPMed = P3DMed(aVP,[](const Pt3dr & aP) {return aP;}); + std::cout << " MedAbs= " << euclid(aPMed) << " " << aPMed << "\n"; +} + +bool SelPds(cBlockATS * aBl) {return aBl->PdsPos()>0;} +bool SelInc(cBlockATS * aBl) {return aBl->WithInc() && (aBl->PdsPos()>0);} +template void cAnalyseTrajStereopolis::Stat(const Type & Fctr,const std::string &Name) +{ + StatWithSel(Fctr,[](cBlockATS *) {return true;},Name); +} + // template void StatWithSel(const Type & Fctr,const Type & aSel,const std::string &Name); + +double cAnalyseTrajStereopolis::ScoreOneLA(const Pt3dr & aLA) const +{ + double aSomEcP = 0; + double aSomP = 0; + for (const auto & aBl : mVBlATS) + { + double aPds = aBl->PdsPos(); + aSomP += aPds; + aSomEcP += euclid(aLA-aBl->LevA()) * aPds; + } + + return aSomEcP / aSomP; +} + +double cAnalyseTrajStereopolis::ScoreOneBoreS(const ElMatrix & aBoreS) const +{ + double aRes = 0; + for (const auto & aBl : mVBlATS) + aRes += sqrt(aBoreS.L2(aBl->BoreS())); + + return aRes / mVBlATS.size(); +} +/* +*/ + + + + +cAnalyseTrajStereopolis::cAnalyseTrajStereopolis(int argc,char ** argv) : + cGS_Appli (argc,argv,cGS_Appli::eComputeBlini), + mBoresEstim (3,3), + mWithInc (false), + mMasq3D (nullptr) +{ + if (EAMIsInit(&mNameMasq3D)) + { + mMasq3D = cMasqBin3D::FromSaisieMasq3d(mNameMasq3D); + } + if (EAMIsInit(&mDirInc)) + { + mWithInc = true; + mMapInc = StdGetSCenterOPK("Ori-"+mDirInc + "/"); + } + int aNbByRayPly = 4; + double aRayPly = 0.01; + + ELISE_ASSERT(mSetBloc.size()==2,"cAnalyseTrajStereopolis require excactly 2 cam in bloc"); + + for (const auto & aPtrBl : mVBlocs) + { + cBlockATS * aPtrBlA = new cBlockATS(aPtrBl); + mVBlATS.push_back(aPtrBlA); + + if (mWithInc) + aPtrBlA->SetInc(mMapInc); + // std::cout << "TR = " << mVBlATS.back().OriC2S().tr() << "\n"; + Pt3dr aLA = aPtrBlA->LevA(); + + if (mMasq3D) + { + double aPds = mMasq3D->IsInMasq(aPtrBlA->Pos()); + aPtrBlA->SetPdsOri(aPds); + aPtrBlA->SetPdsPos(aPds); + } + mPly_LACloud.AddPt(aPtrBlA->StdCoul(),aLA); + } + mPly_LACloud.PutFile("AnTS_LevArmCloud.ply"); + for (int aK=1 ; aKCalculNext(*mVBlATS[aK]); + } + + + // Calcul d'un point moyen par min de som(abs(dist)) + { + double aScCMin = 1e20; + Pt3dr aLAMinDEucl; + for (const auto & aBl : mVBlATS) + { + double aScC = ScoreOneLA(aBl->LevA()); + if (aScCLevA(); + } + } + CreatPlyOnePt("AnTS_LevArmDAbs.ply",aLAMinDEucl,PColBlue,aRayPly,aNbByRayPly); + mLAEstim = aLAMinDEucl; + } + if (0) // Pb Resolu, a priori inutile + { + Pt3dr aMedLA = P3DMed(mVBlATS,[](const cBlockATS * aBl) {return aBl->LevA() ;}); + CreatPlyOnePt("AnTS_LevArmMed.ply",aMedLA,PColOrange,aRayPly,aNbByRayPly); + } + + // Calcul d'un borseight moyen par min de som(abs(dist)) + { + double aScCMin = 1e20; + ElMatrix aBoreSMinDist(3,3); + for (const auto & aBl : mVBlATS) + { + double aScC = ScoreOneBoreS(aBl->BoreS()); + if (aScCBoreS(); + } + } + mBoresEstim = aBoreSMinDist; + + cPlyCloud aPly_BoreSCloud; + for (auto & aBl : mVBlATS) + { + aBl->SetEstimBoreS(mBoresEstim); + aPly_BoreSCloud.AddPt(aBl->StdCoul(),aBl->OPK_V()); + } + aPly_BoreSCloud.PutFile("AnTS_OPKCloud.ply"); + + std::cout << "DISP LA " << ScoreOneLA(mLAEstim) << "\n"; + std::cout << "DISP BORESIGHT " << ScoreOneBoreS(mBoresEstim) << "\n"; + } + + + { + for (int aKp=0 ; aKpOPK(); + } + + double aMulPos = 100; + double aMulOPK = 200; + + Pt3di aCoulTraj = PColOrange; + for (int aKp=0 ; aKp 0) ? PColGreen : PColRed ; + mPly_TrajCOpt.AddSphere(aColPos,aBl.Pos(),0.10,4); + Pt3dr anEcart = aBl.LevA() - mLAEstim; + mPly_TrajLevArm.AddSeg(PColRed,aBl.Pos(),aBl.Pos() + anEcart*aMulPos,100); + + mPly_TrajBoreS_V.AddSeg(PColBlue ,aBl.Pos(),aBl.Pos() + aBl.OPK_V() * aMulOPK ,100); + mPly_TrajBoreS_W.AddSeg(PColCyan,aBl.Pos(),aBl.Pos() + aBl.OPK_W() * aMulOPK ,100); + if (aKp>=1) + { + const cBlockATS & aBlPrec = *mVBlATS.at(aKp-1); + mPly_TrajSeg.AddSeg(aCoulTraj,aBl.Pos(),aBlPrec.Pos(),100); + } + mPly_TrajNameCam.PutString + ( + aBl.StdBl().mTimeId, + aBl.Pos() + Pt3dr(0,0,2), + Pt3dr(1,0,0), + Pt3dr(0,1,0), + PColGrayMed, + 0.3, + 0.05, + 1 // Number of pix ply for 1 pix digit + ); + if (aBl.WithInc()) + { + mPly_TrajIncPos.AddSeg(Pt3di(255,0,128),aBl.Pos(),aBl.Pos() + aBl.IncXYZ()*aMulPos,100); + mPly_TrajIncOPK.AddSeg(Pt3di(0,128,255),aBl.Pos(),aBl.Pos() + aBl.IncOPK()*aMulOPK,100); + } + } + mPly_TrajCOpt.PutFile("AnTS_TrajCenter.ply"); + mPly_TrajSeg.PutFile("AnTS_TrajLine.ply"); + mPly_TrajLevArm.PutFile("AnTS_TrajLevArm.ply"); + mPly_TrajBoreS_V.PutFile("AnTS_TrajBoreS_Vehicule.ply"); + mPly_TrajBoreS_W.PutFile("AnTS_TrajBoreS_Word.ply"); + mPly_TrajNameCam.PutFile("AnTS_TrajNameCam.ply"); + if (mWithInc) + { + mPly_TrajIncPos.PutFile("AnTS_TrajIncXYZ.ply"); + mPly_TrajIncOPK.PutFile("AnTS_TrajIncOPK.ply"); + } + } + StatWithSel ( [this](const cBlockATS & aBl){return aBl.LevA() - mLAEstim;},SelPds, "Lever-Arm"); + StatWithSel ( [](const cBlockATS & aBl){return aBl.OPK_V() ;},SelPds, "Bore-Sight"); + + StatWithSel ( [](const cBlockATS & aBl){return aBl.IncXYZ() ;},SelInc, "XYZInc"); + StatWithSel ( [](const cBlockATS & aBl){return aBl.IncOPK() ;},SelInc, "WKPInc"); +} + +int AnalyseTrajStereopolis_main(int argc,char ** argv) +{ + // GetSCenterOPK("Ori-4MesInc/Sensib-ConvName.txt","Ori-4MesInc/Sensib-Data.dmp"); + cAnalyseTrajStereopolis anAppli(argc,argv); + + return EXIT_SUCCESS; +} + + + +/*Footer-MicMac-eLiSe-25/06/2007 + +Ce logiciel est un programme informatique servant à la mise en +correspondances d'images pour la reconstruction du relief. + +Ce logiciel est régi par la licence CeCILL-B soumise au droit français et +respectant les principes de diffusion des logiciels libres. Vous pouvez +utiliser, modifier et/ou redistribuer ce programme sous les conditions +de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA +sur le site "http://www.cecill.info". + +En contrepartie de l'accessibilité au code source et des droits de copie, +de modification et de redistribution accordés par cette licence, il n'est +offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, +seule une responsabilité restreinte pèse sur l'auteur du programme, le +titulaire des droits patrimoniaux et les concédants successifs. + +A cet égard l'attention de l'utilisateur est attirée sur les risques +associés au chargement, à l'utilisation, à la modification et/ou au +développement et à la reproduction du logiciel par l'utilisateur étant +donné sa spécificité de logiciel libre, qui peut le rendre complexe à +manipuler et qui le réserve donc à des développeurs et des professionnels +avertis possédant des connaissances informatiques approfondies. Les +utilisateurs sont donc invités à charger et tester l'adéquation du +logiciel à leurs besoins dans des conditions permettant d'assurer la +sécurité de leurs systèmes et ou de leurs données et, plus généralement, +à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. + +Le fait que vous puissiez accéder à cet en-tête signifie que vous avez +pris connaissance de la licence CeCILL-B, et que vous en avez accepté les +termes. +Footer-MicMac-eLiSe-25/06/2007*/ diff --git a/src/uti_phgrm/CPP_XYZ2Im.cpp b/src/uti_phgrm/CPP_XYZ2Im.cpp index 2a2044ebfc..de7a338021 100644 --- a/src/uti_phgrm/CPP_XYZ2Im.cpp +++ b/src/uti_phgrm/CPP_XYZ2Im.cpp @@ -301,6 +301,151 @@ int Im2XYZ_main(int argc,char ** argv) { return TransfoCam_main(argc,argv,false); } + +ElRotation3D ListRot2RotPhys(const std::list & aLRot,const ElPackHomologue & aPack); +std::list MatEssToMulipleRot(const ElMatrix & aMEss,double LBase); + +void Sho33( ElMatrix aM) +{ + for (int aY=0 ; aY<3 ; aY++) + printf(" %f \t %f \t %f \n",aM(0,aY),aM(1,aY),aM(2,aY)); +} + +bool ShowMSG_ListRot2RotPhys=false; + +//int PPMD_CalcEss(int argc,char ** argv) +int PPMD_MatEss2Orient(int argc,char ** argv) +{ + ShowMSG_ListRot2RotPhys = true; + + Pt3dr aRefAll = vunit(Pt3dr(0.0743780117532993751,1.39204657194425052, -0.335883991159797279)); + Pt3dr aRef2 = vunit(Pt3dr(0.08730003023518626, 1.6357168231794974 ,-0.393890910854981069)); + + std::string I1,I2,Cal; + std::string PostH="txt"; + std::string SH="_ConvOLDFormat"; + + ElInitArgMain + ( + argc,argv, + LArgMain() << EAMC(I1,"Name Im1") + << EAMC(I2,"Name Im1") + << EAMC(Cal,"Name Calib"), + LArgMain() + ); + + cInterfChantierNameManipulateur * anICNM = cInterfChantierNameManipulateur::BasicAlloc("./"); + std::string aFilePtsIn = anICNM->Assoc1To2("NKS-Assoc-CplIm2Hom@"+ SH+"@"+PostH,I1,I2,true); + + ElPackHomologue aPackInit = ElPackHomologue::FromFile(aFilePtsIn); + CamStenope * aCam1 = anICNM->StdCamStenOfNames(I1,Cal); + CamStenope * aCam2 = anICNM->StdCamStenOfNames(I2,Cal); + + ElPackHomologue aPackPh = aCam1->F2toPtDirRayonL3(aPackInit,aCam2); + + std::vector aVMatPy({ -3.48751824, 20.52539487,-361.5038316, 101.79664035, -6.19477011, + -18.78353249, 351.48896237, -22.88157752,1}); + + ElMatrix aMatPy(3,3); + for (int aX=0 ; aX<3 ; aX++) + { + for (int aY=0 ; aY<3 ; aY++) + { + aMatPy(aX,aY) = aVMatPy.at(aX+3*aY); + } + } +/* + [[ -3.48751824 20.52539487 -361.5038316 ] + [ 101.79664035 -6.19477011 -18.78353249] + [ 351.48896237 -22.88157752 1. ]] + +*/ + ElMatrix aMM_MEss = aPackPh.MatriceEssentielle(true); + aMM_MEss *= 1/aMM_MEss(2,2); + + ElRotation3D aR1toW(Pt3dr(0,0,0),0,0,PI); + std::cout << "==== aR1ToMonde === \n"; + Sho33(aR1toW.Mat()); + + + for (int aKMat=0 ; aKMat<1 ; aKMat++) + { + std::cout << "===============\n"; + bool PyMath = (aKMat==0); + ElMatrix aMEss = PyMath ? aMatPy : aMM_MEss; + Sho33(aMEss); + + std::list aLR = MatEssToMulipleRot(aMEss,1.0); + for (const auto & aR : aLR) + { + std::cout << "=====TR=" << aR.inv().tr() << "\n"; + Sho33( aR.inv().Mat()); + } + + // Orientation Monde to Cam de la camera 1 + ElRotation3D aR1to2 = ListRot2RotPhys(aLR,aPackPh); + ElRotation3D aR2toW = aR1toW * aR1to2.inv(); + + + + std::cout << "WINN = " << aR2toW.tr() << "\n"; + Sho33(aR2toW.Mat()); + } + if (0) + { + std::cout << "Refpts " << aRef2 << " " << aRefAll << "\n"; + + ElMatrix aSvd1(3,3),aDiag(3,3),aSvd2(3,3); + svdcmp_diag(aMatPy,aSvd1,aDiag,aSvd2,true); + std::cout << " ================ SVD1 ============\n"; + Sho33(aSvd1); + std::cout << " ================ DIAG ============\n"; + Sho33(aDiag); + std::cout << " ================ SVD2 ============\n"; + Sho33(aSvd2); + } + { + ElMatrix MTest = ElMatrix::Rotation(0,0,PI/2); + Sho33(MTest); + } + + + return EXIT_SUCCESS; +} + +int XXX_PPMD_MatEss2Orient(int argc,char ** argv) +{ + std::vector VMat; + ElInitArgMain + ( + argc,argv, + LArgMain() << EAMC(VMat,"Matrice as vector of nine double"), + LArgMain() + ); + ELISE_ASSERT(VMat.size()==9,"Bad size 4 essential matrix"); + + ElMatrix aMat(3,3); + for (int aX=0 ; aX<3 ; aX++) + { + for (int aY=0 ; aY<3 ; aY++) + { + aMat(aX,aY) = VMat.at(aX+3*aY); + // aMat(aY,aX) = VMat.at(aX+3*aY); + } + } + + std::list LM= MatEssToMulipleRot(aMat,1.0); + for (const auto & aR : LM) + { + std::cout << aR.tr() << "\n"; + } + + + return EXIT_SUCCESS; +} + + + /* int main(int argc,char ** argv) { diff --git a/src/uti_phgrm/MICMAC/cAppliMICMAC_GPU.cpp b/src/uti_phgrm/MICMAC/cAppliMICMAC_GPU.cpp index 1bb0b255bd..8646d885f0 100644 --- a/src/uti_phgrm/MICMAC/cAppliMICMAC_GPU.cpp +++ b/src/uti_phgrm/MICMAC/cAppliMICMAC_GPU.cpp @@ -1414,25 +1414,61 @@ if (0) int aY0 = anY - mCurSzV0.x; int aY1 = anY + mCurSzV0.x; - + std::string mode = "normal"; +// /* NORMAL + std::vector imageM; for (int aXV=aX0 ; aXV<=aX1 ; aXV++) { for (int aYV=aY0 ; aYV<=aY1 ; aYV++) { double aSV = 0; double aSVV = 0; + std::vector vectMediane; for (int aKIm=0 ; aKImValNorm(aXV,aYV); // std::cout << "VvV = " << aV << "\n"; aSV += aV; aSVV += QSquare(aV) ; + vectMediane.push_back(aV); + } + + if(mode=="normal") + anEC2 += (aSVV-QSquare(aSV)/aNbImCur); + else if(mode=="moyenne") + { + aSV/=aNbImCur; + imageM.push_back(aSV); + } + else if (mode == "mediane") + { + std::sort(vectMediane.begin(), vectMediane.end()); + if (vectMediane.size()%2==0) + imageM.push_back((vectMediane[vectMediane.size()/2]+vectMediane[vectMediane.size()/2-1])/2); + else + imageM.push_back(vectMediane[(vectMediane.size()-1)/2]); } - anEC2 += (aSVV-QSquare(aSV)/aNbImCur); } } + // std::cout << "NOCMS " << anEC2 << "\n"; - aCost = anEC2 / ((aNbImCur -1) * mNbPtsWFixe); + + if(mode=="normal") + aCost = anEC2 / ((aNbImCur -1) * mNbPtsWFixe); + else + { + double aSVmoy = 0; + double aSVVmoy = 0; + for (size_t aI=0 ; aI > histo2d_norm(nb_bins,std::vector(nb_bins,0.)); @@ -692,7 +702,7 @@ void cStatGlob::SetSomsMade(bool aSSM) /*Footer-MicMac-eLiSe-25/06/2007 -Ce logiciel est un programme informatique servant à la mise en +Ce logiciel est un programme informatique servant � la mise en correspondances d'images pour la reconstruction du relief. Ce logiciel est régi par la licence CeCILL-B soumise au droit français et @@ -708,17 +718,17 @@ seule une responsabilité restreinte pèse sur l'auteur du programme, le titulaire des droits patrimoniaux et les concédants successifs. A cet égard l'attention de l'utilisateur est attirée sur les risques -associés au chargement, à l'utilisation, à la modification et/ou au -développement et à la reproduction du logiciel par l'utilisateur étant -donné sa spécificité de logiciel libre, qui peut le rendre complexe à -manipuler et qui le réserve donc à des développeurs et des professionnels +associés au chargement, � l'utilisation, � la modification et/ou au +développement et � la reproduction du logiciel par l'utilisateur étant +donné sa spécificité de logiciel libre, qui peut le rendre complexe � +manipuler et qui le réserve donc � des développeurs et des professionnels avertis possédant des connaissances informatiques approfondies. Les -utilisateurs sont donc invités à charger et tester l'adéquation du -logiciel à leurs besoins dans des conditions permettant d'assurer la +utilisateurs sont donc invités � charger et tester l'adéquation du +logiciel � leurs besoins dans des conditions permettant d'assurer la sécurité de leurs systèmes et ou de leurs données et, plus généralement, -à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. +� l'utiliser et l'exploiter dans les mêmes conditions de sécurité. -Le fait que vous puissiez accéder à cet en-tête signifie que vous avez +Le fait que vous puissiez accéder � cet en-tête signifie que vous avez pris connaissance de la licence CeCILL-B, et que vous en avez accepté les termes. Footer-MicMac-eLiSe-25/06/2007*/ diff --git a/src/uti_phgrm/NewOri/GpsLoc.cpp b/src/uti_phgrm/NewOri/GpsLoc.cpp index 120106ecbb..4ff7a53986 100644 --- a/src/uti_phgrm/NewOri/GpsLoc.cpp +++ b/src/uti_phgrm/NewOri/GpsLoc.cpp @@ -64,6 +64,14 @@ cSolBasculeRig StdSolFromPts int aNbL2 = 5 ); + +enum EstimType +{ + L1, + L1Pds, + L2 +}; + /** cXml_Rotation ElRotation3D Xml2El(const cXml_Rotation & aXml) @@ -126,22 +134,89 @@ class cGpsLoc_Som { public : cGpsLoc_Som(const std::string & aName); - cGpsLoc_Rep & Sol(); - Pt3dr & Gps(); + ~cGpsLoc_Som(); + + cGpsLoc_Rep & Sol(); + std::vector & SolPerTri(); + Pt3dr & Gps(); + + void RemoveOutliers(); + void CalcMedErr(); + + double & ErrMed(); + std::vector & Pds(); + void Save(cNewO_NameManager *); + inline std::string Name() {return mName;} + private : std::string mName; - cGpsLoc_Rep mSol;//centre perspective+rotation absolute calculé - Pt3dr mGPS;//centre perspectif mesuré par le GPS + cGpsLoc_Rep mSol;//final centre perspective+rotation absolute calculé + std::vector mSolPerTri;//vector of solutions from N triplets + Pt3dr mGPS;//centre perspectif mesuré par le GPS + + double * mErrMed; + std::vector mPds; }; cGpsLoc_Som::cGpsLoc_Som(const std::string & aName) : - mName (aName) + mName (aName), + mErrMed(NULL) +{ +} +cGpsLoc_Som::~cGpsLoc_Som() +{ + if (mErrMed) + delete mErrMed; +} + +std::vector & cGpsLoc_Som::SolPerTri() {return mSolPerTri;} +cGpsLoc_Rep & cGpsLoc_Som::Sol() {return mSol;} +Pt3dr & cGpsLoc_Som::Gps() {return mGPS;} +double & cGpsLoc_Som::ErrMed() {return *mErrMed;} +std::vector & cGpsLoc_Som::Pds() {return mPds;} + + +void cGpsLoc_Som::CalcMedErr() +{ + std::vector anErr; + + for (auto aOri : mSolPerTri) + { + anErr.push_back (euclid(mGPS - aOri.Ori())); + } + + mErrMed = new double; + (*mErrMed) = KthValProp(anErr,0.75); + std::cout << mName << " Quantile 75% Err " << (*mErrMed) << "\n"; +} + +void cGpsLoc_Som::RemoveOutliers() { + + if (mErrMed) + { + std::vector aSolPerTriNew; + std::vector aPdsNew; + + double anErr = 0; + int Nb = mSolPerTri.size(); + for (int aK=0; aKStdExportCalibGlob(); + //set the uncertainty + anOC.Externe().IncCentre() = Pt3dr(ErrMed(),ErrMed(),ErrMed()); + std::string aNameOri = aNM->ICNM()->Assoc1To1("NKS-Assoc-Im2Orient@-"+aNM->OriOut()+"-GpsLoc",mName,true); MakeFileXML(anOC,aNameOri); @@ -170,19 +248,37 @@ class cGpsLoc_Triplet public : cGpsLoc_Triplet(tGLS_Ptr aS1,tGLS_Ptr aS2,tGLS_Ptr aS3,const cXml_Ori3ImInit & aXmlOri); void InitSomTrivial(); + void PrintCurSoms(); private : tGLS_Ptr mSoms[3]; //absolute cGpsLoc_Rep mReps[3]; //repere local Pt3dr mPMed; + + cGenGaus3D *mGG; + + cSolBasculeRig mBasc;//transformation relativeto absolut }; cGpsLoc_Triplet::cGpsLoc_Triplet(tGLS_Ptr aS1,tGLS_Ptr aS2,tGLS_Ptr aS3,const cXml_Ori3ImInit & aXmlOri) : - mSoms {aS1,aS2,aS3} + mSoms {aS1,aS2,aS3}, + mBasc(cSolBasculeRig::Id()) { mReps[0] = cGpsLoc_Rep(); mReps[1] = cGpsLoc_Rep(Xml2El(aXmlOri.Ori2On1())); mReps[2] = cGpsLoc_Rep(Xml2El(aXmlOri.Ori3On1())); mPMed = aXmlOri.PMed(); + + //get the ellipse and its eigen values + cXml_Elips3D anEl; + RazEllips(anEl); + AddEllips(anEl,mSoms[0]->Gps(),1.0); + AddEllips(anEl,mSoms[1]->Gps(),1.0); + AddEllips(anEl,mSoms[2]->Gps(),1.0); + NormEllips(anEl); + mGG = new cGenGaus3D(anEl); + + //std::cout << mGG->ValP(0) << " " << mGG->ValP(1) << " " << mGG->ValP(2) << "\n"; + //std::cout << mSoms[0]->Name() << " " << mSoms[1]->Name() << " " << mSoms[2]->Name() << "\n"; } @@ -194,43 +290,61 @@ void cGpsLoc_Triplet::InitSomTrivial() for (auto aK : {0,1,2}) { - //mSoms[aK]->Sol() = mReps[aK]; mVP1.push_back(mReps[aK].Ori()); mVP2.push_back(mSoms[aK]->Gps()); } //le calcul de la similitude (7parametrs) à partir de points dans les deux reperes - cSolBasculeRig aSol = cSolBasculeRig::StdSolFromPts(mVP1,mVP2); + mBasc = cSolBasculeRig::StdSolFromPts(mVP1,mVP2); - //la pose calculée - ElRotation3D aPose(aSol.Tr(),aSol.Rot(),true); + ElRotation3D aPose(mBasc.Tr(),mBasc.Rot(),true); - /* - std::cout << "Bascule, Tr=" << aSol.Tr() << ", Lambda=" << aSol.Lambda() << "\n"; - std::cout << ", Rot=" << aSol.Rot()(0,0) << ", " << aSol.Rot()(0,1) << ", " << aSol.Rot()(0,2) << "\n" - << aSol.Rot()(1,0) << ", " << aSol.Rot()(1,1) << ", " << aSol.Rot()(1,2) << "\n" - << aSol.Rot()(2,0) << ", " << aSol.Rot()(2,1) << ", " << aSol.Rot()(2,2) << "\n"; - */ + + /*std::cout << "Bascule, Tr=" << mBasc.Tr() << ", Lambda=" << mBasc.Lambda() << "\n"; + std::cout << ", Rot=" << mBasc.Rot()(0,0) << ", " << mBasc.Rot()(0,1) << ", " << mBasc.Rot()(0,2) << "\n" + << mBasc.Rot()(1,0) << ", " << mBasc.Rot()(1,1) << ", " << mBasc.Rot()(1,2) << "\n" + << mBasc.Rot()(2,0) << ", " << mBasc.Rot()(2,1) << ", " << mBasc.Rot()(2,2) << "\n";*/ + //sauvgaurde de la pose dans l'objet de la classe for (auto aK : {0,1,2}) { - Pt3dr aPEch( mReps[aK].Ori().x * aSol.Lambda(), - mReps[aK].Ori().y * aSol.Lambda(), - mReps[aK].Ori().z * aSol.Lambda() ); + Pt3dr aPEch( mReps[aK].Ori().x * mBasc.Lambda(), + mReps[aK].Ori().y * mBasc.Lambda(), + mReps[aK].Ori().z * mBasc.Lambda() ); //calcul de la position du centre perspectif de la camera aK dans repere absolut Pt3dr aOriBasc = aPose.ImAff(aPEch); // tk + Mk * Ckj; ElMatrix aRotBasc = aPose.Mat() * mReps[aK].MatRot();// Mk * Mkj mSoms[aK]->Sol() = cGpsLoc_Rep(ElRotation3D(aOriBasc,aRotBasc,true)); - + + //sauvgarde de tous les candidates + std::vector & aSolPerTri = mSoms[aK]->SolPerTri(); + aSolPerTri.push_back(cGpsLoc_Rep(ElRotation3D(aOriBasc,aRotBasc,true))); + + //save Pds + std::vector & aPds = mSoms[aK]->Pds(); + aPds.push_back(1.0); + + if (0) + PrintCurSoms(); } } +void cGpsLoc_Triplet::PrintCurSoms() +{ + for (auto aK : {0,1,2}) + { + std::cout << "img=" << mSoms[aK]->Name() << " " << mSoms[aK]->Sol().Ori() << ", \n" + << mSoms[aK]->Sol().MatRot()(0,0) << ", " << mSoms[aK]->Sol().MatRot()(0,1) << ", " << mSoms[aK]->Sol().MatRot()(0,2) << "\n" + << mSoms[aK]->Sol().MatRot()(1,0) << ", " << mSoms[aK]->Sol().MatRot()(1,1) << ", " << mSoms[aK]->Sol().MatRot()(1,2) << "\n" + << mSoms[aK]->Sol().MatRot()(2,0) << ", " << mSoms[aK]->Sol().MatRot()(2,1) << ", " << mSoms[aK]->Sol().MatRot()(2,2) << "\n"; + } +} /* ========================================= */ @@ -245,12 +359,22 @@ class cAppliGpsLoc : public cCommonMartiniAppli cAppliGpsLoc(int argc,char ** argv); private : void InitSom(); + void CalcOptSol(); + void CalcMedErr(); + void RemoveOutliers(); + + cGpsLoc_Rep CalcL1(std::vector& aCandidateSol); + cGpsLoc_Rep CalcL1Pds(std::vector& aCandidateSol,std::vector& aPds); + + EstimType Str2Enum(std::string& aStr); std::string mDir; // Associe un nom d'image a l'objet C++ std::map mMapS; std::vector mV3; int mNbSom; + + EstimType mET; }; void cAppliGpsLoc::InitSom() @@ -258,14 +382,121 @@ void cAppliGpsLoc::InitSom() } +void cAppliGpsLoc::CalcMedErr() +{ + for(auto aS : mMapS) + aS.second->CalcMedErr(); + +} + +void cAppliGpsLoc::RemoveOutliers() +{ + for(auto aS : mMapS) + aS.second->RemoveOutliers(); +} + + +void cAppliGpsLoc::CalcOptSol() +{ + //calculate the median error per sommet + CalcMedErr(); + + //remove outliers + RemoveOutliers(); + + //calculate the optimal solution on inliers + for(auto aS : mMapS) + { + switch (mET) + { + case L1 : + aS.second->Sol() = CalcL1(aS.second->SolPerTri()); + break; + case L1Pds : + aS.second->Sol() = CalcL1Pds(aS.second->SolPerTri(),aS.second->Pds()); + break; + case L2 : //TO-DO + break; + + } + } +} + +cGpsLoc_Rep cAppliGpsLoc::CalcL1(std::vector& aCandidateSol) +{ + + int Nb = aCandidateSol.size(); + Pt3dr aOri(0,0,0); + ElMatrix aRotBasc(3,3); + + for (auto aK : aCandidateSol) + { + aOri.x += aK.Ori().x; + aOri.y += aK.Ori().y; + aOri.z += aK.Ori().z; + aRotBasc += aK.MatRot(); + } + aOri.x /= Nb; + aOri.y /= Nb; + aOri.z /= Nb; + aRotBasc *= double(1)/Nb; + aRotBasc = NearestRotation(aRotBasc); + + + return cGpsLoc_Rep(ElRotation3D(aOri,aRotBasc,true)); +} + +cGpsLoc_Rep cAppliGpsLoc::CalcL1Pds(std::vector& aCandidateSol, std::vector& aPds) +{ + + ELISE_ASSERT(aPds.size()==aCandidateSol.size(),"Incoherent size for Pds and solution candidates."); + + + int aJ=0; + double aPdsSom=0; + Pt3dr aOri(0,0,0); + ElMatrix aRotBasc(3,3); + + for (auto aK : aCandidateSol) + { + aOri.x += (aK.Ori().x * aPds.at(aJ)); + aOri.y += (aK.Ori().y * aPds.at(aJ)); + aOri.z += (aK.Ori().z * aPds.at(aJ)); + aRotBasc += (aK.MatRot() * aPds.at(aJ)); + + aPdsSom += aPds.at(aJ); + + aJ++; + } + aOri.x /= aPdsSom; + aOri.y /= aPdsSom; + aOri.z /= aPdsSom; + aRotBasc *= double(1)/aPdsSom; + aRotBasc = NearestRotation(aRotBasc); + + return cGpsLoc_Rep(ElRotation3D(aOri,aRotBasc,true)); +} + +EstimType cAppliGpsLoc::Str2Enum(std::string& aStr) +{ + if (aStr=="L1") + return L1; + else if (aStr=="L1Pds") + return L1Pds; + else + return L2; +} + cAppliGpsLoc::cAppliGpsLoc(int argc,char ** argv) : cCommonMartiniAppli (), - mDir ("./") + mDir ("./"), + mET (L1) { int tata; std::string aPat; std::string aDir; std::string aGpsOri; + std::string EstimTypeStr; cInterfChantierNameManipulateur * aICNM; @@ -277,6 +508,7 @@ cAppliGpsLoc::cAppliGpsLoc(int argc,char ** argv) : LArgMain() << EAMC(aPat,"Pattern of images", eSAM_IsExistFile) << EAMC(aGpsOri,"GPS orientation (OrientationConique)", eSAM_IsExistFile) , LArgMain() << EAM(tata,"GenOri",true,"Generate Ori, Def=true, false for quick process to RedTieP") + << EAM(EstimTypeStr,"EType",true,"L1, L1Pds, L2") << ArgCMA() ); @@ -284,6 +516,9 @@ cAppliGpsLoc::cAppliGpsLoc(int argc,char ** argv) : replace( aPat.begin(), aPat.end(), '\\', '/' ); #endif + if (EAMIsInit(&EstimTypeStr)) + mET = Str2Enum(EstimTypeStr); + SplitDirAndFile(aDir,aPat,aPat); StdCorrecNameOrient(aGpsOri,aDir);//ajoutera "Ori-" devant aGpsOri si necessaire @@ -315,7 +550,6 @@ cAppliGpsLoc::cAppliGpsLoc(int argc,char ** argv) : mMapS[aName] = new cGpsLoc_Som(aName); mMapS[aName]->Gps() = aC; - //std::cout << "+Pt3dr=" << mMapS[aName]->Gps() << "\n"; } @@ -327,7 +561,7 @@ cAppliGpsLoc::cAppliGpsLoc(int argc,char ** argv) : cXml_TopoTriplet aLT = StdGetFromSI(aNameLTriplets,Xml_TopoTriplet); //pour chaque triplets - // + verifie s'il existe son sommet + // + verifie s'il y existe son sommet // + recuper les cGpsLoc_Som correspondant a chaque image d'un triplet (absolut) // + recuper le nom de fichier qui contient l'orientation d'un triplet (relatif)(aName3R) // + lecture du fichier (aXml3Ori) @@ -359,17 +593,20 @@ cAppliGpsLoc::cAppliGpsLoc(int argc,char ** argv) : } else { // calcul pour chaque triplet -/* Commente car warning unused + for (auto a3 : mV3) { - //a faire: - //- calcul de lorientation absolute pour chaque sommet dans chaque triplet independement - // (alors on dispose de plusiers poses abs pour chaque sommet) - //- estimer la transformation de similitude (7param) la plus robuste en prennant en compte toutes les resultat + a3.InitSomTrivial(); } -*/ - } + + //calculate an optimal solution + CalcOptSol(); + + //save + for (auto aS : mMapS) + aS.second->Save(aNM); + } diff --git a/src/uti_phgrm/NewOri/NewOri.h b/src/uti_phgrm/NewOri/NewOri.h index c25fdcb21e..70820afef0 100644 --- a/src/uti_phgrm/NewOri/NewOri.h +++ b/src/uti_phgrm/NewOri/NewOri.h @@ -481,6 +481,8 @@ class cExeParalByPaquets int mNbInOnePaquet; }; +CamStenope * DefaultCamera(const std::string & aName); + diff --git a/src/uti_phgrm/NewOri/SolInitNewOri.h b/src/uti_phgrm/NewOri/SolInitNewOri.h index eaad0efc1a..a54ad7cf61 100644 --- a/src/uti_phgrm/NewOri/SolInitNewOri.h +++ b/src/uti_phgrm/NewOri/SolInitNewOri.h @@ -55,7 +55,7 @@ Header-MicMac-eLiSe-25/06/2007*/ * for a nodes to the triplet and edge it share * ... - A triplet cNOSolIn_Triplet represent a set of 3 summits. It contains the 3 submit and edges + A triplet cNOSolIn_Triplet represent a set of 3 summits. It contains the 3 summit and edges addjacent to it tSomNSI * mSoms[3]; tArcNSI * mArcs[3]; diff --git a/src/uti_phgrm/NewOri/Sources.cmake b/src/uti_phgrm/NewOri/Sources.cmake index a5d4ee141a..00a7ef715c 100644 --- a/src/uti_phgrm/NewOri/Sources.cmake +++ b/src/uti_phgrm/NewOri/Sources.cmake @@ -14,6 +14,7 @@ set(uti_phgrm_NewOri_Src_Files ${UTI_PHGRM_NEW_ORI}/cNewO_OptimTriplet.cpp ${UTI_PHGRM_NEW_ORI}/cNewO_SolGlobInit.cpp ${UTI_PHGRM_NEW_ORI}/cNewO_SolGlobInit_Build.cpp + ${UTI_PHGRM_NEW_ORI}/cNewO_SolGlobInit_RandomDFS.cpp ${UTI_PHGRM_NEW_ORI}/cNewO_SolGlob_PondApriori.cpp ${UTI_PHGRM_NEW_ORI}/cNewO_DynFusPtsMul.cpp ${UTI_PHGRM_NEW_ORI}/cNewO_Ellips.cpp @@ -28,4 +29,14 @@ list( APPEND uti_phgrm_Src_Files ${uti_phgrm_NewOri_Src_Files} ) +set(GRAPHVIZ_ENABLED 0) +if(${WITH_GRAPHVIZ}) + set(GRAPHVIZ_ENABLED 1) +endif() + + +configure_file( + ${UTI_PHGRM_NEW_ORI}/cNewO_BuildOptions.h.in + ${PROJECT_SOURCE_DIR}/include/graphes/cNewO_BuildOptions.h +) diff --git a/src/uti_phgrm/NewOri/cNewO_Appli.cpp b/src/uti_phgrm/NewOri/cNewO_Appli.cpp index 1eae0cb646..6c79f9127b 100644 --- a/src/uti_phgrm/NewOri/cNewO_Appli.cpp +++ b/src/uti_phgrm/NewOri/cNewO_Appli.cpp @@ -154,6 +154,8 @@ std::string cCommonMartiniAppli::ComParam() if (EAMIsInit(&mTStdNbMaxTriplet)) aCom += " StdNbPtTrip=" + ToString(mTStdNbMaxTriplet); if (EAMIsInit(&mTQuickNbMaxTriplet)) aCom += " QNbPtTrip=" + ToString(mTQuickNbMaxTriplet); if (EAMIsInit(&mTNbMinTriplet)) aCom += " NbTrip=" + ToString(mTNbMinTriplet); + // MPD corrige oubli !!! + if (EAMIsInit(&mExpTxt)) aCom += " ExpTxt=" + ToString(mExpTxt); return aCom; diff --git a/src/uti_phgrm/NewOri/cNewO_BuildOptions.h.in b/src/uti_phgrm/NewOri/cNewO_BuildOptions.h.in new file mode 100644 index 0000000000..097d5ce950 --- /dev/null +++ b/src/uti_phgrm/NewOri/cNewO_BuildOptions.h.in @@ -0,0 +1 @@ +#cmakedefine GRAPHVIZ_ENABLED diff --git a/src/uti_phgrm/NewOri/cNewO_CpleIm.cpp b/src/uti_phgrm/NewOri/cNewO_CpleIm.cpp index 84fd3f0f5e..0951777837 100644 --- a/src/uti_phgrm/NewOri/cNewO_CpleIm.cpp +++ b/src/uti_phgrm/NewOri/cNewO_CpleIm.cpp @@ -505,6 +505,8 @@ cNewO_OrInit2Im::cNewO_OrInit2Im aInf2 = Inf(aInf2,aP2); aSup2 = Sup(aSup2,aP2); + // std::cout << "HHhhhh " << FocMoy() << " " << aP1 << aP2 << "\n"; getchar(); + aVP1.push_back(Pt2df(aP1.x,aP1.y)); aVP2.push_back(Pt2df(aP2.x,aP2.y)); aVNb.push_back((*itC)->NbArc()); @@ -1028,13 +1030,29 @@ cNO_AppliOneCple::cNO_AppliOneCple(int argc,char **argv) : // Class cNewO_NameManager classe qui permet d'acceder a tous les nom de fichier // crees dans Martini - mNM = new cNewO_NameManager(mExtName,mPrefHom,mQuick,DirOfFile(mNameIm1),mNameOriCalib,mExpTxt ? "txt" : "dat"); + + // MPD MODIF SINON PAS TRANSMISSION DES COMMON APPLI + // mNM = new cNewO_NameManager(mExtName,mPrefHom,mQuick,DirOfFile(mNameIm1),mNameOriCalib,mExpTxt ? "txt" : "dat"); + +/* +{ + cNewO_NameManager * aNM0 = new cNewO_NameManager(mExtName,mPrefHom,mQuick,DirOfFile(mNameIm1),mNameOriCalib,mExpTxt ? "txt" : "dat"); + cNewO_OneIm* aIm0 = new cNewO_OneIm(*aNM0,mNameIm1,mGenOri); + std::cout << " 00000 IIii11KK111 " << aIm0->CS()->Focale() << aIm0->CS()->PP() << "\n"; +} +*/ + + mNM = cCommonMartiniAppli::NM(DirOfFile(mNameIm1)); // Structure d'image specialisee martini mIm1 = new cNewO_OneIm(*mNM,mNameIm1,mGenOri); mIm2 = new cNewO_OneIm(*mNM,mNameIm2,mGenOri); + // std::cout << "IIii11KK111 " << mIm1->CS() << "\n"; + // std::cout << "IIii11KK111 " << mIm1->CS()->Focale() << mIm1->CS()->PP() << "\n"; + // getchar(); + mVI.push_back(mIm1); mVI.push_back(mIm2); diff --git a/src/uti_phgrm/NewOri/cNewO_Ellips.cpp b/src/uti_phgrm/NewOri/cNewO_Ellips.cpp index bb7edf130f..a450aa3ba7 100644 --- a/src/uti_phgrm/NewOri/cNewO_Ellips.cpp +++ b/src/uti_phgrm/NewOri/cNewO_Ellips.cpp @@ -556,12 +556,12 @@ void AddEllips(cXml_Elips3D & anEl,const Pt3dr & aP,double aPds) { ELISE_ASSERT(!anEl.Norm(),"AddEllips"); anEl.CDG() = anEl.CDG() + aP * aPds; - anEl.Sxx() += aPds * aP.x * aP.x; - anEl.Syy() += aPds * aP.y * aP.y; - anEl.Szz() += aPds * aP.z * aP.z; - anEl.Sxy() += aPds * aP.x * aP.y; - anEl.Sxz() += aPds * aP.x * aP.z; - anEl.Syz() += aPds * aP.y * aP.z; + anEl.Sxx() += aPds * aPds * aP.x * aP.x; + anEl.Syy() += aPds * aPds * aP.y * aP.y; + anEl.Szz() += aPds * aPds * aP.z * aP.z; + anEl.Sxy() += aPds * aPds * aP.x * aP.y; + anEl.Sxz() += aPds * aPds * aP.x * aP.z; + anEl.Syz() += aPds * aPds * aP.y * aP.z; anEl.Pds() += aPds; } @@ -569,9 +569,9 @@ void AddEllips(cXml_Elips2D & anEl,const Pt2dr & aP,double aPds) { ELISE_ASSERT(!anEl.Norm(),"AddEllips"); anEl.CDG() = anEl.CDG() + aP * aPds; - anEl.Sxx() += aPds * aP.x * aP.x; - anEl.Syy() += aPds * aP.y * aP.y; - anEl.Sxy() += aPds * aP.x * aP.y; + anEl.Sxx() += aPds * aPds * aP.x * aP.x; + anEl.Syy() += aPds * aPds * aP.y * aP.y; + anEl.Sxy() += aPds * aPds * aP.x * aP.y; anEl.Pds() += aPds; } @@ -583,12 +583,12 @@ void NormEllips(cXml_Elips3D & anEl) anEl.CDG() = anEl.CDG() / aPds; Pt3dr aCdg = anEl.CDG(); - anEl.Sxx() = anEl.Sxx() / aPds - aCdg.x * aCdg.x; - anEl.Syy() = anEl.Syy() / aPds - aCdg.y * aCdg.y; - anEl.Szz() = anEl.Szz() / aPds - aCdg.z * aCdg.z; - anEl.Sxy() = anEl.Sxy() / aPds - aCdg.x * aCdg.y; - anEl.Sxz() = anEl.Sxz() / aPds - aCdg.x * aCdg.z; - anEl.Syz() = anEl.Syz() / aPds - aCdg.y * aCdg.z; + anEl.Sxx() = anEl.Sxx() / (aPds * aPds) - aCdg.x * aCdg.x; + anEl.Syy() = anEl.Syy() / (aPds * aPds) - aCdg.y * aCdg.y; + anEl.Szz() = anEl.Szz() / (aPds * aPds) - aCdg.z * aCdg.z; + anEl.Sxy() = anEl.Sxy() / (aPds * aPds) - aCdg.x * aCdg.y; + anEl.Sxz() = anEl.Sxz() / (aPds * aPds) - aCdg.x * aCdg.z; + anEl.Syz() = anEl.Syz() / (aPds * aPds) - aCdg.y * aCdg.z; } void NormEllips(cXml_Elips2D & anEl) { @@ -598,9 +598,9 @@ void NormEllips(cXml_Elips2D & anEl) anEl.CDG() = anEl.CDG() / aPds; Pt2dr aCdg = anEl.CDG(); - anEl.Sxx() = anEl.Sxx() / aPds - aCdg.x * aCdg.x; - anEl.Syy() = anEl.Syy() / aPds - aCdg.y * aCdg.y; - anEl.Sxy() = anEl.Sxy() / aPds - aCdg.x * aCdg.y; + anEl.Sxx() = anEl.Sxx() / (aPds * aPds) - aCdg.x * aCdg.x; + anEl.Syy() = anEl.Syy() / (aPds * aPds) - aCdg.y * aCdg.y; + anEl.Sxy() = anEl.Sxy() / (aPds * aPds) - aCdg.x * aCdg.y; } diff --git a/src/uti_phgrm/NewOri/cNewO_FicObs.cpp b/src/uti_phgrm/NewOri/cNewO_FicObs.cpp index 7d1ccf863c..e4bd2f371b 100644 --- a/src/uti_phgrm/NewOri/cNewO_FicObs.cpp +++ b/src/uti_phgrm/NewOri/cNewO_FicObs.cpp @@ -37,11 +37,14 @@ English : Header-MicMac-eLiSe-25/06/2007*/ +#include "StdAfx.h" #include "NewOri.h" #include "../TiepTri/MultTieP.h" -#include "../Apero/cPose.cpp" +#include "../Apero/cPose.h" //extern bool ERupnik_MM(); +class cAccumResidu; + ElRotation3D TestOriConvention(std::string & aNameOri, const std::string & mNameIm1, const std::string & mNameIm2); /* contains both triplets and couples; @@ -88,9 +91,9 @@ class cAppliFictObs : public cCommonMartiniAppli void InitNFHomOne(std::string&,std::string&); bool CalculateEllipseParam3(cXml_Elips3D& anEl,std::vector& aVC, - const std::string& aName1,const std::string& aName2,const std::string& aName3); + const std::string& aName1,const std::string& aName2,const std::string& aName3,int& NbPts); bool CalculateEllipseParam2(cXml_Elips3D& anEl,std::vector& aVC, - const std::string& aName1,const std::string& aName2); + const std::string& aName1,const std::string& aName2,int& NbPts); void CalculteFromHomol3(std::vector& aVC, const std::string& aName1,const std::string& aName2,const std::string& aName3, std::vector & aVPts); @@ -147,7 +150,8 @@ class cAppliFictObs : public cCommonMartiniAppli cSetTiePMul * mPMulRed; std::map mHomRed; //hom name, hom std::map> mHomMap; //cam name, cam name, hom name - std::string mHomExp; + std::string mHomExpIn; + std::string mHomExpOut; std::string mNameOriCalib; cXml_TopoTriplet mLT; @@ -187,7 +191,8 @@ cAppliFictObs::cAppliFictObs(int argc,char **argv) : mCalcElip(true), NFHom(true), mPMulRed(0), - mHomExp("dat"), + mHomExpIn("dat"), + mHomExpOut("dat"), mNameOriCalib(""), mCorrCalib(false), mCorrGlob(mCorrCalib ? true : false), @@ -200,7 +205,8 @@ cAppliFictObs::cAppliFictObs(int argc,char **argv) : mPly(false) { - bool aExpTxt=false; + bool aExpTxtIn=false; + bool aExpTxtOut=false; std::vector aNumFPtsStr; ElInitArgMain @@ -217,7 +223,8 @@ cAppliFictObs::cAppliFictObs(int argc,char **argv) : << EAM (mResPoly,"Deg",true,"Degree of polyn to smooth residuals (used only if CorCal=true), Def=2") << EAM (mResMax,"RMax",true,"Maximum residual, everything above will be filtered out, Def=5") << EAM (NFHom,"NF",true,"Save homol to new format?, Def=true") - << EAM (aExpTxt,"ExpTxt",true,"ASCII homol?, Def=true") + << EAM (aExpTxtIn,"ExpTxtIn",true,"ASCII homol old format?, Def=false") + << EAM (aExpTxtOut,"ExpTxtOut",true,"ASCII homol old format?, Def=false") << EAM (mPrefHom,"SH",true,"Homol post-fix, Def=\"\"") << EAM (mNameOriCalib,"OriCalib",true,"Calibration folder if exists, Def=\"\"") << EAM (mOut,"Out",true,"Output file name") @@ -230,7 +237,8 @@ cAppliFictObs::cAppliFictObs(int argc,char **argv) : replace( mPattern.begin(), mPattern.end(), '\\', '/' ); #endif - aExpTxt ? mHomExp="txt" : mHomExp="dat"; + aExpTxtIn ? mHomExpIn="txt" : mHomExpIn="dat"; + aExpTxtOut ? mHomExpOut="txt" : mHomExpOut="dat"; SplitDirAndFile(mDir,mPattern,mPattern); @@ -333,7 +341,7 @@ double cAppliFictObs::BsurH(ElSeg3D& aDir1,ElSeg3D& aDir2) } bool cAppliFictObs::CalculateEllipseParam2(cXml_Elips3D& anEl,std::vector& aVC, - const std::string& aName1,const std::string& aName2) + const std::string& aName1,const std::string& aName2,int& NbPts) { ELISE_ASSERT(int(aVC.size())==2,"cAppliFictObs::CalculateEllipseParam. Two cameras are required."); @@ -367,6 +375,8 @@ std::cout << " ElPackHomologue dddddddhhhhhhhhhhhhhhhhhhhhhh " << aN << " " << ElPackHomologue aPack; FromHomolToPack(aVC,aName1,aName2,aPack); + NbPts = 0; + if ( int(aPack.size()) > MinNbPtTri) { for (ElPackHomologue::const_iterator itP=aPack.begin(); itP!=aPack.end() ; itP++) @@ -406,6 +416,7 @@ std::cout << " ElPackHomologue dddddddhhhhhhhhhhhhhhhhhhhhhh " << aN << " " << // add to ellipse AddEllips(anEl,aInt,aPds); + NbPts++; } } @@ -419,7 +430,7 @@ std::cout << " ElPackHomologue dddddddhhhhhhhhhhhhhhhhhhhhhh " << aN << " " << bool cAppliFictObs::CalculateEllipseParam3(cXml_Elips3D& anEl,std::vector& aVC, - const std::string& aName1,const std::string& aName2,const std::string& aName3) + const std::string& aName1,const std::string& aName2,const std::string& aName3,int& NbPts) { ELISE_ASSERT(int(aVC.size())==3,"cAppliFictObs::CalculateEllipseParam. Three cameras are required."); @@ -516,7 +527,7 @@ bool cAppliFictObs::CalculateEllipseParam3(cXml_Elips3D& anEl,std::vector MinNbPtTri) { for (tListM::const_iterator itM=aLM.begin() ; itM!=aLM.end() ; itM++) @@ -557,7 +568,7 @@ bool cAppliFictObs::CalculateEllipseParam3(cXml_Elips3D& anEl,std::vector& aVC, { // recover tie-pts & tracks - std::string aKey = "NKS-Assoc-CplIm2Hom@"+mPrefHom+"@"+mHomExp; + std::string aKey = "NKS-Assoc-CplIm2Hom@"+mPrefHom+"@"+mHomExpIn; std::string aN = mNM->ICNM()->Assoc1To2(aKey,aName1,aName2,true); std::string aNInv = mNM->ICNM()->Assoc1To2(aKey,aName2,aName1,true); @@ -678,7 +689,7 @@ void cAppliFictObs::FromHomolToMap(std::vector& aVC, bool Hom23Inv=false; // recover tie-pts & tracks - std::string aKey = "NKS-Assoc-CplIm2Hom@" + mPrefHom + "@" + mHomExp; + std::string aKey = "NKS-Assoc-CplIm2Hom@" + mPrefHom + "@" + mHomExpIn; std::string aN12 = mNM->ICNM()->Assoc1To2(aKey,aName1,aName2,true); std::string aN12Inv = mNM->ICNM()->Assoc1To2(aKey,aName2,aName1,true); @@ -944,6 +955,9 @@ void cAppliFictObs::GenerateFicticiousObs() std::vector aVP; bool SUCCESS_ELLIPSE = false; + //Nb of points that contributed to ellipsoid generation + int aNbPts3D=0; + //triplets if (aT.second->mC3) { @@ -952,7 +966,8 @@ void cAppliFictObs::GenerateFicticiousObs() SUCCESS_ELLIPSE = CalculateEllipseParam3(anEl,aVC, mSetName->at(aT.second->mId1), mSetName->at(aT.second->mId2), - mSetName->at(aT.second->mId3)); + mSetName->at(aT.second->mId3), + aNbPts3D); //original tie-pts are used @@ -963,6 +978,9 @@ void cAppliFictObs::GenerateFicticiousObs() mSetName->at(aT.second->mId2), mSetName->at(aT.second->mId3), aVP); + + aNbPts3D = int(aVP.size()); + std::cout << "ORIGINAL PTS FOR: " << mSetName->at(aT.second->mId1) << " " << mSetName->at(aT.second->mId2) << " " << mSetName->at(aT.second->mId3) << "\n"; } @@ -975,6 +993,7 @@ void cAppliFictObs::GenerateFicticiousObs() mSetName->at(aT.second->mId3)); cXml_Ori3ImInit aXml3Ori = StdGetFromSI(aName3R,Xml_Ori3ImInit); anEl = aXml3Ori.Elips(); + aNbPts3D = aXml3Ori.NbTriplet(); } } else//cple @@ -983,7 +1002,8 @@ void cAppliFictObs::GenerateFicticiousObs() { SUCCESS_ELLIPSE = CalculateEllipseParam2(anEl,aVC, mSetName->at(aT.second->mId1), - mSetName->at(aT.second->mId2)); + mSetName->at(aT.second->mId2), + aNbPts3D); //original tie-pts are used @@ -993,6 +1013,8 @@ void cAppliFictObs::GenerateFicticiousObs() mSetName->at(aT.second->mId1), mSetName->at(aT.second->mId2), aVP); + aNbPts3D = int(aVP.size()); + std::cout << "ORIGINAL PTS FOR: " << mSetName->at(aT.second->mId1) << " " << mSetName->at(aT.second->mId2) << "\n"; } @@ -1004,6 +1026,7 @@ void cAppliFictObs::GenerateFicticiousObs() mSetName->at(aT.second->mId2),true); cXml_Ori2Im aXml2Ori = StdGetFromSI(aNamOri,Xml_Ori2Im); anEl = aXml2Ori.Geom().Val().Elips(); + aNbPts3D = aXml2Ori.NbPts(); } } @@ -1053,8 +1076,8 @@ void cAppliFictObs::GenerateFicticiousObs() if (aTriIdsIn.size() >1) { - double aPds = CalcPoids(anEl.Pds()); - + double aPds = CalcPoids(aNbPts3D); + std::vector aAttr; aAttr.push_back(aPds); @@ -1155,7 +1178,7 @@ void cAppliFictObs::GenerateFicticiousObs() SaveHomol(aSaveTo); std::cout << "cAppliFictObs::GenerateFicticiousObs()" << " "; - cout << " " << aNPtNum << " points saved. " << "\n"; + cout << " " << aNPtNum << " points saved." << "\n"; } @@ -1163,14 +1186,15 @@ void cAppliFictObs::GenerateFicticiousObs() double cAppliFictObs::CalcPoids(double aPds) { double aRes=1; - int NbPtsMax = 500; + int NbPtsMax = 100; if (mPdsFun == "C") aRes=1.0; else if (mPdsFun=="L1") aRes= aPds / double(NbPtsMax); else if (mPdsFun == "L2") - aRes = std::pow(aPds,0.3) / std::pow(NbPtsMax,0.3); + aRes = 1- ((NbPtsMax) / (aPds+NbPtsMax)); + //aRes = std::pow(aPds,0.3) / std::pow(NbPtsMax,0.3); //std::cout << "CalcPoids:" << aPds << " " << aRes << "\n"; @@ -1211,19 +1235,21 @@ void cAppliFictObs::SaveHomolOne(std::vector& aId,std::vector& aPImV std::string aN1 = mSetName->at(aId.at(aK1)); std::string aN2 = mSetName->at(aId.at(aK2)); - std::string aNameH = mNM->ICNM()->Assoc1To2("NKS-Assoc-CplIm2Hom@"+mOut+"@"+mHomExp,aN1,aN2,true); + std::string aNameH = mNM->ICNM()->Assoc1To2("NKS-Assoc-CplIm2Hom@"+mOut+"@"+mHomExpOut,aN1,aN2,true); if (DicBoolFind(mHomRed,aNameH)) { - ElCplePtsHomologues aP(aPImV.at(aK1),aPImV.at(aK2),aAttr.at(aK1));//a priori peut importe lequel K pour l'attribute comme il sera homogene par track ie par ellipse + ElCplePtsHomologues aP(aPImV.at(aK1),aPImV.at(aK2),aAttr.at(0));//a priori peut importe lequel K pour l'attribute comme il sera homogene par track ie par ellipse mHomRed[aNameH]->Cple_Add(aP); + } } } } } + } /* Updates the per image residual and the global (i.e. camera res) */ @@ -1364,14 +1390,6 @@ void cAppliFictObs::Initialize() mNM = new cNewO_NameManager("",mPrefHom,true,mDir,mNameOriCalib,"dat"); - //initialize reduced tie-points - if (NFHom) - { - mPMulRed = new cSetTiePMul(1,mSetName); - } - else - InitNFHom(); - //update triplet orientations in mTriMap @@ -1474,6 +1492,7 @@ void cAppliFictObs::Initialize() } } + if (aTriNb!=0) { mSz = mTriMap[0]->mC1->Sz(); @@ -1481,12 +1500,25 @@ void cAppliFictObs::Initialize() } else ELISE_ASSERT(false,"cAppliFictObs::Initialize no couples or triplets found"); + + + + //initialize reduced tie-points + if (NFHom) + { + mPMulRed = new cSetTiePMul(1,mSetName); + } + else + InitNFHom(); + + + } void cAppliFictObs::InitNFHomOne(std::string& N1,std::string& N2) { - std::string aNameH = mNM->ICNM()->Assoc1To2("NKS-Assoc-CplIm2Hom@"+mOut+"@"+mHomExp,N1,N2,true); + std::string aNameH = mNM->ICNM()->Assoc1To2("NKS-Assoc-CplIm2Hom@"+mOut+"@"+mHomExpOut,N1,N2,true); if (! DicBoolFind(mHomRed,aNameH)) { diff --git a/src/uti_phgrm/NewOri/cNewO_NameManager.cpp b/src/uti_phgrm/NewOri/cNewO_NameManager.cpp index 5d13b99ac7..1d0106e7c1 100644 --- a/src/uti_phgrm/NewOri/cNewO_NameManager.cpp +++ b/src/uti_phgrm/NewOri/cNewO_NameManager.cpp @@ -141,7 +141,7 @@ cInterfChantierNameManipulateur * cNewO_NameManager::ICNM() CamStenope * cInterfChantierNameManipulateur::GlobCalibOfName(const std::string & aName,const std::string & aPrefOriCal,bool aModeFraser) { - // std::cout << "cInterfChantierNameManipulateur::GlobCalibOfName \n"; getchar(); + // std::cout << "cInterfChantierNameManipulateur::GlobCalibOfName " << aPrefOriCal << "\n"; getchar(); if (aPrefOriCal =="") diff --git a/src/uti_phgrm/NewOri/cNewO_OneIm.cpp b/src/uti_phgrm/NewOri/cNewO_OneIm.cpp index 835edd454b..e5e83b8b5e 100644 --- a/src/uti_phgrm/NewOri/cNewO_OneIm.cpp +++ b/src/uti_phgrm/NewOri/cNewO_OneIm.cpp @@ -65,8 +65,7 @@ cNewO_OneIm::cNewO_OneIm mName (aName) { -// std::cout << "CSSSSSSSSSSs "<< mCS << "\n"; -// getchar(); + // std::cout << "CSSSSSSSSSSs "<< mCS << " "<< WithOri << "\n"; getchar(); // mCS = aNM.CamOfName(aName); // std::cout << "XXXXXXXXXX "<< mCS << "\n"; diff --git a/src/uti_phgrm/NewOri/cNewO_SolGlobInit_RandomDFS.cpp b/src/uti_phgrm/NewOri/cNewO_SolGlobInit_RandomDFS.cpp new file mode 100644 index 0000000000..102b69f46f --- /dev/null +++ b/src/uti_phgrm/NewOri/cNewO_SolGlobInit_RandomDFS.cpp @@ -0,0 +1,1719 @@ +/*Header-MicMac-eLiSe-25/06/2007 + + MicMac : Multi Image Correspondances par Methodes Automatiques de Correlation + eLiSe : ELements of an Image Software Environnement + + www.micmac.ign.fr + + + Copyright : Institut Geographique National + Author : Marc Pierrot Deseilligny + Contributors : Gregoire Maillet, Didier Boldo. + +[1] M. Pierrot-Deseilligny, N. Paparoditis. + "A multiresolution and optimization-based image matching approach: + An application to surface reconstruction from SPOT5-HRS stereo imagery." + In IAPRS vol XXXVI-1/W41 in ISPRS Workshop On Topographic Mapping From Space + (With Special Emphasis on Small Satellites), Ankara, Turquie, 02-2006. + +[2] M. Pierrot-Deseilligny, "MicMac, un lociel de mise en correspondance + d'images, adapte au contexte geograhique" to appears in + Bulletin d'information de l'Institut Geographique National, 2007. + +Francais : + + MicMac est un logiciel de mise en correspondance d'image adapte + au contexte de recherche en information geographique. Il s'appuie sur + la bibliotheque de manipulation d'image eLiSe. Il est distibue sous la + licences Cecill-B. Voir en bas de fichier et http://www.cecill.info. + + +English : + + MicMac is an open source software specialized in image matching + for research in geographic information. MicMac is built on the + eLiSe image library. MicMac is governed by the "Cecill-B licence". + See below and http://www.cecill.info. + +Header-MicMac-eLiSe-25/06/2007*/ + +#include "cNewO_SolGlobInit_RandomDFS.h" + + +using namespace SolGlobInit_DFS ; + + +#define MIN_WEIGHT 0.5 +#define MAX_WEIGHT 10.0 + +extern double DistBase(Pt3dr aB1,Pt3dr aB2); +extern double DistanceRot(const ElRotation3D & aR1,const ElRotation3D & aR2,double aBSurH); + +void PrintRotation(const ElMatrix Mat,const std::string Msg) +{ + std::cout << " ===R" << Msg << " === \n"; + for (int l=0; l<3; l++){ + for (int c=0; c<3; c++) + std::cout << Mat(l,c) << " "; + + std::cout << "\n"; + } +} + +//===================================================================================== +#ifdef GRAPHVIZ_ENABLED + + +GVC_t *cSolGlobInit_NRandom::GRAPHVIZ_GVCInit(const std::string& aGName) +{ + std::string Prefix = "-o"; + + int SzPref = int(Prefix.size()); + int aSzIn = int(aGName.size()); + int aSzOut = aSzIn + SzPref; + char * aGNChar = new char[aSzOut]; + + //copy the prefix of the name + for (int i=0; i cSolGlobInit_NRandom::GRAPHVIZ_GraphInit(const std::string& aGName) +{ + + GVC_t *gvc = GRAPHVIZ_GVCInit(aGName); + + char * aNG = new char[2]; + aNG[0] = 'g'; + + graph_t *g = agopen(aNG, Agdirected, 0); + + return std::pair(g,gvc); +} + +graph_t *cSolGlobInit_NRandom::GRAPHIZ_GraphRead(std::string& aFName) +{ + graph_t *g; + + FILE *fp; + + fp = fopen(aFName.c_str(), "r"); + if (fp) + { + g = agread(fp,NULL); + } + else + { + ELISE_ASSERT(false,"Could not open the graph file"); + return NULL; + } + + fclose(fp); + + return g; +} + +/* */ +void cSolGlobInit_NRandom::GRAPHIZ_GraphSerialize(std::string& aFName,graph_t *g) +{ + FILE *fp; + + fp = fopen(aFName.c_str(), "w"); + agwrite(g,fp); + fclose(fp); +} + + +void cSolGlobInit_NRandom::GRAPHIZ_GraphKill(graph_t *g,GVC_t *gvc,std::string aWriteName) +{ + gvLayoutJobs(gvc, g); + + gvRenderJobs(gvc, g); + + gvFreeLayout(gvc, g); + + //serialization of the graph + if (aWriteName != "") + { + GRAPHIZ_GraphSerialize(aWriteName,g); + } + + agclose(g); + + gvFreeContext(gvc); + +} + +void cSolGlobInit_NRandom::GRAPHIZ_NodeInit(graph_t *g, + const std::string& aName1, + const std::string& aName2, + const std::string& aName3) +{ + node_t *ns, *ms; + char *aNSNName = (char *)aName1.c_str(); + ns = agnode(g,aNSNName,1); + + + char *aMSNName = (char *)aName2.c_str(); + ms = agnode(g,aMSNName,1); + + //add the new node + node_t *os; + char * aOSNName = (char *)aName3.c_str(); + + os = agnode(g,aOSNName,1); + + //add new edges + //edge_t *e1,*e2,*e3; + agedge(g, ns, ms, 0, 1); + agedge(g, ns, os, 0, 1); + agedge(g, ms, os, 0, 1); + + char * aAttrShape= (char *)"shape"; + char * aShape= (char *)"circle"; + Agsym_t *symShape; + symShape = agattr(g,AGNODE,aAttrShape,aShape); + + if (symShape) + printf("The default shape is %s.\n",symShape->defval); + + /* changing colors removed from here; there are specific funcs to do that + * char * aC = (char *)"color"; + char * aCR = (char *)"blue"; + char aCEmpty = ' '; + + agsafeset(ns,aC,aCR,&aCEmpty); + agsafeset(ms,aC,aCR,&aCEmpty); + agsafeset(os,aC,aCR,&aCEmpty); + + agsafeset(e1,aC,aCR,&aCEmpty); + agsafeset(e2,aC,aCR,&aCEmpty); + agsafeset(e3,aC,aCR,&aCEmpty);*/ + +} + +void cSolGlobInit_NRandom::GRAPHVIZ_NodeAdd(graph_t* g, + const std::string& aName1, + const std::string& aName2, + const std::string& aName3) +{ + node_t *n, *m; + char *aNNName = (char *)aName1.c_str(); + n = agnode(g,aNNName,0); + + char *aMNName = (char *)aName2.c_str(); + m = agnode(g,aMNName,0); + + //add the new node + node_t *o; + char * aONName = (char *)aName3.c_str(); + + o = agnode(g,aONName,1); + + //add new edges + agedge(g, n, o, 0, 1); + agedge(g, m, o, 0, 1); + +} + +void cSolGlobInit_NRandom::GRAPHVIZ_EdgeChgColor(graph_t* g, + const std::string& aName1, + const std::string& aName2, + std::string aColor) +{ + char * aN1Name = (char *)aName1.c_str(); + char * aN2Name = (char *)aName2.c_str(); + + node_t *n = agnode(g,aN1Name,0); + node_t *m = agnode(g,aN2Name,0); + + edge_t *e1; + e1 = agedge(g, n, m, 0, 1); + + // Change color + char * aC = (char *)"color"; + char * aCR = (char *)aColor.c_str(); + char aCEmpty = ' '; + + + agsafeset(e1,aC,aCR,&aCEmpty); + +} + +/* Find node and change its color */ +void cSolGlobInit_NRandom::GRAPHVIZ_NodeChgColor(graph_t* g,const std::string& aName) +{ + + char * aNName = (char *)aName.c_str(); + + + char * aC = (char *)"color"; + char * aCR = (char *)"blue"; + char aCEmpty = ' '; + + node_t *n_ = agnode(g,aNName,0);//0 to indicate that it exists + agsafeset(n_,aC,aCR,&aCEmpty); + +} + +void cSolGlobInit_NRandom::WriteGraphToFile() +{ + // Clear the sommets + mVS.clear(); + + int aNumCC = 0; + + + cNOSolIn_Triplet * aTri0 = mV3[0]; + /*std::cout << "First triplet " << aTri0->KSom(0)->attr().Im()->Name() << " " + << aTri0->KSom(1)->attr().Im()->Name() << " " + << aTri0->KSom(2)->attr().Im()->Name() << "\n";*/ + + //initialise the graph + std::pair aGGVC = GRAPHVIZ_GraphInit(mGraphName); + graph_t *g = aGGVC.first; + GVC_t *gvc = aGGVC.second; + + //initialise the starting node + GRAPHIZ_NodeInit(g, + aTri0->KSom(0)->attr().Im()->Name(), + aTri0->KSom(1)->attr().Im()->Name(), + aTri0->KSom(2)->attr().Im()->Name()); + + // Create a new component + cNO_CC_TripSom * aNewCC3S = new cNO_CC_TripSom; + aNewCC3S->mNumCC = aNumCC; + mVCC.push_back(aNewCC3S); + std::vector * aCC3 = &(aNewCC3S->mTri); + + + // Add first triplet + aCC3->push_back(aTri0); + aTri0->Flag().set_kth_true(mFlag3CC);//explored + aTri0->NumCC() = aNumCC; + int aKCur = 0; + + + // Visit all sommets (not all triplets) + while (aKCur!=int(aCC3->size())) + { + cNOSolIn_Triplet * aTri1 = (*aCC3)[aKCur]; + + // For each edge of the current triplet + for (int aKA=0 ; aKA<3 ; aKA++) + { + + + // Get triplet adjacent to this edge and parse them + std::vector & aLnk = aTri1->KArc(aKA)->attr().ASym()->Lnk3(); + + for (int aKL=0 ; aKLNumCC() = aNumCC; + mVS[aLnk[aKL].S3()->attr().Im()->Name()] = aLnk[aKL].S3(); + + std::cout << aCC3->size() << "=[" << aLnk[aKL].S1()->attr().Im()->Name() ; + std::cout << "," << aLnk[aKL].S2()->attr().Im()->Name() ; + std::cout << "," << aLnk[aKL].S3()->attr().Im()->Name() << "=====\n"; + + + GRAPHVIZ_NodeAdd(g, + aLnk[aKL].S1()->attr().Im()->Name(), + aLnk[aKL].S2()->attr().Im()->Name(), + aLnk[aKL].S3()->attr().Im()->Name()); + } + } + } + aKCur++; + + } + + GRAPHIZ_GraphKill(g,gvc,mGraphName); + + // Unflag all triplets do pursue with DFS + for (int aK3=0 ; aK3Flag().set_kth_false(mFlag3CC); + mV3[aK3]->NumCC() = -1; + } + +} + +#endif + + + +cNOSolIn_Triplet::cNOSolIn_Triplet(cSolGlobInit_NRandom *anAppli,tSomNSI * aS1,tSomNSI * aS2,tSomNSI *aS3,const cXml_Ori3ImInit &aTrip) : + mAppli (anAppli), + mNb3 (aTrip.NbTriplet()), + mNumCC (-1), + mR2on1 (Xml2El(aTrip.Ori2On1())), + mR3on1 (Xml2El(aTrip.Ori3On1())), + mBOnH (aTrip.BSurH()) +{ + mSoms[0] = aS1; + mSoms[1] = aS2; + mSoms[2] = aS3; +} + + +double cNOSolIn_Triplet::CoherTest() const +{ + std::vector aVRLoc; + std::vector aVRAbs; + for (int aK=0 ; aK<3 ; aK++) + { + aVRLoc.push_back(RotOfK(aK)); + aVRAbs.push_back(mSoms[aK]->attr().TestRot()); + } + + // + cSolBasculeRig aSolRig = cSolBasculeRig::SolM2ToM1(aVRAbs,aVRLoc); + double aRes=0; + + for (int aK=0 ; aK<3 ; aK++) + { + const ElRotation3D & aRAbs = aVRAbs[aK]; + const ElRotation3D & aRLoc = aVRLoc[aK]; + ElRotation3D aRA2 = aSolRig.TransformOriC2M(aRLoc); + + double aD = DistanceRot(aRAbs,aRA2,mBOnH); + aRes += aD; + } + aRes = aRes / 3.0; + + + return aRes; +} + +tSomNSI * cLinkTripl::S1() const {return m3->KSom(mK1);} +tSomNSI * cLinkTripl::S2() const {return m3->KSom(mK2);} +tSomNSI * cLinkTripl::S3() const {return m3->KSom(mK3);} + + +cNOSolIn_AttrSom::cNOSolIn_AttrSom(const std::string & aName,cSolGlobInit_NRandom & anAppli) : + mName(aName), + mAppli(&anAppli), + mIm (new cNewO_OneIm(mAppli->NM(),mName)), + mCurRot (ElRotation3D::Id), + mTestRot (ElRotation3D::Id) + +{} + +void cNOSolIn_AttrSom::AddTriplet(cNOSolIn_Triplet * aTrip,int aK1,int aK2,int aK3) +{ + mLnk3.push_back(cLinkTripl(aTrip,aK1,aK2,aK3)); +} + + +cNOSolIn_AttrArc::cNOSolIn_AttrArc(cNOSolIn_AttrASym * anASym,bool OrASym) : + mASym (anASym), + mOrASym (OrASym) +{ +} + +static cNO_CmpTriByCost TheCmp3; + +cNOSolIn_AttrASym::cNOSolIn_AttrASym() : + mHeapTri(TheCmp3) +{ +} + +cLinkTripl * cNOSolIn_AttrASym::GetBestTri() +{ + cLinkTripl * aLnk; + if (mHeapTri.pop(aLnk)) + return aLnk; + + return 0; + + +} + +void cNOSolIn_AttrASym::AddTriplet(cNOSolIn_Triplet * aTrip,int aK1,int aK2,int aK3) +{ + mLnk3.push_back(cLinkTripl(aTrip,aK1,aK2,aK3)); + mLnk3Ptr.push_back(new cLinkTripl(aTrip,aK1,aK2,aK3)); +} + + +void cNOSolIn_Triplet::SetArc(int aK,tArcNSI * anArc) +{ + mArcs[aK] = anArc; +} + + +void cSolGlobInit_NRandom::CreateArc(tSomNSI *aS1,tSomNSI *aS2,cNOSolIn_Triplet *aTripl,int aK1,int aK2,int aK3) +{ + tArcNSI * anArc = mGr.arc_s1s2(*aS1,*aS2); + if (anArc==0) + { + cNOSolIn_AttrASym * anAttrSym = new cNOSolIn_AttrASym; + cNOSolIn_AttrArc anAttr12(anAttrSym,aS1aS2); + anArc = &(mGr.add_arc(*aS1,*aS2,anAttr12,anAttr21)); + mNbArc ++; + } + anArc->attr().ASym()->AddTriplet(aTripl,aK1,aK2,aK3); + aTripl->SetArc(aK3,anArc); +} + +cLinkTripl * cSolGlobInit_NRandom::GetBestTriDyn() +{ + cLinkTripl * aLnk; + if (mHeapTriDyn.pop(aLnk)) + return aLnk; + + return 0; + + +} + + + + +cNOSolIn_Triplet* cSolGlobInit_NRandom::GetBestTri() +{ + cNOSolIn_Triplet * aLnk; + if (mHeapTriAll.pop(aLnk)) + return aLnk; + + return 0; + + +} + +static cNO_CmpTriSolByCost TheCmp3Sol; + +cSolGlobInit_NRandom::cSolGlobInit_NRandom(int argc,char ** argv) : + mNbSom(0), + mNbTrip(0), + mFlag3CC(mAllocFlag3.flag_alloc()), + mFlagS(mGr.alloc_flag_som()), + mDebug(false), + mNbSamples(1000), + mIterCur(0), + mGraphName(""), + mHeapTriAll(TheCmp3Sol), + mHeapTriDyn(TheCmp3) + +{ + bool aModeBin = true; + + ElInitArgMain + ( + argc,argv, + LArgMain() << EAMC(mFullPat,"Pattern"), + LArgMain() << EAM(mDebug,"Debug",true,"Print some stuff, Def=false") + << EAM(mNbSamples,"Nb",true,"Number of samples, Def=1000") + << EAM(aModeBin,"Bin",true,"Binaries file, def = true",eSAM_IsBool) + << ArgCMA() +#ifdef GRAPHVIZ_ENABLED + << EAM(mGraphName,"Graph",true,"GraphViz filename") +#endif + ); + + + mEASF.Init(mFullPat); + mNM = new cNewO_NameManager(mExtName,mPrefHom,mQuick,mEASF.mDir,mNameOriCalib,"dat"); + const cInterfChantierNameManipulateur::tSet * aVIm = mEASF.SetIm(); + + + for (int aKIm=0 ; aKIm size()) ; aKIm++) + { + const std::string & aName = (*aVIm)[aKIm]; + tSomNSI & aSom = mGr.new_som(cNOSolIn_AttrSom(aName,*this)); + mMapS[aName] = &aSom; + + std::cout << mNbSom << "=" << aName << "\n"; + mNbSom++; + + } + + cXml_TopoTriplet aXml3 = StdGetFromSI(mNM->NameTopoTriplet(true),Xml_TopoTriplet); + + for + ( + std::list::const_iterator it3=aXml3.Triplets().begin() ; + it3 !=aXml3.Triplets().end() ; + it3++ + ) + { + tSomNSI * aS1 = mMapS[it3->Name1()]; + tSomNSI * aS2 = mMapS[it3->Name2()]; + tSomNSI * aS3 = mMapS[it3->Name3()]; + + ELISE_ASSERT(it3->Name1()Name2(),"Incogeherence cAppli_NewSolGolInit\n"); + ELISE_ASSERT(it3->Name2()Name3(),"Incogeherence cAppli_NewSolGolInit\n"); + + + + + if (aS1 && aS2 && aS3) + { + if (mDebug){ + std::cout << "Tri=[" << it3->Name1() << "," << it3->Name2() << "," << it3->Name3() << "\n"; + } + + mNbTrip++; + + std::string aN3 = mNM->NameOriOptimTriplet + //std::string aN3 = mNM->NameOriInitTriplet + ( + // mQuick, + aModeBin, // ModeBin + aS1->attr().Im(), + aS2->attr().Im(), + aS3->attr().Im() + ); + + + cXml_Ori3ImInit aXml3Ori = StdGetFromSI(aN3,Xml_Ori3ImInit); + + + cNOSolIn_Triplet * aTriplet = new cNOSolIn_Triplet(this,aS1,aS2,aS3,aXml3Ori); + mV3.push_back(aTriplet); + + if (mDebug) + std::cout << "% " << aN3 << " " << mV3.size() << " " << mNbTrip << "\n"; + + /// ADD-SOM-TRIPLET + aS1->attr().AddTriplet(aTriplet,1,2,0); + aS2->attr().AddTriplet(aTriplet,0,2,1); + aS3->attr().AddTriplet(aTriplet,0,1,2); + + /// ADD-EDGE-TRIPLET + CreateArc(aS1,aS2,aTriplet,0,1,2); + CreateArc(aS2,aS3,aTriplet,1,2,0); + CreateArc(aS3,aS1,aTriplet,2,0,1); + + //aTriplet->CheckArcsSom(); + + } + } + std::cout << "LOADED GRAPH " << mChrono.uval() << ", NbTrip=" << mNbTrip << "\n"; + +#ifdef GRAPHVIZ_ENABLED + + if (mGraphName!="") + { + WriteGraphToFile(); + std::cout << "SAVED GRAPHHIZ " << mChrono.uval() << "\n"; + } + +#endif +} + +/* Connected components */ + +void cSolGlobInit_NRandom::NumeroteCC() +{ + int aNumCC = 0; + + for (int aK3=0 ; aK3Flag().kth(mFlag3CC)) + { + // Create a new component + cNO_CC_TripSom * aNewCC3S = new cNO_CC_TripSom; + aNewCC3S->mNumCC = aNumCC; // give it a number + mVCC.push_back(aNewCC3S); // add it to the vector of component + std::vector * aCC3 = &(aNewCC3S->mTri); // Quick acces to vec of tri in the CC + std::vector * aCCS = &(aNewCC3S->mSoms); // Quick accessto som + + // Calcul des triplets + aCC3->push_back(aTri0); // Add triplet T0 + aTri0->Flag().set_kth_true(mFlag3CC);// Mark it as explored + aTri0->NumCC() = aNumCC; // Put right num to T0 + int aKCur = 0; + // Traditional loop of CC : while no new inexplored neighboor + while (aKCur!=int(aCC3->size())) + { + cNOSolIn_Triplet * aTri1 = (*aCC3)[aKCur]; + // For each edge of the current triplet + for (int aKA=0 ; aKA<3 ; aKA++) + { + // Get triplet adjacent to this edge and parse them + std::vector & aLnk = aTri1->KArc(aKA)->attr().ASym()->Lnk3(); + for (int aKL=0 ; aKLNumCC() = aNumCC; + } + } + } + aKCur++; + } + + // Compute the summit of the CC, it's easy, just be carrful to get them only once + int aFlagSom = mGr.alloc_flag_som(); + for (int aKT=0 ; aKTsize()) ; aKT++) + { + cNOSolIn_Triplet * aTri = (*aCC3)[aKT]; + for (int aKS=0 ; aKS<3 ; aKS++) + { + SetFlagAdd(*aCCS,aTri->KSom(aKS),aFlagSom); + } + } + + FreeAllFlag(*aCCS,aFlagSom); + mGr.free_flag_som(aFlagSom); + + std::cout << "Nb of sommets " << aCCS->size() << " in CC " << aNumCC << "\n"; + + aNumCC++; + } + } + + FreeAllFlag(mV3,mFlag3CC); + std::cout << "Nb of CCs " << aNumCC << "\n"; +} + +/* Randomly choose an adjacent triplet from a set */ +cLinkTripl * cSolGlobInit_NRandom::GetRandTri() +{ + + + cLinkTripl * aTri; + + if (int(mSCur3Adj.size())) + { + int aRndTriIdx = NRrandom3(int(mSCur3Adj.size())-1); + + + // Get the triplet + std::set::iterator it = mSCur3Adj.begin(); + std::advance(it, aRndTriIdx); + aTri = *it; + + + // Remove triplet from the set => mark as explored + mSCur3Adj.erase(it); + + + // If the sommet was in the meantime added to global solution, + // search for another one + while ( aTri->S3()->flag_kth(mFlagS) && int(mSCur3Adj.size())) + { + aRndTriIdx = NRrandom3(int(mSCur3Adj.size())-1); + + it = mSCur3Adj.begin(); + std::advance(it, aRndTriIdx); + aTri = *it; + + mSCur3Adj.erase(it); + + } + + return aTri; + } + return 0; + +} + +/* Add neighbouring/adjacent triplets to set */ +void cSolGlobInit_NRandom::AddArcOrCur(cNOSolIn_AttrASym *anArc) +{ + // Adjacent triplets + std::vector & aLnk = anArc->Lnk3(); + + for (int aK=0; aK< int(aLnk.size()); aK++) + { + + + // Test if the sommet S3 exists + if (! aLnk.at(aK).S3()->flag_kth(mFlagS)) + { + mSCur3Adj.insert(&(aLnk.at(aK))); + + } + // If S3 exists, try to add triplets adjacent to edges: S1-S3 and S2-S3 + else + { + /*std::cout << "Sommet Already added=" + << aLnk.at(aK).S1()->attr().Im()->Name() << " " + << aLnk.at(aK).S2()->attr().Im()->Name() << " " + << aLnk.at(aK).S3()->attr().Im()->Name() << "\n";*/ + + for (int aKArc=0; aKArc<3; aKArc++) + { + if (anArc!=aLnk.at(aK).m3->KArc(aKArc)->attr().ASym()) + { + // Secondary triplets adjacent to S1-S3 or S2-S3 + std::vector & aLnkSec = aLnk.at(aK).m3->KArc(aKArc)->attr().ASym()->Lnk3(); + + for (int aT=0; aT< int(aLnkSec.size()); aT++) + { + // Test if the "collateral" sommet S3 exists + if (! aLnkSec.at(aT).S3()->flag_kth(mFlagS)) + { + mSCur3Adj.insert(&(aLnkSec.at(aT))); + } + } + } + } + } + } +} + + +void cSolGlobInit_NRandom::EstimRt(cLinkTripl * aLnk) +{ + + // Get sommets + tSomNSI * aS1 = aLnk->S1(); + tSomNSI * aS2 = aLnk->S2(); + tSomNSI * aS3 = aLnk->S3(); + + // Get current R,t of the mother pair + ElRotation3D aC1ToM = aS1->attr().CurRot(); + ElRotation3D aC2ToM = aS2->attr().CurRot(); + + // Get rij,tij of the triplet sommets + const ElRotation3D aC1ToL = aLnk->m3->RotOfSom(aS1); + const ElRotation3D aC2ToL = aLnk->m3->RotOfSom(aS2); + const ElRotation3D aC3ToL = aLnk->m3->RotOfSom(aS3); + + // Propagate R,t according to: + // aC1ToM.tr() = T0 + aRL2M * aC1ToL.tr() * Lambda + // + // 1-R + ElMatrix aRL2Mprim = aC1ToM.Mat() * aC1ToL.Mat().transpose(); + ElMatrix aRL2Mbis = aC2ToM.Mat() * aC2ToL.Mat().transpose(); + ElMatrix aRL2M = NearestRotation((aRL2Mprim+aRL2Mbis)*0.5); + + + + // 2-Lambda + double d12L = euclid(aC2ToL.tr() - aC1ToL.tr()); + double d12M = euclid(aC2ToM.tr() - aC1ToM.tr()); + double Lambda = d12M / ElMax(d12L,1e-20); + + + // 3-t + Pt3dr aC1ToLRot = aRL2M * aC1ToL.tr(); + Pt3dr aC2ToLRot = aRL2M * aC2ToL.tr(); + + Pt3dr T0prim = aC1ToM.tr() - aC1ToLRot * Lambda; + Pt3dr T0bis = aC2ToM.tr() - aC2ToLRot * Lambda; + Pt3dr T0 = (T0prim+T0bis) /2.0; + + Pt3dr aT3 = T0 + aRL2M * aC3ToL.tr() * Lambda; + + // 4- Set R3,t3 + aS3->attr().CurRot() = ElRotation3D(aT3,aRL2M*aC3ToL.Mat(),true); + aS3->attr().TestRot() = ElRotation3D(aT3,aRL2M*aC3ToL.Mat(),true);//used in coherence + + // Mark node as vistied + aS3->flag_set_kth_true(mFlagS); +} + +void cSolGlobInit_NRandom::RandomSolOneCC(cNOSolIn_Triplet * aSeed,int NbSomCC) +{ + int aNumCCSom=0; + + for (int aK=0; aK<3; aK++) + { + // Set the current R,t of the seed + aSeed->KSom(aK)->attr().CurRot() = aSeed->RotOfSom(aSeed->KSom(aK)); + + // Mark as explored + aSeed->KSom(aK)->flag_set_kth_true(mFlagS); + + // Mark the concatenation order + aSeed->KSom(aK)->attr().NumCC() = ++aNumCCSom; + + // Add the seed to the set of adj triplets + AddArcOrCur(aSeed->KArc(aK)->attr().ASym()); + } + + + int Cpt=0; + cLinkTripl * aTri=0; + while ((aTri = GetRandTri()) && ((Cpt+3)S1()->attr().Im()->Name() << " " + << aTri->S2()->attr().Im()->Name() << " " + << aTri->S3()->attr().Im()->Name() << "\n";*/ + + // Flag as visted + aTri->m3->Flag().set_kth_true(mFlag3CC); + + // Flag the concatenation order + aTri->S3()->attr().NumCC() = ++aNumCCSom; + + // Propagate R,t and flag sommet as visited + EstimRt(aTri); + + // Add two new edges and their respective adjacent triplets + AddArcOrCur(aTri->m3->KArc(0)->attr().ASym()); + AddArcOrCur(aTri->m3->KArc(1)->attr().ASym()); + AddArcOrCur(aTri->m3->KArc(2)->attr().ASym()); + + Cpt++; + } + + std::cout << "In this CC, nb of connected nodes " << Cpt+3 << "\n"; + + + + +} + + +void cSolGlobInit_NRandom::RandomSolOneCC(cNO_CC_TripSom * aCC) +{ + + NRrandom3InitOfTime(); + std::cout << "DFS per CC, Nb Som " << aCC->mSoms.size() << ", nb triplets " << aCC->mTri.size() << "\n"; + + + // Select random seed triplet + int aSeed = NRrandom3(int(aCC->mTri.size()-1)); + + cNOSolIn_Triplet * aTri0 = aCC->mTri[aSeed]; + std::cout << "Seed triplet " << aTri0->KSom(0)->attr().Im()->Name() << " " + << aTri0->KSom(1)->attr().Im()->Name() << " " + << aTri0->KSom(2)->attr().Im()->Name() << "\n"; + + + // Flag as visited + aTri0->Flag().set_kth_true(mFlag3CC); + + ELISE_ASSERT(aTri0!=0,"Cannot compute seed in RandomSolOneCC"); + + // Build the initial solution in this CC + RandomSolOneCC(aTri0,aCC->mSoms.size()); + + // Calculate coherence scores within this CC + CoherTriplets(aCC->mTri); + //CoherTripletsGraphBased(aCC->mTri); + + // Save + //std::string aOutOri = "DSF_Init" + ToString(mIterCur); + //Save(aOutOri); + + // Print + //for (int aK=0; aKmSoms.size()); aK++) + // std::cout << aCC->mSoms[aK]->flag_kth(mFlagS) << ", " << aCC->mSoms[aK]->attr().Im()->Name() << "\n"; + + // Free flags + FreeAllFlag(aCC->mSoms,mFlagS); + FreeAllFlag(aCC->mTri,mFlag3CC); + + // Free the set of current unvisted adjacent triplets + mSCur3Adj.clear(); + + // Reset the concatenation order + FreeSomNumCCFlag(); +} + +void cSolGlobInit_NRandom::AddTriOnHeap(cLinkTripl *aLnk) +{ + std::vector aVMaj; + + std::vector aSIdx {aLnk->mK1,aLnk->mK2,aLnk->mK3}; + for (int aK=0; aK<3; aK++) + { + std::vector & aVT = aLnk->m3->KArc(aSIdx[aK])->attr().ASym()->Lnk3Ptr(); + + for (int aT=0; aT< int(aVT.size()); aT++) + { + + // If triplet was not visited + if ( !aVT[aT]->m3->Flag().kth(mFlag3CC)) + { + + // Add to heap + mHeapTriDyn.push(aVT[aT]); + + // Push to aVMaj + aVMaj.push_back(aVT[aT]); + + // Flag as marked + aVT[aT]->m3->Flag().set_kth_true(mFlag3CC); + + /*std::cout << "___________ " ; + std::cout << "added triplet Lnk " + << aVT[aT]->S1()->attr().Im()->Name() << " " + << aVT[aT]->S2()->attr().Im()->Name() << " " + << aVT[aT]->S3()->attr().Im()->Name() << "\n";*/ + + + + } + } + } + + for (int aK=0; aKmSoms.size()); + + // Pick the best triplet + cNOSolIn_Triplet * aTri0 = GetBestTri(); + std::cout << "Best triplet " << aTri0->KSom(0)->attr().Im()->Name() << " " + << aTri0->KSom(1)->attr().Im()->Name() << " " + << aTri0->KSom(2)->attr().Im()->Name() << " " + << aTri0->CostArc() << "\n"; + + // Flag triplet as marked + aTri0->Flag().set_kth_true(mFlag3CC); + + + for (int aK=0; aK<3; aK++) + { + // Flag sommets as explored + aTri0->KSom(aK)->flag_set_kth_true(mFlagS); + + // Set the current R,t of the seed + aTri0->KSom(aK)->attr().CurRot() = aTri0->RotOfSom(aTri0->KSom(aK)); + + //PrintRotation(aTri0->KSom(aK)->attr().CurRot().Mat(),ToString(aK)); + + + } + + // Fill the dynamic heap with triplets connected to this triplet + cLinkTripl * aLnk0 = new cLinkTripl(aTri0,0,1,2); + AddTriOnHeap(aLnk0); + + + // Iterate to build the solution while updating the heap + int Cpt=0; + cLinkTripl * aTriNext=0; + while ( (aTriNext=GetBestTriDyn()) && ((Cpt+3)S3()->flag_kth(mFlagS)) + { + std::cout << "=== Add new node " << Cpt << " " + << aTriNext->S1()->attr().Im()->Name() << " " + << aTriNext->S2()->attr().Im()->Name() << " " + << aTriNext->S3()->attr().Im()->Name() << " " + << aTriNext->m3->CostArc() << "\n"; + + + /*PrintRotation(aTriNext->S1()->attr().CurRot().Mat(),"0"); + PrintRotation(aTriNext->S2()->attr().CurRot().Mat(),"1"); + PrintRotation(aTriNext->S3()->attr().CurRot().Mat(),"2");*/ + + + // Propagate R,t + EstimRt(aTriNext); + + + // Add to heap + AddTriOnHeap(aTriNext); + + Cpt++; + + } + else // however, try to adjacent triplets of that triplet + { + + // Add to heap + AddTriOnHeap(aTriNext); + + } + + } + + std::cout << "Nb final sommets=" << Cpt+3 << ", out of " << NbSomCC << "\n"; + + +} + + + +void cSolGlobInit_NRandom::RandomSolAllCC() +{ + std::cout << "Nb of connected components=" << mVCC.size() << "\n"; + for (int aKC=0 ; aKCKSom(0)->attr().Im()->Name() << " " + << aTri0->KSom(1)->attr().Im()->Name() << " " + << aTri0->KSom(2)->attr().Im()->Name() << "\n"; + + if (UseCoherence) + { + aTri0 = GetBestTri(); + std::cout << "Best triplet " << aTri0->KSom(0)->attr().Im()->Name() << " " + << aTri0->KSom(1)->attr().Im()->Name() << " " + << aTri0->KSom(2)->attr().Im()->Name() << " " + << aTri0->CostArc() << "\n"; + } + + mVS[aTri0->KSom(0)->attr().Im()->Name()] = aTri0->KSom(0); + mVS[aTri0->KSom(1)->attr().Im()->Name()] = aTri0->KSom(1); + mVS[aTri0->KSom(2)->attr().Im()->Name()] = aTri0->KSom(2); + + // Set the current R,t of the seed + aTri0->KSom(0)->attr().CurRot() = aTri0->RotOfSom(aTri0->KSom(0)); + aTri0->KSom(1)->attr().CurRot() = aTri0->RotOfSom(aTri0->KSom(1)); + aTri0->KSom(2)->attr().CurRot() = aTri0->RotOfSom(aTri0->KSom(2)); + + getchar(); + +#ifdef GRAPHVIZ_ENABLED + + + // Read the graph from a file (contains all triplets possible) + const std::string aGCurName = "Gr_"+ (UseCoherence ? "BestInit" : ToString(mIterCur)); + + graph_t *g = GRAPHIZ_GraphRead(mGraphName); + GVC_t *gvc = GRAPHVIZ_GVCInit(aGCurName); + + + // Mark the seed triplet in red + GRAPHVIZ_NodeChgColor(g,aTri0->KSom(0)->attr().Im()->Name()); + GRAPHVIZ_NodeChgColor(g,aTri0->KSom(1)->attr().Im()->Name()); + GRAPHVIZ_NodeChgColor(g,aTri0->KSom(2)->attr().Im()->Name()); + + GRAPHVIZ_EdgeChgColor(g, + aTri0->KSom(0)->attr().Im()->Name(), + aTri0->KSom(1)->attr().Im()->Name(), + "blue"); + GRAPHVIZ_EdgeChgColor(g, + aTri0->KSom(0)->attr().Im()->Name(), + aTri0->KSom(2)->attr().Im()->Name(), + "blue"); + GRAPHVIZ_EdgeChgColor(g, + aTri0->KSom(1)->attr().Im()->Name(), + aTri0->KSom(2)->attr().Im()->Name(), + "blue"); +#endif + + + // Create a new component + cNO_CC_TripSom * aNewCC3S = new cNO_CC_TripSom; + aNewCC3S->mNumCC = aNumCC; + mVCC.push_back(aNewCC3S); + std::vector * aCC3 = &(aNewCC3S->mTri); // Quick acces to vec of tri in the CC + // std::vector * aCCS = &(aNewCC3S->mSoms); // Quick access to som + + + + + // Calcul des triplets + aCC3->push_back(aTri0); // Add triplet T0 + + //aTri0->Flag().set_kth_true(mFlag3CC);// Mark it as explored + //aTri0->NumCC() = aNumCC; // Put right num to T0 + + + + // Visit all sommets (not all triplets) + while (int(mVS.size())!=mNbSom) + { + if (mDebug) + std::cout << int(mVS.size()) << "/" << mNbSom << " " ; + + // Randomly select a triplet (out of visited ones) + int t_r = NRrandom3(int(aCC3->size())); + if (mDebug) + std::cout << ", trip_r=" << t_r << "/" << int(aCC3->size()) << " "; + + + cNOSolIn_Triplet * aTri1 = (*aCC3)[t_r]; + + + // Randomly select an edge e_r + int e_r = NRrandom3(3); + + if (mDebug) + std::cout << ", edge_r=" << e_r << "/3 " ; + + //Triplets adjacent to edge e_r + std::vector & aLnk = aTri1->KArc(e_r)->attr().ASym()->Lnk3(); + + + // Pick an edge adjacent to e_r (best or random) + int e_a = NRrandom3(int(aLnk.size())); + + cLinkTripl TriAdjCur = aLnk[e_a]; + if (UseCoherence) + { + cLinkTripl * TriAdjCurPtr; + // If no best exists, it will take a random edge + if ((TriAdjCurPtr = aTri1->KArc(e_r)->attr().ASym()->GetBestTri())) + TriAdjCur = *TriAdjCurPtr; + } + /*cLinkTripl TriAdjCur = (UseCoherence ? *(aTri1->KArc(e_r)->attr().ASym()->GetBestTri()) + : aLnk[e_a]);*/ + + if (mDebug) + std::cout << ", edge_a=" << e_a << "/" << int(aLnk.size()) << "\n"; + + + + + // If not marked, mark it and push it in aCC3, return it was added + if (! DicBoolFind(mVS,TriAdjCur.S3()->attr().Im()->Name())) + { + //TriAdjCur.m3->NumCC() = aNumCC; + mVS[TriAdjCur.S3()->attr().Im()->Name()] = TriAdjCur.S3(); + + //Update aCC3 + aCC3->push_back(TriAdjCur.m3); + + // Get sommets + tSomNSI * aS1 = TriAdjCur.S1(); + tSomNSI * aS2 = TriAdjCur.S2(); + tSomNSI * aS3 = TriAdjCur.S3(); + + // Get current R,t of the mother pair + ElRotation3D aC1ToM = aS1->attr().CurRot(); + ElRotation3D aC2ToM = aS2->attr().CurRot(); + + // Get rij,tij of the triplet sommets + const ElRotation3D aC1ToL = TriAdjCur.m3->RotOfSom(aS1); + const ElRotation3D aC2ToL = TriAdjCur.m3->RotOfSom(aS2); + const ElRotation3D aC3ToL = TriAdjCur.m3->RotOfSom(aS3); + + // Propagate R,t according to: + // aC1ToM.tr() = T0 + aRL2M * aC1ToL.tr() * Lambda + // + // 1-R + ElMatrix aRL2Mprim = aC1ToM.Mat() * aC1ToL.Mat().transpose(); + ElMatrix aRL2Mbis = aC2ToM.Mat() * aC2ToL.Mat().transpose(); + ElMatrix aRL2M = NearestRotation((aRL2Mprim+aRL2Mbis)*0.5); + + + + // 2-Lambda + double d12L = euclid(aC2ToL.tr() - aC1ToL.tr()); + double d12M = euclid(aC2ToM.tr() - aC1ToM.tr()); + double Lambda = d12M / ElMax(d12L,1e-20); + + + // 3-t + Pt3dr aC1ToLRot = aRL2M * aC1ToL.tr(); + Pt3dr aC2ToLRot = aRL2M * aC2ToL.tr(); + + Pt3dr T0prim = aC1ToM.tr() - aC1ToLRot * Lambda; + Pt3dr T0bis = aC2ToM.tr() - aC2ToLRot * Lambda; + Pt3dr T0 = (T0prim+T0bis) /2.0; + + Pt3dr aT3 = T0 + aRL2M * aC3ToL.tr() * Lambda; + + // 4- Set R3,t3 + aS3->attr().CurRot() = ElRotation3D(aT3,aRL2M*aC3ToL.Mat(),true); + aS3->attr().TestRot() = ElRotation3D(aT3,aRL2M*aC3ToL.Mat(),true);//used in coherence + + + + std::cout << "=== " << TriAdjCur.S1()->attr().Im()->Name() << " " + << TriAdjCur.S2()->attr().Im()->Name() << " " + << TriAdjCur.S3()->attr().Im()->Name() << ", Cost=" + << TriAdjCur.m3->CostArc() << "\n"; + +#ifdef GRAPHVIZ_ENABLED + /* Only edge between 2-3 is drawn */ + GRAPHVIZ_EdgeChgColor(g, + TriAdjCur.S2()->attr().Im()->Name(), + TriAdjCur.S3()->attr().Im()->Name()); +#endif + + } + + + } + + + // Calculate coherence scores + CoherTriplets(); + + // Save + std::string aOutOri = "DSF_" + (UseCoherence ? "BestInit" : ToString(mIterCur)); + Save(aOutOri); + + std::cout << "NbTriii " << aCC3->size() << " NbSooom " << mVS.size() << "\n"; + +#ifdef GRAPHVIZ_ENABLED + GRAPHIZ_GraphKill(g,gvc); +#endif +} + + + +void cSolGlobInit_NRandom::CoherTripletsGraphBased(std::vector& aV3) +{ + int Nb = int(aV3.size()); + + double a1 = (MAX_WEIGHT - MIN_WEIGHT)/ElMax(Nb-1,1); + double a2 = (MIN_WEIGHT*Nb - MAX_WEIGHT)/ElMax(Nb-1,1); + + for (int aT=0; aTKSom(0)->attr().NumCC(), + aV3[aT]->KSom(1)->attr().NumCC()); + int aEB2 = ElMin(aV3[aT]->KSom(2)->attr().NumCC(), + ElMax(aV3[aT]->KSom(0)->attr().NumCC(), + aV3[aT]->KSom(1)->attr().NumCC())); + + int aDist = ElMax(aEB1,aEB2); + + + double aCostCur = ElMin(abs(aV3[aT]->CoherTest()),1e9); + + aV3[aT]->CostArcPerSample().push_back(aCostCur/(a1*aDist+a2)); + + //std::cout << "aDist=" << aDist << ", CNom=" << aCostCur << ", Pds=" << (a1*aDist+a2) << ", CPds=" << aCostCur/(a1*aDist+a2) << "\n"; + } + //getchar(); +} + +void cSolGlobInit_NRandom::CoherTriplets(std::vector& aV3) +{ + + for (int aT=0; aTCoherTest()),1e9); + aV3[aT]->CostArcPerSample().push_back(aCostCur); + + //std::cout << "cost=" << aCostCur << "\n"; + } + +} + + + +void cSolGlobInit_NRandom::CoherTriplets() +{ + //std::cout << "size CostArcPerSample=" << int(mV3[0]->CostArcPerSample().size()) << "\n"; + + for (int aT=0; aTCoherTest()),1e9); + mV3[aT]->CostArcPerSample().push_back(aCostCur); + + //std::cout << "cost=" << aCostCur << "\n"; + } + +} + +void cSolGlobInit_NRandom::CoherTripletsAllSamples() +{ + for (int aT=0; aTCostArc() = KthValProp(mV3[aT]->CostArcPerSample(),0.8); + mV3[aT]->CostArcMed() = MedianeSup(mV3[aT]->CostArcPerSample()); + + /*std::cout << "Ec80=" << mV3[aT]->CostArc() << + ", MED=" << mV3[aT]->CostArcMed() << " " << + mV3[aT]->KSom(0)->attr().Im()->Name() << " " << + mV3[aT]->KSom(1)->attr().Im()->Name() << " " << + mV3[aT]->KSom(2)->attr().Im()->Name() << "\n";*/ + } +} + +/* This heap will serve to GetBestTri when building the ultimate init solution */ +void cSolGlobInit_NRandom::HeapPerEdge() +{ + + // For all triplets + for (auto aTri : mV3) + { + + // For each edge of the current triplet + for (int aK=0; aK<3; aK++) + { + std::vector & aLnk = aTri->KArc(aK)->attr().ASym()->Lnk3Ptr(); + + // For all adjacent triplets to the current edge + for (auto aTriAdj : aLnk) + { + // Push to heap + aTri->KArc(aK)->attr().ASym()->mHeapTri.push(aTriAdj); + } + + // Order index + for (auto aTriAdj : aLnk) + { + aTri->KArc(aK)->attr().ASym()->mHeapTri.MAJ(aTriAdj); + } + } + + } + + +} + + +void cSolGlobInit_NRandom::HeapPerSol() +{ + // Update heap + for (auto aTri : mV3) + { + mHeapTriAll.push(aTri); + } + + // Order index + for (auto aTri : mV3) + { + mHeapTriAll.MAJ(aTri); + } +} + +void cSolGlobInit_NRandom::FreeSomNumCCFlag() +{ + for (tItSNSI anItS=mGr.begin(mSubAll) ; anItS.go_on(); anItS++) + { + (*anItS).attr().NumCC() = 0; + } +} + +void cSolGlobInit_NRandom::Save(std::string& OriOut,bool SaveListOfName) +{ + + std::list aListOfName; + + for (tItSNSI anItS=mGr.begin(mSubAll) ; anItS.go_on(); anItS++) + { + if ((*anItS).flag_kth(mFlagS)) + { + cNewO_OneIm * anI = (*anItS).attr().Im(); + std::string aNameIm = anI->Name(); + CamStenope * aCS = anI->CS(); + ElRotation3D aROld2Cam = (*anItS).attr().CurRot().inv(); + + aCS->SetOrientation(aROld2Cam); + + cOrientationConique anOC = aCS->StdExportCalibGlob(); + anOC.Interne().SetNoInit(); + + std::string aFileIterne = mNM->ICNM()->StdNameCalib(mNameOriCalib,aNameIm); + + std::string aNameOri = mNM->ICNM()->Assoc1To1("NKS-Assoc-Im2Orient@-"+OriOut,aNameIm,true); + anOC.FileInterne().SetVal (NameWithoutDir(aFileIterne)); + + // Copy interior orientation + std::string aCom = "cp " + aFileIterne + " " + DirOfFile(aNameOri); + System(aCom); + + aListOfName.push_back(aNameIm); + + MakeFileXML(anOC,aNameOri); + } + } + + if (SaveListOfName) + { + cListOfName aLOF; + aLOF.Name() = aListOfName; + MakeFileXML(aLOF,"ListPattern_" + OriOut + ".xml"); + } +} + + +void cSolGlobInit_NRandom::ShowTripletCost() +{ + for (auto aTri : mV3) + { + std::cout << "[" << aTri->KSom(0)->attr().Im()->Name() << "," + << aTri->KSom(1)->attr().Im()->Name() << "," + << aTri->KSom(2)->attr().Im()->Name() << "], " + << " Cost=" << aTri->CostArc() << " ,MED=" << aTri->CostArcMed() << "\n"; + } +} + +void cSolGlobInit_NRandom::DoRandomDFS() +{ + for (mIterCur=0; mIterCurNameTopoTriplet(true),Xml_TopoTriplet); + mNbTri = int(aXml3.Triplets().size()); + + + // Identify a set of random triplets that will become outliers + std::set aOutlierList; + if (mRatioOutlier>0) + { + int aNbOutliers = std::floor(mRatioOutlier * mNbTri); + + + + + for (int aK=0; aK::const_iterator it3=aXml3.Triplets().begin() ; + it3 !=aXml3.Triplets().end() ; + it3++ + ) + { + + bool Ok; + std::pair aPair = mNM->OriRelTripletFromExisting( + InOri, + it3->Name1(), + it3->Name2(), + it3->Name3(), + Ok); + + std::string aNameSauveXml = mNM->NameOriOptimTriplet(false,it3->Name1(),it3->Name2(),it3->Name3(),false); + std::string aNameSauveBin = mNM->NameOriOptimTriplet(true ,it3->Name1(),it3->Name2(),it3->Name3(),false); + + cXml_Ori3ImInit aXml; + + if (DicBoolFind(aOutlierList,aK)) + { + aXml.Ori2On1() = El2Xml(ElRotation3D(aPair.first.tr(),RandPeturbR(),true)); + aXml.Ori3On1() = El2Xml(ElRotation3D(aPair.second.tr(),RandPeturbR(),true)); + std::cout << "Perturbed R=["<< it3->Name1() <<","<< it3->Name2() << "," << it3->Name3() + << "], " << aPair.first.tr() << " " << aPair.second.tr() << "\n"; + } + else + { + aXml.Ori2On1() = El2Xml(ElRotation3D(aPair.first.tr(),aPair.first.Mat(),true)); + aXml.Ori3On1() = El2Xml(ElRotation3D(aPair.second.tr(),aPair.second.Mat(),true)); + + } + + + MakeFileXML(aXml,aNameSauveXml); + MakeFileXML(aXml,aNameSauveBin); + + + aK++; + } +} + + +ElMatrix cAppliGenOptTriplets::RandPeturbR() +{ + + double aW[] = {NRrandom3(),NRrandom3(),NRrandom3()}; + + Pt3dr aI(exp(0),exp(aW[2]),exp(-aW[1])); + Pt3dr aJ(exp(-aW[2]),exp(0),exp(aW[0])); + Pt3dr aK(exp(aW[1]),exp(-aW[0]),exp(0)); + + ElMatrix aRes = MatFromCol(aI,aJ,aK); + + + return aRes; +} + + +int CPP_GenOptTriplets(int argc,char ** argv) +{ + + cAppliGenOptTriplets aAppGenTri(argc,argv); + + return EXIT_SUCCESS; +} + + + +/*Footer-MicMac-eLiSe-25/06/2007 + +Ce logiciel est un programme informatique servant à la mise en +correspondances d'images pour la reconstruction du relief. + +Ce logiciel est régi par la licence CeCILL-B soumise au droit français et +respectant les principes de diffusion des logiciels libres. Vous pouvez +utiliser, modifier et/ou redistribuer ce programme sous les conditions +de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA +sur le site "http://www.cecill.info". + +En contrepartie de l'accessibilité au code source et des droits de copie, +de modification et de redistribution accordés par cette licence, il n'est +offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, +seule une responsabilité restreinte pèse sur l'auteur du programme, le +titulaire des droits patrimoniaux et les concédants successifs. + +A cet égard l'attention de l'utilisateur est attirée sur les risques +associés au chargement, à l'utilisation, à la modification et/ou au +développement et à la reproduction du logiciel par l'utilisateur étant +donné sa spécificité de logiciel libre, qui peut le rendre complexe à +manipuler et qui le réserve donc à des développeurs et des professionnels +avertis possédant des connaissances informatiques approfondies. Les +utilisateurs sont donc invités à charger et tester l'adéquation du +logiciel à leurs besoins dans des conditions permettant d'assurer la +sécurité de leurs systèmes et ou de leurs données et, plus généralement, +à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. + +Le fait que vous puissiez accéder à cet en-tête signifie que vous avez +pris connaissance de la licence CeCILL-B, et que vous en avez accepté les +termes. +Footer-MicMac-eLiSe-25/06/2007*/ + diff --git a/src/uti_phgrm/NewOri/cNewO_SolGlobInit_RandomDFS.h b/src/uti_phgrm/NewOri/cNewO_SolGlobInit_RandomDFS.h new file mode 100644 index 0000000000..aa0825c747 --- /dev/null +++ b/src/uti_phgrm/NewOri/cNewO_SolGlobInit_RandomDFS.h @@ -0,0 +1,449 @@ +/*Header-MicMac-eLiSe-25/06/2007 + + MicMac : Multi Image Correspondances par Methodes Automatiques de Correlation + eLiSe : ELements of an Image Software Environnement + + www.micmac.ign.fr + + + Copyright : Institut Geographique National + Author : Marc Pierrot Deseilligny + Contributors : Gregoire Maillet, Didier Boldo. + +[1] M. Pierrot-Deseilligny, N. Paparoditis. + "A multiresolution and optimization-based image matching approach: + An application to surface reconstruction from SPOT5-HRS stereo imagery." + In IAPRS vol XXXVI-1/W41 in ISPRS Workshop On Topographic Mapping From Space + (With Special Emphasis on Small Satellites), Ankara, Turquie, 02-2006. + +[2] M. Pierrot-Deseilligny, "MicMac, un lociel de mise en correspondance + d'images, adapte au contexte geograhique" to appears in + Bulletin d'information de l'Institut Geographique National, 2007. + +Francais : + + MicMac est un logiciel de mise en correspondance d'image adapte + au contexte de recherche en information geographique. Il s'appuie sur + la bibliotheque de manipulation d'image eLiSe. Il est distibue sous la + licences Cecill-B. Voir en bas de fichier et http://www.cecill.info. + + +English : + + MicMac is an open source software specialized in image matching + for research in geographic information. MicMac is built on the + eLiSe image library. MicMac is governed by the "Cecill-B licence". + See below and http://www.cecill.info. + +Header-MicMac-eLiSe-25/06/2007*/ + + +#include "NewOri.h" +//#include "general/CMake_defines.h" +#include "graphes/cNewO_BuildOptions.h" + +#ifdef GRAPHVIZ_ENABLED + #include +#endif + + + +namespace SolGlobInit_DFS { + + +#define MIN_LNK_SEED 4 +#define MAX_SAMPLE_SEED 50 + +class cNOSolIn_AttrSom; +class cNOSolIn_AttrASym; +class cNOSolIn_AttrArc; +class cNOSolIn_Triplet; +class cLinkTripl; +class cSolGlobInit_NRandom; +class cNO_HeapIndTri_NSI; +class cNO_CmpTriByCost; + +typedef ElSom tSomNSI; +typedef ElArc tArcNSI; +typedef ElSomIterator tItSNSI; +typedef ElArcIterator tItANSI; +typedef ElGraphe tGrNSI; +typedef ElSubGraphe tSubGrNSI; + +typedef ElHeap tHeapTriNSI; + + +class cNOSolIn_AttrSom +{ + public : + cNOSolIn_AttrSom() : + mCurRot (ElRotation3D::Id), + mTestRot (ElRotation3D::Id), + mNumCC(0) {} + cNOSolIn_AttrSom(const std::string & aName,cSolGlobInit_NRandom & anAppli); + + + void AddTriplet(cNOSolIn_Triplet *,int aK0,int aK1,int aK2); + cNewO_OneIm * Im() {return mIm;} + ElRotation3D & CurRot() {return mCurRot;} + ElRotation3D & TestRot() {return mTestRot;} + + std::vector & Lnk3() {return mLnk3;} + int & NumCC() {return mNumCC;} + + private: + std::string mName; + cSolGlobInit_NRandom * mAppli; + int mHeapIndex; + cNewO_OneIm * mIm; + std::vector mLnk3; + ElRotation3D mCurRot; + ElRotation3D mTestRot; + int mNumCC; +}; + + + +class cNOSolIn_AttrArc +{ + public : + cNOSolIn_AttrArc(cNOSolIn_AttrASym *,bool OrASym); + cNOSolIn_AttrASym * ASym() {return mASym;} + bool IsOrASym() const {return mOrASym;} + + private : + cNOSolIn_AttrASym * mASym; + bool mOrASym; +}; + + +class cNOSolIn_Triplet +{ + public : + cNOSolIn_Triplet(cSolGlobInit_NRandom *,tSomNSI * aS1,tSomNSI * aS2,tSomNSI *aS3,const cXml_Ori3ImInit &); + void SetArc(int aK,tArcNSI *); + tSomNSI * KSom(int aK) const {return mSoms[aK];} + tArcNSI * KArc(int aK) const {return mArcs[aK];} + double CoherTest() const; + + + + int Nb3() const {return mNb3;} + ElTabFlag & Flag() {return mTabFlag;} + int & NumCC() {return mNumCC;} + + const ElRotation3D & RotOfSom(tSomNSI * aS) const + { + if (aS==mSoms[0]) return ElRotation3D::Id; + if (aS==mSoms[1]) return mR2on1; + if (aS==mSoms[2]) return mR3on1; + ELISE_ASSERT(false," RotOfSom"); + return ElRotation3D::Id; + } + const ElRotation3D & RotOfK(int aK) const + { + switch (aK) + { + case 0 : return ElRotation3D::Id; + case 1 : return mR2on1; + case 2 : return mR3on1; + } + ELISE_ASSERT(false," RotOfSom"); + return ElRotation3D::Id; + } + + float CostArc() const {return mCostArc;} + float& CostArc() {return mCostArc;} + float CostArcMed() const {return mCostArcMed;} + float& CostArcMed() {return mCostArcMed;} + std::vector& CostArcPerSample() {return mCostArcPerSample;}; + + int & HeapIndex() {return mHeapIndex;} + + + private : + cNOSolIn_Triplet(const cNOSolIn_Triplet &); // N.I. + cSolGlobInit_NRandom * mAppli; + tSomNSI * mSoms[3]; + tArcNSI * mArcs[3]; + float mCostArc; + float mCostArcMed; + std::vector mCostArcPerSample; + + int mNb3; + ElTabFlag mTabFlag; + int mNumCC; + ElRotation3D mR2on1; + ElRotation3D mR3on1; + float mBOnH; + + int mHeapIndex; +}; + +inline bool ValFlag(cNOSolIn_Triplet & aTrip,int aFlagSom) +{ + return aTrip.Flag().kth(aFlagSom); +} +inline void SetFlag(cNOSolIn_Triplet & aTrip,int aFlag,bool aVal) +{ + aTrip.Flag().set_kth(aFlag,aVal); +} + +class cLinkTripl +{ + public : + cLinkTripl(cNOSolIn_Triplet * aTrip,int aK1,int aK2,int aK3) : + m3 (aTrip), + mK1 (aK1), + mK2 (aK2), + mK3 (aK3) + { + } + + int & HeapIndex() {return mHeapIndex;} + + cNOSolIn_Triplet * m3; + U_INT1 mK1; + U_INT1 mK2; + U_INT1 mK3; + tSomNSI * S1() const; + tSomNSI * S2() const; + tSomNSI * S3() const; + + private: + int mHeapIndex; //Heap index pour tirer le meilleur triplets + +}; + +class cNO_CC_TripSom +{ + public : + std::vector mTri; + std::vector mSoms; + int mNumCC; +}; + + +class cNO_HeapIndTri_NSI +{ + public : + static void SetIndex(cLinkTripl* aV,int i) { aV->HeapIndex()=i;} + static int Index(cLinkTripl * aV) + { + return aV->HeapIndex(); + } + +}; + +class cNO_CmpTriByCost +{ + public: + bool operator()(cLinkTripl * aL1,cLinkTripl * aL2) + { + return (aL1->m3)->CostArc() < (aL2->m3)->CostArc(); + } +}; + +//typedef ElHeap tHeapTriNSI; + +class cNOSolIn_AttrASym +{ + public : + cNOSolIn_AttrASym(); + + void AddTriplet(cNOSolIn_Triplet * aTrip,int aK1,int aK2,int aK3); + std::vector & Lnk3() {return mLnk3;} + std::vector & Lnk3Ptr() {return mLnk3Ptr;} + + cLinkTripl * GetBestTri(); + tHeapTriNSI mHeapTri; + + private : + std::vector mLnk3; // Liste des triplets partageant cet arc + std::vector mLnk3Ptr; //Dirty trick pour faire marcher heap + +}; + +class cNO_HeapIndTriSol_NSI +{ + public : + static void SetIndex(cNOSolIn_Triplet * aV,int i) { aV->HeapIndex()=i;} + static int Index(cNOSolIn_Triplet * aV) + { + return aV->HeapIndex(); + } + +}; + +class cNO_CmpTriSolByCost +{ + public: + bool operator()(cNOSolIn_Triplet * aL1,cNOSolIn_Triplet * aL2) + { + return aL1->CostArc() < aL2->CostArc(); + } +}; + +typedef ElHeap tHeapTriSolNSI; + +class cSolGlobInit_NRandom : public cCommonMartiniAppli +{ + public: + cSolGlobInit_NRandom(int argc,char ** argv); + cNewO_NameManager & NM() {return *mNM;} + + // begin old pipeline + void DoOneRandomDFS(bool UseCoherence=false); + void DoRandomDFS(); + // end old pipeline + + // new pipeline entry point + void DoNRandomSol(); + + void RandomSolAllCC(); + void RandomSolOneCC(cNO_CC_TripSom *); + void RandomSolOneCC(cNOSolIn_Triplet *,int) ; + + void BestSolAllCC(); + void BestSolOneCC(cNO_CC_TripSom *); + + private: + void AddTriOnHeap(cLinkTripl *); + void NumeroteCC(); + void AddArcOrCur(cNOSolIn_AttrASym *); + cLinkTripl * GetRandTri(); + void EstimRt(cLinkTripl *); + + + void CreateArc(tSomNSI *,tSomNSI *,cNOSolIn_Triplet *,int aK0,int aK1,int aK2); + void CoherTriplets(); + void CoherTriplets(std::vector& aV3); + void CoherTripletsGraphBased(std::vector& aV3); + void CoherTripletsAllSamples(); + void HeapPerEdge(); + void HeapPerSol(); + + void ShowTripletCost(); + + cNOSolIn_Triplet * GetBestTri(); + cLinkTripl * GetBestTriDyn(); + + void Save(std::string& OriOut,bool SaveListOfName=false); + void FreeSomNumCCFlag(); + + std::string mFullPat; + cElemAppliSetFile mEASF; + cNewO_NameManager * mNM; + + tGrNSI mGr; + tSubGrNSI mSubAll; + std::map mMapS; + std::map mVS; //variable to keep the visited sommets + + + std::vector mV3; + std::vector mVCC; + + // CC vars + std::set mSCur3Adj;//dynamic list of currently adjacent triplets + + int mNbSom; + int mNbArc; + int mNbTrip; + ElFlagAllocator mAllocFlag3; + int mFlag3CC; + int mFlagS; + bool mDebug; + int mNbSamples; + ElTimer mChrono; + int mIterCur; + + +#ifdef GRAPHVIZ_ENABLED + GVC_t *GRAPHVIZ_GVCInit(const std::string& aGName); + std::pair GRAPHVIZ_GraphInit(const std::string& aGName); + graph_t *GRAPHIZ_GraphRead(std::string& aFName); + void GRAPHIZ_GraphSerialize(std::string& aFName,graph_t *g); + void GRAPHIZ_GraphKill(graph_t *g,GVC_t *gvc,std::string aWriteName=""); + void GRAPHIZ_NodeInit(graph_t *, + const std::string& , + const std::string& , + const std::string& ); + void GRAPHVIZ_NodeAdd(graph_t* , + const std::string& , + const std::string& , + const std::string& ); + void GRAPHVIZ_NodeChgColor(graph_t*,const std::string& ); + void GRAPHVIZ_EdgeChgColor(graph_t*, + const std::string& , + const std::string& , + std::string aColor="red"); + void WriteGraphToFile(); + + graph_t *mG; + GVC_t *mGVC; + +#endif + std::string mGraphName; + tHeapTriSolNSI mHeapTriAll;//contains all triplets + tHeapTriNSI mHeapTriDyn; +}; + + +} //SolGlobInit_DFS + +class cAppliGenOptTriplets : public cCommonMartiniAppli +{ + public: + cAppliGenOptTriplets(int argc,char ** argv); + + + private: + ElMatrix RandPeturbR(); + + std::string mFullPat; + std::string InOri; + + + int mNbTri; + double mSigma;//bruit + double mRatioOutlier;//outlier ratio, if 0.3 => 30% of outliers will be present among the triplets + + cElemAppliSetFile mEASF; + cNewO_NameManager * mNM; + +}; + +/*Footer-MicMac-eLiSe-25/06/2007 + +Ce logiciel est un programme informatique servant à la mise en +correspondances d'images pour la reconstruction du relief. + +Ce logiciel est régi par la licence CeCILL-B soumise au droit français et +respectant les principes de diffusion des logiciels libres. Vous pouvez +utiliser, modifier et/ou redistribuer ce programme sous les conditions +de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA +sur le site "http://www.cecill.info". + +En contrepartie de l'accessibilité au code source et des droits de copie, +de modification et de redistribution accordés par cette licence, il n'est +offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, +seule une responsabilité restreinte pèse sur l'auteur du programme, le +titulaire des droits patrimoniaux et les concédants successifs. + +A cet égard l'attention de l'utilisateur est attirée sur les risques +associés au chargement, à l'utilisation, à la modification et/ou au +développement et à la reproduction du logiciel par l'utilisateur étant +donné sa spécificité de logiciel libre, qui peut le rendre complexe à +manipuler et qui le réserve donc à des développeurs et des professionnels +avertis possédant des connaissances informatiques approfondies. Les +utilisateurs sont donc invités à charger et tester l'adéquation du +logiciel à leurs besoins dans des conditions permettant d'assurer la +sécurité de leurs systèmes et ou de leurs données et, plus généralement, +à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. + +Le fait que vous puissiez accéder à cet en-tête signifie que vous avez +pris connaissance de la licence CeCILL-B, et que vous en avez accepté les +termes. +Footer-MicMac-eLiSe-25/06/2007*/ + diff --git a/src/uti_phgrm/SaisiePts/SaisiePts.h b/src/uti_phgrm/SaisiePts/SaisiePts.h index 542de44fc5..a2648e0953 100644 --- a/src/uti_phgrm/SaisiePts/SaisiePts.h +++ b/src/uti_phgrm/SaisiePts/SaisiePts.h @@ -596,6 +596,9 @@ class cAppli_SaisiePts void OnModifLoadedImage(); cMMByImNM * PIMsFilter(); + bool ValidePt(const cPointGlob & aPG,const Pt3dr & aP3d,cBasicGeomCap3D * aCap) const; + + private : void RenameIdPt(std::string &); diff --git a/src/uti_phgrm/SaisiePts/cAppliSaisiePts.cpp b/src/uti_phgrm/SaisiePts/cAppliSaisiePts.cpp index acd3e92cd6..e076be2a6c 100644 --- a/src/uti_phgrm/SaisiePts/cAppliSaisiePts.cpp +++ b/src/uti_phgrm/SaisiePts/cAppliSaisiePts.cpp @@ -758,6 +758,20 @@ void cAppli_SaisiePts::InitPG() aPG.Name() = itA->NamePt() ; aPG.LargeurFlou().SetVal(itIm->LargeurFlou().Val()); aPG.P3D().SetVal(itA->Pt()); + if (itA->Norm2Surf().IsInit()) + { + aPG.Normale().SetVal(vunit(itA->Norm2Surf().Val())); + } + else if (itA->TetaN2SHor().IsInit()) + { + double aTeta = itA->TetaN2SHor().Val() * (PI/180.0); + Pt2dr aN2 = Pt2dr::FromPolar(1,aTeta); + aPG.Normale().SetVal(Pt3dr(aN2.x,aN2.y,0.0)); + } +/* +itA->TetaN2SHor().Val(); +*/ + aPG.Incert().SetVal(itA->Incertitude()); aPG.ContenuPt().SetNoInit(); aPG.FromDico().SetVal(true); @@ -894,6 +908,35 @@ void cAppli_SaisiePts::AddPGInAllImages(cSP_PointGlob * aSPG) } } +bool cAppli_SaisiePts::ValidePt(const cPointGlob & aPG,const Pt3dr & aP3d,cBasicGeomCap3D * aCapt3D) const +{ + if (! aCapt3D->PIsVisibleInImage(aP3d)) + return false; + + if (mParam.DistMaxVisib().IsInit()) + { + CamStenope *aCS = aCapt3D->DownCastCS() ; + if (euclid (aP3d-aCS->PseudoOpticalCenter()) > mParam.DistMaxVisib().Val()) + return false; + } + + if (mParam.PatternNamePtsVisib().IsInit()) + { + if (!mParam.PatternNamePtsVisib().Val()->Match(aPG.Name())) + return false; + } + + if (aPG.Normale().IsInit()) + { + Pt2dr aPIm = aCapt3D->Ter2Capteur(aP3d); + ElSeg3D aSeg = aCapt3D->Capteur2RayTer(aPIm); + double aScal = scal(aSeg.TgNormee(),aPG.Normale().Val()); + return aScal < 0; + } + + return true; +} + void cAppli_SaisiePts::AddOnePGInImage (cSP_PointGlob * aSPG,cImage & anI,bool WithP3D,const Pt3dr & aP3d,bool InMasq3D) @@ -919,7 +962,7 @@ void cAppli_SaisiePts::AddOnePGInImage - if (! aCapt3D->PIsVisibleInImage(aP3d)) + if (! ValidePt(aPG,aP3d,aCapt3D) ) { OkInIm = false; } @@ -1109,44 +1152,7 @@ void cAppli_SaisiePts::Save() MakeFileXML(aDico,mSauv3D); - /* -*/ } - /* - a voir si pb de versions sous commit -<<<<<<< .mine - - - 103 -645 5 - Coin-Gauche - 10 10 10 - - -======= - A FUSIONNER AVEC LA VERSION SUR PC IGN, pas commite ??? - if (mParam.ExportPointeTerrain().IsInit()) - { - cDicoAppuisFlottant aDic; - for - ( - std::list::iterator itP=mSPG.PointGlob().begin(); - itP!=mSPG.PointGlob().end(); - itP++ - ) - { - if (itP->Mes3DExportable().ValWithDef(false)) - { - cOneAppuisDAF anAp; - anAp.Pt() = itP->P3D.Val(); - anAp.NamePt() = itP->Name(); - anAp.Incertitude() = Pt3dr(1,1,1); - aDic.OneAppuisDAF().push_back(anAp); - } - } - MakeFileXML(aDic, DC()+(mParam.ExportPointeTerrain().Val())); - } ->>>>>>> .r889 -*/ } diff --git a/src/uti_phgrm/SaisiePts/cParamSaisiePts.cpp b/src/uti_phgrm/SaisiePts/cParamSaisiePts.cpp index 7327950208..7dbf5904be 100644 --- a/src/uti_phgrm/SaisiePts/cParamSaisiePts.cpp +++ b/src/uti_phgrm/SaisiePts/cParamSaisiePts.cpp @@ -247,6 +247,17 @@ const cTplValGesInit< Pt3dr > & cPointGlob::Incert()const } +cTplValGesInit< Pt3dr > & cPointGlob::Normale() +{ + return mNormale; +} + +const cTplValGesInit< Pt3dr > & cPointGlob::Normale()const +{ + return mNormale; +} + + cTplValGesInit< double > & cPointGlob::LargeurFlou() { return mLargeurFlou; @@ -392,6 +403,14 @@ void BinaryUnDumpFromFile(cPointGlob & anObj,ELISE_fp & aFp) } else anObj.Incert().SetNoInit(); } ; + { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.Normale().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.Normale().ValForcedForUnUmp(),aFp); + } + else anObj.Normale().SetNoInit(); + } ; { bool IsInit; BinaryUnDumpFromFile(IsInit,aFp); if (IsInit) { @@ -479,6 +498,8 @@ void BinaryDumpInFile(ELISE_fp & aFp,const cPointGlob & anObj) if (anObj.Mes3DExportable().IsInit()) BinaryDumpInFile(aFp,anObj.Mes3DExportable().Val()); BinaryDumpInFile(aFp,anObj.Incert().IsInit()); if (anObj.Incert().IsInit()) BinaryDumpInFile(aFp,anObj.Incert().Val()); + BinaryDumpInFile(aFp,anObj.Normale().IsInit()); + if (anObj.Normale().IsInit()) BinaryDumpInFile(aFp,anObj.Normale().Val()); BinaryDumpInFile(aFp,anObj.LargeurFlou().IsInit()); if (anObj.LargeurFlou().IsInit()) BinaryDumpInFile(aFp,anObj.LargeurFlou().Val()); BinaryDumpInFile(aFp,anObj.ContenuPt().IsInit()); @@ -517,6 +538,8 @@ cElXMLTree * ToXMLTree(const cPointGlob & anObj) aRes->AddFils(::ToXMLTree(std::string("Mes3DExportable"),anObj.Mes3DExportable().Val())->ReTagThis("Mes3DExportable")); if (anObj.Incert().IsInit()) aRes->AddFils(::ToXMLTree(std::string("Incert"),anObj.Incert().Val())->ReTagThis("Incert")); + if (anObj.Normale().IsInit()) + aRes->AddFils(::ToXMLTree(std::string("Normale"),anObj.Normale().Val())->ReTagThis("Normale")); if (anObj.LargeurFlou().IsInit()) aRes->AddFils(::ToXMLTree(std::string("LargeurFlou"),anObj.LargeurFlou().Val())->ReTagThis("LargeurFlou")); if (anObj.ContenuPt().IsInit()) @@ -561,6 +584,8 @@ void xml_init(cPointGlob & anObj,cElXMLTree * aTree) xml_init(anObj.Incert(),aTree->Get("Incert",1)); //tototo + xml_init(anObj.Normale(),aTree->Get("Normale",1)); //tototo + xml_init(anObj.LargeurFlou(),aTree->Get("LargeurFlou",1),double(0.0)); //tototo xml_init(anObj.ContenuPt(),aTree->Get("ContenuPt",1)); //tototo @@ -580,7 +605,7 @@ void xml_init(cPointGlob & anObj,cElXMLTree * aTree) xml_init(anObj.FromDico(),aTree->Get("FromDico",1)); //tototo } -std::string Mangling( cPointGlob *) {return "9EBFCF3DC34C29ADFE3F";}; +std::string Mangling( cPointGlob *) {return "846910AB12572EDDFCBF";}; std::list< cPointGlob > & cSetPointGlob::PointGlob() @@ -639,7 +664,7 @@ void xml_init(cSetPointGlob & anObj,cElXMLTree * aTree) xml_init(anObj.PointGlob(),aTree->GetAll("PointGlob",false,1)); } -std::string Mangling( cSetPointGlob *) {return "6EDC1913507224BDFF3F";}; +std::string Mangling( cSetPointGlob *) {return "37436826261BF5A8FF3F";}; eEtatPointeImage & cOneSaisie::Etat() @@ -1705,6 +1730,28 @@ const cTplValGesInit< std::string > & cSectionTerrain::PIMsFilterVis()const return mPIMsFilterVis; } + +cTplValGesInit< double > & cSectionTerrain::DistMaxVisib() +{ + return mDistMaxVisib; +} + +const cTplValGesInit< double > & cSectionTerrain::DistMaxVisib()const +{ + return mDistMaxVisib; +} + + +cTplValGesInit< cElRegex_Ptr > & cSectionTerrain::PatternNamePtsVisib() +{ + return mPatternNamePtsVisib; +} + +const cTplValGesInit< cElRegex_Ptr > & cSectionTerrain::PatternNamePtsVisib()const +{ + return mPatternNamePtsVisib; +} + void BinaryUnDumpFromFile(cSectionTerrain & anObj,ELISE_fp & aFp) { { bool IsInit; @@ -1739,6 +1786,22 @@ void BinaryUnDumpFromFile(cSectionTerrain & anObj,ELISE_fp & aFp) } else anObj.PIMsFilterVis().SetNoInit(); } ; + { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.DistMaxVisib().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.DistMaxVisib().ValForcedForUnUmp(),aFp); + } + else anObj.DistMaxVisib().SetNoInit(); + } ; + { bool IsInit; + BinaryUnDumpFromFile(IsInit,aFp); + if (IsInit) { + anObj.PatternNamePtsVisib().SetInitForUnUmp(); + BinaryUnDumpFromFile(anObj.PatternNamePtsVisib().ValForcedForUnUmp(),aFp); + } + else anObj.PatternNamePtsVisib().SetNoInit(); + } ; } void BinaryDumpInFile(ELISE_fp & aFp,const cSectionTerrain & anObj) @@ -1751,6 +1814,10 @@ void BinaryDumpInFile(ELISE_fp & aFp,const cSectionTerrain & anObj) if (anObj.Masq3DFilterVis().IsInit()) BinaryDumpInFile(aFp,anObj.Masq3DFilterVis().Val()); BinaryDumpInFile(aFp,anObj.PIMsFilterVis().IsInit()); if (anObj.PIMsFilterVis().IsInit()) BinaryDumpInFile(aFp,anObj.PIMsFilterVis().Val()); + BinaryDumpInFile(aFp,anObj.DistMaxVisib().IsInit()); + if (anObj.DistMaxVisib().IsInit()) BinaryDumpInFile(aFp,anObj.DistMaxVisib().Val()); + BinaryDumpInFile(aFp,anObj.PatternNamePtsVisib().IsInit()); + if (anObj.PatternNamePtsVisib().IsInit()) BinaryDumpInFile(aFp,anObj.PatternNamePtsVisib().Val()); } cElXMLTree * ToXMLTree(const cSectionTerrain & anObj) @@ -1765,6 +1832,10 @@ cElXMLTree * ToXMLTree(const cSectionTerrain & anObj) aRes->AddFils(::ToXMLTree(std::string("Masq3DFilterVis"),anObj.Masq3DFilterVis().Val())->ReTagThis("Masq3DFilterVis")); if (anObj.PIMsFilterVis().IsInit()) aRes->AddFils(::ToXMLTree(std::string("PIMsFilterVis"),anObj.PIMsFilterVis().Val())->ReTagThis("PIMsFilterVis")); + if (anObj.DistMaxVisib().IsInit()) + aRes->AddFils(::ToXMLTree(std::string("DistMaxVisib"),anObj.DistMaxVisib().Val())->ReTagThis("DistMaxVisib")); + if (anObj.PatternNamePtsVisib().IsInit()) + aRes->AddFils(::ToXMLTree(std::string("PatternNamePtsVisib"),anObj.PatternNamePtsVisib().Val())->ReTagThis("PatternNamePtsVisib")); aRes->mGXml = anObj.mGXml; XMLPopContext(anObj.mGXml); return aRes; @@ -1782,9 +1853,13 @@ void xml_init(cSectionTerrain & anObj,cElXMLTree * aTree) xml_init(anObj.Masq3DFilterVis(),aTree->Get("Masq3DFilterVis",1)); //tototo xml_init(anObj.PIMsFilterVis(),aTree->Get("PIMsFilterVis",1)); //tototo + + xml_init(anObj.DistMaxVisib(),aTree->Get("DistMaxVisib",1)); //tototo + + xml_init(anObj.PatternNamePtsVisib(),aTree->Get("PatternNamePtsVisib",1)); //tototo } -std::string Mangling( cSectionTerrain *) {return "9670D68A763FEBAFFE3F";}; +std::string Mangling( cSectionTerrain *) {return "3CBBC271C12BE8E6FC3F";}; cTplValGesInit< cChantierDescripteur > & cParamSaisiePts::DicoLoc() @@ -2139,6 +2214,28 @@ const cTplValGesInit< std::string > & cParamSaisiePts::PIMsFilterVis()const } +cTplValGesInit< double > & cParamSaisiePts::DistMaxVisib() +{ + return SectionTerrain().DistMaxVisib(); +} + +const cTplValGesInit< double > & cParamSaisiePts::DistMaxVisib()const +{ + return SectionTerrain().DistMaxVisib(); +} + + +cTplValGesInit< cElRegex_Ptr > & cParamSaisiePts::PatternNamePtsVisib() +{ + return SectionTerrain().PatternNamePtsVisib(); +} + +const cTplValGesInit< cElRegex_Ptr > & cParamSaisiePts::PatternNamePtsVisib()const +{ + return SectionTerrain().PatternNamePtsVisib(); +} + + cSectionTerrain & cParamSaisiePts::SectionTerrain() { return mSectionTerrain; @@ -2222,6 +2319,6 @@ void xml_init(cParamSaisiePts & anObj,cElXMLTree * aTree) xml_init(anObj.DirectoryChantier(),aTree->Get("DirectoryChantier",1)); //tototo } -std::string Mangling( cParamSaisiePts *) {return "ACAB05A583C30E95FF3F";}; +std::string Mangling( cParamSaisiePts *) {return "5DF90EDA3EA187A4FF3F";}; // }; diff --git a/src/uti_phgrm/SaisiePts/cParamSaisiePts.h b/src/uti_phgrm/SaisiePts/cParamSaisiePts.h index 6f068c223c..eb0e5cd93e 100644 --- a/src/uti_phgrm/SaisiePts/cParamSaisiePts.h +++ b/src/uti_phgrm/SaisiePts/cParamSaisiePts.h @@ -95,6 +95,9 @@ class cPointGlob cTplValGesInit< Pt3dr > & Incert(); const cTplValGesInit< Pt3dr > & Incert()const ; + cTplValGesInit< Pt3dr > & Normale(); + const cTplValGesInit< Pt3dr > & Normale()const ; + cTplValGesInit< double > & LargeurFlou(); const cTplValGesInit< double > & LargeurFlou()const ; @@ -131,6 +134,7 @@ class cPointGlob cTplValGesInit< Pt3dr > mPt3DFromDico; cTplValGesInit< bool > mMes3DExportable; cTplValGesInit< Pt3dr > mIncert; + cTplValGesInit< Pt3dr > mNormale; cTplValGesInit< double > mLargeurFlou; cTplValGesInit< cContenuPt > mContenuPt; cTplValGesInit< int > mNumAuto; @@ -484,11 +488,19 @@ class cSectionTerrain cTplValGesInit< std::string > & PIMsFilterVis(); const cTplValGesInit< std::string > & PIMsFilterVis()const ; + + cTplValGesInit< double > & DistMaxVisib(); + const cTplValGesInit< double > & DistMaxVisib()const ; + + cTplValGesInit< cElRegex_Ptr > & PatternNamePtsVisib(); + const cTplValGesInit< cElRegex_Ptr > & PatternNamePtsVisib()const ; private: cTplValGesInit< double > mIntervPercProf; cTplValGesInit< cProfEstimator > mProfEstimator; cTplValGesInit< std::string > mMasq3DFilterVis; cTplValGesInit< std::string > mPIMsFilterVis; + cTplValGesInit< double > mDistMaxVisib; + cTplValGesInit< cElRegex_Ptr > mPatternNamePtsVisib; }; cElXMLTree * ToXMLTree(const cSectionTerrain &); @@ -605,6 +617,12 @@ class cParamSaisiePts cTplValGesInit< std::string > & PIMsFilterVis(); const cTplValGesInit< std::string > & PIMsFilterVis()const ; + cTplValGesInit< double > & DistMaxVisib(); + const cTplValGesInit< double > & DistMaxVisib()const ; + + cTplValGesInit< cElRegex_Ptr > & PatternNamePtsVisib(); + const cTplValGesInit< cElRegex_Ptr > & PatternNamePtsVisib()const ; + cSectionTerrain & SectionTerrain(); const cSectionTerrain & SectionTerrain()const ; diff --git a/src/uti_phgrm/Sources.cmake b/src/uti_phgrm/Sources.cmake index 79668394d5..c25472e078 100644 --- a/src/uti_phgrm/Sources.cmake +++ b/src/uti_phgrm/Sources.cmake @@ -126,6 +126,7 @@ set( Applis_phgrm_Src_Files ${UTI_PHGRM_DIR}/CPP_Gri2Bin.cpp ${UTI_PHGRM_DIR}/CPP_GCPBascule.cpp ${UTI_PHGRM_DIR}/CPP_Block.cpp + ${UTI_PHGRM_DIR}/CPP_Stereopolis.cpp ${UTI_PHGRM_DIR}/CPP_CenterBascule.cpp ${UTI_PHGRM_DIR}/CPP_MakeGrid.cpp ${UTI_PHGRM_DIR}/CPP_Malt.cpp @@ -170,6 +171,7 @@ set( Applis_phgrm_Src_Files ${UTI_PHGRM_DIR}/CPP_C3DC.cpp ${UTI_PHGRM_DIR}/CPP_GIMMI.cpp ${UTI_PHGRM_DIR}/CPP_Bundler2MM.cpp + ${UTI_PHGRM_DIR}/CPP_MM2OpenMVG.cpp ) diff --git a/src/uti_phgrm/TiepTri/MultTieP.cpp b/src/uti_phgrm/TiepTri/MultTieP.cpp index 70769da0ed..255e7db723 100644 --- a/src/uti_phgrm/TiepTri/MultTieP.cpp +++ b/src/uti_phgrm/TiepTri/MultTieP.cpp @@ -40,6 +40,9 @@ Header-MicMac-eLiSe-25/06/2007*/ #include "StdAfx.h" #include "MultTieP.h" +CamStenope * DefaultCamera(const std::string & aName); + + bool FileModeBin(const std::string & aName) { std::string aPost = StdPostfix(aName); @@ -127,7 +130,8 @@ std::vector VecPtofVecIT(const std::vector > & aVecI const std::list & CreatePMul ( cVirtInterf_NewO_NameManager * aVNM, - const std::vector * aVIm + const std::vector * aVIm, + bool WithOri ) { @@ -137,7 +141,11 @@ const std::list & CreatePMul { const std::string & aNameIm = (*aVIm)[aKIm]; aDicoNumIm[aNameIm] = aKIm; - aDicCam[aNameIm] = aVNM->CalibrationCamera((*aVIm)[aKIm]); + if (WithOri) + aDicCam[aNameIm] = aVNM->CalibrationCamera(aNameIm); + else + aDicCam[aNameIm] = DefaultCamera(aNameIm); + } std::string aNameCple = aVNM->NameListeCpleConnected(true); @@ -159,6 +167,9 @@ const std::list & CreatePMul CamStenope * aCS1 = aDicCam[itV->N1()] ; CamStenope * aCS2 = aDicCam[itV->N2()] ; +// std::cout << "FFFpppp111 " << aCS1->Focale() << aCS1->PP() << "\n"; +// std::cout << "FFFpppp222 " << aCS2->Focale() << aCS2->PP() << "\n"; + std::vector aVP1,aVP2; aVNM->LoadHomFloats(itV->N1(),itV->N2(),&aVP1,&aVP2); int aNum1 = it1->second; @@ -168,6 +179,10 @@ const std::list & CreatePMul { Pt2dr aP1 = aCS1->L3toF2(Pt3dr(aVP1[aKP].x,aVP1[aKP].y,1.0)); Pt2dr aP2 = aCS2->L3toF2(Pt3dr(aVP2[aKP].x,aVP2[aKP].y,1.0)); + +// std::cout << "IIII" << aP1 << aP2 << aVP1[aKP] << aVP2[aKP] << "\n"; getchar(); + + aMergeStruct.AddArc(ToPt2df(aP1),aNum1,ToPt2df(aP2),aNum2,cCMT_NoVal()); } } @@ -221,10 +236,11 @@ cAppliConvertToNewFormatHom::cAppliConvertToNewFormatHom(int argc,char ** argv) mEASF.Init(mPatImage); mFilesIm = mEASF.SetIm(); - ELISE_fp::RmFileIfExist("NewOriTmpQuick"); // => Giang : bug ambiguous : delete all result of NO_AllOri2Im before convert homol ? - ELISE_fp::RmFileIfExist("NewOriTmp" + mSH + "Quick"); + if (mDoNewOri) { + ELISE_fp::PurgeDirRecursif("NewOriTmp" + mSH + "Quick"); + std::string aCom = MM3dBinFile("TestLib NO_AllOri2Im ") + QUOTE(mPatImage) + " GenOri=false " + " SH=" + mSH + " AUS=true"+ " ExpTxt="+ToString(mExpTxt); cout< & aLMR = CreatePMul (mVNM,mFilesIm); + // Conserve les numeros initiaux des images ; Si on a fait NO_AllOri2Im avec GenOri=false => les ori sont default + const std::list & aLMR = CreatePMul (mVNM,mFilesIm,!mDoNewOri); std::cout << "DONE PMUL " << aLMR.size() << " \n"; cSetTiePMul * aSetOutPM = new cSetTiePMul(1); @@ -389,6 +405,7 @@ void cSetPMul1ConfigTPM::Add(const std::vector & aVP,const std::vector