clean code
This commit is contained in:
parent
4656872161
commit
f1e36043e6
@ -41,8 +41,6 @@
|
|||||||
//M*/
|
//M*/
|
||||||
|
|
||||||
#include <precomp.hpp>
|
#include <precomp.hpp>
|
||||||
#include <opencv2/objdetect/objdetect.hpp>
|
|
||||||
#include <opencv2/core/core.hpp>
|
|
||||||
|
|
||||||
cv::SCascade::Channels::Channels(int shr) : shrinkage(shr) {}
|
cv::SCascade::Channels::Channels(int shr) : shrinkage(shr) {}
|
||||||
|
|
||||||
|
@ -41,29 +41,16 @@
|
|||||||
//M*/
|
//M*/
|
||||||
|
|
||||||
#include <precomp.hpp>
|
#include <precomp.hpp>
|
||||||
#include <opencv2/objdetect/objdetect.hpp>
|
|
||||||
#include <opencv2/core/core.hpp>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
// used for noisy printfs
|
|
||||||
// #define WITH_DEBUG_OUT
|
|
||||||
|
|
||||||
#if defined WITH_DEBUG_OUT
|
|
||||||
# define dprintf(format, ...) \
|
|
||||||
do { printf(format, ##__VA_ARGS__); } while (0)
|
|
||||||
#else
|
|
||||||
# define dprintf(format, ...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct Octave
|
struct Octave
|
||||||
{
|
{
|
||||||
|
Octave(const int i, cv::Size origObjSize, const cv::FileNode& fn)
|
||||||
|
: index(i), scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]),
|
||||||
|
size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)),
|
||||||
|
shrinkage((int)fn[SC_OCT_SHRINKAGE]) {}
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
float scale;
|
float scale;
|
||||||
int stages;
|
int stages;
|
||||||
@ -73,49 +60,32 @@ struct Octave
|
|||||||
static const char *const SC_OCT_SCALE;
|
static const char *const SC_OCT_SCALE;
|
||||||
static const char *const SC_OCT_STAGES;
|
static const char *const SC_OCT_STAGES;
|
||||||
static const char *const SC_OCT_SHRINKAGE;
|
static const char *const SC_OCT_SHRINKAGE;
|
||||||
|
|
||||||
Octave(const int i, cv::Size origObjSize, const cv::FileNode& fn)
|
|
||||||
: index(i), scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]),
|
|
||||||
size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)),
|
|
||||||
shrinkage((int)fn[SC_OCT_SHRINKAGE])
|
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *const Octave::SC_OCT_SCALE = "scale";
|
|
||||||
const char *const Octave::SC_OCT_STAGES = "stageNum";
|
|
||||||
const char *const Octave::SC_OCT_SHRINKAGE = "shrinkingFactor";
|
|
||||||
|
|
||||||
struct Weak
|
struct Weak
|
||||||
{
|
{
|
||||||
|
Weak(){}
|
||||||
|
Weak(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]){}
|
||||||
|
|
||||||
float threshold;
|
float threshold;
|
||||||
|
|
||||||
static const char *const SC_STAGE_THRESHOLD;
|
static const char *const SC_STAGE_THRESHOLD;
|
||||||
|
|
||||||
Weak(){}
|
|
||||||
Weak(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]){}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *const Weak::SC_STAGE_THRESHOLD = "stageThreshold";
|
|
||||||
|
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
int feature;
|
|
||||||
float threshold;
|
|
||||||
|
|
||||||
Node(){}
|
Node(){}
|
||||||
Node(const int offset, cv::FileNodeIterator& fIt)
|
Node(const int offset, cv::FileNodeIterator& fIt)
|
||||||
: feature((int)(*(fIt +=2)++) + offset), threshold((float)(*(fIt++))){}
|
: feature((int)(*(fIt +=2)++) + offset), threshold((float)(*(fIt++))){}
|
||||||
|
|
||||||
|
int feature;
|
||||||
|
float threshold;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Feature
|
struct Feature
|
||||||
{
|
{
|
||||||
int channel;
|
|
||||||
cv::Rect rect;
|
|
||||||
float rarea;
|
|
||||||
|
|
||||||
static const char * const SC_F_CHANNEL;
|
|
||||||
static const char * const SC_F_RECT;
|
|
||||||
|
|
||||||
Feature() {}
|
Feature() {}
|
||||||
Feature(const cv::FileNode& fn) : channel((int)fn[SC_F_CHANNEL])
|
Feature(const cv::FileNode& fn) : channel((int)fn[SC_F_CHANNEL])
|
||||||
{
|
{
|
||||||
@ -126,41 +96,23 @@ struct Feature
|
|||||||
// 1 / area
|
// 1 / area
|
||||||
rarea = 1.f / ((rect.width - rect.x) * (rect.height - rect.y));
|
rarea = 1.f / ((rect.width - rect.x) * (rect.height - rect.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int channel;
|
||||||
|
cv::Rect rect;
|
||||||
|
float rarea;
|
||||||
|
|
||||||
|
static const char *const SC_F_CHANNEL;
|
||||||
|
static const char *const SC_F_RECT;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *const Octave::SC_OCT_SCALE = "scale";
|
||||||
|
const char *const Octave::SC_OCT_STAGES = "stageNum";
|
||||||
|
const char *const Octave::SC_OCT_SHRINKAGE = "shrinkingFactor";
|
||||||
|
const char *const Weak::SC_STAGE_THRESHOLD = "stageThreshold";
|
||||||
const char *const Feature::SC_F_CHANNEL = "channel";
|
const char *const Feature::SC_F_CHANNEL = "channel";
|
||||||
const char *const Feature::SC_F_RECT = "rect";
|
const char *const Feature::SC_F_RECT = "rect";
|
||||||
|
|
||||||
struct CascadeIntrinsics
|
|
||||||
{
|
|
||||||
static const float lambda = 1.099f, a = 0.89f;
|
|
||||||
|
|
||||||
static float getFor(bool isUp, float scaling)
|
|
||||||
{
|
|
||||||
if (fabs(scaling - 1.f) < FLT_EPSILON)
|
|
||||||
return 1.f;
|
|
||||||
|
|
||||||
// according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool's and Dallal's papers
|
|
||||||
static const float A[2][2] =
|
|
||||||
{ //channel <= 6, otherwise
|
|
||||||
{ 0.89f, 1.f}, // down
|
|
||||||
{ 1.00f, 1.f} // up
|
|
||||||
};
|
|
||||||
|
|
||||||
static const float B[2][2] =
|
|
||||||
{ //channel <= 6, otherwise
|
|
||||||
{ 1.099f / log(2), 2.f}, // down
|
|
||||||
{ 0.f, 2.f} // up
|
|
||||||
};
|
|
||||||
|
|
||||||
float a = A[(int)(scaling >= 1)][(int)(isUp)];
|
|
||||||
float b = B[(int)(scaling >= 1)][(int)(isUp)];
|
|
||||||
|
|
||||||
dprintf("scaling: %f %f %f %f\n", scaling, a, b, a * pow(scaling, b));
|
|
||||||
return a * pow(scaling, b);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Level
|
struct Level
|
||||||
{
|
{
|
||||||
const Octave* octave;
|
const Octave* octave;
|
||||||
@ -172,37 +124,36 @@ struct Level
|
|||||||
cv::Size workRect;
|
cv::Size workRect;
|
||||||
cv::Size objSize;
|
cv::Size objSize;
|
||||||
|
|
||||||
enum { R_SHIFT = 1 << 15 };
|
float scaling[2]; // 0-th for channels <= 6, 1-st otherwise
|
||||||
|
typedef cv::SCascade::Detection Detection;
|
||||||
float scaling[2];
|
|
||||||
typedef cv::SCascade::Detection detection_t;
|
|
||||||
|
|
||||||
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),
|
||||||
workRect(cv::Size(cvRound(w / (float)shrinkage),cvRound(h / (float)shrinkage))),
|
workRect(cv::Size(cvRound(w / (float)shrinkage),cvRound(h / (float)shrinkage))),
|
||||||
objSize(cv::Size(cvRound(oct.size.width * relScale), cvRound(oct.size.height * relScale)))
|
objSize(cv::Size(cvRound(oct.size.width * relScale), cvRound(oct.size.height * relScale)))
|
||||||
{
|
{
|
||||||
scaling[0] = CascadeIntrinsics::getFor(false, relScale) / (relScale * relScale);
|
scaling[0] = ((relScale >= 1.f)? 1.f : (0.89f * pow(relScale, 1.099f / log(2)))) / (relScale * relScale);
|
||||||
scaling[1] = CascadeIntrinsics::getFor(true, relScale) / (relScale * relScale);
|
scaling[1] = 1.f;
|
||||||
scaleshift = relScale * (1 << 16);
|
scaleshift = relScale * (1 << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDetection(const int x, const int y, float confidence, std::vector<detection_t>& detections) const
|
void addDetection(const int x, const int y, float confidence, std::vector<Detection>& detections) const
|
||||||
{
|
{
|
||||||
int shrinkage = (*octave).shrinkage;
|
int shrinkage = (*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_t(rect, confidence));
|
detections.push_back(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
|
||||||
{
|
{
|
||||||
|
#define SSHIFT(a) ((a) + (1 << 15)) >> 16
|
||||||
// rescale
|
// rescale
|
||||||
scaledRect.x = (scaleshift * scaledRect.x + R_SHIFT) >> 16;
|
scaledRect.x = SSHIFT(scaleshift * scaledRect.x);
|
||||||
scaledRect.y = (scaleshift * scaledRect.y + R_SHIFT) >> 16;
|
scaledRect.y = SSHIFT(scaleshift * scaledRect.y);
|
||||||
scaledRect.width = (scaleshift * scaledRect.width + R_SHIFT) >> 16;
|
scaledRect.width = SSHIFT(scaleshift * scaledRect.width);
|
||||||
scaledRect.height = (scaleshift * scaledRect.height + R_SHIFT) >> 16;
|
scaledRect.height = SSHIFT(scaleshift * scaledRect.height);
|
||||||
|
#undef SSHIFT
|
||||||
float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y);
|
float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y);
|
||||||
|
|
||||||
// compensation areas rounding
|
// compensation areas rounding
|
||||||
@ -219,7 +170,6 @@ struct ChannelStorage
|
|||||||
|
|
||||||
enum {HOG_BINS = 6, HOG_LUV_BINS = 10};
|
enum {HOG_BINS = 6, HOG_LUV_BINS = 10};
|
||||||
|
|
||||||
ChannelStorage() {}
|
|
||||||
ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr)
|
ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr)
|
||||||
{
|
{
|
||||||
hog.clear();
|
hog.clear();
|
||||||
@ -273,29 +223,19 @@ struct cv::SCascade::Fields
|
|||||||
|
|
||||||
cv::Size frameSize;
|
cv::Size frameSize;
|
||||||
|
|
||||||
enum { BOOST = 0 };
|
|
||||||
|
|
||||||
typedef std::vector<Octave>::iterator octIt_t;
|
typedef std::vector<Octave>::iterator octIt_t;
|
||||||
|
|
||||||
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,
|
||||||
std::vector<Detection>& detections) const
|
std::vector<Detection>& detections) const
|
||||||
{
|
{
|
||||||
dprintf("detect at: %d %d\n", dx, dy);
|
|
||||||
|
|
||||||
float detectionScore = 0.f;
|
float detectionScore = 0.f;
|
||||||
|
|
||||||
const Octave& octave = *(level.octave);
|
const Octave& octave = *(level.octave);
|
||||||
int stBegin = octave.index * octave.stages, stEnd = stBegin + 1024;//octave.stages;
|
int stBegin = octave.index * octave.stages, stEnd = stBegin + 1024;//octave.stages;
|
||||||
|
|
||||||
dprintf(" octave stages: %d to %d index %d %f level %f\n",
|
|
||||||
stBegin, stEnd, octave.index, octave.scale, level.origScale);
|
|
||||||
|
|
||||||
int st = stBegin;
|
int st = stBegin;
|
||||||
for(; st < stEnd; ++st)
|
for(; st < stEnd; ++st)
|
||||||
{
|
{
|
||||||
|
|
||||||
dprintf("index: %d\n", st);
|
|
||||||
|
|
||||||
const Weak& stage = stages[st];
|
const Weak& stage = stages[st];
|
||||||
{
|
{
|
||||||
int nId = st * 3;
|
int nId = st * 3;
|
||||||
@ -309,12 +249,8 @@ struct cv::SCascade::Fields
|
|||||||
|
|
||||||
float sum = storage.get(feature.channel, scaledRect);
|
float sum = storage.get(feature.channel, scaledRect);
|
||||||
|
|
||||||
dprintf("root feature %d %f\n",feature.channel, sum);
|
|
||||||
|
|
||||||
int next = (sum >= threshold)? 2 : 1;
|
int next = (sum >= threshold)? 2 : 1;
|
||||||
|
|
||||||
dprintf("go: %d (%f >= %f)\n\n" ,next, sum, threshold);
|
|
||||||
|
|
||||||
// leaves
|
// leaves
|
||||||
const Node& leaf = nodes[nId + next];
|
const Node& leaf = nodes[nId + next];
|
||||||
const Feature& fLeaf = features[leaf.feature];
|
const Feature& fLeaf = features[leaf.feature];
|
||||||
@ -327,25 +263,12 @@ struct cv::SCascade::Fields
|
|||||||
int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0);
|
int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0);
|
||||||
float impact = leaves[(st * 4) + lShift];
|
float impact = leaves[(st * 4) + lShift];
|
||||||
|
|
||||||
dprintf("decided: %d (%f >= %f) %d %f\n\n" ,next, sum, threshold, lShift, impact);
|
|
||||||
|
|
||||||
detectionScore += impact;
|
detectionScore += impact;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf("extracted stage:\n");
|
|
||||||
dprintf("ct %f\n", stage.threshold);
|
|
||||||
dprintf("computed score %f\n\n", detectionScore);
|
|
||||||
|
|
||||||
#if defined WITH_DEBUG_OUT
|
|
||||||
if (st - stBegin > 50 ) break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (detectionScore <= stage.threshold) return;
|
if (detectionScore <= stage.threshold) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf("x %d y %d: %d\n", dx, dy, st - stBegin);
|
|
||||||
dprintf(" got %d\n", st);
|
|
||||||
|
|
||||||
level.addDetection(dx, dy, detectionScore, detections);
|
level.addDetection(dx, dy, detectionScore, detections);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,16 +469,18 @@ void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vect
|
|||||||
if (_rois.kind() == cv::_InputArray::NONE)
|
if (_rois.kind() == cv::_InputArray::NONE)
|
||||||
return detectNoRoi(image, objects);
|
return detectNoRoi(image, objects);
|
||||||
|
|
||||||
|
int shr = fld.shrinkage;
|
||||||
|
|
||||||
cv::Mat roi = _rois.getMat();
|
cv::Mat roi = _rois.getMat();
|
||||||
cv::Mat mask(image.rows / fld.shrinkage, image.cols / fld.shrinkage, CV_8UC1);
|
cv::Mat mask(image.rows / shr, image.cols / shr, CV_8UC1);
|
||||||
|
|
||||||
mask.setTo(cv::Scalar::all(0));
|
mask.setTo(cv::Scalar::all(0));
|
||||||
cv::Rect* r = roi.ptr<cv::Rect>(0);
|
cv::Rect* r = roi.ptr<cv::Rect>(0);
|
||||||
for (int i = 0; i < (int)roi.cols; ++i)
|
for (int i = 0; i < (int)roi.cols; ++i)
|
||||||
cv::Mat(mask, cv::Rect(r[i].x / fld.shrinkage, r[i].y / fld.shrinkage, r[i].width / fld.shrinkage , r[i].height / fld.shrinkage)).setTo(cv::Scalar::all(1));
|
cv::Mat(mask, cv::Rect(r[i].x / shr, r[i].y / shr, r[i].width / shr , r[i].height / shr)).setTo(cv::Scalar::all(1));
|
||||||
|
|
||||||
// create integrals
|
// create integrals
|
||||||
ChannelStorage storage(image, fld.shrinkage);
|
ChannelStorage storage(image, shr);
|
||||||
|
|
||||||
typedef std::vector<Level>::const_iterator lIt;
|
typedef std::vector<Level>::const_iterator lIt;
|
||||||
for (lIt it = fld.levels.begin(); it != fld.levels.end(); ++it)
|
for (lIt it = fld.levels.begin(); it != fld.levels.end(); ++it)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user