@@ -55,10 +55,14 @@ cCircTargExtr::cCircTargExtr(const cExtractedEllipse & anEE) :
5555/* */
5656/* ********************************************* */
5757
58- /* * Class for computing the circular code: make a polar representation , offers mapping polar/cart
59- *
60- *
61- * */
58+ /* * Class for computing the circular code:
59+
60+ * make a polar representation , evaluate if it
61+ * find the phase that maximize the standrd dev insid each interval
62+ * decide code/non code regarding the average std dev
63+ * compute the code
64+
65+ */
6266
6367class cCCDecode
6468{
@@ -67,22 +71,33 @@ class cCCDecode
6771
6872 void Show (const std::string & aPrefix);
6973
74+ // / Compute phase minimizing standard deviation, make a decision if its low enough
7075 void ComputePhaseTeta () ;
71- void ComputeCode (bool Show) ;
72- const cOneEncoding * EnCode () const ;
76+
77+ // / Compute de binary flag, try to interpret as a code, eventually memorize in mEE
78+ void ComputeCode ();
79+
7380 private :
7481
7582 // Aggregation
7683 tREAL8 StdDev (int aK1,int aK2) const ; // /< standard deviation of the interval
7784 tREAL8 Avg (int aK1,int aK2) const ; // /< average of the interval
7885 tREAL8 TotalStdDevOfPhase (int aK0) const ; // /< Sum of standard dev, on all interval, for a given stard
86+ // / Used to compute the total deviation of black or white
87+ tREAL8 StdDevOfSumInterv (const std::vector<cPt2di> &);
88+ // / Add value of interval to dev structure
89+ void AddStdDev (int aK1,int aK2,cComputeStdDev<tREAL8> & aCS) const ;
7990
8091 // Geometric correspondances
8192 tREAL8 K2Rho (int aK) const ; // / index of rho 2 real rho
8293 tREAL8 K2Teta (int aK) const ; // / index of teta 2 real teta
8394 int Rho2K (tREAL8 aR) const ; // / real rho 2 index of rho
8495 cPt2dr KTetaRho2Im (const cPt2di & aKTetaRho) const ; // / index rho-teta 2 cartesian coordinates
85- tREAL8 RhoOfWeight (const tREAL8 &) const ;
96+ // / For weight in [0,1] return a rho corresponding to coding place
97+ tREAL8 CodingRhoOfWeight (const tREAL8 &) const ;
98+
99+ int KBeginInterv (int aK0,int aNumBit) const ;
100+ int KEndInterv (int aK0,int aNumBit) const ;
86101
87102
88103 cCircTargExtr & mEE ;
@@ -128,8 +143,8 @@ cCCDecode::cCCDecode(cCircTargExtr & anEE,const cDataIm2D<tREAL4> & aDIm,const c
128143 mDIP (mImPolar .DIm()),
129144 mAvg ( mNbTeta ,nullptr ,eModeInitImage::eMIA_Null ),
130145 mDAvg ( mAvg .DIm()),
131- mKR0 ( Rho2K(RhoOfWeight (0.25 )) ) ,
132- mKR1 ( Rho2K(RhoOfWeight (0.75 )) ) ,
146+ mKR0 ( Rho2K(CodingRhoOfWeight (0.25 )) ) ,
147+ mKR1 ( Rho2K(CodingRhoOfWeight (0.75 )) ) ,
133148 mPhase0 (-1 ),
134149 mBlack (mEE .mBlack ),
135150 mWhite (mEE .mWhite ),
@@ -172,20 +187,25 @@ cCCDecode::cCCDecode(cCircTargExtr & anEE,const cDataIm2D<tREAL4> & aDIm,const c
172187 ComputePhaseTeta () ;
173188 if (!mOK ) return ;
174189
175- ComputeCode (true );
190+ ComputeCode ();
176191 if (!mOK ) return ;
177192}
178193
179194// ============= Agregation on interval : StdDev , Avg, TotalStdDevOfPhase ====
180195
181-
182- tREAL8 cCCDecode::StdDev (int aK1,int aK2) const
196+ void cCCDecode::AddStdDev (int aK1,int aK2,cComputeStdDev<tREAL8> & aCS) const
183197{
184- cComputeStdDev<tREAL8> aCS;
185198 for (int aK=aK1 ; aK<aK2 ; aK++)
186199 {
187200 aCS.Add (mDAvg .GetV (aK%mNbTeta ));
188201 }
202+ }
203+ // aSum += (KBeginInterv(aK0,aKBit),KEndInterv(aK0,aKBit+1));
204+
205+ tREAL8 cCCDecode::StdDev (int aK1,int aK2) const
206+ {
207+ cComputeStdDev<tREAL8> aCS;
208+ AddStdDev (aK1,aK2,aCS);
189209 return aCS.StdDev (0 );
190210}
191211
@@ -199,30 +219,62 @@ tREAL8 cCCDecode::Avg(int aK1,int aK2) const
199219 return aSom / (aK2-aK1);
200220}
201221
222+ int cCCDecode::KBeginInterv (int aK0,int aNumBit) const { return aK0+aNumBit*mPixPerB +1 ; }
223+ int cCCDecode::KEndInterv (int aK0,int aNumBit) const { return aK0+aNumBit*mPixPerB -1 ; }
224+
225+ tREAL8 cCCDecode::StdDevOfSumInterv (const std::vector<cPt2di> & aVInterv)
226+ {
227+ cComputeStdDev<tREAL8> aCS;
228+ for (const auto & anI : aVInterv)
229+ AddStdDev ( KBeginInterv (mPhase0 ,anI.x ()), KEndInterv (mPhase0 ,anI.y ()), aCS);
230+
231+ return aCS.StdDev (0 );
232+ }
233+
202234tREAL8 cCCDecode::TotalStdDevOfPhase (int aK0) const
203235{
204236 tREAL8 aSum=0 ;
205237 for (int aKBit=0 ; aKBit<mNbB ; aKBit++)
206238 {
207- int aK1 = aK0+aKBit*mPixPerB ;
208- aSum += StdDev (aK1+1 ,aK1+mPixPerB -1 );
239+ // int aK1 = aK0+aKBit*mPixPerB;
240+ // aSum += StdDev(aK1+1,aK1+mPixPerB-1);
241+ aSum += StdDev (KBeginInterv (aK0,aKBit),KEndInterv (aK0,aKBit+1 ));
209242 }
210-
211243 return aSum / mNbB ;
212244}
213245
246+ // ===== Geometric correspondance between indexes, polar, cartesian ....
247+
248+ cPt2dr cCCDecode::KTetaRho2Im (const cPt2di & aKTR) const
249+ {
250+ return mEE .mEllipse .PtOfTeta (K2Teta (aKTR.x ()),K2Rho (aKTR.y ()));
251+ }
252+
253+ tREAL8 cCCDecode::K2Rho (const int aK) const {return mRho0 + ((mRho1 -mRho0 )*aK) / mNbRho ;}
254+ tREAL8 cCCDecode::K2Teta (const int aK) const {return (2 *M_PI*aK)/mNbTeta ;}
255+
256+ int cCCDecode::Rho2K (const tREAL8 aR) const
257+ {
258+ return round_ni ( ((aR-mRho0 )/(mRho1 -mRho0 )) * mNbRho );
259+ }
260+
261+ tREAL8 cCCDecode::CodingRhoOfWeight (const tREAL8 & aW) const
262+ {
263+ return (1 -aW) * mSpec .Rho_1_BeginCode () + aW * mSpec .Rho_2_EndCode ();
264+ }
265+
214266
215267// =================
216268
217269void cCCDecode::ComputePhaseTeta ()
218270{
271+ // Extract phase minimizing the standard dev on all intervall
219272 cWhichMin<int ,tREAL8> aMinDev;
220-
221273 for (int aK0=0 ;aK0< mPixPerB ; aK0++)
222274 aMinDev.Add (aK0,TotalStdDevOfPhase (aK0));
223-
224275 mPhase0 = aMinDev.IndexExtre ();
225276
277+ // decide if sufficiently homogeneous
226278 if ( (aMinDev.ValExtre () > 0.1 * StdDev (0 ,mNbTeta ))
227279 || (aMinDev.ValExtre () > 0.05 * mBWAmpl )
228280 )
@@ -232,8 +284,9 @@ void cCCDecode::ComputePhaseTeta()
232284 }
233285}
234286
235- void cCCDecode::ComputeCode (bool Show )
287+ void cCCDecode::ComputeCode ()
236288{
289+ // compute flag of bit
237290 size_t aFlag=0 ;
238291 for (int aKBit=0 ; aKBit<mNbB ; aKBit++)
239292 {
@@ -244,48 +297,37 @@ void cCCDecode::ComputeCode(bool Show)
244297 aFlag |= (1 <<aKBit);
245298 }
246299
300+ // flag for coding must be eventually inverted, depending of orientation convention
301+ {
302+ size_t aFlagCode = aFlag;
303+ if (! mSpec .AntiClockWiseBit ())
304+ aFlagCode = BitMirror (aFlag,1 <<mSpec .NbBits ());
247305
248- if (! mSpec .AntiClockWiseBit ())
249- aFlag = BitMirror (aFlag,1 <<mSpec .NbBits ());
306+ mEnCode = mSpec .EncodingFromCode (aFlagCode);
250307
251- mEnCode = mSpec .EncodingFromCode (aFlag);
308+ if (! mEnCode ) return ;
309+ }
252310
253- if (! mEnCode ) return ;
311+ // Make supplementary test
312+ std::vector<cPt2di> aV0;
313+ std::vector<cPt2di> aV1;
314+ MaxRunLength (aFlag,1 <<mNbB ,aV0,aV1);
254315
255- mEE .mWithCode = true ;
256- mEE .mEncode = cOneEncoding (mEnCode ->Num (),mEnCode ->Code (),mEnCode ->Name ());
257- if (false )
316+ // Test were made to compute the global deviation on black/white part, but not concluding as
317+ if (0 )
258318 {
259- // bool mWithCode;
260- // cOneEncoding mEncode;
261- StdOut () << " Adr=" << mEnCode << " " ;
262- if (mEnCode )
263- StdOut () << " Name=" << mEnCode ->Name ()
264- << " Code=" << mEnCode ->Code ()
265- << " BF=" << StrOfBitFlag (mEnCode ->Code (), 1 <<mNbB );
266- StdOut () << " \n " ;
319+ tREAL8 aDev0 = StdDevOfSumInterv (aV0);
320+ tREAL8 aDev1 = StdDevOfSumInterv (aV1);
321+ StdOut () << mEnCode ->Name () << " D0=" << aDev0/ mBWAmpl << " D1=" << aDev1/ mBWAmpl << " \n " ;
267322 }
268- }
269323
270324
271325
272- cPt2dr cCCDecode::KTetaRho2Im (const cPt2di & aKTR) const
273- {
274- return mEE .mEllipse .PtOfTeta (K2Teta (aKTR.x ()),K2Rho (aKTR.y ()));
326+ mEE .mWithCode = true ;
327+ mEE .mEncode = cOneEncoding (mEnCode ->Num (),mEnCode ->Code (),mEnCode ->Name ());
275328}
276329
277- tREAL8 cCCDecode::K2Rho (const int aK) const {return mRho0 + ((mRho1 -mRho0 )*aK) / mNbRho ;}
278- tREAL8 cCCDecode::K2Teta (const int aK) const {return (2 *M_PI*aK)/mNbTeta ;}
279-
280- int cCCDecode::Rho2K (const tREAL8 aR) const
281- {
282- return round_ni ( ((aR-mRho0 )/(mRho1 -mRho0 )) * mNbRho );
283- }
284330
285- tREAL8 cCCDecode::RhoOfWeight (const tREAL8 & aW) const
286- {
287- return (1 -aW) * mSpec .Rho_1_BeginCode () + aW * mSpec .Rho_2_EndCode ();
288- }
289331
290332
291333
@@ -307,12 +349,18 @@ void cCCDecode::Show(const std::string & aPrefix)
307349 }
308350
309351 aIm.ToFile (aPrefix + " _ImPolar_" +ToStr (aCpt)+" .tif" );
352+
353+ StdOut () << " Adr=" << mEnCode << " " ;
354+ if (mEnCode )
355+ {
356+ StdOut () << " Name=" << mEnCode ->Name ()
357+ << " Code=" << mEnCode ->Code ()
358+ << " BF=" << StrOfBitFlag (mEnCode ->Code (), 1 <<mNbB );
359+ }
360+ StdOut () << " \n " ;
310361}
311362
312363
313- const cOneEncoding * cCCDecode::EnCode () const {return mEnCode ; }
314- #if (0)
315- #endif
316364
317365/* *********************************************************** */
318366/* */
0 commit comments