【Adaboost算法】C++转C, 分类器结构设计

一、参考OpenCV的CascadeClassifier类LBPEvaluator类

如下,筛选出存放分类器相关信息的成员变量:

【Adaboost算法】C++转C, 分类器结构设计
class CV_EXPORTS_W CascadeClassifier
{
public:
    CV_WRAP CascadeClassifier();
    CV_WRAP CascadeClassifier( const string& filename );
    virtual ~CascadeClassifier();

    CV_WRAP virtual bool empty() const;
    CV_WRAP bool load( const string& filename );
    virtual bool read( const FileNode& node );
    CV_WRAP virtual void detectMultiScale( const Mat& image,
                                   CV_OUT vector<Rect>& objects,
                                   double scaleFactor=1.1,
                                   int minNeighbors=3, int flags=0,
                                   Size minSize=Size(),
                                   Size maxSize=Size() );

    CV_WRAP virtual void detectMultiScale( const Mat& image,
                                   CV_OUT vector<Rect>& objects,
                                   vector<int>& rejectLevels,
                                   vector<double>& levelWeights,
                                   double scaleFactor=1.1,
                                   int minNeighbors=3, int flags=0,
                                   Size minSize=Size(),
                                   Size maxSize=Size(),
                                   bool outputRejectLevels=false );


    bool isOldFormatCascade() const;
    virtual Size getOriginalWindowSize() const;
    int getFeatureType() const;
    bool setImage( const Mat& );

protected:
    //virtual bool detectSingleScale( const Mat& image, int stripCount, Size processingRectSize,
    //                                int stripSize, int yStep, double factor, vector<Rect>& candidates );

    virtual bool detectSingleScale( const Mat& image, int stripCount, Size processingRectSize,
                                    int stripSize, int yStep, double factor, vector<Rect>& candidates,
                                    vector<int>& rejectLevels, vector<double>& levelWeights, bool outputRejectLevels=false);

protected:
    enum { BOOST = 0 };
    enum { DO_CANNY_PRUNING = 1, SCALE_IMAGE = 2,
           FIND_BIGGEST_OBJECT = 4, DO_ROUGH_SEARCH = 8 };

    friend class CascadeClassifierInvoker;

    template<class FEval>
    friend int predictOrdered( CascadeClassifier& cascade, Ptr<FeatureEvaluator> &featureEvaluator, double& weight);

    template<class FEval>
    friend int predictCategorical( CascadeClassifier& cascade, Ptr<FeatureEvaluator> &featureEvaluator, double& weight);

    template<class FEval>
    friend int predictOrderedStump( CascadeClassifier& cascade, Ptr<FeatureEvaluator> &featureEvaluator, double& weight);

    template<class FEval>
    friend int predictCategoricalStump( CascadeClassifier& cascade, Ptr<FeatureEvaluator> &featureEvaluator, double& weight);

    bool setImage( Ptr<FeatureEvaluator>& feval, const Mat& image);
    virtual int runAt( Ptr<FeatureEvaluator>& feval, Point pt, double& weight );

    class Data
    {
    public:
        struct CV_EXPORTS DTreeNode
        {
            int featureIdx;
            float threshold; // for ordered features only
            int left;
            int right;
        };

        struct CV_EXPORTS DTree
        {
            int nodeCount;
        };

        struct CV_EXPORTS Stage
        {
            int first;
            int ntrees;
            float threshold;
        };

        bool read(const FileNode &node);

        bool isStumpBased;

        int stageType;
        int featureType;
        int ncategories;
        Size origWinSize;

        vector<Stage> stages;
        vector<DTree> classifiers;
        vector<DTreeNode> nodes;
        vector<float> leaves;
        vector<int> subsets;
    };

    Data data;
    Ptr<FeatureEvaluator> featureEvaluator;
    Ptr<CvHaarClassifierCascade> oldCascade;

public:
    class CV_EXPORTS MaskGenerator
    {
    public:
        virtual ~MaskGenerator() {}
        virtual cv::Mat generateMask(const cv::Mat& src)=0;
        virtual void initializeMask(const cv::Mat& /*src*/) {};
    };
    void setMaskGenerator(Ptr<MaskGenerator> maskGenerator);
    Ptr<MaskGenerator> getMaskGenerator();

