LBP: switched to PImpl pattern
This commit is contained in:
parent
6c3eeb7d7c
commit
2dc93574e1
@ -1426,8 +1426,6 @@ private:
|
|||||||
class CV_EXPORTS CascadeClassifier_GPU_LBP
|
class CV_EXPORTS CascadeClassifier_GPU_LBP
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum stage { BOOST = 0 };
|
|
||||||
enum feature { LBP = 0 };
|
|
||||||
CascadeClassifier_GPU_LBP(cv::Size detectionFrameSize = cv::Size());
|
CascadeClassifier_GPU_LBP(cv::Size detectionFrameSize = cv::Size());
|
||||||
~CascadeClassifier_GPU_LBP();
|
~CascadeClassifier_GPU_LBP();
|
||||||
|
|
||||||
@ -1438,33 +1436,10 @@ public:
|
|||||||
int detectMultiScale(const GpuMat& image, GpuMat& objectsBuf, double scaleFactor = 1.1, int minNeighbors = 4,
|
int detectMultiScale(const GpuMat& image, GpuMat& objectsBuf, double scaleFactor = 1.1, int minNeighbors = 4,
|
||||||
cv::Size maxObjectSize = cv::Size()/*, Size minSize = Size()*/);
|
cv::Size maxObjectSize = cv::Size()/*, Size minSize = Size()*/);
|
||||||
Size getClassifierSize() const;
|
Size getClassifierSize() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool read(const FileNode &root);
|
struct CascadeClassifierImpl;
|
||||||
void allocateBuffers(cv::Size frame = cv::Size());
|
CascadeClassifierImpl* impl;
|
||||||
|
|
||||||
static const stage stageType = BOOST;
|
|
||||||
static const feature featureType = LBP;
|
|
||||||
|
|
||||||
cv::Size NxM;
|
|
||||||
bool isStumps;
|
|
||||||
int ncategories;
|
|
||||||
int subsetSize;
|
|
||||||
int nodeStep;
|
|
||||||
|
|
||||||
// gpu representation of classifier
|
|
||||||
GpuMat stage_mat;
|
|
||||||
GpuMat trees_mat;
|
|
||||||
GpuMat nodes_mat;
|
|
||||||
GpuMat leaves_mat;
|
|
||||||
GpuMat subsets_mat;
|
|
||||||
GpuMat features_mat;
|
|
||||||
|
|
||||||
GpuMat integral;
|
|
||||||
GpuMat integralBuffer;
|
|
||||||
GpuMat resuzeBuffer;
|
|
||||||
|
|
||||||
GpuMat candidates;
|
|
||||||
static const int integralFactor = 4;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////// SURF //////////////////////////////////////////
|
////////////////////////////////// SURF //////////////////////////////////////////
|
||||||
|
@ -74,10 +74,131 @@ double /*scaleFactor*/, int /*minNeighbors*/, cv::Size /*maxObjectSize*/){ throw
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
cv::gpu::CascadeClassifier_GPU_LBP::CascadeClassifier_GPU_LBP(cv::Size detectionFrameSize) { allocateBuffers(detectionFrameSize); }
|
cv::Size operator -(const cv::Size& a, const cv::Size& b)
|
||||||
cv::gpu::CascadeClassifier_GPU_LBP::~CascadeClassifier_GPU_LBP(){}
|
{
|
||||||
|
return cv::Size(a.width - b.width, a.height - b.height);
|
||||||
|
}
|
||||||
|
|
||||||
void cv::gpu::CascadeClassifier_GPU_LBP::allocateBuffers(cv::Size frame)
|
cv::Size operator +(const cv::Size& a, const int& i)
|
||||||
|
{
|
||||||
|
return cv::Size(a.width + i, a.height + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Size operator *(const cv::Size& a, const float& f)
|
||||||
|
{
|
||||||
|
return cv::Size(cvRound(a.width * f), cvRound(a.height * f));
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Size operator /(const cv::Size& a, const float& f)
|
||||||
|
{
|
||||||
|
return cv::Size(cvRound(a.width / f), cvRound(a.height / f));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator <=(const cv::Size& a, const cv::Size& b)
|
||||||
|
{
|
||||||
|
return a.width <= b.width && a.height <= b.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PyrLavel
|
||||||
|
{
|
||||||
|
PyrLavel(int _order, float _scale, cv::Size frame, cv::Size window) : order(_order)
|
||||||
|
{
|
||||||
|
scale = pow(_scale, order);
|
||||||
|
sFrame = frame / scale;
|
||||||
|
workArea = sFrame - window + 1;
|
||||||
|
sWindow = window * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFeasible(cv::Size maxObj)
|
||||||
|
{
|
||||||
|
return workArea.width > 0 && workArea.height > 0 && sWindow <= maxObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyrLavel next(float factor, cv::Size frame, cv::Size window)
|
||||||
|
{
|
||||||
|
return PyrLavel(order + 1, factor, frame, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
int order;
|
||||||
|
float scale;
|
||||||
|
cv::Size sFrame;
|
||||||
|
cv::Size workArea;
|
||||||
|
cv::Size sWindow;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace cv { namespace gpu { namespace device
|
||||||
|
{
|
||||||
|
namespace lbp
|
||||||
|
{
|
||||||
|
void classifyPyramid(int frameW,
|
||||||
|
int frameH,
|
||||||
|
int windowW,
|
||||||
|
int windowH,
|
||||||
|
float initalScale,
|
||||||
|
float factor,
|
||||||
|
int total,
|
||||||
|
const DevMem2Db& mstages,
|
||||||
|
const int nstages,
|
||||||
|
const DevMem2Di& mnodes,
|
||||||
|
const DevMem2Df& mleaves,
|
||||||
|
const DevMem2Di& msubsets,
|
||||||
|
const DevMem2Db& mfeatures,
|
||||||
|
const int subsetSize,
|
||||||
|
DevMem2D_<int4> objects,
|
||||||
|
unsigned int* classified,
|
||||||
|
DevMem2Di integral);
|
||||||
|
|
||||||
|
void connectedConmonents(DevMem2D_<int4> candidates, int ncandidates, DevMem2D_<int4> objects,int groupThreshold, float grouping_eps, unsigned int* nclasses);
|
||||||
|
}
|
||||||
|
}}}
|
||||||
|
|
||||||
|
struct cv::gpu::CascadeClassifier_GPU_LBP::CascadeClassifierImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Stage
|
||||||
|
{
|
||||||
|
int first;
|
||||||
|
int ntrees;
|
||||||
|
float threshold;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool read(const FileNode &root);
|
||||||
|
void allocateBuffers(cv::Size frame = cv::Size());
|
||||||
|
bool empty() const {return stage_mat.empty();}
|
||||||
|
|
||||||
|
int process(const GpuMat& image, GpuMat& objects, double scaleFactor, int groupThreshold, cv::Size maxObjectSize);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum stage { BOOST = 0 };
|
||||||
|
enum feature { LBP = 0 };
|
||||||
|
|
||||||
|
static const stage stageType = BOOST;
|
||||||
|
static const feature featureType = LBP;
|
||||||
|
|
||||||
|
cv::Size NxM;
|
||||||
|
bool isStumps;
|
||||||
|
int ncategories;
|
||||||
|
int subsetSize;
|
||||||
|
int nodeStep;
|
||||||
|
|
||||||
|
// gpu representation of classifier
|
||||||
|
GpuMat stage_mat;
|
||||||
|
GpuMat trees_mat;
|
||||||
|
GpuMat nodes_mat;
|
||||||
|
GpuMat leaves_mat;
|
||||||
|
GpuMat subsets_mat;
|
||||||
|
GpuMat features_mat;
|
||||||
|
|
||||||
|
GpuMat integral;
|
||||||
|
GpuMat integralBuffer;
|
||||||
|
GpuMat resuzeBuffer;
|
||||||
|
|
||||||
|
GpuMat candidates;
|
||||||
|
static const int integralFactor = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
void cv::gpu::CascadeClassifier_GPU_LBP::CascadeClassifierImpl::allocateBuffers(cv::Size frame)
|
||||||
{
|
{
|
||||||
if (frame == cv::Size())
|
if (frame == cv::Size())
|
||||||
return;
|
return;
|
||||||
@ -102,26 +223,8 @@ void cv::gpu::CascadeClassifier_GPU_LBP::allocateBuffers(cv::Size frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cv::gpu::CascadeClassifier_GPU_LBP::empty() const
|
|
||||||
{
|
|
||||||
return stage_mat.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cv::gpu::CascadeClassifier_GPU_LBP::load(const string& classifierAsXml)
|
|
||||||
{
|
|
||||||
FileStorage fs(classifierAsXml, FileStorage::READ);
|
|
||||||
return fs.isOpened() ? read(fs.getFirstTopLevelNode()) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Stage
|
|
||||||
{
|
|
||||||
int first;
|
|
||||||
int ntrees;
|
|
||||||
float threshold;
|
|
||||||
};
|
|
||||||
|
|
||||||
// currently only stump based boost classifiers are supported
|
// currently only stump based boost classifiers are supported
|
||||||
bool CascadeClassifier_GPU_LBP::read(const FileNode &root)
|
bool CascadeClassifier_GPU_LBP::CascadeClassifierImpl::read(const FileNode &root)
|
||||||
{
|
{
|
||||||
const char *GPU_CC_STAGE_TYPE = "stageType";
|
const char *GPU_CC_STAGE_TYPE = "stageType";
|
||||||
const char *GPU_CC_FEATURE_TYPE = "featureType";
|
const char *GPU_CC_FEATURE_TYPE = "featureType";
|
||||||
@ -262,85 +365,7 @@ bool CascadeClassifier_GPU_LBP::read(const FileNode &root)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace cv { namespace gpu { namespace device
|
int cv::gpu::CascadeClassifier_GPU_LBP::CascadeClassifierImpl::process(const GpuMat& image, GpuMat& objects, double scaleFactor, int groupThreshold, cv::Size maxObjectSize)
|
||||||
{
|
|
||||||
namespace lbp
|
|
||||||
{
|
|
||||||
void classifyPyramid(int frameW,
|
|
||||||
int frameH,
|
|
||||||
int windowW,
|
|
||||||
int windowH,
|
|
||||||
float initalScale,
|
|
||||||
float factor,
|
|
||||||
int total,
|
|
||||||
const DevMem2Db& mstages,
|
|
||||||
const int nstages,
|
|
||||||
const DevMem2Di& mnodes,
|
|
||||||
const DevMem2Df& mleaves,
|
|
||||||
const DevMem2Di& msubsets,
|
|
||||||
const DevMem2Db& mfeatures,
|
|
||||||
const int subsetSize,
|
|
||||||
DevMem2D_<int4> objects,
|
|
||||||
unsigned int* classified,
|
|
||||||
DevMem2Di integral);
|
|
||||||
|
|
||||||
void connectedConmonents(DevMem2D_<int4> candidates, int ncandidates, DevMem2D_<int4> objects,int groupThreshold, float grouping_eps, unsigned int* nclasses);
|
|
||||||
}
|
|
||||||
}}}
|
|
||||||
|
|
||||||
cv::Size operator -(const cv::Size& a, const cv::Size& b)
|
|
||||||
{
|
|
||||||
return cv::Size(a.width - b.width, a.height - b.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Size operator +(const cv::Size& a, const int& i)
|
|
||||||
{
|
|
||||||
return cv::Size(a.width + i, a.height + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Size operator *(const cv::Size& a, const float& f)
|
|
||||||
{
|
|
||||||
return cv::Size(cvRound(a.width * f), cvRound(a.height * f));
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Size operator /(const cv::Size& a, const float& f)
|
|
||||||
{
|
|
||||||
return cv::Size(cvRound(a.width / f), cvRound(a.height / f));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator <=(const cv::Size& a, const cv::Size& b)
|
|
||||||
{
|
|
||||||
return a.width <= b.width && a.height <= b.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PyrLavel
|
|
||||||
{
|
|
||||||
PyrLavel(int _order, float _scale, cv::Size frame, cv::Size window) : order(_order)
|
|
||||||
{
|
|
||||||
scale = pow(_scale, order);
|
|
||||||
sFrame = frame / scale;
|
|
||||||
workArea = sFrame - window + 1;
|
|
||||||
sWindow = window * scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isFeasible(cv::Size maxObj)
|
|
||||||
{
|
|
||||||
return workArea.width > 0 && workArea.height > 0 && sWindow <= maxObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyrLavel next(float factor, cv::Size frame, cv::Size window)
|
|
||||||
{
|
|
||||||
return PyrLavel(order + 1, factor, frame, window);
|
|
||||||
}
|
|
||||||
|
|
||||||
int order;
|
|
||||||
float scale;
|
|
||||||
cv::Size sFrame;
|
|
||||||
cv::Size workArea;
|
|
||||||
cv::Size sWindow;
|
|
||||||
};
|
|
||||||
|
|
||||||
int cv::gpu::CascadeClassifier_GPU_LBP::detectMultiScale(const GpuMat& image, GpuMat& objects, double scaleFactor, int groupThreshold, cv::Size maxObjectSize)
|
|
||||||
{
|
{
|
||||||
CV_Assert(!empty() && scaleFactor > 1 && image.depth() == CV_8U);
|
CV_Assert(!empty() && scaleFactor > 1 && image.depth() == CV_8U);
|
||||||
|
|
||||||
@ -419,6 +444,26 @@ int cv::gpu::CascadeClassifier_GPU_LBP::detectMultiScale(const GpuMat& image, Gp
|
|||||||
return classified;
|
return classified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::gpu::CascadeClassifier_GPU_LBP::CascadeClassifier_GPU_LBP(cv::Size detectionFrameSize) : impl(new CascadeClassifierImpl()) { (*impl).allocateBuffers(detectionFrameSize); }
|
||||||
|
cv::gpu::CascadeClassifier_GPU_LBP::~CascadeClassifier_GPU_LBP(){ delete impl; }
|
||||||
|
|
||||||
|
|
||||||
|
bool cv::gpu::CascadeClassifier_GPU_LBP::empty() const
|
||||||
|
{
|
||||||
|
return (*impl).empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cv::gpu::CascadeClassifier_GPU_LBP::load(const string& classifierAsXml)
|
||||||
|
{
|
||||||
|
FileStorage fs(classifierAsXml, FileStorage::READ);
|
||||||
|
return fs.isOpened() ? (*impl).read(fs.getFirstTopLevelNode()) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cv::gpu::CascadeClassifier_GPU_LBP::detectMultiScale(const GpuMat& image, GpuMat& objects, double scaleFactor, int groupThreshold, cv::Size maxObjectSize)
|
||||||
|
{
|
||||||
|
return (*impl).process(image, objects, scaleFactor, groupThreshold, maxObjectSize);
|
||||||
|
}
|
||||||
|
|
||||||
// ============ old fashioned haar cascade ==============================================//
|
// ============ old fashioned haar cascade ==============================================//
|
||||||
struct cv::gpu::CascadeClassifier_GPU::CascadeClassifierImpl
|
struct cv::gpu::CascadeClassifier_GPU::CascadeClassifierImpl
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user