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 485