OpenCV的softcascade代码解读(3)

//do_train()的核心函数如下:
CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx )
{
    CvDTreeNode* root = 0;
    CvMat* isubsample_idx = 0;
    CvMat* subsample_co = 0;

bool isMakeRootCopy = true;

CV_FUNCNAME( "CvDTreeTrainData::subsample_data" );

__BEGIN__;

if( !data_root )
        CV_ERROR( CV_StsError, "No training data has been set" );

if( _subsample_idx )
    {
        CV_CALL( isubsample_idx = cvPreprocessIndexArray( _subsample_idx, sample_count )); //如果已训练出了一些弱分类器,则在这里进行一定的处理。_subsample_idx只能是一个行向量或者是列向量
                       //_subsample_idx中保存的可能是选中的样本的索引,也可能长度为sample_count的表明选择的'0''1'掩膜,但
                       //输出只包含了选择的样本的编号,并且进行了排序。
        if( isubsample_idx->cols + isubsample_idx->rows - 1 == sample_count ) //isubsample_idx是一个指向行向量或者列向量的指针,这里验证元素个数与样本数是否相等。
        {
            const int* sidx = isubsample_idx->data.i;
            for( int i = 0; i < sample_count; i++ )
            {
                if( sidx[i] != i )
                {
                    isMakeRootCopy = false;  //若尚无任何弱分类器,则'isMakeRootCopy = true',
                    break;
                }
            }
        }
        else
            isMakeRootCopy = false;
    }

if( isMakeRootCopy )
    {
        // make a copy of the root node
        CvDTreeNode temp;
        int i;
        root = new_node( 0, 1, 0, 0 );
        temp = *root;
        *root = *data_root;
        root->num_valid = temp.num_valid;
        if( root->num_valid )
        {
            for( i = 0; i < var_count; i++ )
                root->num_valid[i] = data_root->num_valid[i];
        }
        root->cv_Tn = temp.cv_Tn;
        root->cv_node_risk = temp.cv_node_risk;
        root->cv_node_error = temp.cv_node_error;
    }
    else
    {
        int* sidx = isubsample_idx->data.i;
        // co - array of count/offset pairs (to handle duplicated values in _subsample_idx)
        int* co, cur_ofs = 0;
        int vi, i;
        int workVarCount = get_work_var_count(); //得到已使用的特征个数?
        int count = isubsample_idx->rows + isubsample_idx->cols - 1; //该弱分类器判断为正的样本个数

root = new_node( 0, count, 1, 0 );

CV_CALL( subsample_co = cvCreateMat( 1, sample_count*2, CV_32SC1 ));
        cvZero( subsample_co );
        co = subsample_co->data.i;
        for( i = 0; i < count; i++ )
            co[sidx[i]*2]++;
        for( i = 0; i < sample_count; i++ )
        {
            if( co[i*2] )
            {
                co[i*2+1] = cur_ofs;
                cur_ofs += co[i*2];
            }
            else
                co[i*2+1] = -1;
        }

cv::AutoBuffer<uchar> inn_buf(sample_count*(2*sizeof(int) + sizeof(float)));
        for( vi = 0; vi < workVarCount; vi++ )
        {
            int ci = get_var_type(vi);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/b28fd9f04c615ef47ca5ae9f988b73c3.html