cascade.xml参数解析

转载自: http://blog.csdn.net/wuxiaoyao12/article/details/48088999

上图显示的参数,大多与opencv_traincascade.exe的输入参数已知。其中maxCatCount和featSize定义如下

   maxCatCount:int maxCatCount; // 0 in case of numerical features
  featSize:int featSize; // 1 in case of simple features (HAAR, LBP) and N_BINS(9)*N_CELLS(4) in case of Dalal's HOG features

feature结构对于上两值默认的是:

        CvFeatureParams::CvFeatureParams() : maxCatCount( 0 ), featSize( 1 ) {...};

其中

      LBP:maxCatCount = 256;

      HOG:featSize = N_BINS * N_CELLS;

其他情况均用默认值。


关于maxWeakCountstageThresholdweakClassifiers,如下:

  1. void CvCascadeBoost::write( FileStorage &fs, const Mat& featureMap ) const  
  2. {  
  3.     CvCascadeBoostTree* weakTree;  
  4.     fs << CC_WEAK_COUNT << weak->total;                  //弱分类器总数  
  5.     fs << CC_STAGE_THRESHOLD << threshold;               //见后续补充  
  6.     fs << CC_WEAK_CLASSIFIERS << "[";  
  7.     forint wi = 0; wi < weak->total; wi++)  
  8.     {  
  9.         weakTree = *((CvCascadeBoostTree**) cvGetSeqElem( weak, wi ));  
  10.         weakTree->write( fs, featureMap );  
  11.     }  
  12.     fs << "]";  
  13. }  
关于weakClassifiers的internalNodesleafValues参数,如下:
  1. void CvCascadeBoostTree::write( FileStorage &fs, const Mat& featureMap )  
  2. {  
  3.     int maxCatCount = ((CvCascadeBoostTrainData*)data)->featureEvaluator->getMaxCatCount();  
  4.     int subsetN = (maxCatCount + 31)/32;  
  5.     queue<CvDTreeNode*> internalNodesQueue;  
  6.     int size = (int)pow( 2.f, (float)ensemble->get_params().max_depth);  
  7.     Ptr<float> leafVals = new float[size];  
  8.     int leafValIdx = 0;  
  9.     int internalNodeIdx = 1;  
  10.     CvDTreeNode* tempNode;  
  11.   
  12.     CV_DbgAssert( root );  
  13.     internalNodesQueue.push( root );  
  14.   
  15.     fs << "{";  
  16.     fs << CC_INTERNAL_NODES << "[:";  
  17.     while (!internalNodesQueue.empty())  
  18.     {  
  19.         tempNode = internalNodesQueue.front();  
  20.         CV_Assert( tempNode->left ); //左分支存在  
  21.         if ( !tempNode->left->left && !tempNode->left->right) // left node is leaf 左分支是叶子节点  
  22.         {  
  23.             leafVals[-leafValIdx] = (float)tempNode->left->value;  
  24.             fs << leafValIdx-- ;      //0 -1 -2...  
  25.         }  
  26.         else                         //左分支不是叶子节点  
  27.         {  
  28.             internalNodesQueue.push( tempNode->left );  
  29.             fs << internalNodeIdx++; //1 2 3...  
  30.         }  
  31.         CV_Assert( tempNode->right );  //右分支存在  
  32.         if ( !tempNode->right->left && !tempNode->right->right) // right node is leaf 右分支是叶子节点  
  33.         {  
  34.             leafVals[-leafValIdx] = (float)tempNode->right->value;  
  35.             fs << leafValIdx--;     //0,-1,-2...  
  36.         }  
  37.         else//右分支不是叶子节点  
  38.         {  
  39.             internalNodesQueue.push( tempNode->right );  
  40.             fs << internalNodeIdx++; //1 2 3...  
  41.         }  
  42.         int fidx = tempNode->split->var_idx; //var_idx:分裂中所用到的变量的索引  
  43.         fidx = featureMap.empty() ? fidx : featureMap.at<int>(0, fidx);  
  44.         fs << fidx;  
  45.         if ( !maxCatCount )  
  46.             fs << tempNode->split->ord.c; //c:用在数值变量的分裂上的阈值。规则如下:如果var_value<c,那么next_node<-left,否则next_node<-right。  
  47.         else  
  48.             forint i = 0; i < subsetN; i++ )  
  49.                 fs << tempNode->split->subset[i];//subset:二值集合,用在在类别向量的分裂上。规则如下:如果var_value在subset里,那么next_node<-left,否则next_node<-right。  
  50.         internalNodesQueue.pop();  
  51.     }  
  52.     fs << "]"// CC_INTERNAL_NODES  
  53.   
  54.     fs << CC_LEAF_VALUES << "[:";  
  55.     for (int ni = 0; ni < -leafValIdx; ni++)  
  56.         fs << leafVals[ni];    //即从上面得到的节点value  
  57.     fs << "]"// CC_LEAF_VALUES  
  58.     fs << "}";  
  59. }  
