diff --git a/MMVII/Doc/Methods/Line-Detection-Theory.tex b/MMVII/Doc/Methods/Line-Detection-Theory.tex index f434693975..f236b60725 100644 --- a/MMVII/Doc/Methods/Line-Detection-Theory.tex +++ b/MMVII/Doc/Methods/Line-Detection-Theory.tex @@ -501,6 +501,50 @@ \subsection{Selection of \emph{best} lines} \end{itemize} +%----------------------------------------------------------------------- +%----------------------------------------------------------------------- +%----------------------------------------------------------------------- + +\section{The \PPP command } + +The command for line extraction is {\tt ExtractLine}. It takes $4$ mandatory parameters in the following order : + + +\begin{itemize} + \item the set of images where the line must be extracted ; + \item a boolean indicate if the wire is white (used when orientation of line is meaningfull like computing neighboorhouds + or matching anti parallel line); + \item a folder indicating the location of an existing calibration \footnote{it is planned to be able to use + it w/o calibration using the key word {\tt NONE}, by the way it is still not fully working}; + \item a folder where storing the results. +\end{itemize} + +For example : + +\begin{verbatim} + MMVII ExtractLine AllImFil.xml true BA_311_C Fils + MMVII ExtractLine (.*)_0158.tif true BA_311_C Fils + MMVII ExtractLine 043_0158.tif true BA_311_C Fils +\end{verbatim} + +For example with last command : + +\begin{itemize} + \item we will extract white line on image {\tt 043\_0158.tif}; + + \item for distorsion correction we will look for intrisic calibration in + folder {\tt MMVII-PhgrProj/Ori/BA\_311\_/} ; + + \item the result will be stored in folder {\tt MMVII-PhgrProj/PointsMeasure/Fils}; +\end{itemize} + +The result will be stored in two way : + +\begin{itemize} + \item a xml file by image, that is used by \PPP ; + \item a global file {\tt Lines.csv} that is generated for convenient use by external software. +\end{itemize} + % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % \subsubsection{AAA} diff --git a/MMVII/include/MMVII_ExtractLines.h b/MMVII/include/MMVII_ExtractLines.h index 649abf8ec2..7c0119652a 100755 --- a/MMVII/include/MMVII_ExtractLines.h +++ b/MMVII/include/MMVII_ExtractLines.h @@ -35,6 +35,7 @@ class cHoughPS // : public cMemCheck const tREAL8 & Rho() const; ///< Accessor const tSeg & Seg() const ; ///< Accessor const tREAL8 & Cumul() const; ///< Accessor + const tREAL8 & SigmaL() const; ///< Accessor eCodeHPS Code() const ; ///< Accessor void SetCode(eCodeHPS); ///< Modifior const cHoughTransform * HT() const; ///< Accessor @@ -45,7 +46,7 @@ class cHoughPS // : public cMemCheck bool Match(const cHoughPS &,bool IsDark,tREAL8 aMaxTeta,tREAL8 aDMin,tREAL8 aDMax) const; static std::vector> GetMatches(const std::vector& mVPS,bool IsLight,tREAL8 aMaxTeta,tREAL8 aDMin,tREAL8 aDMax); - void UpdateSegImage(const tSeg & aNewSeg,tREAL8 aNewCumul); + void UpdateSegImage(const tSeg & aNewSeg,tREAL8 aNewCumul,tREAL8 aSigmaL); protected : void UpdateMatch(cHoughPS *,tREAL8 aDist); @@ -53,6 +54,7 @@ class cHoughPS // : public cMemCheck const cHoughTransform * mHT; cPt2dr mTetaRho; tREAL8 mCumul; + tREAL8 mSigmaL; tSeg mSegE; eCodeHPS mCode; }; diff --git a/MMVII/include/MMVII_Geom3D.h b/MMVII/include/MMVII_Geom3D.h index c0c4c0612f..f38f5955ee 100755 --- a/MMVII/include/MMVII_Geom3D.h +++ b/MMVII/include/MMVII_Geom3D.h @@ -137,8 +137,15 @@ template class cRotation3D //// Compute a normal repair, first vector being colinear to P1, second in the plane P1,P2 // static cRotation3D CompleteRON(const tPt & aP0,const tPt & aP1); - // Extract Axes of a rotation and compute its angle - void ExtractAxe(tPt & anAxe,Type & aTeta); + /// Extract Axes of a rotation and compute its angle + void ExtractAxe(tPt & anAxe,Type & aTeta) const; + /// More modern interface to ExtractAxe + std::pair ExtractAxe() const; + + /// Convenient if you only need Angle, but slow else + Type Angle() const; + /// Convenient if you only need Axe, but slow else + tPt Axe() const; /// conversion to Omega Phi Kapa static cRotation3D RotFromWPK(const tPt & aWPK); diff --git a/MMVII/include/MMVII_MeasuresIm.h b/MMVII/include/MMVII_MeasuresIm.h index 3c9a43ee7d..f46a074e4c 100755 --- a/MMVII/include/MMVII_MeasuresIm.h +++ b/MMVII/include/MMVII_MeasuresIm.h @@ -530,7 +530,7 @@ class cOneLineAntiParal tREAL8 mWidth; tREAL8 mCumul; tREAL8 mRadHom; - tREAL8 mSimgaLine; + tREAL8 mSigmaLine; }; void AddData(const cAuxAr2007 & anAux,cOneLineAntiParal & anEx); diff --git a/MMVII/include/cMMVII_Appli.h b/MMVII/include/cMMVII_Appli.h index 39feadb926..11bd039a56 100755 --- a/MMVII/include/cMMVII_Appli.h +++ b/MMVII/include/cMMVII_Appli.h @@ -531,14 +531,19 @@ class cMMVII_Appli : public cMMVII_Ap_NameManip, std::string DirReport(); std::string DirSubPReport(const std::string &anId); std::string NameTmpReport(const std::string &anId,const std::string &anImg); + /// If we want to create a subdir inside the report, to have multiple reports void SetReportSubDir(const std::string &); + /// Redirect the file in NewDir, typically when mecanism is used for exporting in csv, and not for report + void SetReportRedir(const std::string &anId,const std::string & aNewDir); /// Mehod called when the report is finished, usefull when the report is used to memorize problem virtual void OnCloseReport(int aNbLine,const std::string & anIdent,const std::string & aNameFile) const; - void InitReport(const std::string &anId,const std::string & aPost,bool IsMul,const std::vector & aHeader={}); + /// Generate a new entry for report "anId", IsMul -> indicate if we are in multi process (for merge at end) + void InitReport(const std::string &anId,const std::string & aPostfix,bool IsMul,const std::vector & aHeader={}); // void AddTopReport(const std::string &anId,const std::string & VecMsg); + void AddOneReportCSV(const std::string &anId,const std::vector & VecMsg); /// Add a header line, do it only it at top-level void AddHeaderReportCSV(const std::string &anId,const std::vector & VecMsg); @@ -729,6 +734,8 @@ class cMMVII_Appli : public cMMVII_Ap_NameManip, char mCSVSep; ///< separator in csv file, for now hard coded to "," std::map mMapIdFilesReport; ///< For a given id memorize the post fix, as "csv" std::map mMapIdPostReport; ///< For a given id , memorize the file (Global of Tmp in sub process) + /// If finally, we want to store finall result is another Dir (when report is used for generating data in csv as export) + std::map mMapIdRedirect; std::set mReport2Merge; ///< Memorize all the report identifier that must be merged std::string mReportSubDir; ///< In case we want to write in separate subdir (like with GCP) diff --git a/MMVII/src/Appli/cMMVII_Appli_MakeReport.cpp b/MMVII/src/Appli/cMMVII_Appli_MakeReport.cpp index a772fa0d45..1ab88ef32f 100755 --- a/MMVII/src/Appli/cMMVII_Appli_MakeReport.cpp +++ b/MMVII/src/Appli/cMMVII_Appli_MakeReport.cpp @@ -25,6 +25,13 @@ void cMMVII_Appli::SetReportSubDir(const std::string & aSubDir) mReportSubDir = aSubDir; } +void cMMVII_Appli::SetReportRedir(const std::string &anId,const std::string & aNewDir) +{ + CreateDirectories(aNewDir,false); + mMapIdRedirect[anId] = aNewDir; +} + + std::string cMMVII_Appli::DirSubPReport(const std::string &anId) { return DirReport() + "Tmp-" + anId + StringDirSeparator(); @@ -161,13 +168,18 @@ void cMMVII_Appli::DoMergeReport() } } RemoveRecurs(DirSubPReport(anId),false,false); + } OnCloseReport(aNbLines,anIt.first,anIt.second); } + if (MapBoolFind(mMapIdRedirect,anIt.first) && (LevelCall()==0)) + { + std::string aNewFile = mMapIdRedirect[anIt.first] + FileOfPath(anIt.second); + RenameFiles(anIt.second,aNewFile); + } } } - // By default nothing to do void cMMVII_Appli::OnCloseReport(int aNbLine,const std::string & anIdent,const std::string & aNameFile) const { diff --git a/MMVII/src/Geom3D/cRotation3D.cpp b/MMVII/src/Geom3D/cRotation3D.cpp index c2ee0f5ed3..0e3f026c92 100755 --- a/MMVII/src/Geom3D/cRotation3D.cpp +++ b/MMVII/src/Geom3D/cRotation3D.cpp @@ -411,7 +411,7 @@ template cRotation3D cRotation3D::RandomRot(const Type } -template void cRotation3D::ExtractAxe(tPt & anAxe,Type & aTeta) +template void cRotation3D::ExtractAxe(tPt & anAxe,Type & aTeta) const { cDenseVect aDVAxe = mMat.EigenVect(1.0); anAxe = cPtxd::FromVect(aDVAxe); @@ -430,6 +430,24 @@ template void cRotation3D::ExtractAxe(tPt & anAxe,Type & aTet aTeta = aRhoTeta.y(); } +template std::pair,Type> cRotation3D::ExtractAxe() const +{ + tPt anAxe; + Type aTeta; + ExtractAxe(anAxe,aTeta); + return std::pair,Type> (anAxe,aTeta); +} + +template cPtxd cRotation3D::Axe() const { return ExtractAxe().first; } +template Type cRotation3D::Angle() const { return ExtractAxe().second; } + + + +/* +*/ + + + /* WPK = Rx(W) Ry(P) Rz(K) * YPR = Rz(Y) Ry(P) Rx(R) * diff --git a/MMVII/src/ImagesInfoExtract/cAppliExtractLine.cpp b/MMVII/src/ImagesInfoExtract/cAppliExtractLine.cpp index 0a2f479e5e..b19ea1be1d 100755 --- a/MMVII/src/ImagesInfoExtract/cAppliExtractLine.cpp +++ b/MMVII/src/ImagesInfoExtract/cAppliExtractLine.cpp @@ -143,13 +143,15 @@ class cAppliExtractLine : public cMMVII_Appli bool mGTHasSeg; ///< Does the GT "says" that here is no valid segment std::optional mSegGT; cTimerSegm mTimeSeg; + + std::string mIdExportCSV; ///< used of export lines in CSV files }; cAppliExtractLine::cAppliExtractLine(const std::vector & aVArgs,const cSpecMMVII_Appli & aSpec) : cMMVII_Appli (aVArgs,aSpec), mPhProj (*this), - mGenVisu (1), + mGenVisu (0), mParamMatch {6e-4,2.0,7.0}, mCalib (nullptr), // mCalDUD (nullptr), @@ -165,7 +167,8 @@ cAppliExtractLine::cAppliExtractLine(const std::vector & aVArgs,con mHoughSeuilAng (0.20), mWithGT (false), mGTHasSeg (false), - mTimeSeg (this) + mTimeSeg (this), + mIdExportCSV ("Lines") { } @@ -179,6 +182,7 @@ cCollecSpecArg2007 & cAppliExtractLine::ArgObl(cCollecSpecArg2007 & anArgObl) return anArgObl << Arg2007(mPatImage,"Name of input Image", {eTA2007::FileDirProj,{eTA2007::MPatFile,"0"}}) << Arg2007(mLineIsWhite," True : its a light line , false dark ") + << mPhProj.DPOrient().ArgDirInMand() << mPhProj.DPPointsMeasures().ArgDirOutMand() ; } @@ -186,7 +190,6 @@ cCollecSpecArg2007 & cAppliExtractLine::ArgObl(cCollecSpecArg2007 & anArgObl) cCollecSpecArg2007 & cAppliExtractLine::ArgOpt(cCollecSpecArg2007 & anArgOpt) { return anArgOpt - << mPhProj.DPOrient().ArgDirInOpt("","Folder for calibration to integrate distorsion") << AOpt2007(mAccurateHough,"AccurateHough","Accurate/Quick hough",{eTA2007::HDV}) << AOpt2007(mGenVisu,"GenVisu","Generate Visu 0 none, 1 déroulé, 2 image wire, 3",{eTA2007::HDV}) << AOpt2007(mZoomImL,"ZoomImL","Zoom for images of line",{eTA2007::HDV}) @@ -200,7 +203,7 @@ cCollecSpecArg2007 & cAppliExtractLine::ArgOpt(cCollecSpecArg2007 & anArgOpt) std::vector cAppliExtractLine::Samples() const { return { - "MMVII ExtractLine 'DSC_.*.JPG' ShowSteps=1 InOri=FB" + "MMVII ExtractLine AllImFil.xml true BA_311_C Fils" }; } @@ -425,6 +428,19 @@ void cAppliExtractLine::DoOneImage(const std::string & aNameIm) */ } mPhProj.SaveLines(aExAllLines); + + for (const auto & aLine : aExAllLines.mLines) + { + cPt2dr aP1 = aLine.mSeg.P1(); + cPt2dr aP2 = aLine.mSeg.P2(); + std::vector aVS { aNameIm, + ToStr(aP1.x()),ToStr(aP1.y()),ToStr(aP2.x()),ToStr(aP2.y()), + ToStr(aLine.mWidth),ToStr(aLine.mSigmaLine) + }; + AddOneReportCSV(mIdExportCSV,aVS); + } + // InitReport(mIdExportCSV,"csv",true,{"NameIm","X1","Y1","X2","Y2","Witdh","Sigma"}); + // AddOneReportCSV(mNameReportByLine,{mNameCurIm,ToStr(aEx1L.mAng),ToStr(aEx1L.mWidth),ToStr(aEx1L.mCumul),ToStr(aHS1->RadHom())}); } #if (0) @@ -563,6 +579,9 @@ int cAppliExtractLine::Exe() InitReport(mNameReportByLine,"csv",true,{"NameIm","Paral","Larg","Score","RadHom"}); InitReport(mNameReportByIm,"csv",true,{"NameIm","CodeResult"}); + InitReport(mIdExportCSV,"csv",true,{"NameIm","X1","Y1","X2","Y2","Witdh","Sigma"}); + SetReportRedir(mIdExportCSV,mPhProj.DPPointsMeasures().FullDirOut()); + // AddHeaderReportCSV(mNameReportByLine,{"NameIm","Paral","Larg","Cumul"}); // AddHeaderReportCSV(mNameReportByIm,{"NameIm","CodeResult"}); if (RunMultiSet(0,0)) diff --git a/MMVII/src/ImagesInfoExtract/cExtractLines.cpp b/MMVII/src/ImagesInfoExtract/cExtractLines.cpp index 6e15aebf24..be3ae7807d 100755 --- a/MMVII/src/ImagesInfoExtract/cExtractLines.cpp +++ b/MMVII/src/ImagesInfoExtract/cExtractLines.cpp @@ -367,7 +367,8 @@ template void cExtractLines::RefineLineInSpace(cHoughPS & aH } // StdOut() << "RefineLineInSpacellll " << __LINE__ << "\n"; - aHPS.UpdateSegImage(aNewSeg,aSumNumbering.back()); + aHPS.UpdateSegImage(aNewSeg,aSumNumbering.back(),aVStat.back().QuadAvg()); +// StdOut() << "RESSSS " << aVStat.at(aKIter+1).QuadAvg() << "\n"; } diff --git a/MMVII/src/ImagesInfoExtract/cHoughTransform.cpp b/MMVII/src/ImagesInfoExtract/cHoughTransform.cpp index de29919d0f..9158fa0c43 100755 --- a/MMVII/src/ImagesInfoExtract/cHoughTransform.cpp +++ b/MMVII/src/ImagesInfoExtract/cHoughTransform.cpp @@ -41,6 +41,7 @@ cOneLineAntiParal cParalLine::GetLAP(const cPerspCamIntrCalib & aCalib) const aOLAP.mRadHom = mRadHom; aOLAP.mWidth = mWidth; aOLAP.mCumul = mScoreMatch; + aOLAP.mSigmaLine = (mVHS.at(0).SigmaL() + mVHS.at(1).SigmaL()) / 2.0; return aOLAP; } @@ -231,14 +232,16 @@ cHoughPS::cHoughPS(const cHoughTransform * aHT,const cPt2dr & aTR,tREAL8 aCumul, mHT (aHT), mTetaRho (aTR), mCumul (aCumul), + mSigmaL (-1), // undef mSegE (aP1,aP2), mCode (eCodeHPS::Ok) { } -void cHoughPS::UpdateSegImage(const tSeg & aNewSeg,tREAL8 aNewCumul) +void cHoughPS::UpdateSegImage(const tSeg & aNewSeg,tREAL8 aNewCumul,tREAL8 aSigma) { mCumul = aNewCumul; + mSigmaL = aSigma; mSegE = aNewSeg; mTetaRho = mHT->Line2PtInit(aNewSeg); } @@ -260,6 +263,7 @@ const cPt2dr & cHoughPS::TetaRho() const {return mTetaRho;} const tREAL8 & cHoughPS::Teta() const {return mTetaRho.x();} const tREAL8 & cHoughPS::Rho() const {return mTetaRho.y();} const tREAL8 & cHoughPS::Cumul() const {return mCumul;} +const tREAL8 & cHoughPS::SigmaL() const {return mSigmaL;} // cHoughPS * cHoughPS::Matched() const {return mMatched;} eCodeHPS cHoughPS::Code() const {return mCode;} void cHoughPS::SetCode(eCodeHPS aCode) { mCode = aCode;} diff --git a/MMVII/src/ImportFormat/ImportLines.cpp b/MMVII/src/ImportFormat/ImportLines.cpp index a75f3d7dd7..8aa08e1974 100644 --- a/MMVII/src/ImportFormat/ImportLines.cpp +++ b/MMVII/src/ImportFormat/ImportLines.cpp @@ -128,7 +128,7 @@ int cAppli_ImportLines::Exe() aLine.mSeg = tSeg2dr(aP1,aP2); if (WithSigma) - aLine.mSimgaLine = aNRFS.GetFloat(mNameSigma,aK); + aLine.mSigmaLine = aNRFS.GetFloat(mNameSigma,aK); if (WithWidth) aLine.mWidth = aNRFS.GetFloat(mNameWidth,aK); diff --git a/MMVII/src/Instrumental/cClinoInit.cpp b/MMVII/src/Instrumental/cClinoInit.cpp index ecd1fb9cb4..5cf1e033a0 100644 --- a/MMVII/src/Instrumental/cClinoInit.cpp +++ b/MMVII/src/Instrumental/cClinoInit.cpp @@ -3,6 +3,7 @@ #include "MMVII_Geom3D.h" #include "MMVII_PCSens.h" #include "MMVII_Clino.h" +#include "MMVII_Tpl_Images.h" /** @@ -521,6 +522,7 @@ int cAppli_ClinoInit::Exe() if (mVKClino.size() > 1) { StdOut() << "=============== Result of individual optimization =============" << std::endl; + std::vector aREnd; for (size_t aKCSel=0 ; aKCSel::Identity(3); + tREAL8 aDwpk = Norm2(aWPK); + tREAL8 aDId = aDifId.DIm().L2Norm(false); + StdOut() << " R=" << aDwpk / aDId + << " DW" << aDwpk/aEps + << " DA=" << aRot.Angle()/aEps + << " DId=" << aDId/aEps << "\n"; + if ((aKW==1) && (aKP==0) && (aKK==0)) + { + aDifId.Show() ; + } + } + } + + /* std::string aNameOut = mPhProj.DPClinoMeters().FullDirOut() + "ClinoCalib-" + aNameCalibCam + "."+ GlobTaggedNameDefSerial(); SaveInFile(mCalibSetClino,aNameOut); diff --git a/MMVII/src/Instrumental/cWire3DInit.cpp b/MMVII/src/Instrumental/cWire3DInit.cpp index 7414baa0e2..71b15b6a7e 100644 --- a/MMVII/src/Instrumental/cWire3DInit.cpp +++ b/MMVII/src/Instrumental/cWire3DInit.cpp @@ -234,8 +234,9 @@ int cAppli_Wire3DInit::Exe() + "-" + mPhProj.DPRigBloc().DirIn() ; SetReportSubDir(aDirRep); - InitReport(mRepW,"csv",true); - InitReport(mRepPt,"csv",true); + + InitReport(mRepW,"csv",false); + InitReport(mRepPt,"csv",false); AddOneReportCSV(mRepW,{"TimeBloc","NbPlane","Dist Ground","Dist Pix"}); AddOneReportCSV(mRepPt,{"TimeBloc","NbPt","Dist Pix"}); diff --git a/MMVII/src/Sensors/Measures.cpp b/MMVII/src/Sensors/Measures.cpp index 1637276ca4..ef8acca768 100644 --- a/MMVII/src/Sensors/Measures.cpp +++ b/MMVII/src/Sensors/Measures.cpp @@ -21,10 +21,11 @@ namespace MMVII cOneLineAntiParal::cOneLineAntiParal() : mSeg (cPt2dr(0,0),cPt2dr(1,0)), // Diff else error (cstr check not identic) - mAngDif (-1), - mWidth (-1), - mCumul (-1), - mRadHom (-1) + mAngDif (-1), + mWidth (-1), + mCumul (-1), + mRadHom (-1), + mSigmaLine (-1) { } @@ -35,7 +36,7 @@ void AddData(const cAuxAr2007 & anAux,cOneLineAntiParal & anEx) AddData(cAuxAr2007("ParalAng",anAux),anEx.mAngDif); AddData(cAuxAr2007("Width",anAux),anEx.mWidth); AddData(cAuxAr2007("Cumul",anAux),anEx.mCumul); - AddData(cAuxAr2007("SigmaL",anAux),anEx.mSimgaLine); + AddData(cAuxAr2007("SigmaL",anAux),anEx.mSigmaLine); } void AddData(const cAuxAr2007 & anAux,cLinesAntiParal1Im & anEx)