a bit refactored soft cascade

pull/311/head
marina.kolpakova 12 years ago
parent f1b4b13e64
commit 9efd668a57
  1. 80
      modules/objdetect/src/softcascade.cpp

@ -223,7 +223,7 @@ struct cv::SCascade::Fields
int shrinkage; int shrinkage;
std::vector<Octave> octaves; std::vector<Octave> octaves;
std::vector<Weak> stages; std::vector<Weak> weaks;
std::vector<Node> nodes; std::vector<Node> nodes;
std::vector<float> leaves; std::vector<float> leaves;
std::vector<Feature> features; std::vector<Feature> features;
@ -233,47 +233,46 @@ struct cv::SCascade::Fields
cv::Size frameSize; cv::Size frameSize;
typedef std::vector<Octave>::iterator octIt_t; typedef std::vector<Octave>::iterator octIt_t;
typedef std::vector<Detection> dvector;
void detectAt(const int dx, const int dy, const Level& level, const ChannelStorage& storage, void detectAt(const int dx, const int dy, const Level& level, const ChannelStorage& storage, dvector& detections) const
std::vector<Detection>& detections) const
{ {
float detectionScore = 0.f; float detectionScore = 0.f;
const Octave& octave = *(level.octave); const Octave& octave = *(level.octave);
int stBegin = octave.index * octave.weaks, stEnd = stBegin + ((octave.index)? 1024 : 416); int stBegin = octave.index * octave.weaks, stEnd = stBegin + octave.weaks;
int st = stBegin; for(int st = stBegin; st < stEnd; ++st)
int offset = (octave.index)? -2: 0;
for(; st < stEnd; ++st)
{ {
const Weak& stage = stages[st]; const Weak& weak = weaks[st];
{
int nId = st * 3 + offset;
// work with root node int nId = st * 3;
const Node& node = nodes[nId];
const Feature& feature = features[node.feature + offset];
cv::Rect scaledRect(feature.rect);
float threshold = level.rescale(scaledRect, node.threshold,(int)(feature.channel > 6)) * feature.rarea; // work with root node
float sum = storage.get(feature.channel, scaledRect); const Node& node = nodes[nId];
int next = (sum >= threshold)? 2 : 1; const Feature& feature = features[node.feature];
// leaves cv::Rect scaledRect(feature.rect);
const Node& leaf = nodes[nId + next];
const Feature& fLeaf = features[leaf.feature + offset];
scaledRect = fLeaf.rect; float threshold = level.rescale(scaledRect, node.threshold, (int)(feature.channel > 6)) * feature.rarea;
threshold = level.rescale(scaledRect, leaf.threshold, (int)(fLeaf.channel > 6)) * fLeaf.rarea; float sum = storage.get(feature.channel, scaledRect);
sum = storage.get(fLeaf.channel, scaledRect); int next = (sum >= threshold)? 2 : 1;
int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0); // leaves
float impact = leaves[(st * 4 + offset) + lShift]; const Node& leaf = nodes[nId + next];
const Feature& fLeaf = features[leaf.feature];
detectionScore += impact; scaledRect = fLeaf.rect;
} threshold = level.rescale(scaledRect, leaf.threshold, (int)(fLeaf.channel > 6)) * fLeaf.rarea;
if (detectionScore <= stage.threshold) return; sum = storage.get(fLeaf.channel, scaledRect);
int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0);
float impact = leaves[(st * 4) + lShift];
detectionScore += impact;
if (detectionScore <= weak.threshold) return;
} }
if (detectionScore > 0) if (detectionScore > 0)
@ -346,13 +345,14 @@ struct cv::SCascade::Fields
static const char *const SC_ORIG_H = "height"; static const char *const SC_ORIG_H = "height";
static const char *const SC_OCTAVES = "octaves"; static const char *const SC_OCTAVES = "octaves";
static const char *const SC_STAGES = "stages"; static const char *const SC_TREES = "trees";
static const char *const SC_FEATURES = "features"; static const char *const SC_FEATURES = "features";
static const char *const SC_WEEK = "weakClassifiers";
static const char *const SC_INTERNAL = "internalNodes"; static const char *const SC_INTERNAL = "internalNodes";
static const char *const SC_LEAF = "leafValues"; static const char *const SC_LEAF = "leafValues";
static const char *const SC_SHRINKAGE = "shrinkage";
// only Ada Boost supported // only Ada Boost supported
std::string stageTypeStr = (string)root[SC_STAGE_TYPE]; std::string stageTypeStr = (string)root[SC_STAGE_TYPE];
CV_Assert(stageTypeStr == SC_BOOST); CV_Assert(stageTypeStr == SC_BOOST);
@ -364,17 +364,14 @@ struct cv::SCascade::Fields
origObjWidth = (int)root[SC_ORIG_W]; origObjWidth = (int)root[SC_ORIG_W];
origObjHeight = (int)root[SC_ORIG_H]; origObjHeight = (int)root[SC_ORIG_H];
shrinkage = (int)root["shrinkage"]; shrinkage = (int)root[SC_SHRINKAGE];
FileNode fn = root[SC_OCTAVES]; FileNode fn = root[SC_OCTAVES];
if (fn.empty()) return false; if (fn.empty()) return false;
FileNodeIterator it = fn.begin(), it_end = fn.end();
int feature_offset = 0;
int octIndex = 0;
// for each octave // for each octave
for (; it != it_end; ++it) FileNodeIterator it = fn.begin(), it_end = fn.end();
for (int octIndex = 0; it != it_end; ++it, ++octIndex)
{ {
FileNode fns = *it; FileNode fns = *it;
Octave octave(octIndex, cv::Size(origObjWidth, origObjHeight), fns); Octave octave(octIndex, cv::Size(origObjWidth, origObjHeight), fns);
@ -384,19 +381,18 @@ struct cv::SCascade::Fields
FileNode ffs = fns[SC_FEATURES]; FileNode ffs = fns[SC_FEATURES];
if (ffs.empty()) return false; if (ffs.empty()) return false;
fns = fns["trees"]; fns = fns[SC_TREES];
if (fn.empty()) return false; if (fn.empty()) return false;
// for each tree (~ decision tree with H = 2)
FileNodeIterator st = fns.begin(), st_end = fns.end(); FileNodeIterator st = fns.begin(), st_end = fns.end();
for (; st != st_end; ++st ) for (; st != st_end; ++st )
{ {
stages.push_back(Weak(*st)); weaks.push_back(Weak(*st));
fns = (*st)[SC_INTERNAL]; fns = (*st)[SC_INTERNAL];
FileNodeIterator inIt = fns.begin(), inIt_end = fns.end(); FileNodeIterator inIt = fns.begin(), inIt_end = fns.end();
for (; inIt != inIt_end;) for (; inIt != inIt_end;)
nodes.push_back(Node(feature_offset, inIt)); nodes.push_back(Node(features.size(), inIt));
fns = (*st)[SC_LEAF]; fns = (*st)[SC_LEAF];
inIt = fns.begin(), inIt_end = fns.end(); inIt = fns.begin(), inIt_end = fns.end();
@ -408,10 +404,8 @@ struct cv::SCascade::Fields
st = ffs.begin(), st_end = ffs.end(); st = ffs.begin(), st_end = ffs.end();
for (; st != st_end; ++st ) for (; st != st_end; ++st )
features.push_back(Feature(*st)); features.push_back(Feature(*st));
feature_offset += octave.weaks * 3;
++octIndex;
} }
return true; return true;
} }
}; };

Loading…
Cancel
Save