:internalNodes中四个变量代表一个node,分别为node中的left/right标记、特征池中的ID和threshold。leafValues中两个变量代表一个node,分别为left leaf的值和right leaf的值。

补充threshold

  1. int i, count = data->sample_count, nz_count = 0;  
  2. double sum, threshold;  
  3.   
  4. if( params.weight_trim_rate <= 0. || params.weight_trim_rate >= 1. )  
  5.     EXIT;  
  6.   
  7. // use weak_eval as temporary buffer for sorted weights  
  8. cvCopy( weights, weak_eval );  
  9.   
  10. icvSort_64f( weak_eval->data.db, count, 0 );  
  11.   
  12. // as weight trimming(调整) occurs immediately after updating the weights,  
  13. // where they are renormalized, we assume that the weight sum = 1.  
  14. sum = 1. - params.weight_trim_rate;  
  15.   
  16. for( i = 0; i < count; i++ )  
  17. {  
  18.     double w = weak_eval->data.db[i];  
  19.     if( sum <= 0 )  
  20.         break;  
  21.     sum -= w;  
  22. }  
  23.   
  24. threshold = i < count ? weak_eval->data.db[i] : DBL_MAX;  


关于features

  1. void _writeFeatures( const std::vector<Feature> features, cv::FileStorage &fs, const cv::Mat& featureMap )  
  2. {  
  3.     fs << FEATURES << "[";  
  4.     const cv::Mat_<int>& featureMap_ = (const cv::Mat_<int>&)featureMap;  
  5.     for ( int fi = 0; fi < featureMap.cols; fi++ )              //个数即featureMap.cols  
  6.         if ( featureMap_(0, fi) >= 0 )  
  7.         {  
  8.             fs << "{";  
  9.             features[fi].write( fs );  
  10.             fs << "}";  
  11.         }  
  12.     fs << "]";  
  13. }  
其中的rects
  1. void CvHaarEvaluator::Feature::write( FileStorage &fs ) const  
  2. {  
  3.     fs << CC_RECTS << "[";  
  4.     forint ri = 0; ri < CV_HAAR_FEATURE_MAX && rect[ri].r.width != 0; ++ri )   //CV_HAAR_FEATURE_MAX=3,上图就表示了我们只用了一个特征  
  5.     {  
  6.         fs << "[:" << rect[ri].r.x << rect[ri].r.y <<  
  7.             rect[ri].r.width << rect[ri].r.height << rect[ri].weight << "]";  
  8.     }  
  9.     fs << "]" << CC_TILTED << tilted; //bool型  
  10. }  
说明:opencv learning书中有提到(550页),我们使用1个特征(一个只有一个分裂的树),最多3个。

