rename SCascade -> SoftCascadeDetector

This commit is contained in:
marina.kolpakova 2013-01-29 13:09:49 +04:00
parent 1b43b0e2df
commit 61441a1014
6 changed files with 95 additions and 94 deletions

View File

@ -56,11 +56,6 @@ protected:
enum {BINS = 10}; enum {BINS = 10};
}; };
// Implementation of soft (stageless) cascaded detector.
class CV_EXPORTS_W SCascade : public Algorithm
{
public:
// Representation of detectors result. // Representation of detectors result.
struct CV_EXPORTS Detection struct CV_EXPORTS Detection
{ {
@ -101,6 +96,13 @@ public:
int shrinkage; int shrinkage;
}; };
// ========================================================================== //
// Implementation of soft (stageless) cascaded detector.
// ========================================================================== //
class CV_EXPORTS_W SoftCascadeDetector : public Algorithm
{
public:
enum { NO_REJECT = 1, DOLLAR = 2, /*PASCAL = 4,*/ DEFAULT = NO_REJECT}; enum { NO_REJECT = 1, DOLLAR = 2, /*PASCAL = 4,*/ DEFAULT = NO_REJECT};
// An empty cascade will be created. // An empty cascade will be created.
@ -108,24 +110,25 @@ public:
// Param minScale is a maximum scale relative to the original size of the image on which cascade will be applied. // Param minScale is a maximum scale relative to the original size of the image on which cascade will be applied.
// Param scales is a number of scales from minScale to maxScale. // Param scales is a number of scales from minScale to maxScale.
// Param rejCriteria is used for NMS. // Param rejCriteria is used for NMS.
CV_WRAP SCascade(const double minScale = 0.4, const double maxScale = 5., const int scales = 55, const int rejCriteria = 1); CV_WRAP SoftCascadeDetector(double minScale = 0.4, double maxScale = 5., int scales = 55, int rejCriteria = 1);
CV_WRAP virtual ~SCascade(); CV_WRAP virtual ~SoftCascadeDetector();
cv::AlgorithmInfo* info() const; cv::AlgorithmInfo* info() const;
// Load cascade from FileNode. // Load soft cascade from FileNode.
// Param fn is a root node for cascade. Should be <cascade>. // Param fileNode is a root node for cascade.
CV_WRAP virtual bool load(const FileNode& fn); CV_WRAP virtual bool load(const FileNode& fileNode);
// Load cascade config. // Load soft cascade config.
CV_WRAP virtual void read(const FileNode& fn); CV_WRAP virtual void read(const FileNode& fileNode);
// Return the vector of Detection objects. // Return the vector of Detection objects.
// Param image is a frame on which detector will be applied. // Param image is a frame on which detector will be applied.
// Param rois is a vector of regions of interest. Only the objects that fall into one of the regions will be returned. // Param rois is a vector of regions of interest. Only the objects that fall into one of the regions will be returned.
// Param objects is an output array of Detections // Param objects is an output array of Detections
virtual void detect(InputArray image, InputArray rois, std::vector<Detection>& objects) const; virtual void detect(InputArray image, InputArray rois, std::vector<Detection>& objects) const;
// Param rects is an output array of bounding rectangles for detected objects. // Param rects is an output array of bounding rectangles for detected objects.
// Param confs is an output array of confidence for detected objects. i-th bounding rectangle corresponds i-th confidence. // Param confs is an output array of confidence for detected objects. i-th bounding rectangle corresponds i-th confidence.
CV_WRAP virtual void detect(InputArray image, InputArray rois, CV_OUT OutputArray rects, CV_OUT OutputArray confs) const; CV_WRAP virtual void detect(InputArray image, InputArray rois, CV_OUT OutputArray rects, CV_OUT OutputArray confs) const;
@ -144,6 +147,7 @@ private:
}; };
CV_EXPORTS bool initModule_softcascade(void); CV_EXPORTS bool initModule_softcascade(void);
} }
#endif #endif

View File