    void setFaceDetectionMaskGenerator();

protected:
    Ptr<MaskGenerator> maskGenerator;
};



class LBPEvaluator : public FeatureEvaluator
{
public:
    struct Feature
    {
        Feature();
        Feature( int x, int y, int _block_w, int _block_h  ) :
        rect(x, y, _block_w, _block_h) {}

        int calc( int offset ) const;
        void updatePtrs( const Mat& sum );
        bool read(const FileNode& node );

        Rect rect; // weight and height for block
        const int* p[16]; // fast
    };

    LBPEvaluator();
    virtual ~LBPEvaluator();

    virtual bool read( const FileNode& node );
    virtual Ptr<FeatureEvaluator> clone() const;
    virtual int getFeatureType() const { return FeatureEvaluator::LBP; }

    virtual bool setImage(const Mat& image, Size _origWinSize);
    virtual bool setWindow(Point pt);

    int operator()(int featureIdx) const
    { return featuresPtr[featureIdx].calc(offset); }
    virtual int calcCat(int featureIdx) const
    { return (*this)(featureIdx); }
protected:
    Size origWinSize;
    Ptr<vector<Feature> > features;
    Feature* featuresPtr; // optimization
    Mat sum0, sum;
    Rect normrect;

    int offset;
};
【Adaboost算法】C++转C, 分类器结构设计

二、开始设计适合自己分类器的数据结构

如下图,因为我们打算使用数组方式存储信息,为避免溢出,首先了解自己分类器的强分类器级数,nodes,leaves等信息,由于我们的分类器是通过opencv训练的,所以可以直接Debug查看分类器信息,或者通过xml文件查看。

【Adaboost算法】C++转C, 分类器结构设计

设计结构体如下:

【Adaboost算法】C++转C, 分类器结构设计
#ifndef    _CP_ADABOOST_
#define    _CP_ADABOOST_
#ifdef   __cplusplus
extern "C"{
#endif  
typedef struct tagCpSize
{
    int iWidth;
    int iHeight;
}CP_SIZE_S;

typedef struct  tagCPDTreeNode
{
    int featureIdx;
    float threshold; // for ordered features only
    int left;
    int right;
}CP_DTREE_NODE_S;

typedef struct  tagCpDTree
{
    int nodeCount;
}CP_DTREE_S;

typedef struct  tagCpStage
{
    int first;
    int ntrees;
    float threshold;
}CP_STAGE_S;

typedef struct tagCPRect
{
    int x;
    int y;
    int width;
    int height;
}CP_RECT_S;

typedef struct tagLBPFeature
{
    CP_RECT_S rect;/*特征位置*/
    int* p[16];/* 特征在积分图中的地址 */
}CP_LBP_FEATURE_S;

typedef struct tagCpClassifier
{
    bool isStumpBased;

    int stageType;
    int featureType;
    int ncategories;
    CP_SIZE_S origWinSize;

    CP_STAGE_S stages[50]; /*强分类器级数*/
    int stagerNum;    
CP_DTREE_S classifiers[
500];
int classfierNum; CP_DTREE_NODE_S nodes[
500];
int nodeNum; CP_LBP_FEATURE_S feature[
500];
int featureNum;
float leaves[1000];
int leaveNum;
int subsets[5000];
int subsetNum; }CP_CLASSIFIER_S; #ifdef __cplusplus }
#endif #endif /* _CP_ADABOOST_ */
【Adaboost算法】C++转C, 分类器结构设计

本文转自风一样的码农博客园博客,原文链接:http://www.cnblogs.com/chenpi/p/5128229.html,如需转载请自行联系原作者
上一篇:Nginx学习之三-ngx_http_request_t结构体


下一篇:利用c语言制作简易计算器