From ab6be9b7b7691967e42297aa6d3a67fb07597fd8 Mon Sep 17 00:00:00 2001 From: Peter Minin Date: Thu, 6 Jun 2013 19:00:55 +0400 Subject: [PATCH] Add a variant of detectMultiScale with an argument 'weights' that receives the number of neighbors joined into each detected object --- .../objdetect/doc/cascade_classification.rst | 3 +++ .../include/opencv2/objdetect/objdetect.hpp | 11 ++++++++- modules/objdetect/src/cascadedetect.cpp | 24 ++++++++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/modules/objdetect/doc/cascade_classification.rst b/modules/objdetect/doc/cascade_classification.rst index eb07a6c8f7..a00bdc933a 100644 --- a/modules/objdetect/doc/cascade_classification.rst +++ b/modules/objdetect/doc/cascade_classification.rst @@ -189,6 +189,7 @@ CascadeClassifier::detectMultiScale Detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles. .. ocv:function:: void CascadeClassifier::detectMultiScale( const Mat& image, vector& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size()) +.. ocv:function:: void CascadeClassifier::detectMultiScale( const Mat& image, vector& objects, vector& weights, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size()) .. ocv:pyfunction:: cv2.CascadeClassifier.detectMultiScale(image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]]) -> objects .. ocv:pyfunction:: cv2.CascadeClassifier.detectMultiScale(image, rejectLevels, levelWeights[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize[, outputRejectLevels]]]]]]) -> objects @@ -203,6 +204,8 @@ Detects objects of different sizes in the input image. The detected objects are :param objects: Vector of rectangles where each rectangle contains the detected object. + :param weights: Vector of weights of the corresponding objects. Weight is the number of neighboring positively classified rectangles that were joined into one object. + :param scaleFactor: Parameter specifying how much the image size is reduced at each image scale. :param minNeighbors: Parameter specifying how many neighbors each candidate rectangle should have to retain it. diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 8d7efb0ba4..7924b67e5d 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -382,6 +382,14 @@ public: Size minSize=Size(), Size maxSize=Size() ); + CV_WRAP virtual void detectMultiScale( const Mat& image, + CV_OUT vector& objects, + vector& weights, + double scaleFactor=1.1, + int minNeighbors=3, int flags=0, + Size minSize=Size(), + Size maxSize=Size() ); + CV_WRAP virtual void detectMultiScale( const Mat& image, CV_OUT vector& objects, vector& rejectLevels, @@ -390,7 +398,8 @@ public: int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size(), - bool outputRejectLevels=false ); + bool outputRejectLevels=false, + bool outputWeights=false ); bool isOldFormatCascade() const; diff --git a/modules/objdetect/src/cascadedetect.cpp b/modules/objdetect/src/cascadedetect.cpp index 9e78dce243..341ef2a0d6 100644 --- a/modules/objdetect/src/cascadedetect.cpp +++ b/modules/objdetect/src/cascadedetect.cpp @@ -1023,6 +1023,7 @@ public: }; struct getRect { Rect operator ()(const CvAvgComp& e) const { return e.rect; } }; +struct getNeighbors { int operator ()(const CvAvgComp& e) const { return e.neighbors; } }; bool CascadeClassifier::detectSingleScale( const Mat& image, int stripCount, Size processingRectSize, @@ -1092,11 +1093,12 @@ void CascadeClassifier::detectMultiScale( const Mat& image, vector& object vector& levelWeights, double scaleFactor, int minNeighbors, int flags, Size minObjectSize, Size maxObjectSize, - bool outputRejectLevels ) + bool outputRejectLevels, bool outputWeights ) { const double GROUP_EPS = 0.2; CV_Assert( scaleFactor > 1 && image.depth() == CV_8U ); + CV_Assert( !( outputRejectLevels && outputWeights ) ); if( empty() ) return; @@ -1111,6 +1113,12 @@ void CascadeClassifier::detectMultiScale( const Mat& image, vector& object Seq(_objects).copyTo(vecAvgComp); objects.resize(vecAvgComp.size()); std::transform(vecAvgComp.begin(), vecAvgComp.end(), objects.begin(), getRect()); + if( outputWeights ) + { + rejectLevels.resize(vecAvgComp.size()); + std::transform(vecAvgComp.begin(), vecAvgComp.end(), rejectLevels.begin(), + getNeighbors()); + } return; } @@ -1183,6 +1191,10 @@ void CascadeClassifier::detectMultiScale( const Mat& image, vector& object { groupRectangles( objects, rejectLevels, levelWeights, minNeighbors, GROUP_EPS ); } + else if( outputWeights ) + { + groupRectangles( objects, rejectLevels, minNeighbors, GROUP_EPS ); + } else { groupRectangles( objects, minNeighbors, GROUP_EPS ); @@ -1199,6 +1211,16 @@ void CascadeClassifier::detectMultiScale( const Mat& image, vector& object minNeighbors, flags, minObjectSize, maxObjectSize, false ); } +void CascadeClassifier::detectMultiScale( const Mat& image, CV_OUT vector& objects, + vector& weights, double scaleFactor, + int minNeighbors, int flags, Size minObjectSize, + Size maxObjectSize ) +{ + vector fakeLevelWeights; + detectMultiScale( image, objects, weights, fakeLevelWeights, scaleFactor, + minNeighbors, flags, minObjectSize, maxObjectSize, false, true ); +} + bool CascadeClassifier::Data::read(const FileNode &root) { static const float THRESHOLD_EPS = 1e-5f;