类haar特征的tilted取法如下(包括特征计算)

  1. void CvHaarEvaluator::generateFeatures()  
  2. {  
  3.     int mode = ((const CvHaarFeatureParams*)((CvFeatureParams*)featureParams))->mode;  
  4.     int offset = winSize.width + 1;  
  5.     forint x = 0; x < winSize.width; x++ )  
  6.     {  
  7.         forint y = 0; y < winSize.height; y++ )  
  8.         {  
  9.             forint dx = 1; dx <= winSize.width; dx++ )  
  10.             {  
  11.                 forint dy = 1; dy <= winSize.height; dy++ )  
  12.                 {  
  13.                     // haar_x2  
  14.                     if ( (x+dx*2 <= winSize.width) && (y+dy <= winSize.height) )  
  15.                     {  
  16.                         features.push_back( Feature( offset, false,x,    y, dx*2, dy, -1,//开始tilted都是false   
  17.                             x+dx, y, dx  , dy, +2 ) );  
  18.                     }  
  19.                     // haar_y2  
  20.                     if ( (x+dx <= winSize.width) && (y+dy*2 <= winSize.height) )  
  21.                     {  
  22.                         features.push_back( Feature( offset, false,  
  23.                             x,    y, dx, dy*2, -1,  
  24.                             x, y+dy, dx, dy,   +2 ) );  
  25.                     }  
  26.                     // haar_x3  
  27.                     if ( (x+dx*3 <= winSize.width) && (y+dy <= winSize.height) )  
  28.                     {  
  29.                         features.push_back( Feature( offset, false,  
  30.                             x,    y, dx*3, dy, -1,  
  31.                             x+dx, y, dx  , dy, +3 ) );  
  32.                     }  
  33.                     // haar_y3  
  34.                     if ( (x+dx <= winSize.width) && (y+dy*3 <= winSize.height) )  
  35.                     {  
  36.                         features.push_back( Feature( offset, false,  
  37.                             x, y,    dx, dy*3, -1,  
  38.                             x, y+dy, dx, dy,   +3 ) );  
  39.                     }  
  40.                     if( mode != CvHaarFeatureParams::BASIC )  
  41.                     {  
  42.                         // haar_x4  
  43.                         if ( (x+dx*4 <= winSize.width) && (y+dy <= winSize.height) )  
  44.                         {  
  45.                             features.push_back( Feature( offset, false,  
  46.                                 x,    y, dx*4, dy, -1,  
  47.                                 x+dx, y, dx*2, dy, +2 ) );  
  48.                         }  
  49.                         // haar_y4  
  50.                         if ( (x+dx <= winSize.width ) && (y+dy*4 <= winSize.height) )  
  51.                         {  
  52.                             features.push_back( Feature( offset, false,  
  53.                                 x, y,    dx, dy*4, -1,  
  54.                                 x, y+dy, dx, dy*2, +2 ) );  
  55.                         }  
  56.                     }  
  57.                     // x2_y2  
  58.                     if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) )  
  59.                     {  
  60.                         features.push_back( Feature( offset, false,  
  61.                             x,    y,    dx*2, dy*2, -1,  
  62.                             x,    y,    dx,   dy,   +2,  
  63.                             x+dx, y+dy, dx,   dy,   +2 ) );  
  64.                     }  
  65.                     if (mode != CvHaarFeatureParams::BASIC)  
  66.                     {  
  67.                         if ( (x+dx*3 <= winSize.width) && (y+dy*3 <= winSize.height) )  
  68.                         {  
  69.                             features.push_back( Feature( offset, false,  
  70.                                 x   , y   , dx*3, dy*3, -1,  
  71.                                 x+dx, y+dy, dx  , dy  , +9) );  
  72.                         }  
  73.                     }  
  74.                     if (mode == CvHaarFeatureParams::ALL)  
  75.                     {  
  76.                         // tilted haar_x2  
  77.                         if ( (x+2*dx <= winSize.width) && (y+2*dx+dy <= winSize.height) && (x-dy>= 0) )  
  78.                         {  
  79.                             features.push_back( Feature( offset, true,             //这里开始tilted是true  
  80.                                 x, y, dx*2, dy, -1,  
  81.                                 x, y, dx,   dy, +2 ) );  
  82.                         }  
  83.                         // tilted haar_y2  
  84.                         if ( (x+dx <= winSize.width) && (y+dx+2*dy <= winSize.height) && (x-2*dy>= 0) )  
  85.                         {  
  86.                             features.push_back( Feature( offset, true,  
  87.                                 x, y, dx, 2*dy, -1,  
  88.                                 x, y, dx, dy,   +2 ) );  
  89.                         }  
  90.                         // tilted haar_x3  
  91.                         if ( (x+3*dx <= winSize.width) && (y+3*dx+dy <= winSize.height) && (x-dy>= 0) )  
  92.                         {  
  93.                             features.push_back( Feature( offset, true,  
  94.                                 x,    y,    dx*3, dy, -1,  
  95.                                 x+dx, y+dx, dx,   dy, +3 ) );  
  96.                         }  
  97.                         // tilted haar_y3  
  98.                         if ( (x+dx <= winSize.width) && (y+dx+3*dy <= winSize.height) && (x-3*dy>= 0) )  
  99.                         {  
  100.                             features.push_back( Feature( offset, true,  
  101.                                 x,    y,    dx, 3*dy, -1,  
  102.                                 x-dy, y+dy, dx, dy,   +3 ) );  
  103.                         }  
  104.                         // tilted haar_x4  
  105.                         if ( (x+4*dx <= winSize.width) && (y+4*dx+dy <= winSize.height) && (x-dy>= 0) )  
  106.                         {  
  107.                             features.push_back( Feature( offset, true,  
  108.                                 x,    y,    dx*4, dy, -1,  
  109.                                 x+dx, y+dx, dx*2, dy, +2 ) );  
  110.                         }  
  111.                         // tilted haar_y4  
  112.                         if ( (x+dx <= winSize.width) && (y+dx+4*dy <= winSize.height) && (x-4*dy>= 0) )  
  113.                         {  
  114.                             features.push_back( Feature( offset, true,  
  115.                                 x,    y,    dx, 4*dy, -1,  
  116.                                 x-dy, y+dy, dx, 2*dy, +2 ) );  
  117.                         }  
  118.                     }  
  119.                 }  
  120.             }  
  121.         }  
  122.     }  
  123.     numFeatures = (int)features.size();  
  124. }  
