add detectAt to soft cascade
This commit is contained in:
parent
801368ee82
commit
8d90b973b0
@ -66,6 +66,8 @@ struct Octave
|
|||||||
size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)),
|
size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)),
|
||||||
shrinkage((int)fn[SC_OCT_SHRINKAGE])
|
shrinkage((int)fn[SC_OCT_SHRINKAGE])
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
int index() const {return (int)log(scale);}
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *const Octave::SC_OCT_SCALE = "scale";
|
const char *const Octave::SC_OCT_SCALE = "scale";
|
||||||
@ -182,6 +184,89 @@ struct Level
|
|||||||
// {1, 2, 1, 2}
|
// {1, 2, 1, 2}
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
void calcHistBins(const cv::Mat& grey, cv::Mat& magIntegral, std::vector<cv::Mat>& histInts,
|
||||||
|
const int bins, int shrinkage)
|
||||||
|
{
|
||||||
|
CV_Assert( grey.type() == CV_8U);
|
||||||
|
|
||||||
|
float scale = 1.f / shrinkage;
|
||||||
|
|
||||||
|
const int rows = grey.rows + 1;
|
||||||
|
const int cols = grey.cols + 1;
|
||||||
|
cv::Size intSumSize(cols, rows);
|
||||||
|
|
||||||
|
histInts.clear();
|
||||||
|
std::vector<cv::Mat> hist;
|
||||||
|
for (int bin = 0; bin < bins; ++bin)
|
||||||
|
{
|
||||||
|
hist.push_back(cv::Mat(rows, cols, CV_32FC1));
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat df_dx, df_dy, mag, angle;
|
||||||
|
cv::Sobel(grey, df_dx, CV_32F, 1, 0);
|
||||||
|
cv::Sobel(grey, df_dy, CV_32F, 0, 1);
|
||||||
|
|
||||||
|
cv::cartToPolar(df_dx, df_dy, mag, angle, true);
|
||||||
|
|
||||||
|
const float magnitudeScaling = 1.0 / sqrt(2);
|
||||||
|
mag *= magnitudeScaling;
|
||||||
|
angle /= 60;
|
||||||
|
|
||||||
|
for (int h = 0; h < mag.rows; ++h)
|
||||||
|
{
|
||||||
|
float* magnitude = mag.ptr<float>(h);
|
||||||
|
float* ang = angle.ptr<float>(h);
|
||||||
|
|
||||||
|
for (int w = 0; w < mag.cols; ++w)
|
||||||
|
{
|
||||||
|
hist[(int)ang[w]].ptr<float>(h)[w] = magnitude[w];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int bin = 0; bin < bins; ++bin)
|
||||||
|
{
|
||||||
|
cv::Mat shrunk, sum;
|
||||||
|
cv::resize(hist[bin], shrunk, cv::Size(), scale, scale, cv::INTER_AREA);
|
||||||
|
cv::integral(shrunk, sum);
|
||||||
|
histInts.push_back(sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat shrMag;
|
||||||
|
cv::resize(mag, shrMag, cv::Size(), scale, scale, cv::INTER_AREA);
|
||||||
|
|
||||||
|
cv::integral(shrMag, magIntegral, mag.depth());
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ChannelStorage
|
||||||
|
{
|
||||||
|
std::vector<cv::Mat> hog;
|
||||||
|
cv::Mat magnitude;
|
||||||
|
cv::Mat luv;
|
||||||
|
|
||||||
|
int shrinkage;
|
||||||
|
|
||||||
|
enum {HOG_BINS = 6};
|
||||||
|
|
||||||
|
ChannelStorage() {}
|
||||||
|
ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr)
|
||||||
|
{
|
||||||
|
cv::Mat _luv;
|
||||||
|
cv::cvtColor(colored, _luv, CV_BGR2Luv);
|
||||||
|
|
||||||
|
cv::integral(luv, luv);
|
||||||
|
|
||||||
|
cv::Mat grey;
|
||||||
|
cv::cvtColor(colored, grey, CV_RGB2GRAY);
|
||||||
|
|
||||||
|
calcHistBins(grey, magnitude, hog, HOG_BINS, shrinkage);
|
||||||
|
}
|
||||||
|
|
||||||
|
float get(int chennel, cv::Rect area) const
|
||||||
|
{
|
||||||
|
return 1.f;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cv::SoftCascade::Filds
|
struct cv::SoftCascade::Filds
|
||||||
@ -203,28 +288,38 @@ struct cv::SoftCascade::Filds
|
|||||||
|
|
||||||
std::vector<Level> levels;
|
std::vector<Level> levels;
|
||||||
|
|
||||||
// typedef std::vector<Stage>::iterator stIter_t;
|
|
||||||
|
|
||||||
// // carrently roi must be save for out of ranges.
|
|
||||||
// void detectInRoi(const cv::Rect& roi, const Integral& ints, std::vector<cv::Rect>& objects, const int step)
|
|
||||||
// {
|
|
||||||
// for (int dy = roi.y; dy < roi.height; dy+=step)
|
|
||||||
// for (int dx = roi.x; dx < roi.width; dx += step)
|
|
||||||
// {
|
|
||||||
// applyCascade(ints, dx, dy);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void applyCascade(const Integral& ints, const int x, const int y)
|
|
||||||
// {
|
|
||||||
// for (stIter_t sIt = stages.begin(); sIt != stages.end(); ++sIt)
|
|
||||||
// {
|
|
||||||
// Stage& stage = *sIt;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
typedef std::vector<Octave>::iterator octIt_t;
|
typedef std::vector<Octave>::iterator octIt_t;
|
||||||
|
|
||||||
|
void detectAt(const Level& level, const int dx, const int dy, const ChannelStorage& storage,
|
||||||
|
const std::vector<cv::Rect>& detections) const
|
||||||
|
{
|
||||||
|
float detectionScore = 0.f;
|
||||||
|
|
||||||
|
const Octave& octave = *(level.octave);
|
||||||
|
int stBegin = octave.index() * octave.stages, stEnd = stBegin + octave.stages;
|
||||||
|
for(int st = stBegin; st < stEnd; ++st)
|
||||||
|
{
|
||||||
|
const Stage& stage = stages[st];
|
||||||
|
if (detectionScore > stage.threshold)
|
||||||
|
{
|
||||||
|
int nId = st * 3;
|
||||||
|
const Node& node = nodes[nId];
|
||||||
|
const Feature& feature = features[node.feature];
|
||||||
|
|
||||||
|
float sum = storage.get(feature.channel, feature.rect);
|
||||||
|
int next = (sum >= node.threshold)? 2 : 1;
|
||||||
|
|
||||||
|
const Node& leaf = nodes[nId + next];
|
||||||
|
const Feature& fLeaf = features[node.feature];
|
||||||
|
sum = storage.get(feature.channel, feature.rect);
|
||||||
|
|
||||||
|
int lShift = (next - 1) * 2 + (sum >= leaf.threshold) ? 1 : 0;
|
||||||
|
float impact = leaves[nId + lShift];
|
||||||
|
detectionScore += impact;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
octIt_t fitOctave(const float& logFactor)
|
octIt_t fitOctave(const float& logFactor)
|
||||||
{
|
{
|
||||||
float minAbsLog = FLT_MAX;
|
float minAbsLog = FLT_MAX;
|
||||||
@ -407,90 +502,9 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector<cv::Rect>& rois,
|
||||||
|
std::vector<cv::Rect>& objects,
|
||||||
void calcHistBins(const cv::Mat& grey, cv::Mat& magIntegral, std::vector<cv::Mat>& histInts, const int bins, int shrinkage)
|
const int step, const int rejectfactor)
|
||||||
{
|
|
||||||
CV_Assert( grey.type() == CV_8U);
|
|
||||||
|
|
||||||
float scale = 1.f / shrinkage;
|
|
||||||
|
|
||||||
const int rows = grey.rows + 1;
|
|
||||||
const int cols = grey.cols + 1;
|
|
||||||
cv::Size intSumSize(cols, rows);
|
|
||||||
|
|
||||||
histInts.clear();
|
|
||||||
std::vector<cv::Mat> hist;
|
|
||||||
for (int bin = 0; bin < bins; ++bin)
|
|
||||||
{
|
|
||||||
hist.push_back(cv::Mat(rows, cols, CV_32FC1));
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Mat df_dx, df_dy, mag, angle;
|
|
||||||
cv::Sobel(grey, df_dx, CV_32F, 1, 0);
|
|
||||||
cv::Sobel(grey, df_dy, CV_32F, 0, 1);
|
|
||||||
|
|
||||||
cv::cartToPolar(df_dx, df_dy, mag, angle, true);
|
|
||||||
|
|
||||||
const float magnitudeScaling = 1.0 / sqrt(2);
|
|
||||||
mag *= magnitudeScaling;
|
|
||||||
angle /= 60;
|
|
||||||
|
|
||||||
for (int h = 0; h < mag.rows; ++h)
|
|
||||||
{
|
|
||||||
float* magnitude = mag.ptr<float>(h);
|
|
||||||
float* ang = angle.ptr<float>(h);
|
|
||||||
|
|
||||||
for (int w = 0; w < mag.cols; ++w)
|
|
||||||
{
|
|
||||||
hist[(int)ang[w]].ptr<float>(h)[w] = magnitude[w];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int bin = 0; bin < bins; ++bin)
|
|
||||||
{
|
|
||||||
cv::Mat shrunk, sum;
|
|
||||||
cv::resize(hist[bin], shrunk, cv::Size(), scale, scale, cv::INTER_AREA);
|
|
||||||
cv::integral(shrunk, sum);
|
|
||||||
histInts.push_back(sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Mat shrMag;
|
|
||||||
cv::resize(mag, shrMag, cv::Size(), scale, scale, cv::INTER_AREA);
|
|
||||||
|
|
||||||
cv::integral(shrMag, magIntegral, mag.depth());
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ChannelStorage
|
|
||||||
{
|
|
||||||
std::vector<cv::Mat> hog;
|
|
||||||
cv::Mat luv;
|
|
||||||
cv::Mat magnitude;
|
|
||||||
|
|
||||||
int shrinkage;
|
|
||||||
|
|
||||||
enum {HOG_BINS = 6};
|
|
||||||
|
|
||||||
ChannelStorage() {}
|
|
||||||
ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr)
|
|
||||||
{
|
|
||||||
cv::Mat _luv;
|
|
||||||
cv::cvtColor(colored, _luv, CV_BGR2Luv);
|
|
||||||
|
|
||||||
cv::integral(luv, luv);
|
|
||||||
|
|
||||||
cv::Mat grey;
|
|
||||||
cv::cvtColor(colored, grey, CV_RGB2GRAY);
|
|
||||||
|
|
||||||
calcHistBins(grey, magnitude, hog, HOG_BINS, shrinkage);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector<cv::Rect>& rois, std::vector<cv::Rect>& objects,
|
|
||||||
const int step, const int rejectfactor)// add step scaling
|
|
||||||
{
|
{
|
||||||
typedef std::vector<cv::Rect>::const_iterator RIter_t;
|
typedef std::vector<cv::Rect>::const_iterator RIter_t;
|
||||||
// only color images are supperted
|
// only color images are supperted
|
||||||
@ -506,10 +520,17 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector<cv::R
|
|||||||
// create integrals
|
// create integrals
|
||||||
ChannelStorage storage(image, fld.shrinkage);
|
ChannelStorage storage(image, fld.shrinkage);
|
||||||
|
|
||||||
// for (RIter_t it = rois.begin(); it != rois.end(); ++it)
|
// object candidates
|
||||||
// {
|
std::vector<cv::Rect> detections;
|
||||||
// const cv::Rect& roi = *it;
|
|
||||||
// (*filds).detectInRoi(roi, integrals, objects, step);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
typedef std::vector<Level>::const_iterator lIt;
|
||||||
|
for (lIt it = fld.levels.begin(); it != fld.levels.end(); ++it)
|
||||||
|
{
|
||||||
|
const Level& level = *it;
|
||||||
|
for (int dy = 0; dy < level.workRect.height; ++dy)
|
||||||
|
for (int dx = 0; dx < level.workRect.width; ++dx)
|
||||||
|
fld.detectAt(level, dx, dy, storage, detections);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::swap(detections, objects);
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user