/* // Computation root filters displacement and values of score function // // API // int searchObjectThresholdSomeComponents(const featurePyramid *H, const filterObject **filters, int kComponents, const int *kPartFilters, const float *b, float scoreThreshold, CvPoint **points, CvPoint **oppPoints, float **score, int *kPoints); // INPUT // H - feature pyramid // filters - filters (root filter then it's part filters, etc.) // kComponents - root filters number // kPartFilters - array of part filters number for each component // b - array of linear terms // scoreThreshold - score threshold // OUTPUT // points - root filters displacement (top left corners) // oppPoints - root filters displacement (bottom right corners) // score - array of score values // kPoints - number of boxes // RESULT // Error status */ int searchObjectThresholdSomeComponents(const CvLSVMFeaturePyramid *H, const CvLSVMFilterObject **filters, int kComponents, const int *kPartFilters, const float *b, float scoreThreshold, CvPoint **points, CvPoint **oppPoints, float **score, int *kPoints) { int error = 0; int i, j, s, f, componentIndex; unsigned int maxXBorder, maxYBorder; CvPoint **pointsArr, **oppPointsArr, ***partsDisplacementArr; float **scoreArr; int *kPointsArr, **levelsArr; // Allocation memory pointsArr = (CvPoint **)malloc(sizeof(CvPoint *) * kComponents); oppPointsArr = (CvPoint **)malloc(sizeof(CvPoint *) * kComponents); scoreArr = (float **)malloc(sizeof(float *) * kComponents); kPointsArr = (int *)malloc(sizeof(int) * kComponents); levelsArr = (int **)malloc(sizeof(int *) * kComponents); partsDisplacementArr = (CvPoint ***)malloc(sizeof(CvPoint **) * kComponents); // Getting maximum filter dimensions error = getMaxFilterDims(filters, kComponents, kPartFilters, &maxXBorder, &maxYBorder); componentIndex = 0; *kPoints = 0; // For each component perform searching for (i = 0; i < kComponents; i++) { searchObjectThreshold(H, &(filters[componentIndex]), kPartFilters[i], b[i], maxXBorder, maxYBorder, scoreThreshold, &(pointsArr[i]), &(levelsArr[i]), &(kPointsArr[i]), &(scoreArr[i]), &(partsDisplacementArr[i])); estimateBoxes(pointsArr[i], levelsArr[i], kPointsArr[i], filters[componentIndex]->sizeX, filters[componentIndex]->sizeY, &(oppPointsArr[i])); componentIndex += (kPartFilters[i] + 1); *kPoints += kPointsArr[i]; } *points = (CvPoint *)malloc(sizeof(CvPoint) * (*kPoints)); *oppPoints = (CvPoint *)malloc(sizeof(CvPoint) * (*kPoints)); *score = (float *)malloc(sizeof(float) * (*kPoints)); s = 0; for (i = 0; i < kComponents; i++) { f = s + kPointsArr[i]; for (j = s; j < f; j++) { (*points)[j].x = pointsArr[i][j - s].x; (*points)[j].y = pointsArr[i][j - s].y; (*oppPoints)[j].x = oppPointsArr[i][j - s].x; (*oppPoints)[j].y = oppPointsArr[i][j - s].y; (*score)[j] = scoreArr[i][j - s]; } s = f; } // Release allocated memory for (i = 0; i < kComponents; i++) { free(pointsArr[i]); free(oppPointsArr[i]); free(scoreArr[i]); free(levelsArr[i]); for (j = 0; j < kPointsArr[i]; j++) { free(partsDisplacementArr[i][j]); } free(partsDisplacementArr[i]); } free(pointsArr); free(oppPointsArr); free(scoreArr); free(kPointsArr); free(levelsArr); free(partsDisplacementArr); return LATENT_SVM_OK; }
/* // find rectangular regions in the given image that are likely // to contain objects and corresponding confidence levels // // API // CvSeq* cvLatentSvmDetectObjects(const IplImage* image, // CvLatentSvmDetector* detector, // CvMemStorage* storage, // float overlap_threshold = 0.5f, int numThreads = -1); // INPUT // image - image to detect objects in // detector - Latent SVM detector in internal representation // storage - memory storage to store the resultant sequence // of the object candidate rectangles // overlap_threshold - threshold for the non-maximum suppression algorithm [here will be the reference to original paper] // OUTPUT // sequence of detected objects (bounding boxes and confidence levels stored in CvObjectDetection structures) */ CvSeq* cvLatentSvmDetectObjects(IplImage* image, CvLatentSvmDetector* detector, CvMemStorage* storage, float overlap_threshold, int numThreads) { CvLSVMFeaturePyramid *H = 0; CvPoint *points = 0, *oppPoints = 0; int kPoints = 0; float *score = 0; unsigned int maxXBorder = 0, maxYBorder = 0; int numBoxesOut = 0; CvPoint *pointsOut = 0; CvPoint *oppPointsOut = 0; float *scoreOut = 0; CvSeq* result_seq = 0; int error = 0; if(image->nChannels == 3) cvCvtColor(image, image, CV_BGR2RGB); // Getting maximum filter dimensions getMaxFilterDims((const CvLSVMFilterObject**)(detector->filters), detector->num_components, detector->num_part_filters, &maxXBorder, &maxYBorder); // Create feature pyramid with nullable border H = createFeaturePyramidWithBorder(image, maxXBorder, maxYBorder); // Search object error = searchObjectThresholdSomeComponents(H, (const CvLSVMFilterObject**)(detector->filters), detector->num_components, detector->num_part_filters, detector->b, detector->score_threshold, &points, &oppPoints, &score, &kPoints, numThreads); if (error != LATENT_SVM_OK) { return NULL; } // Clipping boxes clippingBoxes(image->width, image->height, points, kPoints); clippingBoxes(image->width, image->height, oppPoints, kPoints); // NMS procedure nonMaximumSuppression(kPoints, points, oppPoints, score, overlap_threshold, &numBoxesOut, &pointsOut, &oppPointsOut, &scoreOut); result_seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvObjectDetection), storage ); for (int i = 0; i < numBoxesOut; i++) { CvObjectDetection detection = {{0, 0, 0, 0}, 0}; detection.score = scoreOut[i]; CvRect bounding_box = {0, 0, 0, 0}; bounding_box.x = pointsOut[i].x; bounding_box.y = pointsOut[i].y; bounding_box.width = oppPointsOut[i].x - pointsOut[i].x; bounding_box.height = oppPointsOut[i].y - pointsOut[i].y; detection.rect = bounding_box; cvSeqPush(result_seq, &detection); } if(image->nChannels == 3) cvCvtColor(image, image, CV_RGB2BGR); freeFeaturePyramidObject(&H); free(points); free(oppPoints); free(score); return result_seq; }