2 #include "_lsvmparser.h"
3 #include "_lsvm_matching.h"
6 // load trained detector from a file
9 // CvLatentSvmDetector* cvLoadLatentSvmDetector(const char* filename);
11 // filename - path to the file containing the parameters of
12 // - trained Latent SVM detector
14 // trained Latent SVM detector in internal representation
16 CvLatentSvmDetector* cvLoadLatentSvmDetector(const char* filename)
18 CvLatentSvmDetector* detector = 0;
19 CvLSVMFilterObject** filters = 0;
22 int* kPartFilters = 0;
24 float scoreThreshold = 0.f;
27 err_code = loadModel(filename, &filters, &kFilters, &kComponents, &kPartFilters, &b, &scoreThreshold);
28 if (err_code != LATENT_SVM_OK) return 0;
30 detector = (CvLatentSvmDetector*)malloc(sizeof(CvLatentSvmDetector));
31 detector->filters = filters;
33 detector->num_components = kComponents;
34 detector->num_filters = kFilters;
35 detector->num_part_filters = kPartFilters;
36 detector->score_threshold = scoreThreshold;
42 // release memory allocated for CvLatentSvmDetector structure
45 // void cvReleaseLatentSvmDetector(CvLatentSvmDetector** detector);
47 // detector - CvLatentSvmDetector structure to be released
50 void cvReleaseLatentSvmDetector(CvLatentSvmDetector** detector)
53 free((*detector)->num_part_filters);
54 for (int i = 0; i < (*detector)->num_filters; i++)
56 free((*detector)->filters[i]->H);
57 free((*detector)->filters[i]);
59 free((*detector)->filters);
65 // find rectangular regions in the given image that are likely
66 // to contain objects and corresponding confidence levels
69 // CvSeq* cvLatentSvmDetectObjects(const IplImage* image,
70 // CvLatentSvmDetector* detector,
71 // CvMemStorage* storage,
72 // float overlap_threshold = 0.5f,
75 // image - image to detect objects in
76 // detector - Latent SVM detector in internal representation
77 // storage - memory storage to store the resultant sequence
78 // of the object candidate rectangles
79 // overlap_threshold - threshold for the non-maximum suppression algorithm [here will be the reference to original paper]
81 // sequence of detected objects (bounding boxes and confidence levels stored in CvObjectDetection structures)
83 CvSeq* cvLatentSvmDetectObjects(IplImage* image,
84 CvLatentSvmDetector* detector,
85 CvMemStorage* storage,
86 float overlap_threshold, int numThreads)
88 CvLSVMFeaturePyramid *H = 0;
89 CvPoint *points = 0, *oppPoints = 0;
92 unsigned int maxXBorder = 0, maxYBorder = 0;
94 CvPoint *pointsOut = 0;
95 CvPoint *oppPointsOut = 0;
97 CvSeq* result_seq = 0;
100 if(image->nChannels == 3)
101 cvCvtColor(image, image, CV_BGR2RGB);
103 // Getting maximum filter dimensions
104 getMaxFilterDims((const CvLSVMFilterObject**)(detector->filters), detector->num_components,
105 detector->num_part_filters, &maxXBorder, &maxYBorder);
106 // Create feature pyramid with nullable border
107 H = createFeaturePyramidWithBorder(image, maxXBorder, maxYBorder);
109 error = searchObjectThresholdSomeComponents(H, (const CvLSVMFilterObject**)(detector->filters),
110 detector->num_components, detector->num_part_filters, detector->b, detector->score_threshold,
111 &points, &oppPoints, &score, &kPoints, numThreads);
112 if (error != LATENT_SVM_OK)
117 clippingBoxes(image->width, image->height, points, kPoints);
118 clippingBoxes(image->width, image->height, oppPoints, kPoints);
120 nonMaximumSuppression(kPoints, points, oppPoints, score, overlap_threshold,
121 &numBoxesOut, &pointsOut, &oppPointsOut, &scoreOut);
123 result_seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvObjectDetection), storage );
125 for (int i = 0; i < numBoxesOut; i++)
127 CvObjectDetection detection = {{0, 0, 0, 0}, 0};
128 detection.score = scoreOut[i];
129 CvRect bounding_box = {0, 0, 0, 0};
130 bounding_box.x = pointsOut[i].x;
131 bounding_box.y = pointsOut[i].y;
132 bounding_box.width = oppPointsOut[i].x - pointsOut[i].x;
133 bounding_box.height = oppPointsOut[i].y - pointsOut[i].y;
134 detection.rect = bounding_box;
135 cvSeqPush(result_seq, &detection);
138 if(image->nChannels == 3)
139 cvCvtColor(image, image, CV_RGB2BGR);
141 freeFeaturePyramidObject(&H);
152 LatentSvmDetector::ObjectDetection::ObjectDetection() : score(0.f), classID(-1)
155 LatentSvmDetector::ObjectDetection::ObjectDetection( const Rect& _rect, float _score, int _classID ) :
156 rect(_rect), score(_score), classID(_classID)
159 LatentSvmDetector::LatentSvmDetector()
162 LatentSvmDetector::LatentSvmDetector( const vector<string>& filenames, const vector<string>& _classNames )
164 load( filenames, _classNames );
167 LatentSvmDetector::~LatentSvmDetector()
172 void LatentSvmDetector::clear()
174 for( size_t i = 0; i < detectors.size(); i++ )
175 cvReleaseLatentSvmDetector( &detectors[i] );
181 bool LatentSvmDetector::empty() const
183 return detectors.empty();
186 const vector<string>& LatentSvmDetector::getClassNames() const
191 size_t LatentSvmDetector::getClassCount() const
193 return classNames.size();
196 static string extractModelName( const string& filename )
198 size_t startPos = filename.rfind('/');
199 if( startPos == string::npos )
200 startPos = filename.rfind('\\');
202 if( startPos == string::npos )
207 const int extentionSize = 4; //.xml
209 int substrLength = (int)(filename.size() - startPos - extentionSize);
211 return filename.substr(startPos, substrLength);
214 bool LatentSvmDetector::load( const vector<string>& filenames, const vector<string>& _classNames )
218 CV_Assert( _classNames.empty() || _classNames.size() == filenames.size() );
220 for( size_t i = 0; i < filenames.size(); i++ )
222 const string filename = filenames[i];
223 if( filename.length() < 5 || filename.substr(filename.length()-4, 4) != ".xml" )
226 CvLatentSvmDetector* detector = cvLoadLatentSvmDetector( filename.c_str() );
229 detectors.push_back( detector );
230 if( _classNames.empty() )
232 classNames.push_back( extractModelName(filenames[i]) );
235 classNames.push_back( _classNames[i] );
242 void LatentSvmDetector::detect( const Mat& image,
243 vector<ObjectDetection>& objectDetections,
244 float overlapThreshold,
247 objectDetections.clear();
248 if( numThreads <= 0 )
251 for( size_t classID = 0; classID < detectors.size(); classID++ )
253 IplImage image_ipl = image;
254 CvMemStorage* storage = cvCreateMemStorage(0);
255 CvSeq* detections = cvLatentSvmDetectObjects( &image_ipl, detectors[classID], storage, overlapThreshold, numThreads );
258 objectDetections.reserve( objectDetections.size() + detections->total );
259 for( int detectionIdx = 0; detectionIdx < detections->total; detectionIdx++ )
261 CvObjectDetection detection = *(CvObjectDetection*)cvGetSeqElem( detections, detectionIdx );
262 objectDetections.push_back( ObjectDetection(Rect(detection.rect), detection.score, (int)classID) );
265 cvReleaseMemStorage( &storage );