• 【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_ */
  • 相关阅读:
    Shell判断文件或目录是否存在
    linux使用wpa_supplicant手动配置wifi
    ubuntu更换apt源后依然搜索旧软件源下载失败问题
    在Ubuntu下解决E: 无法对目录 /var/lib/apt/lists/ 加锁的问题
    Bash中判断一个命令的输出结果是否为空
    [解决]/bin/bash^M: bad interpreter: No such file or directory
    【转】 使用 NetworkManager 命令行工具 nmcli
    【转】wpa_supplicant及wpa_cli使用方法
    [RK3288] Vendor Storage区域知识及探讨
    安装oracle 时“[INS-30014]无法检查指定的位置是否位于 CFS上”问题
  • 原文地址:https://www.cnblogs.com/chenpi/p/5128229.html
Copyright © 2020-2023  润新知