@ -9,9 +9,8 @@ typedef perf::TestBaseWithParam<fixture> detect;
namespace { namespace {
typedef cv::SCascade::Detection detection_t;
void extractRacts(std::vector<detection_t> objectBoxes, std::vector<Rect>& rects) void extractRacts(std::vector<cv::Detection> objectBoxes, std::vector<Rect>& rects)
{ {
rects.clear(); rects.clear();
for (int i = 0; i < (int)objectBoxes.size(); ++i) for (int i = 0; i < (int)objectBoxes.size(); ++i)
@ -20,20 +19,19 @@ void extractRacts(std::vector<detection_t> objectBoxes, std::vector<Rect>& rects
} }
PERF_TEST_P(detect, SCascade, PERF_TEST_P(detect, SoftCascadeDetector,
testing::Combine(testing::Values(std::string("cv/cascadeandhog/cascades/inria_caltech-17.01.2013.xml")), testing::Combine(testing::Values(std::string("cv/cascadeandhog/cascades/inria_caltech-17.01.2013.xml")),
testing::Values(std::string("cv/cascadeandhog/images/image_00000000_0.png")))) testing::Values(std::string("cv/cascadeandhog/images/image_00000000_0.png"))))
{ {
typedef cv::SCascade::Detection Detection;
cv::Mat colored = cv::imread(getDataPath(get<1>(GetParam()))); cv::Mat colored = cv::imread(getDataPath(get<1>(GetParam())));
ASSERT_FALSE(colored.empty()); ASSERT_FALSE(colored.empty());
cv::SCascade cascade; cv::SoftCascadeDetector cascade;
cv::FileStorage fs(getDataPath(get<0>(GetParam())), cv::FileStorage::READ); cv::FileStorage fs(getDataPath(get<0>(GetParam())), cv::FileStorage::READ);
ASSERT_TRUE(fs.isOpened()); ASSERT_TRUE(fs.isOpened());
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode())); ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
std::vector<detection_t> objectBoxes; std::vector<cv::Detection> objectBoxes;
cascade.detect(colored, cv::noArray(), objectBoxes); cascade.detect(colored, cv::noArray(), objectBoxes);
TEST_CYCLE() TEST_CYCLE()

View File

@ -99,9 +99,9 @@ void cv::ICFPreprocessor::apply(cv::InputArray _frame, cv::OutputArray _integral
cv::integral(shrunk, integrals, cv::noArray(), CV_32S); cv::integral(shrunk, integrals, cv::noArray(), CV_32S);
} }
cv::SCascade::Channels::Channels(int shr) : shrinkage(shr) {} cv::Channels::Channels(int shr) : shrinkage(shr) {}
void cv::SCascade::Channels::appendHogBins(const cv::Mat& gray, std::vector<cv::Mat>& integrals, int bins) const void cv::Channels::appendHogBins(const cv::Mat& gray, std::vector<cv::Mat>& integrals, int bins) const
{ {
CV_Assert(gray.type() == CV_8UC1); CV_Assert(gray.type() == CV_8UC1);
int h = gray.rows; int h = gray.rows;
@ -149,7 +149,7 @@ void cv::SCascade::Channels::appendHogBins(const cv::Mat& gray, std::vector<cv::
integrals.push_back(mag); integrals.push_back(mag);
} }
void cv::SCascade::Channels::appendLuvBins(const cv::Mat& frame, std::vector<cv::Mat>& integrals) const void cv::Channels::appendLuvBins(const cv::Mat& frame, std::vector<cv::Mat>& integrals) const
{ {
CV_Assert(frame.type() == CV_8UC3); CV_Assert(frame.type() == CV_8UC3);
CV_Assert(!(frame.cols % shrinkage) && !(frame.rows % shrinkage)); CV_Assert(!(frame.cols % shrinkage) && !(frame.rows % shrinkage));

View File

@ -134,7 +134,6 @@ struct Level
cv::Size objSize; cv::Size objSize;
float scaling[2]; // 0-th for channels <= 6, 1-st otherwise float scaling[2]; // 0-th for channels <= 6, 1-st otherwise
typedef cv::SCascade::Detection Detection;
Level(const Octave& oct, const float scale, const int shrinkage, const int w, const int h) Level(const Octave& oct, const float scale, const int shrinkage, const int w, const int h)
: octave(&oct), origScale(scale), relScale(scale / oct.scale), : octave(&oct), origScale(scale), relScale(scale / oct.scale),
@ -146,13 +145,13 @@ struct Level
scaleshift = static_cast<int>(relScale * (1 << 16)); scaleshift = static_cast<int>(relScale * (1 << 16));
} }
void addDetection(const int x, const int y, float confidence, std::vector<Detection>& detections) const void addDetection(const int x, const int y, float confidence, std::vector<cv::Detection>& detections) const
{ {
// fix me // fix me
int shrinkage = 4;//(*octave).shrinkage; int shrinkage = 4;//(*octave).shrinkage;
cv::Rect rect(cvRound(x * shrinkage), cvRound(y * shrinkage), objSize.width, objSize.height); cv::Rect rect(cvRound(x * shrinkage), cvRound(y * shrinkage), objSize.width, objSize.height);
detections.push_back(Detection(rect, confidence)); detections.push_back(cv::Detection(rect, confidence));
} }
float rescale(cv::Rect& scaledRect, const float threshold, int idx) const float rescale(cv::Rect& scaledRect, const float threshold, int idx) const
@ -184,9 +183,9 @@ struct ChannelStorage
{ {
hog.clear(); hog.clear();
hog.reserve(10); hog.reserve(10);
cv::SCascade::Channels ints(shr); cv::Channels ints(shr);
// convert to grey // convert to gray
cv::Mat grey; cv::Mat grey;
cv::cvtColor(colored, grey, CV_BGR2GRAY); cv::cvtColor(colored, grey, CV_BGR2GRAY);
@ -213,7 +212,7 @@ struct ChannelStorage
} }
struct cv::SCascade::Fields struct cv::SoftCascadeDetector::Fields
{ {
float minScale; float minScale;
float maxScale; float maxScale;
@ -417,17 +416,17 @@ struct cv::SCascade::Fields
} }
}; };
cv::SCascade::SCascade(const double mins, const double maxs, const int nsc, const int rej) cv::SoftCascadeDetector::SoftCascadeDetector(const double mins, const double maxs, const int nsc, const int rej)
: fields(0), minScale(mins), maxScale(maxs), scales(nsc), rejCriteria(rej) {} : fields(0), minScale(mins), maxScale(maxs), scales(nsc), rejCriteria(rej) {}
cv::SCascade::~SCascade() { delete fields;} cv::SoftCascadeDetector::~SoftCascadeDetector() { delete fields;}
void cv::SCascade::read(const FileNode& fn) void cv::SoftCascadeDetector::read(const FileNode& fn)
{ {
Algorithm::read(fn); Algorithm::read(fn);
} }
bool cv::SCascade::load(const FileNode& fn) bool cv::SoftCascadeDetector::load(const FileNode& fn)
{ {
if (fields) delete fields; if (fields) delete fields;
@ -436,13 +435,13 @@ bool cv::SCascade::load(const FileNode& fn)
} }
namespace { namespace {
typedef cv::SCascade::Detection Detection;
typedef std::vector<Detection> dvector; typedef std::vector<cv::Detection> dvector;
struct ConfidenceGt struct ConfidenceGt
{ {
bool operator()(const Detection& a, const Detection& b) const bool operator()(const cv::Detection& a, const cv::Detection& b) const
{ {
return a.confidence > b.confidence; return a.confidence > b.confidence;
} }
@ -463,10 +462,10 @@ void DollarNMS(dvector& objects)
for (dvector::iterator dIt = objects.begin(); dIt != objects.end(); ++dIt) for (dvector::iterator dIt = objects.begin(); dIt != objects.end(); ++dIt)
{ {
const Detection &a = *dIt; const cv::Detection &a = *dIt;
for (dvector::iterator next = dIt + 1; next != objects.end(); ) for (dvector::iterator next = dIt + 1; next != objects.end(); )
{ {
const Detection &b = *next; const cv::Detection &b = *next;
const float ovl = overlap(a.bb, b.bb) / std::min(a.bb.area(), b.bb.area()); const float ovl = overlap(a.bb, b.bb) / std::min(a.bb.area(), b.bb.area());
@ -478,15 +477,15 @@ void DollarNMS(dvector& objects)
} }
} }
static void suppress(int type, std::vector<Detection>& objects) static void suppress(int type, std::vector<cv::Detection>& objects)
{ {
CV_Assert(type == cv::SCascade::DOLLAR); CV_Assert(type == cv::SoftCascadeDetector::DOLLAR);
DollarNMS(objects); DollarNMS(objects);
} }
} }
void cv::SCascade::detectNoRoi(const cv::Mat& image, std::vector<Detection>& objects) const void cv::SoftCascadeDetector::detectNoRoi(const cv::Mat& image, std::vector<Detection>& objects) const
{ {
Fields& fld = *fields; Fields& fld = *fields;
// create integrals // create integrals
@ -513,9 +512,9 @@ void cv::SCascade::detectNoRoi(const cv::Mat& image, std::vector<Detection>& obj
if (rejCriteria != NO_REJECT) suppress(rejCriteria, objects); if (rejCriteria != NO_REJECT) suppress(rejCriteria, objects);
} }
void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vector<Detection>& objects) const void cv::SoftCascadeDetector::detect(cv::InputArray _image, cv::InputArray _rois, std::vector<Detection>& objects) const
{ {
// only color images are supperted // only color images are suppered
cv::Mat image = _image.getMat(); cv::Mat image = _image.getMat();
CV_Assert(image.type() == CV_8UC3); CV_Assert(image.type() == CV_8UC3);
@ -565,7 +564,7 @@ void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vect
if (rejCriteria != NO_REJECT) suppress(rejCriteria, objects); if (rejCriteria != NO_REJECT) suppress(rejCriteria, objects);
} }
void cv::SCascade::detect(InputArray _image, InputArray _rois, OutputArray _rects, OutputArray _confs) const void cv::SoftCascadeDetector::detect(InputArray _image, InputArray _rois, OutputArray _rects, OutputArray _confs) const
{ {
std::vector<Detection> objects; std::vector<Detection> objects;
detect( _image, _rois, objects); detect( _image, _rois, objects);

View File

@ -45,7 +45,7 @@
namespace cv namespace cv
{ {
CV_INIT_ALGORITHM(SCascade, "CascadeDetector.SCascade", CV_INIT_ALGORITHM(SoftCascadeDetector, "CascadeDetector.SoftCascadeDetector",
obj.info()->addParam(obj, "minScale", obj.minScale); obj.info()->addParam(obj, "minScale", obj.minScale);
obj.info()->addParam(obj, "maxScale", obj.maxScale); obj.info()->addParam(obj, "maxScale", obj.maxScale);
obj.info()->addParam(obj, "scales", obj.scales); obj.info()->addParam(obj, "scales", obj.scales);
@ -53,7 +53,7 @@ CV_INIT_ALGORITHM(SCascade, "CascadeDetector.SCascade",
bool initModule_softcascade(void) bool initModule_softcascade(void)
{ {
Ptr<Algorithm> sc = createSCascade(); Ptr<Algorithm> sc = createSoftCascadeDetector();
return sc->info() != 0; return sc->info() != 0;
} }

View File

@ -45,20 +45,20 @@
#include "test_precomp.hpp" #include "test_precomp.hpp"
TEST(SCascade, readCascade) TEST(SoftCascadeDetector, readCascade)
{ {
std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/cascades/inria_caltech-17.01.2013.xml"; std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/cascades/inria_caltech-17.01.2013.xml";
cv::SCascade cascade; cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ); cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(fs.isOpened()); ASSERT_TRUE(fs.isOpened());
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode())); ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
} }
TEST(SCascade, detect) TEST(SoftCascadeDetector, detect)
{ {
typedef cv::SCascade::Detection Detection; typedef cv::Detection Detection;
std::string xml = cvtest::TS::ptr()->get_data_path()+ "cascadeandhog/cascades/inria_caltech-17.01.2013.xml"; std::string xml = cvtest::TS::ptr()->get_data_path()+ "cascadeandhog/cascades/inria_caltech-17.01.2013.xml";
cv::SCascade cascade; cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ); cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode())); ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
@ -71,11 +71,11 @@ TEST(SCascade, detect)
ASSERT_EQ(719, (int)objects.size()); ASSERT_EQ(719, (int)objects.size());
} }
TEST(SCascade, detectSeparate) TEST(SoftCascadeDetector, detectSeparate)
{ {
typedef cv::SCascade::Detection Detection; typedef cv::Detection Detection;
std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/cascades/inria_caltech-17.01.2013.xml"; std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/cascades/inria_caltech-17.01.2013.xml";
cv::SCascade cascade; cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ); cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode())); ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
@ -88,11 +88,11 @@ TEST(SCascade, detectSeparate)
ASSERT_EQ(719, confs.cols); ASSERT_EQ(719, confs.cols);
} }
TEST(SCascade, detectRoi) TEST(SoftCascadeDetector, detectRoi)
{ {
typedef cv::SCascade::Detection Detection; typedef cv::Detection Detection;
std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/cascades/inria_caltech-17.01.2013.xml"; std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/cascades/inria_caltech-17.01.2013.xml";
cv::SCascade cascade; cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ); cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode())); ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
@ -107,11 +107,11 @@ TEST(SCascade, detectRoi)
ASSERT_EQ(719, (int)objects.size()); ASSERT_EQ(719, (int)objects.size());
} }
TEST(SCascade, detectNoRoi) TEST(SoftCascadeDetector, detectNoRoi)
{ {
typedef cv::SCascade::Detection Detection; typedef cv::Detection Detection;
std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/cascades/inria_caltech-17.01.2013.xml"; std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/cascades/inria_caltech-17.01.2013.xml";
cv::SCascade cascade; cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ); cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode())); ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
@ -126,11 +126,11 @@ TEST(SCascade, detectNoRoi)
ASSERT_EQ(719, (int)objects.size()); ASSERT_EQ(719, (int)objects.size());
} }
TEST(SCascade, detectEmptyRoi) TEST(SoftCascadeDetector, detectEmptyRoi)
{ {
typedef cv::SCascade::Detection Detection; typedef cv::Detection Detection;
std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/cascades/inria_caltech-17.01.2013.xml"; std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/cascades/inria_caltech-17.01.2013.xml";
cv::SCascade cascade; cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ); cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode())); ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));