Commit 1ab7af69 authored by marina.kolpakova's avatar marina.kolpakova

GPU soft cascade: buffers preallocation

parent 2b7ce8b1
...@@ -1563,18 +1563,6 @@ public: ...@@ -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 @@ ...@@ -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 { ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment