mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 11:40:44 +08:00
Merge pull request #976 from PeterMinin:num_detections
This commit is contained in:
commit
83fa4d38a4
@ -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<Rect>& 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<Rect>& objects, vector<int>& numDetections, 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[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize[, outputRejectLevels]]]]]]) -> objects, rejectLevels, levelWeights
|
||||
@ -201,6 +202,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, the rectangles may be partially outside the original image.
|
||||
|
||||
:param numDetections: Vector of detection numbers for the corresponding objects. An object's number of detections is the number of neighboring positively classified rectangles that were joined together to form the 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.
|
||||
|
@ -149,6 +149,14 @@ public:
|
||||
Size minSize = Size(),
|
||||
Size maxSize = Size() );
|
||||
|
||||
CV_WRAP virtual void detectMultiScale( const Mat& image,
|
||||
CV_OUT std::vector<Rect>& objects,
|
||||
CV_OUT std::vector<int>& numDetections,
|
||||
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 std::vector<Rect>& objects,
|
||||
CV_OUT std::vector<int>& rejectLevels,
|
||||
@ -168,7 +176,12 @@ public:
|
||||
protected:
|
||||
virtual bool detectSingleScale( const Mat& image, int stripCount, Size processingRectSize,
|
||||
int stripSize, int yStep, double factor, std::vector<Rect>& candidates,
|
||||
std::vector<int>& rejectLevels, std::vector<double>& levelWeights, bool outputRejectLevels = false);
|
||||
std::vector<int>& rejectLevels, std::vector<double>& levelWeights, bool outputRejectLevels = false );
|
||||
|
||||
virtual void detectMultiScaleNoGrouping( const Mat& image, std::vector<Rect>& candidates,
|
||||
std::vector<int>& rejectLevels, std::vector<double>& levelWeights,
|
||||
double scaleFactor, Size minObjectSize, Size maxObjectSize,
|
||||
bool outputRejectLevels = false );
|
||||
|
||||
protected:
|
||||
enum { BOOST = 0
|
||||
|
@ -1022,6 +1022,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,
|
||||
@ -1086,39 +1087,33 @@ bool CascadeClassifier::setImage(const Mat& image)
|
||||
return featureEvaluator->setImage(image, data.origWinSize);
|
||||
}
|
||||
|
||||
void CascadeClassifier::detectMultiScale( const Mat& image, std::vector<Rect>& objects,
|
||||
std::vector<int>& rejectLevels,
|
||||
std::vector<double>& levelWeights,
|
||||
double scaleFactor, int minNeighbors,
|
||||
int flags, Size minObjectSize, Size maxObjectSize,
|
||||
bool outputRejectLevels )
|
||||
static void detectMultiScaleOldFormat( const Mat& image, Ptr<CvHaarClassifierCascade> oldCascade,
|
||||
std::vector<Rect>& objects,
|
||||
std::vector<int>& rejectLevels,
|
||||
std::vector<double>& levelWeights,
|
||||
std::vector<CvAvgComp>& vecAvgComp,
|
||||
double scaleFactor, int minNeighbors,
|
||||
int flags, Size minObjectSize, Size maxObjectSize,
|
||||
bool outputRejectLevels = false )
|
||||
{
|
||||
const double GROUP_EPS = 0.2;
|
||||
MemStorage storage(cvCreateMemStorage(0));
|
||||
CvMat _image = image;
|
||||
CvSeq* _objects = cvHaarDetectObjectsForROC( &_image, oldCascade, storage, rejectLevels, levelWeights, scaleFactor,
|
||||
minNeighbors, flags, minObjectSize, maxObjectSize, outputRejectLevels );
|
||||
Seq<CvAvgComp>(_objects).copyTo(vecAvgComp);
|
||||
objects.resize(vecAvgComp.size());
|
||||
std::transform(vecAvgComp.begin(), vecAvgComp.end(), objects.begin(), getRect());
|
||||
}
|
||||
|
||||
CV_Assert( scaleFactor > 1 && image.depth() == CV_8U );
|
||||
void CascadeClassifier::detectMultiScaleNoGrouping( const Mat& image, std::vector<Rect>& candidates,
|
||||
std::vector<int>& rejectLevels, std::vector<double>& levelWeights,
|
||||
double scaleFactor, Size minObjectSize, Size maxObjectSize,
|
||||
bool outputRejectLevels )
|
||||
{
|
||||
candidates.clear();
|
||||
|
||||
if( empty() )
|
||||
return;
|
||||
|
||||
if( isOldFormatCascade() )
|
||||
{
|
||||
MemStorage storage(cvCreateMemStorage(0));
|
||||
CvMat _image = image;
|
||||
CvSeq* _objects = cvHaarDetectObjectsForROC( &_image, oldCascade, storage, rejectLevels, levelWeights, scaleFactor,
|
||||
minNeighbors, flags, minObjectSize, maxObjectSize, outputRejectLevels );
|
||||
std::vector<CvAvgComp> vecAvgComp;
|
||||
Seq<CvAvgComp>(_objects).copyTo(vecAvgComp);
|
||||
objects.resize(vecAvgComp.size());
|
||||
std::transform(vecAvgComp.begin(), vecAvgComp.end(), objects.begin(), getRect());
|
||||
return;
|
||||
}
|
||||
|
||||
objects.clear();
|
||||
|
||||
if (!maskGenerator.empty()) {
|
||||
if (!maskGenerator.empty())
|
||||
maskGenerator->initializeMask(image);
|
||||
}
|
||||
|
||||
|
||||
if( maxObjectSize.height == 0 || maxObjectSize.width == 0 )
|
||||
maxObjectSize = image.size();
|
||||
@ -1132,7 +1127,6 @@ void CascadeClassifier::detectMultiScale( const Mat& image, std::vector<Rect>& o
|
||||
}
|
||||
|
||||
Mat imageBuffer(image.rows + 1, image.cols + 1, CV_8U);
|
||||
std::vector<Rect> candidates;
|
||||
|
||||
for( double factor = 1; ; factor *= scaleFactor )
|
||||
{
|
||||
@ -1173,18 +1167,39 @@ void CascadeClassifier::detectMultiScale( const Mat& image, std::vector<Rect>& o
|
||||
rejectLevels, levelWeights, outputRejectLevels ) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CascadeClassifier::detectMultiScale( const Mat& image, std::vector<Rect>& objects,
|
||||
std::vector<int>& rejectLevels,
|
||||
std::vector<double>& levelWeights,
|
||||
double scaleFactor, int minNeighbors,
|
||||
int flags, Size minObjectSize, Size maxObjectSize,
|
||||
bool outputRejectLevels )
|
||||
{
|
||||
CV_Assert( scaleFactor > 1 && image.depth() == CV_8U );
|
||||
|
||||
objects.resize(candidates.size());
|
||||
std::copy(candidates.begin(), candidates.end(), objects.begin());
|
||||
if( empty() )
|
||||
return;
|
||||
|
||||
if( outputRejectLevels )
|
||||
if( isOldFormatCascade() )
|
||||
{
|
||||
groupRectangles( objects, rejectLevels, levelWeights, minNeighbors, GROUP_EPS );
|
||||
std::vector<CvAvgComp> fakeVecAvgComp;
|
||||
detectMultiScaleOldFormat( image, oldCascade, objects, rejectLevels, levelWeights, fakeVecAvgComp, scaleFactor,
|
||||
minNeighbors, flags, minObjectSize, maxObjectSize, outputRejectLevels );
|
||||
}
|
||||
else
|
||||
{
|
||||
groupRectangles( objects, minNeighbors, GROUP_EPS );
|
||||
detectMultiScaleNoGrouping( image, objects, rejectLevels, levelWeights, scaleFactor, minObjectSize, maxObjectSize,
|
||||
outputRejectLevels );
|
||||
const double GROUP_EPS = 0.2;
|
||||
if( outputRejectLevels )
|
||||
{
|
||||
groupRectangles( objects, rejectLevels, levelWeights, minNeighbors, GROUP_EPS );
|
||||
}
|
||||
else
|
||||
{
|
||||
groupRectangles( objects, minNeighbors, GROUP_EPS );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1195,7 +1210,35 @@ void CascadeClassifier::detectMultiScale( const Mat& image, std::vector<Rect>& o
|
||||
std::vector<int> fakeLevels;
|
||||
std::vector<double> fakeWeights;
|
||||
detectMultiScale( image, objects, fakeLevels, fakeWeights, scaleFactor,
|
||||
minNeighbors, flags, minObjectSize, maxObjectSize, false );
|
||||
minNeighbors, flags, minObjectSize, maxObjectSize );
|
||||
}
|
||||
|
||||
void CascadeClassifier::detectMultiScale( const Mat& image, std::vector<Rect>& objects,
|
||||
std::vector<int>& numDetections, double scaleFactor,
|
||||
int minNeighbors, int flags, Size minObjectSize,
|
||||
Size maxObjectSize )
|
||||
{
|
||||
CV_Assert( scaleFactor > 1 && image.depth() == CV_8U );
|
||||
|
||||
if( empty() )
|
||||
return;
|
||||
|
||||
std::vector<int> fakeLevels;
|
||||
std::vector<double> fakeWeights;
|
||||
if( isOldFormatCascade() )
|
||||
{
|
||||
std::vector<CvAvgComp> vecAvgComp;
|
||||
detectMultiScaleOldFormat( image, oldCascade, objects, fakeLevels, fakeWeights, vecAvgComp, scaleFactor,
|
||||
minNeighbors, flags, minObjectSize, maxObjectSize );
|
||||
numDetections.resize(vecAvgComp.size());
|
||||
std::transform(vecAvgComp.begin(), vecAvgComp.end(), numDetections.begin(), getNeighbors());
|
||||
}
|
||||
else
|
||||
{
|
||||
detectMultiScaleNoGrouping( image, objects, fakeLevels, fakeWeights, scaleFactor, minObjectSize, maxObjectSize );
|
||||
const double GROUP_EPS = 0.2;
|
||||
groupRectangles( objects, numDetections, minNeighbors, GROUP_EPS );
|
||||
}
|
||||
}
|
||||
|
||||
bool CascadeClassifier::Data::read(const FileNode &root)
|
||||
|
Loading…
Reference in New Issue
Block a user