2016-02-25 37 views
0

我正在從30000個隨機生成的功能中學習增強樹。學習僅限於說最好的100個功能。在學習瞭如何從CvBoost對象中提取決策樹使用的特徵的索引之後。使用Adaboost時訪問和修改OpenCV決策樹節點

我這樣做的動機是消除生成所有30000個功能並僅計算將要使用的功能的需求。我已經包含了從CvBoost.save函數生成的yml文件的打印輸出。我想我要的是識別的功能,如深度爲1的決策樹如下圖所示稱爲sample_count值:

trees: 
     - 
     best_tree_idx: -1 
     nodes: 
      - 
       depth: 0 
       sample_count: 11556 
       value: -1.8339875099775065e+00 
       norm_class_idx: 0 
       Tn: 0 
       complexity: 0 
       alpha: 0. 
       node_risk: 0. 
       tree_risk: 0. 
       tree_error: 0. 
       splits: 
        - { var:497, quality:8.6223608255386353e-01, 
         le:5.3123302459716797e+00 } 
      - 
       depth: 1 
       sample_count: 10702 
       value: -1.8339875099775065e+00 
       norm_class_idx: 0 
       Tn: 0 
       complexity: 0 
       alpha: 0. 
       node_risk: 0. 
       tree_risk: 0. 
       tree_error: 0. 
      - 
       depth: 1 
       sample_count: 854 
       value: 1.8339875099775065e+00 
       norm_class_idx: 1 
       Tn: 0 
       complexity: 0 
       alpha: 0. 
       node_risk: 0. 
       tree_risk: 0. 
       tree_error: 0. 

編輯

目前,我有訪問數據下面的代碼:

//Interrogate the Decision Tree. Each element is a Decision Tree, making up the classifer 
    CvSeq* decisionTree = boostDevice.get_weak_predictors(); 

    simplifyFeatureSet(decisionTree, firstOrderROIs); 

這個功能是:

inline void Chnftrs::simplifyFeatureSet(CvSeq* decisionTree, std::vector<boost::tuple<int, cv::Rect> >& rois) 
{ 
    //This variable stores the index of the feature used from rois and a pointer to the split so that the variable there can 
    //be updated when the rois are pruned and reordered. 
    std::vector<boost::tuple<int, CvDTreeSplit* > > featureIdx; 

    //Determine the max depth of the tree 

    printf("Size of boost %d \n", decisionTree->total); 

    for (int i = 0; i < decisionTree->total; i++) 
    { 
      //Get the root of the tree 
      CvBoostTree *tree =0; 
      tree = (CvBoostTree*)cvGetSeqElem(decisionTree, i); 

      if(tree == 0) 
       printf("Tree is NULL\n"); 
      else 
       printf("Tree Addr %ld\n", tree);    

      const CvDTreeNode *root = tree->get_root(); 

      printf("Class_idx %d, Value %f ", root->sample_count, root->value); 

      featureIdx.push_back(boost::tuple<int, CvDTreeSplit*>(root->split->var_idx, root->split)); 

        //Search down the right hand side 
      depthFirstSearch(root->right, featureIdx); 

      //Search down the left hand side 
      depthFirstSearch(root->left, featureIdx); 


    } 
} 

但是,當我嘗試訪問任何根的成員(如root->sample_count)時,出現分段錯誤。除非將CvTreeTrainData.shared設置爲true(默認情況下它爲false),否則CvTree的成員可能無法訪問。指示here

任何幫助將是巨大的

歡呼

彼得

回答

0

好吧,

之所以能夠通過以下對如何CV升壓分類源的方法來編輯決策樹保存並從磁盤讀取。出於某種原因,對於決策樹類型對象,cvGetSeqElem()不會從傳遞給它的CvSeq對象返回有效指針。

爲了獲得決策樹的副本,CvSeqReader和宏cvStartReadSeq工作得最好。宏CV_READ_SEQ_ELEM()似乎在循環過程中獲得Seq中的下一棵樹。:

CvSeqReader reader; 
    cvStartReadSeq(weak, &reader); 

    for (int i = 0; i < weak->total; i++) 
     { 

      CvBoostTree* tree; 
      CV_READ_SEQ_ELEM(tree, reader); 

       const CvDTreeNode *root = 0; 
       root = tree->get_root(); 

       printf("Root Split VarIdx : %d c: %f, ", root->split->var_idx, root->split->ord.c); 

       featureIdx.push_back(boost::tuple<int, CvDTreeSplit*>(root->split->var_idx, root->split)); 

       //Search down the right hand side 
       depthFirstSearch(root->right, featureIdx); 

       //Search down the left hand side 
       depthFirstSearch(root->left, featureIdx); 


     }