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 
bbf_ScanDetector_init(struct bbs_Context * cpA,struct bbf_ScanDetector * ptrA)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 
bbf_ScanDetector_exit(struct bbs_Context * cpA,struct bbf_ScanDetector * ptrA)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 
bbf_ScanDetector_copy(struct bbs_Context * cpA,struct bbf_ScanDetector * ptrA,const struct bbf_ScanDetector * srcPtrA)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 
bbf_ScanDetector_equal(struct bbs_Context * cpA,const struct bbf_ScanDetector * ptrA,const struct bbf_ScanDetector * srcPtrA)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 
bbf_ScanDetector_memSize(struct bbs_Context * cpA,const struct bbf_ScanDetector * ptrA)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 
bbf_ScanDetector_memWrite(struct bbs_Context * cpA,const struct bbf_ScanDetector * ptrA,uint16 * memPtrA)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 
bbf_ScanDetector_memRead(struct bbs_Context * cpA,struct bbf_ScanDetector * ptrA,const uint16 * memPtrA,struct bbs_MemTbl * mtpA)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 
bbf_ScanDetector_process(struct bbs_Context * cpA,struct bbf_ScanDetector * ptrA,const void * imagePtrA,uint32 imageWidthA,uint32 imageHeightA,const struct bts_Int16Rect * roiPtrA,int32 ** outArrPtrPtrA)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