diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b031005a8..674e8da971 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,7 +207,7 @@ if(${WITH_QT5}) message (" WindowsSDKDir : " ${CMAKE_PREFIX_PATH} ) endif() - add_compile_definitions(QT_NO_DEPRECATED_WARNINGS=1) # to work with both ubuntu 20.04 and 22.04... + #add_compile_definitions(QT_NO_DEPRECATED_WARNINGS=1) # to work with both ubuntu 20.04 and 22.04... find_package(Qt5Widgets REQUIRED) find_package(Qt5Xml REQUIRED) find_package(Qt5Concurrent REQUIRED) diff --git a/MMVII/include/MMVII_nums.h b/MMVII/include/MMVII_nums.h index a88193c04c..b7381fe065 100755 --- a/MMVII/include/MMVII_nums.h +++ b/MMVII/include/MMVII_nums.h @@ -845,6 +845,8 @@ size_t Str2BitFlag(const std::string & aStr); void BitsToVect(std::vector & aVBits,tU_INT4 aVal,size_t aPow2); /// return the maximal length of consecutive 0 & 1, interpreted circularly (94="01111010", 256=2^8) => (3,2) cPt2di MaxRunLength(tU_INT4 aVal,size_t aPow2); +/// idem above + memo the intervals +cPt2di MaxRunLength(tU_INT4 aVal,size_t aPow2,std::vector & aV0,std::vector & aV1); /// Max of both run (0 and 1) size_t MaxRun2Length(tU_INT4 aVal,size_t aPow2); diff --git a/MMVII/src/CodedTarget/cCircTargetExtract.cpp b/MMVII/src/CodedTarget/cCircTargetExtract.cpp index 3b1eeacdba..7973e189a7 100755 --- a/MMVII/src/CodedTarget/cCircTargetExtract.cpp +++ b/MMVII/src/CodedTarget/cCircTargetExtract.cpp @@ -55,10 +55,14 @@ cCircTargExtr::cCircTargExtr(const cExtractedEllipse & anEE) : /* */ /* ********************************************* */ -/** Class for computing the circular code: make a polar representation , offers mapping polar/cart - * - * - * */ +/** Class for computing the circular code: + + * make a polar representation , evaluate if it + * find the phase that maximize the standrd dev insid each interval + * decide code/non code regarding the average std dev + * compute the code + + */ class cCCDecode { @@ -67,22 +71,33 @@ class cCCDecode void Show(const std::string & aPrefix); + /// Compute phase minimizing standard deviation, make a decision if its low enough void ComputePhaseTeta() ; - void ComputeCode(bool Show) ; - const cOneEncoding * EnCode() const; + + /// Compute de binary flag, try to interpret as a code, eventually memorize in mEE + void ComputeCode(); + private : // Aggregation tREAL8 StdDev(int aK1,int aK2) const; ///< standard deviation of the interval tREAL8 Avg(int aK1,int aK2) const; ///< average of the interval tREAL8 TotalStdDevOfPhase(int aK0) const; ///< Sum of standard dev, on all interval, for a given stard + /// Used to compute the total deviation of black or white + tREAL8 StdDevOfSumInterv(const std::vector &); + /// Add value of interval to dev structure + void AddStdDev(int aK1,int aK2,cComputeStdDev & aCS) const; // Geometric correspondances tREAL8 K2Rho (int aK) const; /// index of rho 2 real rho tREAL8 K2Teta(int aK) const; /// index of teta 2 real teta int Rho2K (tREAL8 aR) const; /// real rho 2 index of rho cPt2dr KTetaRho2Im(const cPt2di & aKTetaRho) const; /// index rho-teta 2 cartesian coordinates - tREAL8 RhoOfWeight(const tREAL8 &) const; + /// For weight in [0,1] return a rho corresponding to coding place + tREAL8 CodingRhoOfWeight(const tREAL8 &) const; + + int KBeginInterv(int aK0,int aNumBit) const; + int KEndInterv(int aK0,int aNumBit) const; cCircTargExtr & mEE; @@ -128,8 +143,8 @@ cCCDecode::cCCDecode(cCircTargExtr & anEE,const cDataIm2D & aDIm,const c mDIP (mImPolar.DIm()), mAvg ( mNbTeta,nullptr,eModeInitImage::eMIA_Null ), mDAvg ( mAvg.DIm()), - mKR0 ( Rho2K(RhoOfWeight(0.25)) ) , - mKR1 ( Rho2K(RhoOfWeight(0.75)) ) , + mKR0 ( Rho2K(CodingRhoOfWeight(0.25)) ) , + mKR1 ( Rho2K(CodingRhoOfWeight(0.75)) ) , mPhase0 (-1), mBlack (mEE.mBlack), mWhite (mEE.mWhite), @@ -172,20 +187,25 @@ cCCDecode::cCCDecode(cCircTargExtr & anEE,const cDataIm2D & aDIm,const c ComputePhaseTeta() ; if (!mOK) return; - ComputeCode(true); + ComputeCode(); if (!mOK) return; } // ============= Agregation on interval : StdDev , Avg, TotalStdDevOfPhase ==== - -tREAL8 cCCDecode::StdDev(int aK1,int aK2) const +void cCCDecode::AddStdDev(int aK1,int aK2,cComputeStdDev & aCS) const { - cComputeStdDev aCS; for (int aK=aK1 ; aK aCS; + AddStdDev(aK1,aK2,aCS); return aCS.StdDev(0); } @@ -199,30 +219,62 @@ tREAL8 cCCDecode::Avg(int aK1,int aK2) const return aSom / (aK2-aK1); } +int cCCDecode::KBeginInterv(int aK0,int aNumBit) const { return aK0+aNumBit*mPixPerB +1 ; } +int cCCDecode::KEndInterv(int aK0,int aNumBit) const { return aK0+aNumBit*mPixPerB -1 ; } + +tREAL8 cCCDecode::StdDevOfSumInterv(const std::vector & aVInterv) +{ + cComputeStdDev aCS; + for (const auto & anI : aVInterv) + AddStdDev( KBeginInterv(mPhase0,anI.x()), KEndInterv(mPhase0,anI.y()), aCS); + + return aCS.StdDev(0); +} + tREAL8 cCCDecode::TotalStdDevOfPhase(int aK0) const { tREAL8 aSum=0; for (int aKBit=0 ; aKBit aMinDev; - for (int aK0=0 ;aK0< mPixPerB ; aK0++) aMinDev.Add(aK0,TotalStdDevOfPhase(aK0)); - mPhase0 = aMinDev.IndexExtre(); + // decide if sufficiently homogeneous if ( (aMinDev.ValExtre() > 0.1 * StdDev(0,mNbTeta)) || (aMinDev.ValExtre() > 0.05 * mBWAmpl) ) @@ -232,8 +284,9 @@ void cCCDecode::ComputePhaseTeta() } } -void cCCDecode::ComputeCode(bool Show) +void cCCDecode::ComputeCode() { + // compute flag of bit size_t aFlag=0; for (int aKBit=0 ; aKBit aV0; + std::vector aV1; + MaxRunLength(aFlag,1<Num(),mEnCode->Code(),mEnCode->Name()); - if (false) + // Test were made to compute the global deviation on black/white part, but not concluding as + if (0) { - // bool mWithCode; - // cOneEncoding mEncode; - StdOut() << "Adr=" << mEnCode << " "; - if (mEnCode) - StdOut() << " Name=" << mEnCode->Name() - << " Code=" << mEnCode->Code() - << " BF=" << StrOfBitFlag(mEnCode->Code(), 1<Name() << " D0=" << aDev0/ mBWAmpl << " D1=" << aDev1/ mBWAmpl << "\n"; } -} -cPt2dr cCCDecode::KTetaRho2Im(const cPt2di & aKTR) const -{ - return mEE.mEllipse.PtOfTeta(K2Teta(aKTR.x()),K2Rho(aKTR.y())); + mEE.mWithCode = true; + mEE.mEncode = cOneEncoding(mEnCode->Num(),mEnCode->Code(),mEnCode->Name()); } -tREAL8 cCCDecode::K2Rho(const int aK) const {return mRho0+ ((mRho1-mRho0)*aK) / mNbRho;} -tREAL8 cCCDecode::K2Teta(const int aK) const {return (2*M_PI*aK)/mNbTeta;} - -int cCCDecode::Rho2K(const tREAL8 aR) const -{ - return round_ni( ((aR-mRho0)/(mRho1-mRho0)) * mNbRho ); -} -tREAL8 cCCDecode::RhoOfWeight(const tREAL8 & aW) const -{ - return (1-aW) * mSpec.Rho_1_BeginCode() + aW * mSpec.Rho_2_EndCode(); -} @@ -307,12 +349,18 @@ void cCCDecode::Show(const std::string & aPrefix) } aIm.ToFile(aPrefix + "_ImPolar_"+ToStr(aCpt)+".tif"); + + StdOut() << "Adr=" << mEnCode << " "; + if (mEnCode) + { + StdOut() << " Name=" << mEnCode->Name() + << " Code=" << mEnCode->Code() + << " BF=" << StrOfBitFlag(mEnCode->Code(), 1< & aVBits,tU_INT4 aVal,size_t aPow2) } /// return the maximal length of consecutive 0 & 1, interpreted circularly (94="01111010", 256=2^8) => (3,2) -cPt2di MaxRunLength(tU_INT4 aVal,size_t aPow2) +/// fill vector will all interval +cPt2di MaxRunLength(tU_INT4 aVal,size_t aPow2,std::vector & aVInterv0,std::vector & aVInterv1) { + + aVInterv0.clear(); + aVInterv1.clear(); + std::vector aVBits; BitsToVect(aVBits,aVal,aPow2); @@ -182,9 +187,15 @@ cPt2di MaxRunLength(tU_INT4 aVal,size_t aPow2) while ( ValCirc(aVBits,aK1)==ValCirc(aVBits,aK2) ) // reach next diff aK2++; if (ValCirc(aVBits,aK1)) // update count for 0 or 1 + { + aVInterv1.push_back(cPt2di(aK1,aK2)); UpdateMax(aMaxR1,aK2-aK1); + } else + { + aVInterv0.push_back(cPt2di(aK1,aK2)); UpdateMax(aMaxR0,aK2-aK1); + } } } @@ -199,6 +210,13 @@ cPt2di MaxRunLength(tU_INT4 aVal,size_t aPow2) return cPt2di(aMaxR0,aMaxR1); } +cPt2di MaxRunLength(tU_INT4 aVal,size_t aPow2) +{ + std::vector aVInterv0; + std::vector aVInterv1; + return MaxRunLength(aVal,aPow2,aVInterv0,aVInterv1); +} + /// Max of both run (0 and 1) size_t MaxRun2Length(tU_INT4 aVal,size_t aPow2) {