From 0197e01ddba9cebd4fd13ff69b83e3ccc2b23b74 Mon Sep 17 00:00:00 2001 From: deseilligny Date: Mon, 10 Jun 2024 19:26:17 +0200 Subject: [PATCH] New option in codetarget recognition to avoid error in multiple target --- MMVII/Doc/Methods/CodedTarget-Theory.tex | 11 ++ MMVII/include/MMVII_ExtractLines.h | 11 ++ MMVII/include/MMVII_Geom2D.h | 7 + MMVII/src/Appli/cMMVII_Appli_MakeReport.cpp | 37 ++--- MMVII/src/Bench/BenchGeom.cpp | 20 +++ .../CodedTarget/cCheckBoardTargetExtract.cpp | 135 ++++++++++++++---- MMVII/src/CodedTarget/cCircTargetExtract.cpp | 7 +- MMVII/src/Geom2D/GeomsBase2D.cpp | 34 +++++ .../src/ImagesInfoExtract/cScoreTetaLine.cpp | 29 ++-- 9 files changed, 232 insertions(+), 59 deletions(-) diff --git a/MMVII/Doc/Methods/CodedTarget-Theory.tex b/MMVII/Doc/Methods/CodedTarget-Theory.tex index e2833bb47d..6cabd87520 100644 --- a/MMVII/Doc/Methods/CodedTarget-Theory.tex +++ b/MMVII/Doc/Methods/CodedTarget-Theory.tex @@ -1,6 +1,17 @@ \chapter{Coded target} \label{Chap:CodedTarget} +%----------------------------------------------------------------------- +%----------------------------------------------------------------------- +%----------------------------------------------------------------------- + +\section{Todo} + +\begin{itemize} + \item {\tt 2023-12-14-CurTestClino/Calib-1/Processing/} target partially occluded are recognized as others, + for example {\tt 043\_0078.JPG}, target {\tt 66 (?)} is interpreted as {\tt 34} ; +\end{itemize} + %----------------------------------------------------------------------- %----------------------------------------------------------------------- diff --git a/MMVII/include/MMVII_ExtractLines.h b/MMVII/include/MMVII_ExtractLines.h index 95680a4599..309e16591f 100755 --- a/MMVII/include/MMVII_ExtractLines.h +++ b/MMVII/include/MMVII_ExtractLines.h @@ -1,6 +1,9 @@ #ifndef _MMVII_EXTRACT_LINES_H_ #define _MMVII_EXTRACT_LINES_H_ + #include "MMVII_Image2D.h" +#include "MMVII_Interpolators.h" +#include "MMVII_Mappings.h" namespace MMVII @@ -264,6 +267,14 @@ class cScoreTetaLine : public tFunc1DReal // herit from tFunc1DReal for optimiza /// extract the 2 angle of line in checkboar, aStepInit & aStepLim => used in cOptimByStep std::pair Tetas_CheckBoard(const cPt2dr& aC,tREAL8 aStepInit,tREAL8 aStepLim); + + typedef tREAL8 t2Teta[2]; + /// Assure that teta1->teta2 is trigo and teta1 * DIm() const; ///< Accessor + private : /// fix center of reusing the data (to avoid cost for cTabulatedDiffInterpolator) diff --git a/MMVII/include/MMVII_Geom2D.h b/MMVII/include/MMVII_Geom2D.h index efa6831dc1..dfa16d7142 100755 --- a/MMVII/include/MMVII_Geom2D.h +++ b/MMVII/include/MMVII_Geom2D.h @@ -12,6 +12,7 @@ namespace MMVII typedef cSegment tSeg2dr; + /** \file MMVII_Geom2D.h \brief contain classes for geometric manipulation, specific to 2D space : 2D line, 2D plane, rotation, ... @@ -95,10 +96,16 @@ template class cSegment2DCompiled : public cSegmentCompiled Type Dist(const tPt& aPt) const; ///< Faster than upper class const tPt & Normal() const {return mNorm;} + + tPt InterSeg(const cSegment2DCompiled &,tREAL8 aMinAngle=1e-5,bool *IsOk=nullptr); private : tPt mNorm; }; +/** this class a represent a "closed" segment , it has same data than cSegment2DCompiled, + * but as a set/geometric primitive, it is limited by extremities + */ + class cClosedSeg2D { public : diff --git a/MMVII/src/Appli/cMMVII_Appli_MakeReport.cpp b/MMVII/src/Appli/cMMVII_Appli_MakeReport.cpp index 301330b700..a772fa0d45 100755 --- a/MMVII/src/Appli/cMMVII_Appli_MakeReport.cpp +++ b/MMVII/src/Appli/cMMVII_Appli_MakeReport.cpp @@ -139,26 +139,29 @@ void cMMVII_Appli::DoMergeReport() { if (BoolFind(mReport2Merge,anIt.first)) { - cMMVII_Ofs aFileGlob(anIt.second, eFileModeOut::AppendText); - const std::string & anId = anIt.first; - int aNbLines = 0; - if (mRMSWasUsed) - { - for (const auto & aNameIm : VectMainSet(0)) - { - std::string aNameIn = DirSubPReport(anId) + FileOfPath(aNameIm,false) + "." + mMapIdPostReport[anId]; - cMMVII_Ifs aIn(aNameIn, eFileModeIn::Text); - - std::string aLine; - while (std::getline(aIn.Ifs(), aLine)) + // Put aFileGlob in {} to create destruction before OnCloseReport that may generat error + { + cMMVII_Ofs aFileGlob(anIt.second, eFileModeOut::AppendText); + const std::string & anId = anIt.first; + + if (mRMSWasUsed) + { + for (const auto & aNameIm : VectMainSet(0)) { - aFileGlob.Ofs() << aLine<< "\n"; - aNbLines++; - } + std::string aNameIn = DirSubPReport(anId) + FileOfPath(aNameIm,false) + "." + mMapIdPostReport[anId]; + cMMVII_Ifs aIn(aNameIn, eFileModeIn::Text); + + std::string aLine; + while (std::getline(aIn.Ifs(), aLine)) + { + aFileGlob.Ofs() << aLine<< "\n"; + aNbLines++; + } + } } - } - RemoveRecurs(DirSubPReport(anId),false,false); + RemoveRecurs(DirSubPReport(anId),false,false); + } OnCloseReport(aNbLines,anIt.first,anIt.second); } } diff --git a/MMVII/src/Bench/BenchGeom.cpp b/MMVII/src/Bench/BenchGeom.cpp index 51d4a529fa..3e74e006ca 100755 --- a/MMVII/src/Bench/BenchGeom.cpp +++ b/MMVII/src/Bench/BenchGeom.cpp @@ -585,11 +585,31 @@ void BenchMap2D() void BenchPlane3D(); void BenchHomogr2D(); +void BenchSeg2D() +{ + for (int aK=0 ; aK<100 ; aK++) + { + cPt2dr aP1 = cPt2dr::PRandC(); + cPt2dr aT1 = cPt2dr::PRandUnit(); + cSegment2DCompiled aSeg1(aP1,aP1+aT1); + + cPt2dr aP2 = cPt2dr::PRandC(); + cPt2dr aT2 = cPt2dr::PRandUnitNonAligned(aT1); + cSegment2DCompiled aSeg2(aP2,aP2+aT2); + + cPt2dr aI = aSeg1.InterSeg(aSeg2); + + MMVII_INTERNAL_ASSERT_bench(aSeg1.DistLine(aI)<1e-8,"InterSeg"); + MMVII_INTERNAL_ASSERT_bench(aSeg2.DistLine(aI)<1e-8,"InterSeg"); + } +} void BenchGeom(cParamExeBench & aParam) { if (! aParam.NewBench("Geom")) return; + BenchSeg2D(); + BenchSampleQuat(); BenchHomogr2D(); diff --git a/MMVII/src/CodedTarget/cCheckBoardTargetExtract.cpp b/MMVII/src/CodedTarget/cCheckBoardTargetExtract.cpp index f34711fb4b..5713b052bf 100755 --- a/MMVII/src/CodedTarget/cCheckBoardTargetExtract.cpp +++ b/MMVII/src/CodedTarget/cCheckBoardTargetExtract.cpp @@ -8,6 +8,7 @@ #include "MMVII_Sensor.h" #include "MMVII_HeuristikOpt.h" #include "MMVII_ExtractLines.h" +#include "MMVII_TplImage_PtsFromValue.h" namespace MMVII @@ -26,23 +27,23 @@ class cOptimPosSeg : public tFunc2DReal tSeg2dr OptimizeSeg(tREAL8 aStepInit,tREAL8 aStepLim,bool IsMin,tREAL8 aMaxDInfInit) const; private : - cSegment2DCompiled mSeg0; + cSegment2DCompiled mSegInit; cPt2dr mP0Loc; cPt2dr mP1Loc; }; cOptimPosSeg::cOptimPosSeg(const tSeg2dr & aSeg0) : - mSeg0 (aSeg0), - mP0Loc (mSeg0.ToCoordLoc(mSeg0.P1())), - mP1Loc (mSeg0.ToCoordLoc(mSeg0.P2())) + mSegInit (aSeg0), + mP0Loc (mSegInit.ToCoordLoc(mSegInit.P1())), + mP1Loc (mSegInit.ToCoordLoc(mSegInit.P2())) { } cSegment2DCompiled cOptimPosSeg::ModifiedSeg(const cPt2dr & aPModif) const { - cPt2dr aP0Glob = mSeg0.FromCoordLoc(mP0Loc+cPt2dr(0,aPModif.x())); - cPt2dr aP1Glob = mSeg0.FromCoordLoc(mP1Loc+cPt2dr(0,aPModif.y())); + cPt2dr aP0Glob = mSegInit.FromCoordLoc(mP0Loc+cPt2dr(0,aPModif.x())); + cPt2dr aP1Glob = mSegInit.FromCoordLoc(mP1Loc+cPt2dr(0,aPModif.y())); return cSegment2DCompiled(aP0Glob,aP1Glob); } @@ -63,16 +64,31 @@ tSeg2dr cOptimPosSeg::OptimizeSeg(tREAL8 aStepInit,tREAL8 aStepLim,bool IsMin,tR class cOptimSeg_ValueIm : public cOptimPosSeg { public : - cOptimSeg_ValueIm(const tSeg2dr &,tREAL8 aStepOnSeg,const cDataIm2D & aDIm,tREAL8 aTargetValue); + cOptimSeg_ValueIm(const tSeg2dr &,tREAL8 aStepOnSeg,const cDataIm2D & aDIm,tREAL8 aTargetValue); tREAL8 CostOfSeg(const cSegment2DCompiled &) const override; private : tREAL8 mStepOnSeg; int mNbOnSeg; - const cDataIm2D & mDataIm; + const cDataIm2D & mDataIm; tREAL8 mTargetValue; }; +cOptimSeg_ValueIm::cOptimSeg_ValueIm +( + const tSeg2dr & aSegInit, + tREAL8 aStepOnSeg, + const cDataIm2D & aDIm, + tREAL8 aTargetValue +) : + cOptimPosSeg (aSegInit), + mStepOnSeg (aStepOnSeg), + mNbOnSeg (round_up( Norm2(aSegInit.V12()) / mStepOnSeg )) , + mDataIm (aDIm), + mTargetValue (aTargetValue) +{ +} + tREAL8 cOptimSeg_ValueIm::CostOfSeg(const cSegment2DCompiled & aSeg) const { tREAL8 aSum=0; @@ -89,6 +105,7 @@ tREAL8 cOptimSeg_ValueIm::CostOfSeg(const cSegment2DCompiled & aSeg) con + static constexpr tU_INT1 eNone = 0 ; static constexpr tU_INT1 eTopo0 = 1 ; static constexpr tU_INT1 eTopoTmpCC = 2 ; @@ -125,13 +142,16 @@ class cCdRadiom : public cCdSym { public : cCdRadiom(const cCdSym &,const cDataIm2D & aDIm,tREAL8 aTeta1,tREAL8 aTeta2,tREAL8 aThickness); - cMatIner2Var StatGray(const cDataIm2D & aDIm,tREAL8 aThickness,bool IncludeSegs); - tREAL8 mTeta0; - tREAL8 mTeta1; + /// Once blac/white & teta are computed, refine seg using + void OptimSegIm(const cDataIm2D & aDIm,tREAL8 aLength); + +// cOptimSeg_ValueIm(const tSeg2dr &,tREAL8 aStepOnSeg,const cDataIm2D & aDIm,tREAL8 aTargetValue); + tREAL8 mTetas[2]; tREAL8 mCostCorrel; // 1-Correlation of model + tREAL8 mRatioBW; // ratio min/max of BW tREAL8 mBlack; tREAL8 mWhite; }; @@ -163,11 +183,12 @@ class cCdRadiomCompiled : public cCdRadiom cSegment2DCompiled mSeg1 ; }; + cCdRadiomCompiled::cCdRadiomCompiled(const cCdRadiom & aCDR,tREAL8 aThickness) : cCdRadiom (aCDR), mThickness (aThickness), - mSeg0 (mC,mC+FromPolar(1.0,mTeta0)), - mSeg1 (mC,mC+FromPolar(1.0,mTeta1)) + mSeg0 (mC,mC+FromPolar(1.0,mTetas[0])), + mSeg1 (mC,mC+FromPolar(1.0,mTetas[1])) { } @@ -222,15 +243,15 @@ std::pair cCdRadiomCompiled::TheorRadiom(const cPt2dr &aPt) con cCdRadiom::cCdRadiom(const cCdSym & aCdSym,const cDataIm2D & aDIm,tREAL8 aTeta0,tREAL8 aTeta1,tREAL8 aThickness) : cCdSym (aCdSym), - mTeta0 (aTeta0), - mTeta1 (aTeta1), - mCostCorrel (2.001) // over maximal theoreticall value + mTetas {aTeta0,aTeta1}, + mCostCorrel (2.001), // over maximal theoreticall value + mRatioBW (0) { static int aCpt=0 ; aCpt++; - cSegment2DCompiled aSeg0 (mC,mC+FromPolar(1.0,mTeta0)); - cSegment2DCompiled aSeg1 (mC,mC+FromPolar(1.0,mTeta1)); + cSegment2DCompiled aSeg0 (mC,mC+FromPolar(1.0,mTetas[0])); + cSegment2DCompiled aSeg1 (mC,mC+FromPolar(1.0,mTetas[1])); static std::vector aDisk = VectOfRadius(0.0,5); cStdStatRes aW0; cStdStatRes aW1; @@ -262,8 +283,8 @@ cCdRadiom::cCdRadiom(const cCdSym & aCdSym,const cDataIm2D & aDIm,tREAL8 } } - tREAL8 aRatioNb = std::min(aNbIn0,aNbIn1) / (tREAL8) std::max(aNbIn0,aNbIn1); - if (aRatioNb <0.2) + mRatioBW = std::min(aNbIn0,aNbIn1) / (tREAL8) std::max(aNbIn0,aNbIn1); + if (mRatioBW <0.05) { return ; } @@ -274,6 +295,27 @@ cCdRadiom::cCdRadiom(const cCdSym & aCdSym,const cDataIm2D & aDIm,tREAL8 mWhite = a+b; } +void cCdRadiom::OptimSegIm(const cDataIm2D & aDIm,tREAL8 aLength) +{ + std::vector> aVSegOpt; + for (int aKTeta=0 ; aKTeta<2 ; aKTeta++) + { + cPt2dr aTgt = FromPolar(aLength,mTetas[aKTeta]); + tSeg2dr aSegInit(mC-aTgt,mC+aTgt); + cOptimSeg_ValueIm aOSVI(aSegInit,0.5,aDIm,(mBlack+mWhite)/2.0); + tSeg2dr aSegOpt = aOSVI.OptimizeSeg(0.5,0.01,true,2.0); + + aVSegOpt.push_back(aSegOpt); + mTetas[aKTeta] = Teta(aSegOpt.V12()); + // mTetas[aKTeta] = aSegOpt.I// + } + + cPt2dr aC = aVSegOpt.at(0).InterSeg(aVSegOpt.at(1)); + + mC = aC; + cScoreTetaLine::NormalizeTeta(mTetas); +} + /* *********************************************************** */ /* */ /* cAppliCheckBoardTargetExtract */ @@ -320,6 +362,7 @@ class cAppliCheckBoardTargetExtract : public cMMVII_Appli // -- tREAL8 mThickness; ///< used for fine estimation of radiom + bool mOptimSegByRadiom; ///< Do we optimize the segment on average radiom // =========== Internal param ============ tIm mImIn; ///< Input global image @@ -343,6 +386,7 @@ cAppliCheckBoardTargetExtract::cAppliCheckBoardTargetExtract(const std::vector= (int) eTopoMaxLoc) { - aRGB.SetRGBPix(aPix,(aDMasq.GetV(aPix)==eFilterSym) ? cRGBImage::Red : cRGBImage::Green ); + cPt3di aCoul = cRGBImage::Yellow; + if (aDMasq.GetV(aPix)== eFilterSym) aCoul = cRGBImage::Green; + if (aDMasq.GetV(aPix)== eFilterRadiom) aCoul = cRGBImage::Red; + aRGB.SetRGBPix(aPix,aCoul); } } aRGB.ToFile("Saddles.tif"); @@ -401,16 +449,25 @@ cCdRadiom cAppliCheckBoardTargetExtract::TestBinarization(cScoreTetaLine & aSTL, cCdRadiom aCdRadiom(aCdSym,*mDImIn,aTeta0,aTeta1,aThickness); + if (mOptimSegByRadiom) + { + aCdRadiom.OptimSegIm(*(aSTL.DIm()),aSTL.Length()); + } + if (IsPtTest(aCdSym.mC)) { + + static int aCpt=0 ; aCpt++; - StdOut() << " CPT=" << aCpt << " Corrrr=" << aCdRadiom.mCostCorrel << " V0="<< aCdRadiom.mBlack << " V1=" << aCdRadiom.mWhite << "\n"; + StdOut() << " CPT=" << aCpt << " Corrrr=" << aCdRadiom.mCostCorrel + << " Ratio=" << aCdRadiom.mRatioBW + << " V0="<< aCdRadiom.mBlack << " V1=" << aCdRadiom.mWhite << "\n"; // StdOut() << " CPT=" << aCpt << " TETASRef= " << aTeta0 << " " << aTeta1 << "\n"; int aZoom = 9; cPt2di aSz(50,50); cPt2di aDec = ToI(aCdSym.mC) - aSz/2; - cPt2dr aCLoc = aCdSym.mC-ToR(aDec); + cPt2dr aCLoc = aCdRadiom.mC-ToR(aDec); cRGBImage aIm = cRGBImage:: FromFile(mNameIm,cBox2di(aDec,aDec+aSz),aZoom); aIm.ResetGray(); @@ -430,22 +487,37 @@ cCdRadiom cAppliCheckBoardTargetExtract::TestBinarization(cScoreTetaLine & aSTL, } int aKT=0; - for (const auto & aTeta : {aTeta0,aTeta1}) + for (const auto & aTeta : aCdRadiom.mTetas) { for (int aK= -aZoom * 20 ; aK<=aZoom*20 ; aK++) { - tREAL8 aAbsc= aK/ (2.0 * aZoom); - cPt2dr aPt = aCLoc + FromPolar(aAbsc,aTeta); - aIm.SetRGBPoint(aPt,cRGBImage::Green); - if (aK==6*aZoom) - aIm.DrawCircle((aKT==0) ? cRGBImage::Blue : cRGBImage::Red,aPt,0.5); + tREAL8 aAbsc= aK/ (2.0 * aZoom); + cPt2dr aPt = aCLoc + FromPolar(aAbsc,aTeta); + if (aK==6*aZoom) + aIm.DrawCircle((aKT==0) ? cRGBImage::Blue : cRGBImage::Red,aPt,0.5); // aIm.SetRGBPoint(aPt, (aKT==0) ? cRGBImage::Blue : cRGBImage::Red); + tREAL8 aSign = ((aAbsc>0) ? 1.0 : -1.0) * ((aKT==0) ? 1 : -1) ; + cPt2dr aNorm = FromPolar(1.0,aTeta + M_PI/2.0) * aSign; + aIm.SetRGBPoint(aPt,cRGBImage::Yellow); + if (std::abs(aAbsc) > 1.0) + { + tREAL8 aV = (aCdRadiom.mBlack+aCdRadiom.mWhite) /2.0; + + cGetPts_ImInterp_FromValue aGIFV(*mDImIn,aV,0.1,aPt+ToR(aDec)-aNorm, aNorm); + if (aGIFV.Ok()) + { + aIm.SetRGBPoint(aGIFV.PRes()-ToR(aDec),cRGBImage::Blue); + } + // StdOut() << "OKKK " << aGIFV.Ok() << " K=" << aK << "\n"; + } + // aIm.SetRGBPoint(aPt,cRGBImage::Green); } aKT++; } aIm.SetRGBPoint(aCLoc,cRGBImage::Red); aIm.ToFile("TestCenter_" + ToStr(aCpt) + ".tif"); +// getchar(); } return aCdRadiom; @@ -462,7 +534,7 @@ void cAppliCheckBoardTargetExtract::DoOneImage() tREAL8 mDistCalcSym0 = 8.0; // distance for evaluating symetry criteria tREAL8 mDistDivSym = 2.0; // maximal distance to initial value in symetry opt - tREAL8 mLengtSInit = 5.0; + tREAL8 mLengtSInit = 05.0; tREAL8 mStepSeg = 0.5; tREAL8 mMaxCostCorrIm = 0.1; @@ -621,7 +693,10 @@ void cAppliCheckBoardTargetExtract::DoOneImage() { cCdRadiom aCdRad = TestBinarization(aSTL,aCdtSym,mThickness); if (aCdRad.mCostCorrel <= mMaxCostCorrIm) + { aVCdtRad.push_back(aCdRad); + mDImLabel->SetV(ToI(aCdRad.mC),eFilterRadiom); + } } } diff --git a/MMVII/src/CodedTarget/cCircTargetExtract.cpp b/MMVII/src/CodedTarget/cCircTargetExtract.cpp index c87ea7334e..a96ef36aa9 100755 --- a/MMVII/src/CodedTarget/cCircTargetExtract.cpp +++ b/MMVII/src/CodedTarget/cCircTargetExtract.cpp @@ -671,6 +671,7 @@ class cAppliExtractCircTarget : public cMMVII_Appli, std::string mReportMutipleDetec; // Name for report of multiple detection in on target double mRatioDMML; + int mNbMaxMulTarget; cThresholdCircTarget mThresh; std::vector mGTMissed; @@ -697,7 +698,8 @@ cAppliExtractCircTarget::cAppliExtractCircTarget mPatHihlight ("XXXXX"), mUseSimul (false), mDoReportSimul (false), - mRatioDMML (1.5) + mRatioDMML (1.5), + mNbMaxMulTarget (2) { } @@ -724,6 +726,7 @@ cCollecSpecArg2007 & cAppliExtractCircTarget::ArgOpt(cCollecSpecArg2007 & anArgO << AOpt2007(mZoomVisuSeed,"ZoomVisuSeed","Make a visualisation of seed point",{eTA2007::HDV}) << AOpt2007(mZoomVisuElFinal,"ZoomVisuEllipse","Make a visualisation extracted ellispe & target",{eTA2007::HDV}) << AOpt2007(mPatHihlight,"PatHL","Pattern for highliting targets in visu",{eTA2007::HDV}) + << AOpt2007(mNbMaxMulTarget,"NbMMT","Nb max of multiple target acceptable",{eTA2007::HDV}) << mPhProj.DPPointsMeasures().ArgDirOutOptWithDef("Std") ); } @@ -1060,7 +1063,7 @@ void cAppliExtractCircTarget::OnCloseReport(int aNbLine,const std::string & anId { if (anIdent==mReportMutipleDetec) { - if (aNbLine>4) // Each target is detected 2 times + if (aNbLine>(mNbMaxMulTarget*2)) // Each target is detected 2 times { MMVII_UsersErrror(eTyUEr::eMultipleTargetInOneImage,"Nb Multiple Target = " + ToStr(aNbLine/2)); } diff --git a/MMVII/src/Geom2D/GeomsBase2D.cpp b/MMVII/src/Geom2D/GeomsBase2D.cpp index dc88b927b7..291b26b39a 100755 --- a/MMVII/src/Geom2D/GeomsBase2D.cpp +++ b/MMVII/src/Geom2D/GeomsBase2D.cpp @@ -97,6 +97,40 @@ template Type cSegment2DCompiled::DistClosedSeg(const tPt& aP return std::abs(aPL.y()); } +template + cPtxd cSegment2DCompiled::InterSeg + ( + const cSegment2DCompiled & aSeg2, + tREAL8 aMinAngle, + bool *IsOk + ) +{ + // (aM1 + L1 T1) . N2 = M2 . N2 + // L1 (T1.N2) = N2. (aM2-aM1) + tPt aM1 = this->PMil(); + tPt aM2 = aSeg2.PMil(); + + Type aScalT1N2 = Scal(this->mTgt,aSeg2.mNorm); + + if (std::abs(aScalT1N2) <= aMinAngle) + { + if (IsOk) + { + *IsOk = false; + return cPtxd::Dummy(); + } + MMVII_INTERNAL_ERROR("Segment2DCompiled::InterSeg : almost parallel"); + } + + if (IsOk) + *IsOk = true; + + Type aLambda = Scal(aM2-aM1,aSeg2.mNorm) / aScalT1N2 ; + + return aM1 + this->mTgt * aLambda; +} + + /* ========================== */ /* cClosedSeg2D */ /* ========================== */ diff --git a/MMVII/src/ImagesInfoExtract/cScoreTetaLine.cpp b/MMVII/src/ImagesInfoExtract/cScoreTetaLine.cpp index bc138b08a4..bfdace3f18 100755 --- a/MMVII/src/ImagesInfoExtract/cScoreTetaLine.cpp +++ b/MMVII/src/ImagesInfoExtract/cScoreTetaLine.cpp @@ -104,25 +104,34 @@ tREAL8 cScoreTetaLine::Refine(tREAL8 aTeta0,tREAL8 aStepPix,int aSign) std::pair cScoreTetaLine::Tetas_CheckBoard(const cPt2dr & aC,tREAL8 aStepInit,tREAL8 aStepLim) { - std::vector aVTeta; + tREAL8 aVTeta[2]; SetCenter(aC); for (const auto & aSign : {-1,1}) { tREAL8 aTetaInit = GetTetasInit(aStepInit,aSign); tREAL8 aTetaRefine = Refine(aTetaInit,aStepLim,aSign); - - // at this step the angles are define % pi, theoretically in [0,Pi], btw after due to optim it can be slightly outside - aTetaRefine = mod_real(aTetaRefine,M_PI); - aVTeta.push_back(aTetaRefine); + aVTeta[(1+aSign)/2] = aTetaRefine; } + NormalizeTeta(aVTeta); + + return std::pair(aVTeta[0],aVTeta[1]); +} - // the angle are defined %pi, to have a single representation we need that teta1/teta2 - // correpond to a direct repair - if (aVTeta.at(0)> aVTeta.at(1)) - aVTeta.at(1) += M_PI; +void cScoreTetaLine::NormalizeTeta(t2Teta & aVTeta) +{ + // the angles are define % pi, t2ddo have a unique representation + for (int aK=0 ; aK<2 ; aK++) + aVTeta[aK] = mod_real(aVTeta[aK],M_PI); + + // we need that teta1/teta2 correpond to a direct repair + if (aVTeta[0]> aVTeta[1]) + aVTeta[1] += M_PI; - return std::pair(aVTeta.at(0),aVTeta.at(1)); } +const tREAL8 & cScoreTetaLine::Length() const {return mLength;} +cDataIm2D * cScoreTetaLine::DIm() const {return mDIm;} + + };