CV_BOOST_IMPL
CvClassifier* cvCreateStumpClassifier( CvMat* trainData, //训练样本的数据,包含图像大小。数量,类别,权重等
int flags, //0表示矩阵的列是训练样本。1表示行是训练样本
CvMat* trainClasses, //表示训练样本的类别矩阵
CvMat* /*typeMask*/,
CvMat* missedMeasurementsMask,
CvMat* compIdx, //特征序列
CvMat* sampleIdx, //训练样本排序后的寻列
CvMat* weights, //训练样本的权重矩阵
CvClassifierTrainParams* trainParams//训练參数
)
{
CvStumpClassifier* stump = NULL;
int m = 0; /* 样本数量number of samples */
int n = 0; /* 特征数量number of components */
uchar* data = NULL;
int cstep = 0; //一个特征(component)在水平方向上的长度,即是水平方向上所占字节数
int sstep = 0; //一个样本(sample)在水平方向上的长度,即是水平方向上所占字节数(这两个參数我看了非常长时间才看出来)
uchar* ydata = NULL;
int ystep = 0;
uchar* idxdata = NULL;
int idxstep = 0;
int l = 0; /* number of indices */
uchar* wdata = NULL;
int wstep = 0; int* idx = NULL;
int i = 0; float sumw = FLT_MAX;
float sumwy = FLT_MAX;
float sumwyy = FLT_MAX; CV_Assert( trainData != NULL );
CV_Assert( CV_MAT_TYPE( trainData->type ) == CV_32FC1 );
CV_Assert( trainClasses != NULL );
CV_Assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 );
CV_Assert( missedMeasurementsMask == NULL );
CV_Assert( compIdx == NULL );
CV_Assert( weights != NULL );
CV_Assert( CV_MAT_TYPE( weights->type ) == CV_32FC1 );
CV_Assert( trainParams != NULL ); data = trainData->data.ptr;
if( CV_IS_ROW_SAMPLE( flags ) )//当traindata训练样本是按行排列,一行表示一个训练样本在不同特征下的特征值
{
cstep = CV_ELEM_SIZE( trainData->type );
sstep = trainData->step;
m = trainData->rows; //行数表示样本数量
n = trainData->cols; //列数表示特征的个数
}
else //当traindata训练样本是按列排列,一列表示一个训练样本在不同特征下的特征值
{
sstep = CV_ELEM_SIZE( trainData->type );
cstep = trainData->step;
m = trainData->cols; //列数表示样本的数量
n = trainData->rows; //行数表示特征的个数
} ydata = trainClasses->data.ptr;
if( trainClasses->rows == 1 )
{
assert( trainClasses->cols == m );
ystep = CV_ELEM_SIZE( trainClasses->type );
}
else
{
assert( trainClasses->rows == m );
ystep = trainClasses->step;
} wdata = weights->data.ptr;
if( weights->rows == 1 )
{
assert( weights->cols == m );
wstep = CV_ELEM_SIZE( weights->type );
}
else
{
assert( weights->rows == m );
wstep = weights->step;
} l = m;
if( sampleIdx != NULL )
{
assert( CV_MAT_TYPE( sampleIdx->type ) == CV_32FC1 ); idxdata = sampleIdx->data.ptr;
if( sampleIdx->rows == 1 )
{
l = sampleIdx->cols;
idxstep = CV_ELEM_SIZE( sampleIdx->type );
}
else
{
l = sampleIdx->rows;
idxstep = sampleIdx->step;
}
assert( l <= m );
} idx = (int*) cvAlloc( l * sizeof( int ) );//为idx分配内存
stump = (CvStumpClassifier*) cvAlloc( sizeof( CvStumpClassifier) );//为stump分配内存 /* START */
memset( (void*) stump, 0, sizeof( CvStumpClassifier ) );//stump内存初始化为零 stump->eval = cvEvalStumpClassifier;
stump->tune = NULL;
stump->save = NULL;
stump->release = cvReleaseStumpClassifier; stump->lerror = FLT_MAX;
stump->rerror = FLT_MAX;
stump->left = 0.0F;
stump->right = 0.0F; /* copy indices */
if( sampleIdx != NULL )
{
for( i = 0; i < l; i++ )
{
idx[i] = (int) *((float*) (idxdata + i*idxstep));
}
}
else
{
for( i = 0; i < l; i++ )
{
idx[i] = i;
}
} for( i = 0; i < n; i++ ) //遍历全部特征
{
CvValArray va; va.data = data + i * ((size_t) cstep);
va.step = sstep;
icvSortIndexedValArray_32s( idx, l, &va );//对数据进行排序
if( findStumpThreshold_32s[(int) ((CvStumpTrainParams*) trainParams)->error]
//该error是计算不纯度的方式,包含四种,各自是:熵不纯度,吉尼不纯度,错分类不纯度,和最小二乘不纯度
( data + i * ((size_t) cstep), sstep,
wdata, wstep, ydata, ystep, (uchar*) idx, sizeof( int ), l,
&(stump->lerror), &(stump->rerror),
&(stump->threshold), &(stump->left), &(stump->right),
&sumw, &sumwy, &sumwyy ) ) //寻找树桩分类器的阈值
{
stump->compidx = i;
}
} /* for each component */ /* END */ cvFree( &idx ); if( ((CvStumpTrainParams*) trainParams)->type == CV_CLASSIFICATION_CLASS )
{
stump->left = 2.0F * (stump->left >= 0.5F) - 1.0F;
stump->right = 2.0F * (stump->right >= 0.5F) - 1.0F;
} return (CvClassifier*) stump;
}

