@@ -55,10 +55,14 @@ cCircTargExtr::cCircTargExtr(const cExtractedEllipse & anEE) :
55
55
/* */
56
56
/* ********************************************* */
57
57
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
+ */
62
66
63
67
class cCCDecode
64
68
{
@@ -67,22 +71,33 @@ class cCCDecode
67
71
68
72
void Show (const std::string & aPrefix);
69
73
74
+ // / Compute phase minimizing standard deviation, make a decision if its low enough
70
75
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
+
73
80
private :
74
81
75
82
// Aggregation
76
83
tREAL8 StdDev (int aK1,int aK2) const ; // /< standard deviation of the interval
77
84
tREAL8 Avg (int aK1,int aK2) const ; // /< average of the interval
78
85
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 ;
79
90
80
91
// Geometric correspondances
81
92
tREAL8 K2Rho (int aK) const ; // / index of rho 2 real rho
82
93
tREAL8 K2Teta (int aK) const ; // / index of teta 2 real teta
83
94
int Rho2K (tREAL8 aR) const ; // / real rho 2 index of rho
84
95
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 ;
86
101
87
102
88
103
cCircTargExtr & mEE ;
@@ -128,8 +143,8 @@ cCCDecode::cCCDecode(cCircTargExtr & anEE,const cDataIm2D<tREAL4> & aDIm,const c
128
143
mDIP (mImPolar .DIm()),
129
144
mAvg ( mNbTeta ,nullptr ,eModeInitImage::eMIA_Null ),
130
145
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 )) ) ,
133
148
mPhase0 (-1 ),
134
149
mBlack (mEE .mBlack ),
135
150
mWhite (mEE .mWhite ),
@@ -172,20 +187,25 @@ cCCDecode::cCCDecode(cCircTargExtr & anEE,const cDataIm2D<tREAL4> & aDIm,const c
172
187
ComputePhaseTeta () ;
173
188
if (!mOK ) return ;
174
189
175
- ComputeCode (true );
190
+ ComputeCode ();
176
191
if (!mOK ) return ;
177
192
}
178
193
179
194
// ============= Agregation on interval : StdDev , Avg, TotalStdDevOfPhase ====
180
195
181
-
182
- tREAL8 cCCDecode::StdDev (int aK1,int aK2) const
196
+ void cCCDecode::AddStdDev (int aK1,int aK2,cComputeStdDev<tREAL8> & aCS) const
183
197
{
184
- cComputeStdDev<tREAL8> aCS;
185
198
for (int aK=aK1 ; aK<aK2 ; aK++)
186
199
{
187
200
aCS.Add (mDAvg .GetV (aK%mNbTeta ));
188
201
}
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);
189
209
return aCS.StdDev (0 );
190
210
}
191
211
@@ -199,30 +219,62 @@ tREAL8 cCCDecode::Avg(int aK1,int aK2) const
199
219
return aSom / (aK2-aK1);
200
220
}
201
221
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
+
202
234
tREAL8 cCCDecode::TotalStdDevOfPhase (int aK0) const
203
235
{
204
236
tREAL8 aSum=0 ;
205
237
for (int aKBit=0 ; aKBit<mNbB ; aKBit++)
206
238
{
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 ));
209
242
}
210
-
211
243
return aSum / mNbB ;
212
244
}
213
245
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
+
214
266
215
267
// =================
216
268
217
269
void cCCDecode::ComputePhaseTeta ()
218
270
{
271
+ // Extract phase minimizing the standard dev on all intervall
219
272
cWhichMin<int ,tREAL8> aMinDev;
220
-
221
273
for (int aK0=0 ;aK0< mPixPerB ; aK0++)
222
274
aMinDev.Add (aK0,TotalStdDevOfPhase (aK0));
223
-
224
275
mPhase0 = aMinDev.IndexExtre ();
225
276
277
+ // decide if sufficiently homogeneous
226
278
if ( (aMinDev.ValExtre () > 0.1 * StdDev (0 ,mNbTeta ))
227
279
|| (aMinDev.ValExtre () > 0.05 * mBWAmpl )
228
280
)
@@ -232,8 +284,9 @@ void cCCDecode::ComputePhaseTeta()
232
284
}
233
285
}
234
286
235
- void cCCDecode::ComputeCode (bool Show )
287
+ void cCCDecode::ComputeCode ()
236
288
{
289
+ // compute flag of bit
237
290
size_t aFlag=0 ;
238
291
for (int aKBit=0 ; aKBit<mNbB ; aKBit++)
239
292
{
@@ -244,48 +297,37 @@ void cCCDecode::ComputeCode(bool Show)
244
297
aFlag |= (1 <<aKBit);
245
298
}
246
299
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 ());
247
305
248
- if (! mSpec .AntiClockWiseBit ())
249
- aFlag = BitMirror (aFlag,1 <<mSpec .NbBits ());
306
+ mEnCode = mSpec .EncodingFromCode (aFlagCode);
250
307
251
- mEnCode = mSpec .EncodingFromCode (aFlag);
308
+ if (! mEnCode ) return ;
309
+ }
252
310
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);
254
315
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 )
258
318
{
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 " ;
267
322
}
268
- }
269
323
270
324
271
325
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 ());
275
328
}
276
329
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
- }
284
330
285
- tREAL8 cCCDecode::RhoOfWeight (const tREAL8 & aW) const
286
- {
287
- return (1 -aW) * mSpec .Rho_1_BeginCode () + aW * mSpec .Rho_2_EndCode ();
288
- }
289
331
290
332
291
333
@@ -307,12 +349,18 @@ void cCCDecode::Show(const std::string & aPrefix)
307
349
}
308
350
309
351
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 " ;
310
361
}
311
362
312
363
313
- const cOneEncoding * cCCDecode::EnCode () const {return mEnCode ; }
314
- #if (0)
315
- #endif
316
364
317
365
/* *********************************************************** */
318
366
/* */
0 commit comments