2 #include "opencv2/imgproc/imgproc_c.h"
3 #include "opencv2/objdetect/objdetect_c.h"
4 #include "_lsvmparser.h"
5 #include "_lsvm_matching.h"
8 // load trained detector from a file
11 // CvLatentSvmDetector* cvLoadLatentSvmDetector(const char* filename);
13 // filename - path to the file containing the parameters of
14 // - trained Latent SVM detector
16 // trained Latent SVM detector in internal representation
18 CvLatentSvmDetector* cvLoadLatentSvmDetector(const char* filename)
20 CvLatentSvmDetector* detector = 0;
21 CvLSVMFilterObject** filters = 0;
24 int* kPartFilters = 0;
26 float scoreThreshold = 0.f;
29 err_code = loadModel(filename, &filters, &kFilters, &kComponents, &kPartFilters, &b, &scoreThreshold);
30 if (err_code != LATENT_SVM_OK) return 0;
32 detector = (CvLatentSvmDetector*)malloc(sizeof(CvLatentSvmDetector));
33 detector->filters = filters;
35 detector->num_components = kComponents;
36 detector->num_filters = kFilters;
37 detector->num_part_filters = kPartFilters;
38 detector->score_threshold = scoreThreshold;
44 // release memory allocated for CvLatentSvmDetector structure
47 // void cvReleaseLatentSvmDetector(CvLatentSvmDetector** detector);
49 // detector - CvLatentSvmDetector structure to be released
52 void cvReleaseLatentSvmDetector(CvLatentSvmDetector** detector)
55 free((*detector)->num_part_filters);
56 for (int i = 0; i < (*detector)->num_filters; i++)
58 free((*detector)->filters[i]->H);
59 free((*detector)->filters[i]);
61 free((*detector)->filters);
67 // find rectangular regions in the given image that are likely
68 // to contain objects and corresponding confidence levels
71 // CvSeq* cvLatentSvmDetectObjects(const IplImage* image,
72 // CvLatentSvmDetector* detector,
73 // CvMemStorage* storage,
74 // float overlap_threshold = 0.5f,
77 // image - image to detect objects in
78 // detector - Latent SVM detector in internal representation
79 // storage - memory storage to store the resultant sequence
80 // of the object candidate rectangles
81 // overlap_threshold - threshold for the non-maximum suppression algorithm [here will be the reference to original paper]
83 // sequence of detected objects (bounding boxes and confidence levels stored in CvObjectDetection structures)
85 CvSeq* cvLatentSvmDetectObjects(IplImage* image,
86 CvLatentSvmDetector* detector,
87 CvMemStorage* storage,
88 float overlap_threshold, int numThreads)
90 CvLSVMFeaturePyramid *H = 0;
91 CvPoint *points = 0, *oppPoints = 0;
94 unsigned int maxXBorder = 0, maxYBorder = 0;
96 CvPoint *pointsOut = 0;
97 CvPoint *oppPointsOut = 0;
99 CvSeq* result_seq = 0;
102 if(image->nChannels == 3)
103 cvCvtColor(image, image, CV_BGR2RGB);
105 // Getting maximum filter dimensions
106 getMaxFilterDims((const CvLSVMFilterObject**)(detector->filters), detector->num_components,
107 detector->num_part_filters, &maxXBorder, &maxYBorder);
108 // Create feature pyramid with nullable border
109 H = createFeaturePyramidWithBorder(image, maxXBorder, maxYBorder);
111 error = searchObjectThresholdSomeComponents(H, (const CvLSVMFilterObject**)(detector->filters),
112 detector->num_components, detector->num_part_filters, detector->b, detector->score_threshold,
113 &points, &oppPoints, &score, &kPoints, numThreads);
114 if (error != LATENT_SVM_OK)
119 clippingBoxes(image->width, image->height, points, kPoints);
120 clippingBoxes(image->width, image->height, oppPoints, kPoints);
122 nonMaximumSuppression(kPoints, points, oppPoints, score, overlap_threshold,
123 &numBoxesOut, &pointsOut, &oppPointsOut, &scoreOut);
125 result_seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvObjectDetection), storage );
127 for (int i = 0; i < numBoxesOut; i++)
129 CvObjectDetection detection = {CvRect(), 0};
130 detection.score = scoreOut[i];
132 bounding_box.x = pointsOut[i].x;
133 bounding_box.y = pointsOut[i].y;
134 bounding_box.width = oppPointsOut[i].x - pointsOut[i].x;
135 bounding_box.height = oppPointsOut[i].y - pointsOut[i].y;
136 detection.rect = bounding_box;
137 cvSeqPush(result_seq, &detection);
140 if(image->nChannels == 3)
141 cvCvtColor(image, image, CV_RGB2BGR);
143 freeFeaturePyramidObject(&H);
154 LatentSvmDetector::ObjectDetection::ObjectDetection() : score(0.f), classID(-1)
157 LatentSvmDetector::ObjectDetection::ObjectDetection( const Rect& _rect, float _score, int _classID ) :
158 rect(_rect), score(_score), classID(_classID)
161 LatentSvmDetector::LatentSvmDetector()
164 LatentSvmDetector::LatentSvmDetector( const std::vector<String>& filenames, const std::vector<String>& _classNames )
166 load( filenames, _classNames );
169 LatentSvmDetector::~LatentSvmDetector()
174 void LatentSvmDetector::clear()
176 for( size_t i = 0; i < detectors.size(); i++ )
177 cvReleaseLatentSvmDetector( &detectors[i] );
183 bool LatentSvmDetector::empty() const
185 return detectors.empty();
188 const std::vector<String>& LatentSvmDetector::getClassNames() const
193 size_t LatentSvmDetector::getClassCount() const
195 return classNames.size();
198 static String extractModelName( const String& filename )
200 size_t startPos = filename.rfind('/');
201 if( startPos == String::npos )
202 startPos = filename.rfind('\\');
204 if( startPos == String::npos )
209 const int extentionSize = 4; //.xml
211 int substrLength = (int)(filename.size() - startPos - extentionSize);
213 return filename.substr(startPos, substrLength);
216 bool LatentSvmDetector::load( const std::vector<String>& filenames, const std::vector<String>& _classNames )
220 CV_Assert( _classNames.empty() || _classNames.size() == filenames.size() );
222 for( size_t i = 0; i < filenames.size(); i++ )
224 const String filename = filenames[i];
225 if( filename.length() < 5 || filename.substr(filename.length()-4, 4) != ".xml" )
228 CvLatentSvmDetector* detector = cvLoadLatentSvmDetector( filename.c_str() );
231 detectors.push_back( detector );
232 if( _classNames.empty() )
234 classNames.push_back( extractModelName(filenames[i]) );
237 classNames.push_back( _classNames[i] );
244 void LatentSvmDetector::detect( const Mat& image,
245 std::vector<ObjectDetection>& objectDetections,
246 float overlapThreshold,
249 objectDetections.clear();
250 if( numThreads <= 0 )
253 for( size_t classID = 0; classID < detectors.size(); classID++ )
255 IplImage image_ipl = image;
256 CvMemStorage* storage = cvCreateMemStorage(0);
257 CvSeq* detections = cvLatentSvmDetectObjects( &image_ipl, detectors[classID], storage, overlapThreshold, numThreads );
260 objectDetections.reserve( objectDetections.size() + detections->total );
261 for( int detectionIdx = 0; detectionIdx < detections->total; detectionIdx++ )
263 CvObjectDetection detection = *(CvObjectDetection*)cvGetSeqElem( detections, detectionIdx );
264 objectDetections.push_back( ObjectDetection(Rect(detection.rect), detection.score, (int)classID) );
267 cvReleaseMemStorage( &storage );