cvCreateStumpClassifier的更多相关文章

  1. opencv源代码之中的一个:cvboost.cpp

    我使用的是opencv2.4.9.安装后.我的cvboost..cpp文件的路径是........\opencv\sources\apps\haartraining\cvboost.cpp.研究源代码 ...

  2. 史上最全opencv源代码解读,opencv源代码具体解读文件夹

    本博原创,如有转载请注明本博网址http://blog.csdn.net/ding977921830/article/details/46799043. opencv源代码主要是基于adaboost算 ...

随机推荐

  1. mysql连接池模块

    如果不想程序在查询数据时卡死或等待过长时间,一般不推荐在node中开启一个连接后全部查询都用这个链接并且不关闭.因为node里面的mysql不像php里的那样会在完成查询后断开,只要不主动断开,连接一 ...

  2. 基于Prometheus的Pushgateway实战

    一.Pushgateway 简介 Pushgateway 是 Prometheus 生态中一个重要工具,使用它的原因主要是: Prometheus 采用 pull 模式,可能由于不在一个子网或者防火墙 ...

  3. vue组件库(一):前期准备工作

    前言 将近期项目内自行开发一个vue组件,做个总结,记录下自己的思维过程~~~ 正文 接到这个任务后,还是要做些准备工作的. 主要内容如下: 1.优化下所在团队前端开发流程 服务器搭建gitlab,采 ...

  4. 微信小程序Http高级封装 es6 promise

    公司突然要开放微信小程序,持续蒙蔽的我还不知道小程序是个什么玩意. 于是上网查了一下,就开始着手开发..... 首先开发客户端的东西,都有个共同点,那就是  数据请求! 看了下小程序的请求方式大概和a ...

  5. Java之路(三) 控制执行流程

    Java的控制语句设计的关键字有if-else while do-while for return break和switch. Java虽然保留goto关键字,但不支持goto语句. 1.true和f ...

  6. sqrt

    sqrt特别慢,两边同时平方,尽量避免开方.

  7. 009.MySQL-Keepalived搭配脚本03

    vim /etc/keepalived/check_MySQL.sh #vim #!/bin/bash MYSQL=/usr/local/mysql/bin/mysql MYSQL_HOST=loca ...

  8. Qt5编译oracle驱动教程

    我们都知道oracle数据库的强大,并且好多企业或者教学用到数据库时都会推荐使用.但是Qt因为版权问题没有封装oracle数据库专用驱动,网上也有一大堆说法和教程,但是或多或少的都有问题.下面废话不多 ...

  9. collectionFramwork-1

    1. Set.List和Map可以看做集合的三大类. List集合是有序集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问. Set集合是无序集合,集合中的元素不可以重复,访问集合中 ...

  10. C#开发Unity游戏教程之Scene视图与脚本的使用

    C#开发Unity游戏教程之Scene视图与脚本的使用 Unity中Scene视图的快捷操作 Scene视图是开发者开发游戏时,操作最频繁的视图.因为一旦一个游戏对象被添加到游戏的场景中,就需要首先使 ...