}
}
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 inn_buf(sample_count*(2*sizeof(int) + sizeof(float)));
for( vi = 0; vi < workVarCount; vi++ )
{
int ci = get_var_type(vi);
if( ci >= 0 || vi >= var_count )
{
int num_valid = 0;
const int* src = CvDTreeTrainData::get_cat_var_data( data_root, vi, (int*)(uchar*)inn_buf );
if (is_buf_16u)
{
unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() +
vi*sample_count + root->offset);
for( i = 0; i < count; i++ )
{
int val = src[sidx[i]];
udst[i] = (unsigned short)val;
num_valid += val >= 0;
}
}
else
{
int* idst = buf->data.i + root->buf_idx*get_length_subbuf() +
vi*sample_count + root->offset;
for( i = 0; i < count; i++ )
{
int val = src[sidx[i]];
idst[i] = val;
num_valid += val >= 0;
}
}
if( vi < var_count )
root->set_num_valid(vi, num_valid);
}
else
{
int *src_idx_buf = (int*)(uchar*)inn_buf;
float *src_val_buf = (float*)(src_idx_buf + sample_count);
int* sample_indices_buf = (int*)(src_val_buf + sample_count);
const int* src_idx = 0;
const float* src_val = 0;
get_ord_var_data( data_root, vi, src_val_buf, src_idx_buf, &src_val, &src_idx, sample_indices_buf );
int j = 0, idx, count_i;
int num_valid = data_root->get_num_valid(vi);
if (is_buf_16u)
{
unsigned short* udst_idx = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() +
vi*sample_count + data_root->offset);
for( i = 0; i < num_valid; i++ )
{
idx = src_idx[i];
count_i = co[idx*2];
if( count_i )
for( cur_ofs = co[idx*2+1]; count_i > 0; count_i--, j++, cur_ofs++ )
udst_idx[j] = (unsigned short)cur_ofs;
}
root->set_num_valid(vi, j);
for( ; i < sample_count; i++ )
{
idx = src_idx[i];
count_i = co[idx*2];
if( count_i )
for( cur_ofs = co[idx*2+1]; count_i > 0; count_i--, j++, cur