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,50 +56,52 @@ protected:
enum {BINS = 10};
};
// Implementation of soft (stageless) cascaded detector.
class CV_EXPORTS_W SCascade : public Algorithm
// Representation of detectors result.
struct CV_EXPORTS Detection
{
// Default object type.
enum {PEDESTRIAN = 1};
// Creates Detection from an object bounding box and confidence.
// Param b is a bounding box
// Param c is a confidence that object belongs to class k
// Param k is an object class
Detection(const cv::Rect& b, const float c, int k = PEDESTRIAN) : bb(b), confidence(c), kind(k) {}
cv::Rect bb;
float confidence;
int kind;
};
// Create channel integrals for Soft Cascade detector.
class CV_EXPORTS Channels
{
public:
// constrictor form resizing factor.
// Param shrinkage is a resizing factor. Resize is applied before the computing integral sum
Channels(const int shrinkage);
// Representation of detectors result.
struct CV_EXPORTS Detection
{
// Default object type.
enum {PEDESTRIAN = 1};
// Appends specified number of HOG first-order features integrals into given vector.
// Param gray is an input 1-channel gray image.
// Param integrals is a vector of integrals. Hog-channels will be appended to it.
// Param bins is a number of hog-bins
void appendHogBins(const cv::Mat& gray, std::vector<cv::Mat>& integrals, int bins) const;
// Creates Detection from an object bounding box and confidence.
// Param b is a bounding box
// Param c is a confidence that object belongs to class k
// Param k is an object class
Detection(const cv::Rect& b, const float c, int k = PEDESTRIAN) : bb(b), confidence(c), kind(k) {}
// Converts 3-channel BGR input frame in Luv and appends each channel to the integrals.
// Param frame is an input 3-channel BGR colored image.
// Param integrals is a vector of integrals. Computed from the frame luv-channels will be appended to it.
void appendLuvBins(const cv::Mat& frame, std::vector<cv::Mat>& integrals) const;
cv::Rect bb;
float confidence;
int kind;
};
private:
int shrinkage;
};
// Create channel integrals for Soft Cascade detector.
class CV_EXPORTS Channels
{
public:
// constrictor form resizing factor.
// Param shrinkage is a resizing factor. Resize is applied before the computing integral sum
Channels(const int shrinkage);
// Appends specified number of HOG first-order features integrals into given vector.
// Param gray is an input 1-channel gray image.
// Param integrals is a vector of integrals. Hog-channels will be appended to it.
// Param bins is a number of hog-bins
void appendHogBins(const cv::Mat& gray, std::vector<cv::Mat>& integrals, int bins) const;
// Converts 3-channel BGR input frame in Luv and appends each channel to the integrals.
// Param frame is an input 3-channel BGR colored image.
// Param integrals is a vector of integrals. Computed from the frame luv-channels will be appended to it.
void appendLuvBins(const cv::Mat& frame, std::vector<cv::Mat>& integrals) const;
private:
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};
@ -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 scales is a number of scales from minScale to maxScale.
// 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;
// Load cascade from FileNode.
// Param fn is a root node for cascade. Should be <cascade>.
CV_WRAP virtual bool load(const FileNode& fn);
// Load soft cascade from FileNode.
// Param fileNode is a root node for cascade.
CV_WRAP virtual bool load(const FileNode& fileNode);
// Load cascade config.
CV_WRAP virtual void read(const FileNode& fn);
// Load soft cascade config.
CV_WRAP virtual void read(const FileNode& fileNode);
// Return the vector of Detection objects.
// 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 objects is an output array of Detections
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 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;
@ -144,6 +147,7 @@ private:
};
CV_EXPORTS bool initModule_softcascade(void);
}
#endif

View File

@ -9,9 +9,8 @@ typedef perf::TestBaseWithParam<fixture> detect;
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();
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::Values(std::string("cv/cascadeandhog/images/image_00000000_0.png"))))
{
typedef cv::SCascade::Detection Detection;
cv::Mat colored = cv::imread(getDataPath(get<1>(GetParam())));
ASSERT_FALSE(colored.empty());
cv::SCascade cascade;
cv::SoftCascadeDetector cascade;
cv::FileStorage fs(getDataPath(get<0>(GetParam())), cv::FileStorage::READ);
ASSERT_TRUE(fs.isOpened());
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
std::vector<detection_t> objectBoxes;
std::vector<cv::Detection> objectBoxes;
cascade.detect(colored, cv::noArray(), objectBoxes);
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::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);
int h = gray.rows;
@ -149,7 +149,7 @@ void cv::SCascade::Channels::appendHogBins(const cv::Mat& gray, std::vector<cv::
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.cols % shrinkage) && !(frame.rows % shrinkage));

View File

@ -134,7 +134,6 @@ struct Level
cv::Size objSize;
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)
: octave(&oct), origScale(scale), relScale(scale / oct.scale),
@ -146,13 +145,13 @@ struct Level
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
int shrinkage = 4;//(*octave).shrinkage;
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
@ -184,9 +183,9 @@ struct ChannelStorage
{
hog.clear();
hog.reserve(10);
cv::SCascade::Channels ints(shr);
cv::Channels ints(shr);
// convert to grey
// convert to gray
cv::Mat grey;
cv::cvtColor(colored, grey, CV_BGR2GRAY);
@ -213,7 +212,7 @@ struct ChannelStorage
}
struct cv::SCascade::Fields
struct cv::SoftCascadeDetector::Fields
{
float minScale;
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) {}
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);
}
bool cv::SCascade::load(const FileNode& fn)
bool cv::SoftCascadeDetector::load(const FileNode& fn)
{
if (fields) delete fields;
@ -436,13 +435,13 @@ bool cv::SCascade::load(const FileNode& fn)
}
namespace {
typedef cv::SCascade::Detection Detection;
typedef std::vector<Detection> dvector;
typedef std::vector<cv::Detection> dvector;
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;
}
@ -463,10 +462,10 @@ void DollarNMS(dvector& objects)
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(); )
{
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());
@ -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);
}
}
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;
// 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);
}
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_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);
}
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;
detect( _image, _rois, objects);

View File

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

View File

@ -45,20 +45,20 @@
#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";
cv::SCascade cascade;
cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(fs.isOpened());
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";
cv::SCascade cascade;
cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
@ -71,11 +71,11 @@ TEST(SCascade, detect)
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";
cv::SCascade cascade;
cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
@ -88,11 +88,11 @@ TEST(SCascade, detectSeparate)
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";
cv::SCascade cascade;
cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
@ -107,11 +107,11 @@ TEST(SCascade, detectRoi)
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";
cv::SCascade cascade;
cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));
@ -126,11 +126,11 @@ TEST(SCascade, detectNoRoi)
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";
cv::SCascade cascade;
cv::SoftCascadeDetector cascade;
cv::FileStorage fs(xml, cv::FileStorage::READ);
ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode()));