其中的Feature构造如下:
  1. CvHaarEvaluator::Feature::Feature( int offset, bool _tilted,  
  2.                                           int x0, int y0, int w0, int h0, float wt0,  
  3.                                           int x1, int y1, int w1, int h1, float wt1,  
  4.                                           int x2, int y2, int w2, int h2, float wt2 )  
  5. {  
  6.     tilted = _tilted;  
  7.   
  8.     rect[0].r.x = x0;  
  9.     rect[0].r.y = y0;  
  10.     rect[0].r.width  = w0;  
  11.     rect[0].r.height = h0;  
  12.     rect[0].weight   = wt0;  
  13.   
  14.     rect[1].r.x = x1;  
  15.     rect[1].r.y = y1;  
  16.     rect[1].r.width  = w1;  
  17.     rect[1].r.height = h1;  
  18.     rect[1].weight   = wt1;  
  19.   
  20.     rect[2].r.x = x2;  
  21.     rect[2].r.y = y2;  
  22.     rect[2].r.width  = w2;  
  23.     rect[2].r.height = h2;  
  24.     rect[2].weight   = wt2;  
  25.   
  26.     if( !tilted )  
  27.     {  
  28.         forint j = 0; j < CV_HAAR_FEATURE_MAX; j++ )  
  29.         {  
  30.             if( rect[j].weight == 0.0F )  
  31.                 break;  
  32.             CV_SUM_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )  
  33.         }  
  34.     }  
  35.     else  
  36.     {  
  37.         forint j = 0; j < CV_HAAR_FEATURE_MAX; j++ )  
  38.         {  
  39.             if( rect[j].weight == 0.0F )  
  40.                 break;  
  41.             CV_TILTED_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )  
  42.         }  
  43.     }  
  44. }  

