Home | History | Annotate | Download | only in b_BitFeatureEm
      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