auto import from //depot/cupcake/@135843
[android/platform/external/neven.git] / Embedded / common / src / b_BitFeatureEm / ScanDetector.c
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /* ---- includes ----------------------------------------------------------- */
18
19 #include "b_BasicEm/Functions.h"
20 #include "b_BasicEm/Math.h"
21 #include "b_BitFeatureEm/ScanDetector.h"
22
23 /* ------------------------------------------------------------------------- */
24
25 /* ========================================================================= */
26 /*                                                                           */
27 /* ---- \ghd{ auxiliary functions } ---------------------------------------- */
28 /*                                                                           */
29 /* ========================================================================= */
30
31 /* ------------------------------------------------------------------------- */
32
33 /* ========================================================================= */
34 /*                                                                           */
35 /* ---- \ghd{ constructor / destructor } ----------------------------------- */
36 /*                                                                           */
37 /* ========================================================================= */
38
39 /* ------------------------------------------------------------------------- */
40
41 void bbf_ScanDetector_init( struct bbs_Context* cpA,
42                                                     struct bbf_ScanDetector* ptrA )
43 {
44         uint32 iL;
45
46         ptrA->minScaleE = 0;
47         ptrA->maxScaleE = 0;
48         ptrA->maxImageWidthE = 0;
49         ptrA->maxImageHeightE = 0;
50         bbf_Scanner_init( cpA, &ptrA->scannerE );
51
52         ptrA->patchWidthE = 0;
53         ptrA->patchHeightE = 0;
54         ptrA->minDefScaleE = 0;
55         ptrA->maxDefScaleE = 0;
56         ptrA->scaleStepE = 0;
57         ptrA->overlapThrE = 0;
58         ptrA->borderWidthE = 0;
59         ptrA->borderHeightE = 0;
60         ptrA->featuresE = 0;
61         for( iL = 0; iL < bbf_SCAN_DETECTOR_MAX_FEATURES; iL++ ) bbf_BitParam_init( cpA, &ptrA->bitParamArrE[ iL ] );
62         for( iL = 0; iL < bbf_SCAN_DETECTOR_MAX_FEATURES; iL++ ) bbf_Sequence_init( cpA, &ptrA->featureArrE[ iL ] );
63         bts_IdCluster2D_init( cpA, &ptrA->refClusterE );
64         ptrA->refDistanceE = 10;
65 }
66
67 /* ------------------------------------------------------------------------- */
68
69 void bbf_ScanDetector_exit( struct bbs_Context* cpA,
70                                                     struct bbf_ScanDetector* ptrA )
71 {
72         uint32 iL;
73
74         ptrA->minScaleE = 0;
75         ptrA->maxScaleE = 0;
76         ptrA->maxImageWidthE = 0;
77         ptrA->maxImageHeightE = 0;
78         bbf_Scanner_exit( cpA, &ptrA->scannerE );
79
80         ptrA->patchWidthE = 0;
81         ptrA->patchHeightE = 0;
82         ptrA->minDefScaleE = 0;
83         ptrA->maxDefScaleE = 0;
84         ptrA->scaleStepE = 0;
85         ptrA->overlapThrE = 0;
86         ptrA->borderWidthE = 0;
87         ptrA->borderHeightE = 0;
88         ptrA->featuresE = 0;
89         for( iL = 0; iL < bbf_SCAN_DETECTOR_MAX_FEATURES; iL++ ) bbf_BitParam_exit( cpA, &ptrA->bitParamArrE[ iL ] );
90         for( iL = 0; iL < bbf_SCAN_DETECTOR_MAX_FEATURES; iL++ ) bbf_Sequence_exit( cpA, &ptrA->featureArrE[ iL ] );
91         bts_IdCluster2D_exit( cpA, &ptrA->refClusterE );
92         ptrA->refDistanceE = 0;
93 }
94
95 /* ------------------------------------------------------------------------- */
96
97 /* ========================================================================= */
98 /*                                                                           */
99 /* ---- \ghd{ operators } -------------------------------------------------- */
100 /*                                                                           */
101 /* ========================================================================= */
102
103 /* ------------------------------------------------------------------------- */
104
105 void bbf_ScanDetector_copy( struct bbs_Context* cpA,
106                                                     struct bbf_ScanDetector* ptrA, 
107                                                     const struct bbf_ScanDetector* srcPtrA )
108 {
109         bbs_ERROR0( "bbf_ScanDetector_copy:\n Function is not available" );
110 }
111
112 /* ------------------------------------------------------------------------- */
113
114 flag bbf_ScanDetector_equal( struct bbs_Context* cpA,
115                                                      const struct bbf_ScanDetector* ptrA, 
116                                                      const struct bbf_ScanDetector* srcPtrA )
117 {
118         bbs_ERROR0( "bbf_ScanDetector_equal:\n Function is not available" );
119         return TRUE;
120 }
121
122 /* ------------------------------------------------------------------------- */
123
124 /* ========================================================================= */
125 /*                                                                           */
126 /* ---- \ghd{ query functions } -------------------------------------------- */
127 /*                                                                           */
128 /* ========================================================================= */
129
130 /* ------------------------------------------------------------------------- */
131
132 /* ========================================================================= */
133 /*                                                                           */
134 /* ---- \ghd{ modify functions } ------------------------------------------- */
135 /*                                                                           */
136 /* ========================================================================= */
137
138 /* ------------------------------------------------------------------------- */
139         
140 /* ========================================================================= */
141 /*                                                                           */
142 /* ---- \ghd{ I/O } -------------------------------------------------------- */
143 /*                                                                           */
144 /* ========================================================================= */
145
146 /* ------------------------------------------------------------------------- */
147         
148 uint32 bbf_ScanDetector_memSize( struct bbs_Context* cpA,
149                                                              const struct bbf_ScanDetector* ptrA )
150 {
151         uint32 iL;
152         uint32 memSizeL = bbs_SIZEOF16( uint32 ) +
153                                           bbs_SIZEOF16( uint32 ); /* version */
154
155         memSizeL += bbs_SIZEOF16( ptrA->patchWidthE );
156         memSizeL += bbs_SIZEOF16( ptrA->patchHeightE );
157         memSizeL += bbs_SIZEOF16( ptrA->minDefScaleE );
158         memSizeL += bbs_SIZEOF16( ptrA->maxDefScaleE );
159         memSizeL += bbs_SIZEOF16( ptrA->scaleStepE );
160         memSizeL += bbs_SIZEOF16( ptrA->overlapThrE );
161         memSizeL += bbs_SIZEOF16( ptrA->borderWidthE );
162         memSizeL += bbs_SIZEOF16( ptrA->borderHeightE );
163         memSizeL += bbs_SIZEOF16( ptrA->featuresE );
164         for( iL = 0; iL < ptrA->featuresE; iL++ ) memSizeL += bbf_BitParam_memSize( cpA, &ptrA->bitParamArrE[ iL ] );
165         for( iL = 0; iL < ptrA->featuresE; iL++ ) memSizeL += bbf_Sequence_memSize( cpA, &ptrA->featureArrE[ iL ] );
166         memSizeL += bts_IdCluster2D_memSize( cpA, &ptrA->refClusterE );
167         memSizeL += bbs_SIZEOF16( ptrA->refDistanceE );
168
169         return memSizeL; 
170 }
171
172 /* ------------------------------------------------------------------------- */
173         
174 uint32 bbf_ScanDetector_memWrite( struct bbs_Context* cpA,
175                                                               const struct bbf_ScanDetector* ptrA, 
176                                                                   uint16* memPtrA )
177 {
178         uint32 iL;
179         uint32 memSizeL = bbf_ScanDetector_memSize( cpA, ptrA );
180         memPtrA += bbs_memWrite32( &memSizeL, memPtrA );
181         memPtrA += bbs_memWriteUInt32( bbf_SCAN_DETECTOR_VERSION, memPtrA );
182
183         memPtrA += bbs_memWrite32( &ptrA->patchWidthE, memPtrA );
184         memPtrA += bbs_memWrite32( &ptrA->patchHeightE, memPtrA );
185         memPtrA += bbs_memWrite32( &ptrA->minDefScaleE, memPtrA );
186         memPtrA += bbs_memWrite32( &ptrA->maxDefScaleE, memPtrA );
187         memPtrA += bbs_memWrite32( &ptrA->scaleStepE, memPtrA );
188         memPtrA += bbs_memWrite32( &ptrA->overlapThrE, memPtrA );
189         memPtrA += bbs_memWrite32( &ptrA->borderWidthE, memPtrA );
190         memPtrA += bbs_memWrite32( &ptrA->borderHeightE, memPtrA );
191         memPtrA += bbs_memWrite32( &ptrA->featuresE, memPtrA );
192         for( iL = 0; iL < ptrA->featuresE; iL++ ) memPtrA += bbf_BitParam_memWrite( cpA, &ptrA->bitParamArrE[ iL ], memPtrA );
193         for( iL = 0; iL < ptrA->featuresE; iL++ ) memPtrA += bbf_Sequence_memWrite( cpA, &ptrA->featureArrE[ iL ], memPtrA );
194         memPtrA += bts_IdCluster2D_memWrite( cpA, &ptrA->refClusterE, memPtrA );
195         memPtrA += bbs_memWrite32( &ptrA->refDistanceE, memPtrA );
196
197         return memSizeL;
198 }
199
200 /* ------------------------------------------------------------------------- */
201
202 uint32 bbf_ScanDetector_memRead( struct bbs_Context* cpA,
203                                                              struct bbf_ScanDetector* ptrA, 
204                                                              const uint16* memPtrA, 
205                                                              struct bbs_MemTbl* mtpA )
206 {
207         bbs_DEF_fNameL( "bbf_ScanDetector_memRead" )
208
209         /* debugging hint: set this flag to FALSE when you suspect a shared memory conflict */
210         const flag maximizeSharedMemoryL = TRUE;
211
212         uint32 iL;
213         uint32 memSizeL, versionL;
214         struct bbs_MemTbl memTblL = *mtpA;
215         struct bbs_MemSeg* espL = bbs_MemTbl_segPtr( cpA, &memTblL, 0 );
216         if( bbs_Context_error( cpA ) ) return 0;
217
218         memPtrA += bbs_memRead32( &memSizeL, memPtrA );
219         memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_SCAN_DETECTOR_VERSION, memPtrA );
220
221         memPtrA += bbs_memRead32( &ptrA->patchWidthE, memPtrA );
222         memPtrA += bbs_memRead32( &ptrA->patchHeightE, memPtrA );
223         memPtrA += bbs_memRead32( &ptrA->minDefScaleE, memPtrA );
224         memPtrA += bbs_memRead32( &ptrA->maxDefScaleE, memPtrA );
225         memPtrA += bbs_memRead32( &ptrA->scaleStepE, memPtrA );
226         memPtrA += bbs_memRead32( &ptrA->overlapThrE, memPtrA );
227         memPtrA += bbs_memRead32( &ptrA->borderWidthE, memPtrA );
228         memPtrA += bbs_memRead32( &ptrA->borderHeightE, memPtrA );
229         memPtrA += bbs_memRead32( &ptrA->featuresE, memPtrA );
230         for( iL = 0; iL < ptrA->featuresE; iL++ ) memPtrA += bbf_BitParam_memRead( cpA, &ptrA->bitParamArrE[ iL ], memPtrA );
231         for( iL = 0; iL < ptrA->featuresE; iL++ ) memPtrA += bbf_Sequence_memRead( cpA, &ptrA->featureArrE[ iL ], memPtrA, &memTblL );
232         memPtrA += bts_IdCluster2D_memRead( cpA, &ptrA->refClusterE, memPtrA, espL );
233         memPtrA += bbs_memRead32( &ptrA->refDistanceE, memPtrA );
234 /*
235         if( memSizeL != bbf_ScanDetector_memSize( cpA, ptrA ) )
236         {
237                 bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_ScanDetector_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n"
238                                 "size mismatch" );
239                 return 0;
240         }
241 */
242
243         ptrA->minScaleE = ptrA->minDefScaleE;
244         ptrA->maxScaleE = ptrA->maxDefScaleE;
245
246         /* initialize scanner; be aware of shared memory settings(!) */
247         {
248                 uint32 maxImageSizeL = ptrA->maxImageWidthE * ptrA->maxImageHeightE;
249
250                 /* estimate of maximal possible faces in image */
251                 uint32 maxFacesL = maxImageSizeL / ( 768 << 1 );
252
253                 uint32 maxRadiusL = 0;
254
255                 if( maxImageSizeL == 0 ) 
256                 {
257                         bbs_ERROR1( "%s:\nMaximum image size was not defined (size variables must be set before calling _memRead)", fNameL );
258                         return memSizeL; 
259                 }
260
261                 for( iL = 0; iL < ptrA->featuresE; iL++ ) 
262                 {
263                         maxRadiusL = maxRadiusL > ptrA->bitParamArrE[ iL ].outerRadiusE ? maxRadiusL : ptrA->bitParamArrE[ iL ].outerRadiusE;
264                 }
265
266                 if( maxFacesL < 1 ) maxFacesL = 1;
267
268                 bbf_Scanner_create( cpA, &ptrA->scannerE, 
269                                                         maximizeSharedMemoryL,
270                                                         ptrA->maxImageWidthE,
271                                                         ptrA->maxImageHeightE,
272                                                         maxRadiusL, 
273                                                         ptrA->patchWidthE,
274                                                         ptrA->patchHeightE,
275                                                         ptrA->minScaleE,
276                                                         ptrA->maxScaleE,
277                                                         ptrA->scaleStepE,
278                                                         ptrA->borderWidthE,
279                                                         ptrA->borderHeightE,
280                                                         maxFacesL * 20,  /* bufferSizeA */
281                                                         &memTblL );
282         }
283
284         return memSizeL;
285 }
286
287 /* ------------------------------------------------------------------------- */
288         
289 /* ========================================================================= */
290 /*                                                                           */
291 /* ---- \ghd{ exec functions } --------------------------------------------- */
292 /*                                                                           */
293 /* ========================================================================= */
294         
295 /* ------------------------------------------------------------------------- */
296
297 uint32 bbf_ScanDetector_process( struct bbs_Context* cpA, 
298                                                              struct bbf_ScanDetector* ptrA,
299                                                              const void* imagePtrA,
300                                                                  uint32 imageWidthA,
301                                                                  uint32 imageHeightA,
302                                                                  const struct bts_Int16Rect* roiPtrA,
303                                                                  int32** outArrPtrPtrA )
304 {
305         /* best global values (used when no positives could be found) */
306         int32 bestGlobalActL = ( int32 )0x80000000;
307         int32 bestGlobalXL = 0;
308         int32 bestGlobalYL = 0;
309         uint32 bestGlobalScaleL = 0;
310
311         struct bbf_Scanner* scannerPtrL = &ptrA->scannerE;
312
313         scannerPtrL->minScaleE = ptrA->minScaleE;
314         scannerPtrL->maxScaleE = ptrA->maxScaleE;
315
316         *outArrPtrPtrA = NULL;
317
318         if( bbs_Context_error( cpA ) ) return 0;
319         if( ptrA->featuresE == 0 )
320         {
321                 bbs_ERROR0( "bbf_ScanDetector_process: detector has no features" );
322                 return 0;
323         }
324
325         if( imageWidthA > ptrA->maxImageWidthE || imageHeightA > ptrA->maxImageHeightE )
326         {
327                 bbs_ERROR0( "bbf_ScanDetector_process: images size exceeds preallocated size" );
328                 return 0;
329         }
330
331         /* resets output positions */
332         bbf_Scanner_resetOutPos( cpA, scannerPtrL ); 
333
334         /* assign image to scanner - reset scanner */
335         bbf_Scanner_assign( cpA, scannerPtrL, imagePtrA, imageWidthA, imageHeightA, roiPtrA, &ptrA->bitParamArrE[ 0 ] );
336
337         while( bbf_Scanner_positions( scannerPtrL ) > 0 )
338         {
339                 int32 bestActL = ( int32 )0x80000000;
340                 uint32 bestIdxL = 0;
341                 uint32 bestLvlL = 0;
342                 uint32 iL;
343
344                 const struct bbf_Feature* featurePtrL = ( const struct bbf_Feature* )&ptrA->featureArrE[ 0 ];
345                 const struct bbf_BitParam* paramPtrL = &ptrA->bitParamArrE[ 0 ];
346                 bbf_Scanner_bitParam( cpA, scannerPtrL, paramPtrL );
347
348                 /* resets internal positions */
349                 bbf_Scanner_resetIntPos( cpA, scannerPtrL );
350
351                 do
352                 {
353                         int32 actL = featurePtrL->vpActivityE( featurePtrL, bbf_Scanner_getPatch( scannerPtrL ) );
354                         if( actL > 0 ) 
355                         {
356                                 bbf_Scanner_addIntPos( cpA, scannerPtrL, bbf_Scanner_scanIndex( scannerPtrL ), actL );
357                         }
358                         
359                         if( actL > bestActL )
360                         {
361                                 bestActL = actL;
362                                 bestIdxL = bbf_Scanner_scanIndex( scannerPtrL );
363                         }
364                 }
365                 while( bbf_Scanner_next( cpA, scannerPtrL ) );
366
367                 for( iL = 1; iL < ptrA->featuresE; iL++ )
368                 {
369                         const struct bbf_Feature* featurePtrL = ( const struct bbf_Feature* )&ptrA->featureArrE[ iL ];
370                         const struct bbf_BitParam* paramPtrL = &ptrA->bitParamArrE[ iL ];
371                         uint32* idxArrL = scannerPtrL->idxArrE.arrPtrE;
372                         int32* actArrL = scannerPtrL->actArrE.arrPtrE;
373
374                         uint32 kL = 0;
375                         uint32 jL;
376
377                         if( scannerPtrL->intCountE == 0 ) break;
378                         bestActL = ( int32 )0x80000000;
379                         bbf_Scanner_bitParam( cpA, scannerPtrL, paramPtrL );
380
381                         for( jL = 0; jL < scannerPtrL->intCountE; jL++ )
382                         {
383                                 int32 actL;
384                                 bbf_Scanner_goToIndex( cpA, scannerPtrL, idxArrL[ jL ] );
385                                 actL = featurePtrL->vpActivityE( featurePtrL, bbf_Scanner_getPatch( scannerPtrL ) );
386                                 if( actL > 0 )
387                                 {
388                                         idxArrL[ kL ] = idxArrL[ jL ];
389                                         actArrL[ kL ] = ( actArrL[ jL ] + actL ) >> 1;
390                                         kL++;
391                                 }
392
393                                 if( actL > bestActL )
394                                 {
395                                         bestActL = actL;
396                                         bestIdxL = idxArrL[ jL ];
397                                         bestLvlL = iL;
398                                 }
399                         }
400
401                         scannerPtrL->intCountE = kL;
402                 }
403
404                 if( scannerPtrL->intCountE == 0 )
405                 {
406                         int32 xL, yL;
407                         uint32 scaleL;
408
409                         /* 8.24 */
410                         int32 actL = ( bestActL >> 4 ) + ( ( ( int32 )( bestLvlL + 1 - ptrA->featuresE ) << 24 ) / ( int32 )ptrA->featuresE );
411
412                         /* 4.28 */
413                         actL <<= 4;
414
415                         bbf_Scanner_idxPos( scannerPtrL, bestIdxL, &xL, &yL, &scaleL );
416
417                         if( actL > bestGlobalActL )
418                         {
419                 bestGlobalActL = actL;
420                                 bestGlobalXL = xL;
421                                 bestGlobalYL = yL;
422                                 bestGlobalScaleL = scaleL;
423                         }
424                 }
425                 else
426                 {
427                         /* remove overlaps for current scale */
428                         bbf_Scanner_removeIntOverlaps( cpA, scannerPtrL, ptrA->overlapThrE );
429
430                         for( iL = 0; iL < scannerPtrL->intCountE; iL++ )
431                         {
432                                 int32 xL, yL;
433                                 uint32 scaleL;
434                                 uint32* idxArrL = scannerPtrL->idxArrE.arrPtrE;
435                                 int32* actArrL = scannerPtrL->actArrE.arrPtrE;
436
437                                 int32 actL = actArrL[ iL ];
438                                 bbf_Scanner_idxPos( scannerPtrL, idxArrL[ iL ], &xL, &yL, &scaleL );
439
440                                 /* add external position */
441                                 bbf_Scanner_addOutPos( cpA, scannerPtrL, xL, yL, scaleL, actL ); 
442                         }
443
444                         /* remove overlapping positions */
445                         bbf_Scanner_removeOutOverlaps( cpA, scannerPtrL, ptrA->overlapThrE ); 
446
447                 }
448
449                 if( !bbf_Scanner_nextScale( cpA, scannerPtrL ) ) break;
450         }
451 /*
452         {
453                 uint32 iL;
454                 printf( "\n-----------------------------------------------" );
455                 for( iL = 0; iL < scannerPtrL->outCountE; iL++ )
456                 {
457                         printf( "\n%02i: %6.1f %6.1f %6.2f %6.3f", 
458                                         iL,
459                                         ( float )scannerPtrL->outArrE.arrPtrE[ iL * 4 + 0 ] / ( 1L << 16 ),
460                                         ( float )scannerPtrL->outArrE.arrPtrE[ iL * 4 + 1 ] / ( 1L << 16 ),
461                                         ( float )scannerPtrL->outArrE.arrPtrE[ iL * 4 + 2 ] / ( 1L << 20 ),
462                                         ( float )scannerPtrL->outArrE.arrPtrE[ iL * 4 + 3 ] / ( 1L << 28 ) );
463
464                 }
465         }
466 */
467
468         *outArrPtrPtrA = scannerPtrL->outArrE.arrPtrE;
469         if( scannerPtrL->outCountE == 0 )
470         {
471                 /* no positive activities found: store best negative activity */
472                 bbf_Scanner_addOutPos( cpA, scannerPtrL, bestGlobalXL, bestGlobalYL, bestGlobalScaleL, bestGlobalActL );
473                 return 0;
474         }
475         else
476         {
477                 return scannerPtrL->outCountE;
478         }
479 }
480
481 /* ------------------------------------------------------------------------- */
482
483 /* ========================================================================= */
484