另外,是不是觉得参数输入与输出不配,其实如下:(人家是有默认输入的)

  1. Feature( int offset, bool _tilted,  
  2.           int x0, int y0, int w0, int h0, float wt0,  
  3.           int x1, int y1, int w1, int h1, float wt1,  
  4.           int x2 = 0, int y2 = 0, int w2 = 0, int h2 = 0, float wt2 = 0.0F );  
其中的CV_SUM_OFFSETSCV_TILTED_OFFSETS如下:
  1. #define CV_SUM_OFFSETS( p0, p1, p2, p3, rect, step )                      \  
  2.     /* (x, y) */                                                          \  
  3.     (p0) = (rect).x + (step) * (rect).y;                                  \  
  4.     /* (x + w, y) */                                                      \  
  5.     (p1) = (rect).x + (rect).width + (step) * (rect).y;                   \  
  6.     /* (x, y + h) */                                                      \  
  7.     (p2) = (rect).x + (step) * ((rect).y + (rect).height);                \  
  8.     /* (x + w, y + h) */                                                  \  
  9.     (p3) = (rect).x + (rect).width + (step) * ((rect).y + (rect).height);  
  10.   
  11. #define CV_TILTED_OFFSETS( p0, p1, p2, p3, rect, step )                   \  
  12.     /* (x, y) */                                                          \  
  13.     (p0) = (rect).x + (step) * (rect).y;                                  \  
  14.     /* (x - h, y + h) */                                                  \  
  15.     (p1) = (rect).x - (rect).height + (step) * ((rect).y + (rect).height);\  
  16.     /* (x + w, y + w) */                                                  \  
  17.     (p2) = (rect).x + (rect).width + (step) * ((rect).y + (rect).width);  \  
  18.     /* (x + w - h, y + w + h) */                                          \  
  19.     (p3) = (rect).x + (rect).width - (rect).height                        \  
  20.            + (step) * ((rect).y + (rect).width + (rect).height);  

Feature类组成如下:

  1. class Feature  
  2.     {  
  3.     public:  
  4.         Feature();  
  5.         Feature( int offset, bool _tilted,  
  6.             int x0, int y0, int w0, int h0, float wt0,  
  7.             int x1, int y1, int w1, int h1, float wt1,  
  8.             int x2 = 0, int y2 = 0, int w2 = 0, int h2 = 0, float wt2 = 0.0F );  
  9.         float calc( const cv::Mat &sum, const cv::Mat &tilted, size_t y) const;  
  10.         void write( cv::FileStorage &fs ) const;  
  11.   
  12.         bool  tilted;  
  13.         struct  
  14.         {  
  15.             cv::Rect r;  
  16.             float weight;  
  17.         } rect[CV_HAAR_FEATURE_MAX];  
  18.   
  19.         struct  
  20.         {  
  21.             int p0, p1, p2, p3;  
  22.         } fastRect[CV_HAAR_FEATURE_MAX];  
  23.     };  
  1. inline float CvHaarEvaluator::operator()(int featureIdx, int sampleIdx) const  
  2. {  
  3.     float nf = normfactor.at<float>(0, sampleIdx);  
  4.     return !nf ? 0.0f : (features[featureIdx].calc( sum, tilted, sampleIdx)/nf);  
  5. }  
  6.   
  7. inline float CvHaarEvaluator::Feature::calc( const cv::Mat &_sum, const cv::Mat &_tilted, size_t y) const  
  8. {  
  9.     const int* img = tilted ? _tilted.ptr<int>((int)y) : _sum.ptr<int>((int)y);  
  10.     float ret = rect[0].weight * (img[fastRect[0].p0] - img[fastRect[0].p1] - img[fastRect[0].p2] + img[fastRect[0].p3] ) +  
  11.         rect[1].weight * (img[fastRect[1].p0] - img[fastRect[1].p1] - img[fastRect[1].p2] + img[fastRect[1].p3] );  
  12.     if( rect[2].weight != 0.0f )  
  13.         ret += rect[2].weight * (img[fastRect[2].p0] - img[fastRect[2].p1] - img[fastRect[2].p2] + img[fastRect[2].p3] );  
  14.     return ret;  
  15. }  



