2 #include "_latentsvm.h"
3 #include "_lsvm_matching.h"
6 // Transformation filter displacement from the block space
7 // to the space of pixels at the initial image
10 // int convertPoints(int countLevel, CvPoint *points, int *levels,
11 CvPoint **partsDisplacement, int kPoints, int n);
13 // countLevel - the number of levels in the feature pyramid
14 // points - the set of root filter positions (in the block space)
15 // levels - the set of levels
16 // partsDisplacement - displacement of part filters (in the block space)
17 // kPoints - number of root filter positions
18 // n - number of part filters
19 // initialImageLevel - level that contains features for initial image
20 // maxXBorder - the largest root filter size (X-direction)
21 // maxYBorder - the largest root filter size (Y-direction)
23 // points - the set of root filter positions (in the space of pixels)
24 // partsDisplacement - displacement of part filters (in the space of pixels)
28 int convertPoints(int /*countLevel*/, int lambda,
29 int initialImageLevel,
30 CvPoint *points, int *levels,
31 CvPoint **partsDisplacement, int kPoints, int n,
37 step = powf( 2.0f, 1.0f / ((float)lambda) );
39 computeBorderSize(maxXBorder, maxYBorder, &bx, &by);
41 for (i = 0; i < kPoints; i++)
43 // scaling factor for root filter
44 scale = SIDE_LENGTH * powf(step, (float)(levels[i] - initialImageLevel));
45 points[i].x = (int)((points[i].x - bx + 1) * scale);
46 points[i].y = (int)((points[i].y - by + 1) * scale);
48 // scaling factor for part filters
49 scale = SIDE_LENGTH * powf(step, (float)(levels[i] - lambda - initialImageLevel));
50 for (j = 0; j < n; j++)
52 partsDisplacement[i][j].x = (int)((partsDisplacement[i][j].x -
54 partsDisplacement[i][j].y = (int)((partsDisplacement[i][j].y -
62 // Elimination boxes that are outside the image boudaries
65 // int clippingBoxes(int width, int height,
66 CvPoint *points, int kPoints);
68 // width - image wediht
69 // height - image heigth
70 // points - a set of points (coordinates of top left or
72 // kPoints - points number
74 // points - updated points (if coordinates less than zero then
75 set zero coordinate, if coordinates more than image
76 size then set coordinates equal image size)
80 int clippingBoxes(int width, int height,
81 CvPoint *points, int kPoints)
84 for (i = 0; i < kPoints; i++)
86 if (points[i].x > width - 1)
88 points[i].x = width - 1;
94 if (points[i].y > height - 1)
96 points[i].y = height - 1;
103 return LATENT_SVM_OK;
107 // Creation feature pyramid with nullable border
110 // featurePyramid* createFeaturePyramidWithBorder(const IplImage *image,
111 int maxXBorder, int maxYBorder);
114 // image - initial image
115 // maxXBorder - the largest root filter size (X-direction)
116 // maxYBorder - the largest root filter size (Y-direction)
119 // Feature pyramid with nullable border
121 CvLSVMFeaturePyramid* createFeaturePyramidWithBorder(IplImage *image,
122 int maxXBorder, int maxYBorder)
127 CvLSVMFeaturePyramid *H;
129 // Obtaining feature pyramid
130 opResult = getFeaturePyramid(image, &H);
132 if (opResult != LATENT_SVM_OK)
134 freeFeaturePyramidObject(&H);
136 } /* if (opResult != LATENT_SVM_OK) */
138 // Addition nullable border for each feature map
139 // the size of the border for root filters
140 computeBorderSize(maxXBorder, maxYBorder, &bx, &by);
141 for (level = 0; level < H->numLevels; level++)
143 addNullableBorder(H->pyramid[level], bx, by);
149 // Computation of the root filter displacement and values of score function
152 // int searchObject(const featurePyramid *H, const filterObject **all_F, int n,
156 CvPoint **points, int **levels, int *kPoints, float *score,
157 CvPoint ***partsDisplacement);
159 // image - initial image for searhing object
160 // all_F - the set of filters (the first element is root filter,
161 other elements - part filters)
162 // n - the number of part filters
163 // b - linear term of the score function
164 // maxXBorder - the largest root filter size (X-direction)
165 // maxYBorder - the largest root filter size (Y-direction)
167 // points - positions (x, y) of the upper-left corner
169 // levels - levels that correspond to each position
170 // kPoints - number of positions
171 // score - value of the score function
172 // partsDisplacement - part filters displacement for each position
177 int searchObject(const CvLSVMFeaturePyramid *H, const CvLSVMFilterObject **all_F,
181 CvPoint **points, int **levels, int *kPoints, float *score,
182 CvPoint ***partsDisplacement)
187 opResult = maxFunctionalScore(all_F, n, H, b, maxXBorder, maxYBorder,
188 score, points, levels,
189 kPoints, partsDisplacement);
190 if (opResult != LATENT_SVM_OK)
192 return LATENT_SVM_SEARCH_OBJECT_FAILED;
195 // Transformation filter displacement from the block space
196 // to the space of pixels at the initial image
197 // that settles at the level number LAMBDA
198 convertPoints(H->numLevels, LAMBDA, LAMBDA, (*points),
199 (*levels), (*partsDisplacement), (*kPoints), n,
200 maxXBorder, maxYBorder);
202 return LATENT_SVM_OK;
206 // Computation right bottom corners coordinates of bounding boxes
209 // int estimateBoxes(CvPoint *points, int *levels, int kPoints,
210 int sizeX, int sizeY, CvPoint **oppositePoints);
212 // points - left top corners coordinates of bounding boxes
213 // levels - levels of feature pyramid where points were found
214 // (sizeX, sizeY) - size of root filter
216 // oppositePoins - right bottom corners coordinates of bounding boxes
220 static int estimateBoxes(CvPoint *points, int *levels, int kPoints,
221 int sizeX, int sizeY, CvPoint **oppositePoints)
226 step = powf( 2.0f, 1.0f / ((float)(LAMBDA)));
228 *oppositePoints = (CvPoint *)malloc(sizeof(CvPoint) * kPoints);
229 for (i = 0; i < kPoints; i++)
231 getOppositePoint(points[i], sizeX, sizeY, step, levels[i] - LAMBDA, &((*oppositePoints)[i]));
233 return LATENT_SVM_OK;
237 // Computation of the root filter displacement and values of score function
240 // int searchObjectThreshold(const featurePyramid *H,
241 const filterObject **all_F, int n,
243 int maxXBorder, int maxYBorder,
244 float scoreThreshold,
245 CvPoint **points, int **levels, int *kPoints,
246 float **score, CvPoint ***partsDisplacement);
248 // H - feature pyramid
249 // all_F - the set of filters (the first element is root filter,
250 other elements - part filters)
251 // n - the number of part filters
252 // b - linear term of the score function
253 // maxXBorder - the largest root filter size (X-direction)
254 // maxYBorder - the largest root filter size (Y-direction)
255 // scoreThreshold - score threshold
257 // points - positions (x, y) of the upper-left corner
259 // levels - levels that correspond to each position
260 // kPoints - number of positions
261 // score - values of the score function
262 // partsDisplacement - part filters displacement for each position
267 int searchObjectThreshold(const CvLSVMFeaturePyramid *H,
268 const CvLSVMFilterObject **all_F, int n,
270 int maxXBorder, int maxYBorder,
271 float scoreThreshold,
272 CvPoint **points, int **levels, int *kPoints,
273 float **score, CvPoint ***partsDisplacement,
283 opResult = LATENT_SVM_TBB_NUMTHREADS_NOT_CORRECT;
286 opResult = tbbThresholdFunctionalScore(all_F, n, H, b, maxXBorder, maxYBorder,
287 scoreThreshold, numThreads, score,
288 points, levels, kPoints,
291 opResult = thresholdFunctionalScore(all_F, n, H, b,
292 maxXBorder, maxYBorder,
294 score, points, levels,
295 kPoints, partsDisplacement);
299 if (opResult != LATENT_SVM_OK)
301 return LATENT_SVM_SEARCH_OBJECT_FAILED;
304 // Transformation filter displacement from the block space
305 // to the space of pixels at the initial image
306 // that settles at the level number LAMBDA
307 convertPoints(H->numLevels, LAMBDA, LAMBDA, (*points),
308 (*levels), (*partsDisplacement), (*kPoints), n,
309 maxXBorder, maxYBorder);
311 return LATENT_SVM_OK;
315 // Compute opposite point for filter box
318 // int getOppositePoint(CvPoint point,
319 int sizeX, int sizeY,
320 float step, int degree,
321 CvPoint *oppositePoint);
324 // point - coordinates of filter top left corner
325 (in the space of pixels)
326 // (sizeX, sizeY) - filter dimension in the block space
327 // step - scaling factor
328 // degree - degree of the scaling factor
330 // oppositePoint - coordinates of filter bottom corner
331 (in the space of pixels)
335 int getOppositePoint(CvPoint point,
336 int sizeX, int sizeY,
337 float step, int degree,
338 CvPoint *oppositePoint)
341 scale = SIDE_LENGTH * powf(step, (float)degree);
342 oppositePoint->x = (int)(point.x + sizeX * scale);
343 oppositePoint->y = (int)(point.y + sizeY * scale);
344 return LATENT_SVM_OK;
349 // Drawing root filter boxes
352 // int showRootFilterBoxes(const IplImage *image,
353 const filterObject *filter,
354 CvPoint *points, int *levels, int kPoints,
355 CvScalar color, int thickness,
356 int line_type, int shift);
358 // image - initial image
359 // filter - root filter object
360 // points - a set of points
361 // levels - levels of feature pyramid
362 // kPoints - number of points
363 // color - line color for each box
364 // thickness - line thickness
365 // line_type - line type
368 // window contained initial image and filter boxes
372 int showRootFilterBoxes(IplImage *image,
373 const CvLSVMFilterObject *filter,
374 CvPoint *points, int *levels, int kPoints,
375 CvScalar color, int thickness,
376 int line_type, int shift)
380 CvPoint oppositePoint;
381 step = powf( 2.0f, 1.0f / ((float)LAMBDA));
383 for (i = 0; i < kPoints; i++)
385 // Drawing rectangle for filter
386 getOppositePoint(points[i], filter->sizeX, filter->sizeY,
387 step, levels[i] - LAMBDA, &oppositePoint);
388 cvRectangle(image, points[i], oppositePoint,
389 color, thickness, line_type, shift);
391 #ifdef HAVE_OPENCV_HIGHGUI
392 cvShowImage("Initial image", image);
394 return LATENT_SVM_OK;
398 // Drawing part filter boxes
401 // int showPartFilterBoxes(const IplImage *image,
402 const filterObject *filter,
403 CvPoint *points, int *levels, int kPoints,
404 CvScalar color, int thickness,
405 int line_type, int shift);
407 // image - initial image
408 // filters - a set of part filters
409 // n - number of part filters
410 // partsDisplacement - a set of points
411 // levels - levels of feature pyramid
412 // kPoints - number of foot filter positions
413 // color - line color for each box
414 // thickness - line thickness
415 // line_type - line type
418 // window contained initial image and filter boxes
422 int showPartFilterBoxes(IplImage *image,
423 const CvLSVMFilterObject **filters,
424 int n, CvPoint **partsDisplacement,
425 int *levels, int kPoints,
426 CvScalar color, int thickness,
427 int line_type, int shift)
431 CvPoint oppositePoint;
433 step = powf( 2.0f, 1.0f / ((float)LAMBDA));
435 for (i = 0; i < kPoints; i++)
437 for (j = 0; j < n; j++)
439 // Drawing rectangles for part filters
440 getOppositePoint(partsDisplacement[i][j],
441 filters[j + 1]->sizeX, filters[j + 1]->sizeY,
442 step, levels[i] - 2 * LAMBDA, &oppositePoint);
443 cvRectangle(image, partsDisplacement[i][j], oppositePoint,
444 color, thickness, line_type, shift);
447 #ifdef HAVE_OPENCV_HIGHGUI
448 cvShowImage("Initial image", image);
450 return LATENT_SVM_OK;
457 // int showBoxes(const IplImage *img,
458 const CvPoint *points, const CvPoint *oppositePoints, int kPoints,
459 CvScalar color, int thickness, int line_type, int shift);
461 // img - initial image
462 // points - top left corner coordinates
463 // oppositePoints - right bottom corner coordinates
464 // kPoints - points number
465 // color - line color for each box
466 // thickness - line thickness
467 // line_type - line type
473 int showBoxes(IplImage *img,
474 const CvPoint *points, const CvPoint *oppositePoints, int kPoints,
475 CvScalar color, int thickness, int line_type, int shift)
478 for (i = 0; i < kPoints; i++)
480 cvRectangle(img, points[i], oppositePoints[i],
481 color, thickness, line_type, shift);
483 #ifdef HAVE_OPENCV_HIGHGUI
484 cvShowImage("Initial image", img);
486 return LATENT_SVM_OK;
490 // Computation maximum filter size for each dimension
493 // int getMaxFilterDims(const filterObject **filters, int kComponents,
494 const int *kPartFilters,
495 unsigned int *maxXBorder, unsigned int *maxYBorder);
497 // filters - a set of filters (at first root filter, then part filters
498 and etc. for all components)
499 // kComponents - number of components
500 // kPartFilters - number of part filters for each component
502 // maxXBorder - maximum of filter size at the horizontal dimension
503 // maxYBorder - maximum of filter size at the vertical dimension
507 int getMaxFilterDims(const CvLSVMFilterObject **filters, int kComponents,
508 const int *kPartFilters,
509 unsigned int *maxXBorder, unsigned int *maxYBorder)
511 int i, componentIndex;
512 *maxXBorder = filters[0]->sizeX;
513 *maxYBorder = filters[0]->sizeY;
514 componentIndex = kPartFilters[0] + 1;
515 for (i = 1; i < kComponents; i++)
517 if ((unsigned)filters[componentIndex]->sizeX > *maxXBorder)
519 *maxXBorder = filters[componentIndex]->sizeX;
521 if ((unsigned)filters[componentIndex]->sizeY > *maxYBorder)
523 *maxYBorder = filters[componentIndex]->sizeY;
525 componentIndex += (kPartFilters[i] + 1);
527 return LATENT_SVM_OK;
531 // Computation root filters displacement and values of score function
534 // int searchObjectThresholdSomeComponents(const featurePyramid *H,
535 const filterObject **filters,
536 int kComponents, const int *kPartFilters,
537 const float *b, float scoreThreshold,
538 CvPoint **points, CvPoint **oppPoints,
539 float **score, int *kPoints);
541 // H - feature pyramid
542 // filters - filters (root filter then it's part filters, etc.)
543 // kComponents - root filters number
544 // kPartFilters - array of part filters number for each component
545 // b - array of linear terms
546 // scoreThreshold - score threshold
548 // points - root filters displacement (top left corners)
549 // oppPoints - root filters displacement (bottom right corners)
550 // score - array of score values
551 // kPoints - number of boxes
555 int searchObjectThresholdSomeComponents(const CvLSVMFeaturePyramid *H,
556 const CvLSVMFilterObject **filters,
557 int kComponents, const int *kPartFilters,
558 const float *b, float scoreThreshold,
559 CvPoint **points, CvPoint **oppPoints,
560 float **score, int *kPoints,
564 int i, j, s, f, componentIndex;
565 unsigned int maxXBorder, maxYBorder;
566 CvPoint **pointsArr, **oppPointsArr, ***partsDisplacementArr;
568 int *kPointsArr, **levelsArr;
571 pointsArr = (CvPoint **)malloc(sizeof(CvPoint *) * kComponents);
572 oppPointsArr = (CvPoint **)malloc(sizeof(CvPoint *) * kComponents);
573 scoreArr = (float **)malloc(sizeof(float *) * kComponents);
574 kPointsArr = (int *)malloc(sizeof(int) * kComponents);
575 levelsArr = (int **)malloc(sizeof(int *) * kComponents);
576 partsDisplacementArr = (CvPoint ***)malloc(sizeof(CvPoint **) * kComponents);
578 // Getting maximum filter dimensions
579 /*error = */getMaxFilterDims(filters, kComponents, kPartFilters, &maxXBorder, &maxYBorder);
582 // For each component perform searching
583 for (i = 0; i < kComponents; i++)
585 int error = searchObjectThreshold(H, &(filters[componentIndex]), kPartFilters[i],
586 b[i], maxXBorder, maxYBorder, scoreThreshold,
587 &(pointsArr[i]), &(levelsArr[i]), &(kPointsArr[i]),
588 &(scoreArr[i]), &(partsDisplacementArr[i]), numThreads);
589 if (error != LATENT_SVM_OK)
591 // Release allocated memory
597 free(partsDisplacementArr);
598 return LATENT_SVM_SEARCH_OBJECT_FAILED;
600 estimateBoxes(pointsArr[i], levelsArr[i], kPointsArr[i],
601 filters[componentIndex]->sizeX, filters[componentIndex]->sizeY, &(oppPointsArr[i]));
602 componentIndex += (kPartFilters[i] + 1);
603 *kPoints += kPointsArr[i];
606 *points = (CvPoint *)malloc(sizeof(CvPoint) * (*kPoints));
607 *oppPoints = (CvPoint *)malloc(sizeof(CvPoint) * (*kPoints));
608 *score = (float *)malloc(sizeof(float) * (*kPoints));
610 for (i = 0; i < kComponents; i++)
612 f = s + kPointsArr[i];
613 for (j = s; j < f; j++)
615 (*points)[j].x = pointsArr[i][j - s].x;
616 (*points)[j].y = pointsArr[i][j - s].y;
617 (*oppPoints)[j].x = oppPointsArr[i][j - s].x;
618 (*oppPoints)[j].y = oppPointsArr[i][j - s].y;
619 (*score)[j] = scoreArr[i][j - s];
624 // Release allocated memory
625 for (i = 0; i < kComponents; i++)
628 free(oppPointsArr[i]);
631 for (j = 0; j < kPointsArr[i]; j++)
633 free(partsDisplacementArr[i][j]);
635 free(partsDisplacementArr[i]);
642 free(partsDisplacementArr);
643 return LATENT_SVM_OK;