zoukankan      html  css  js  c++  java
  • 【Adaboost算法】C++转C, 分类器结构设计

    一、参考OpenCV的CascadeClassifier类LBPEvaluator类

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

    复制代码
    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;
    };
    复制代码

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

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

    设计结构体如下:

    复制代码
    #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_ */
    复制代码

    本文转自风一样的码农博客园博客,原文链接:http://www.cnblogs.com/chenpi/p/5128229.html,如需转载请自行联系原作者
  • 相关阅读:
    xls与csv文件的区别
    青音,经典爱情语录
    win7用户账户自动登录方法汇总
    How to using Procedure found Lead Blocker
    FTS(3) BSD 库函数手册 遍历文件夹(二)
    FTS(3) BSD 库函数手册 遍历文件夹(一)
    DisplayMetrics类 获取手机显示屏的基本信息 包括尺寸、密度、字体缩放等信息
    About App Distribution 关于应用发布
    FTS(3) 遍历文件夹实例
    OpenCV 2.1.0 with Visual Studio 2008
  • 原文地址:https://www.cnblogs.com/twodog/p/12138203.html
Copyright © 2011-2022 走看看