补充

HOG计算:

  1. void CvHOGEvaluator::generateFeatures()  
  2. {  
  3.     int offset = winSize.width + 1;  
  4.     Size blockStep;  
  5.     int x, y, t, w, h;  
  6.   
  7.     for (t = 8; t <= winSize.width/2; t+=8) //t = size of a cell. blocksize = 4*cellSize  
  8.     {  
  9.         blockStep = Size(4,4);  
  10.         w = 2*t; //width of a block  
  11.         h = 2*t; //height of a block  
  12.         for (x = 0; x <= winSize.width - w; x += blockStep.width)  
  13.         {  
  14.             for (y = 0; y <= winSize.height - h; y += blockStep.height)  
  15.             {  
  16.                 features.push_back(Feature(offset, x, y, t, t));  
  17.             }  
  18.         }  
  19.         w = 2*t;  
  20.         h = 4*t;  
  21.         for (x = 0; x <= winSize.width - w; x += blockStep.width)  
  22.         {  
  23.             for (y = 0; y <= winSize.height - h; y += blockStep.height)  
  24.             {  
  25.                 features.push_back(Feature(offset, x, y, t, 2*t));  
  26.             }  
  27.         }  
  28.         w = 4*t;  
  29.         h = 2*t;  
  30.         for (x = 0; x <= winSize.width - w; x += blockStep.width)  
  31.         {  
  32.             for (y = 0; y <= winSize.height - h; y += blockStep.height)  
  33.             {  
  34.                 features.push_back(Feature(offset, x, y, 2*t, t));  
  35.             }  
  36.         }  
  37.     }  
  38.   
  39.     numFeatures = (int)features.size();  
  40. }  
  1. CvHOGEvaluator::Feature::Feature( int offset, int x, int y, int cellW, int cellH )  
  2. {  
  3.     rect[0] = Rect(x, y, cellW, cellH); //cell0  
  4.     rect[1] = Rect(x+cellW, y, cellW, cellH); //cell1  
  5.     rect[2] = Rect(x, y+cellH, cellW, cellH); //cell2  
  6.     rect[3] = Rect(x+cellW, y+cellH, cellW, cellH); //cell3  
  7.   
  8.     for (int i = 0; i < N_CELLS; i++)  
  9.     {  
  10.         CV_SUM_OFFSETS(fastRect[i].p0, fastRect[i].p1, fastRect[i].p2, fastRect[i].p3, rect[i], offset);  
  11.     }  
  12. }  
LBP计算:
  1. void CvLBPEvaluator::generateFeatures()  
  2. {  
  3.     int offset = winSize.width + 1;  
  4.     forint x = 0; x < winSize.width; x++ )  
  5.         forint y = 0; y < winSize.height; y++ )  
  6.             forint w = 1; w <= winSize.width / 3; w++ )  
  7.                 forint h = 1; h <= winSize.height / 3; h++ )  
  8.                     if ( (x+3*w <= winSize.width) && (y+3*h <= winSize.height) )  
  9.                         features.push_back( Feature(offset, x, y, w, h ) );  
  10.     numFeatures = (int)features.size();  
  11. }  
  1. CvLBPEvaluator::Feature::Feature( int offset, int x, int y, int _blockWidth, int _blockHeight )  
  2. {  
  3.     Rect tr = rect = cvRect(x, y, _blockWidth, _blockHeight);  
  4.     CV_SUM_OFFSETS( p[0], p[1], p[4], p[5], tr, offset )  
  5.     tr.x += 2*rect.width;  
  6.     CV_SUM_OFFSETS( p[2], p[3], p[6], p[7], tr, offset )  
  7.     tr.y +=2*rect.height;  
  8.     CV_SUM_OFFSETS( p[10], p[11], p[14], p[15], tr, offset )  
  9.     tr.x -= 2*rect.width;  
  10.     CV_SUM_OFFSETS( p[8], p[9], p[12], p[13], tr, offset )  
  11. }  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值