GPU soft cascade: buffers preallocation
This commit is contained in:
parent
2b7ce8b160
commit
1ab7af6995
@ -1563,18 +1563,6 @@ public:
|
|||||||
virtual void detectMultiScale(const GpuMat& image, const GpuMat& rois, GpuMat& objects,
|
virtual void detectMultiScale(const GpuMat& image, const GpuMat& rois, GpuMat& objects,
|
||||||
int rejectfactor = 1, Stream stream = Stream::Null());
|
int rejectfactor = 1, Stream stream = Stream::Null());
|
||||||
|
|
||||||
protected:
|
|
||||||
enum { BOOST = 0 };
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
FRAME_WIDTH = 640,
|
|
||||||
FRAME_HEIGHT = 480,
|
|
||||||
TOTAL_SCALES = 55,
|
|
||||||
CLASSIFIERS = 5,
|
|
||||||
ORIG_OBJECT_WIDTH = 64,
|
|
||||||
ORIG_OBJECT_HEIGHT = 128
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Filds;
|
struct Filds;
|
||||||
Filds* filds;
|
Filds* filds;
|
||||||
|
@ -40,6 +40,8 @@
|
|||||||
//
|
//
|
||||||
//M*/
|
//M*/
|
||||||
|
|
||||||
|
#include <opencv2/gpu/device/common.hpp>
|
||||||
|
|
||||||
#ifndef __OPENCV_ICF_HPP__
|
#ifndef __OPENCV_ICF_HPP__
|
||||||
#define __OPENCV_ICF_HPP__
|
#define __OPENCV_ICF_HPP__
|
||||||
|
|
||||||
@ -54,12 +56,24 @@ namespace icf {
|
|||||||
|
|
||||||
struct Cascade
|
struct Cascade
|
||||||
{
|
{
|
||||||
|
Cascade() {}
|
||||||
|
Cascade(const cv::gpu::PtrStepSzb& octs, const cv::gpu::PtrStepSzf& sts, const cv::gpu::PtrStepSzb& nds,
|
||||||
|
const cv::gpu::PtrStepSzf& lvs, const cv::gpu::PtrStepSzb& fts, const cv::gpu::PtrStepSzb& lls)
|
||||||
|
: octaves(octs), stages(sts), nodes(nds), leaves(lvs), features(fts), levels(lls) {}
|
||||||
|
|
||||||
|
cv::gpu::PtrStepSzb octaves;
|
||||||
|
cv::gpu::PtrStepSzf stages;
|
||||||
|
cv::gpu::PtrStepSzb nodes;
|
||||||
|
cv::gpu::PtrStepSzf leaves;
|
||||||
|
cv::gpu::PtrStepSzb features;
|
||||||
|
|
||||||
|
cv::gpu::PtrStepSzb levels;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ChannelStorage
|
struct ChannelStorage
|
||||||
{
|
{
|
||||||
|
ChannelStorage(const cv::gpu::PtrStepSzb& /*f*/, const int /*shrinkage*/) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct __align__(16) Octave
|
struct __align__(16) Octave
|
||||||
|
@ -72,19 +72,41 @@ struct cv::gpu::SoftCascade::Filds
|
|||||||
GpuMat nodes;
|
GpuMat nodes;
|
||||||
GpuMat leaves;
|
GpuMat leaves;
|
||||||
GpuMat features;
|
GpuMat features;
|
||||||
|
GpuMat levels;
|
||||||
|
|
||||||
|
// preallocated buffer 640x480x10
|
||||||
|
GpuMat dmem;
|
||||||
|
// 160x120x10
|
||||||
|
GpuMat shrunk;
|
||||||
|
// 161x121x10
|
||||||
|
GpuMat hogluv;
|
||||||
|
|
||||||
std::vector<float> scales;
|
std::vector<float> scales;
|
||||||
|
|
||||||
icf::Cascade cascade;
|
icf::Cascade cascade;
|
||||||
|
|
||||||
bool fill(const FileNode &root, const float mins, const float maxs);
|
bool fill(const FileNode &root, const float mins, const float maxs);
|
||||||
|
void detect(const icf::ChannelStorage& /*channels*/) const {}
|
||||||
|
|
||||||
|
enum { BOOST = 0 };
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FRAME_WIDTH = 640,
|
||||||
|
FRAME_HEIGHT = 480,
|
||||||
|
TOTAL_SCALES = 55,
|
||||||
|
CLASSIFIERS = 5,
|
||||||
|
ORIG_OBJECT_WIDTH = 64,
|
||||||
|
ORIG_OBJECT_HEIGHT = 128,
|
||||||
|
HOG_BINS = 6,
|
||||||
|
HOG_LUV_BINS = 10
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void calcLevels(const std::vector<icf::Octave>& octs,
|
void calcLevels(const std::vector<icf::Octave>& octs,
|
||||||
int frameW, int frameH, int nscales);
|
int frameW, int frameH, int nscales);
|
||||||
|
|
||||||
typedef std::vector<icf::Octave>::const_iterator octIt_t;
|
typedef std::vector<icf::Octave>::const_iterator octIt_t;
|
||||||
int fitOctave(const std::vector<icf::Octave>& octs, const float& logFactor)
|
int fitOctave(const std::vector<icf::Octave>& octs, const float& logFactor) const
|
||||||
{
|
{
|
||||||
float minAbsLog = FLT_MAX;
|
float minAbsLog = FLT_MAX;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
@ -145,10 +167,10 @@ inline bool cv::gpu::SoftCascade::Filds::fill(const FileNode &root, const float
|
|||||||
CV_Assert(featureTypeStr == SC_ICF);
|
CV_Assert(featureTypeStr == SC_ICF);
|
||||||
|
|
||||||
origObjWidth = (int)root[SC_ORIG_W];
|
origObjWidth = (int)root[SC_ORIG_W];
|
||||||
CV_Assert(origObjWidth == SoftCascade::ORIG_OBJECT_WIDTH);
|
CV_Assert(origObjWidth == ORIG_OBJECT_WIDTH);
|
||||||
|
|
||||||
origObjHeight = (int)root[SC_ORIG_H];
|
origObjHeight = (int)root[SC_ORIG_H];
|
||||||
CV_Assert(origObjHeight == SoftCascade::ORIG_OBJECT_HEIGHT);
|
CV_Assert(origObjHeight == ORIG_OBJECT_HEIGHT);
|
||||||
|
|
||||||
FileNode fn = root[SC_OCTAVES];
|
FileNode fn = root[SC_OCTAVES];
|
||||||
if (fn.empty()) return false;
|
if (fn.empty()) return false;
|
||||||
@ -165,6 +187,7 @@ inline bool cv::gpu::SoftCascade::Filds::fill(const FileNode &root, const float
|
|||||||
FileNodeIterator it = fn.begin(), it_end = fn.end();
|
FileNodeIterator it = fn.begin(), it_end = fn.end();
|
||||||
int feature_offset = 0;
|
int feature_offset = 0;
|
||||||
ushort octIndex = 0;
|
ushort octIndex = 0;
|
||||||
|
ushort shrinkage = 1;
|
||||||
|
|
||||||
for (; it != it_end; ++it)
|
for (; it != it_end; ++it)
|
||||||
{
|
{
|
||||||
@ -173,9 +196,9 @@ inline bool cv::gpu::SoftCascade::Filds::fill(const FileNode &root, const float
|
|||||||
scales.push_back(scale);
|
scales.push_back(scale);
|
||||||
ushort nstages = saturate_cast<ushort>((int)fn[SC_OCT_STAGES]);
|
ushort nstages = saturate_cast<ushort>((int)fn[SC_OCT_STAGES]);
|
||||||
ushort2 size;
|
ushort2 size;
|
||||||
size.x = cvRound(SoftCascade::ORIG_OBJECT_WIDTH * scale);
|
size.x = cvRound(ORIG_OBJECT_WIDTH * scale);
|
||||||
size.y = cvRound(SoftCascade::ORIG_OBJECT_HEIGHT * scale);
|
size.y = cvRound(ORIG_OBJECT_HEIGHT * scale);
|
||||||
ushort shrinkage = saturate_cast<ushort>((int)fn[SC_OCT_SHRINKAGE]);
|
shrinkage = saturate_cast<ushort>((int)fn[SC_OCT_SHRINKAGE]);
|
||||||
|
|
||||||
icf::Octave octave(octIndex, nstages, shrinkage, size, scale);
|
icf::Octave octave(octIndex, nstages, shrinkage, size, scale);
|
||||||
CV_Assert(octave.stages > 0);
|
CV_Assert(octave.stages > 0);
|
||||||
@ -247,7 +270,16 @@ inline bool cv::gpu::SoftCascade::Filds::fill(const FileNode &root, const float
|
|||||||
CV_Assert(!features.empty());
|
CV_Assert(!features.empty());
|
||||||
|
|
||||||
// compute levels
|
// compute levels
|
||||||
calcLevels(voctaves, (int)SoftCascade::FRAME_WIDTH, (int)SoftCascade::FRAME_HEIGHT, (int)SoftCascade::TOTAL_SCALES);
|
calcLevels(voctaves, FRAME_WIDTH, FRAME_HEIGHT, TOTAL_SCALES);
|
||||||
|
CV_Assert(!levels.empty());
|
||||||
|
|
||||||
|
// init Cascade
|
||||||
|
cascade = icf::Cascade(octaves, stages, nodes, leaves, features, levels);
|
||||||
|
|
||||||
|
// allocate buffers
|
||||||
|
dmem.create(FRAME_HEIGHT * HOG_LUV_BINS, FRAME_WIDTH, CV_8UC1);
|
||||||
|
shrunk.create(FRAME_HEIGHT / shrinkage * HOG_LUV_BINS, FRAME_WIDTH / shrinkage, CV_8UC1);
|
||||||
|
hogluv.create( (FRAME_HEIGHT / shrinkage * HOG_LUV_BINS) + 1, (FRAME_WIDTH / shrinkage) + 1, CV_16UC1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -291,7 +323,7 @@ inline void cv::gpu::SoftCascade::Filds::calcLevels(const std::vector<icf::Octav
|
|||||||
{
|
{
|
||||||
CV_Assert(nscales > 1);
|
CV_Assert(nscales > 1);
|
||||||
|
|
||||||
std::vector<icf::Level> levels;
|
std::vector<icf::Level> vlevels;
|
||||||
float logFactor = (::log(maxScale) - ::log(minScale)) / (nscales -1);
|
float logFactor = (::log(maxScale) - ::log(minScale)) / (nscales -1);
|
||||||
|
|
||||||
float scale = minScale;
|
float scale = minScale;
|
||||||
@ -310,11 +342,13 @@ inline void cv::gpu::SoftCascade::Filds::calcLevels(const std::vector<icf::Octav
|
|||||||
if (!width || !height)
|
if (!width || !height)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
levels.push_back(level);
|
vlevels.push_back(level);
|
||||||
|
|
||||||
if (::fabs(scale - maxScale) < FLT_EPSILON) break;
|
if (::fabs(scale - maxScale) < FLT_EPSILON) break;
|
||||||
scale = ::std::min(maxScale, ::expf(::log(scale) + logFactor));
|
scale = ::std::min(maxScale, ::expf(::log(scale) + logFactor));
|
||||||
|
|
||||||
|
levels.upload(cv::Mat(1, vlevels.size() * sizeof(icf::Level), CV_8UC1, (uchar*)&(vlevels[0]) ));
|
||||||
|
|
||||||
// std::cout << "level " << sc << " scale "
|
// std::cout << "level " << sc << " scale "
|
||||||
// << levels[sc].origScale
|
// << levels[sc].origScale
|
||||||
// << " octeve "
|
// << " octeve "
|
||||||
@ -355,10 +389,22 @@ bool cv::gpu::SoftCascade::load( const string& filename, const float minScale, c
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::gpu::SoftCascade::detectMultiScale(const GpuMat& /*image*/, const GpuMat& /*rois*/,
|
void cv::gpu::SoftCascade::detectMultiScale(const GpuMat& image, const GpuMat& /*rois*/,
|
||||||
GpuMat& /*objects*/, const int /*rejectfactor*/, Stream /*stream*/)
|
GpuMat& /*objects*/, const int /*rejectfactor*/, Stream /*stream*/)
|
||||||
{
|
{
|
||||||
// empty
|
// only color images are supperted
|
||||||
|
CV_Assert(image.type() == CV_8UC3);
|
||||||
|
|
||||||
|
// only this window size allowed
|
||||||
|
CV_Assert(image.cols == 640 && image.rows == 480);
|
||||||
|
|
||||||
|
|
||||||
|
// ToDo: add shrincage in whole cascade.
|
||||||
|
const int shrincage = 4;
|
||||||
|
icf::ChannelStorage storage(image, shrincage);
|
||||||
|
|
||||||
|
const Filds& flds = *filds;
|
||||||
|
flds.detect(storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user