在opencv的ml模块中有个统计模型类,而其他的比如朴素贝叶斯分类器、knn、svm等等其他模型都是基于该模型上派生出来的。所以先介绍下该模型。

该类的定义在文件“opencv\sources\modules\ml\include\opencv2\ml\ml.hpp”中:

class CV_EXPORTS_W CvStatModel
{
public:
CvStatModel();
virtual ~CvStatModel(); virtual void clear(); //save函数用来将整个模型状态保持到指定的XML 或者YAML文件中,并按照具体的类看是使用默认的名字还是指定的名字.
//使用了CxCore中的数据持久性功能。
CV_WRAP virtual void save(const char* filename, const char* name = 0) const; // load函数从指定的XML或者YAML中装载模型中指定的或者默认名字部分 //而之前的被装载的模型已经通过CvStatModel::clear()初始化了.
CV_WRAP virtual void load(const char* filename, const char* name = 0); // write函数会以将完整的模型以指定或者默认名字存储到文件中。该函数会被 CvStatModel::save()调用.
virtual void write(CvFileStorage* storage, const char* name) const; // read函数会从文件中指定的节点上读取整个模型。使用函数GetFileNodeByName()来定位节点。
//之前的模型也是需要被函数 CvStatModel::clear()初始化的.
virtual void read(CvFileStorage* storage, CvFileNode* node); //下面这几个函数被注释掉是因为它们不存在该模型中,只是对于其他的ml模型
//来说是有的,所以这里就完全不设定该函数,只是虽然各自派生的ml模型有各
//自的这几个函数,可是行为还是很类似的,所以就统一在该基类中介绍了。
// virtual bool train( const Mat& train_data, [int tflag,] ...,
// const Mat& responses, ..., [const Mat& var_idx,] ...,
// [const Mat& sample_idx,] ... [const Mat& var_type,] ...,
// [const Mat& missing_mask,] <misc_training_alg_params> ...
// )=0; // virtual float predict( const Mat& sample ... ) const=0; protected:
const char* default_model_name;
};

实现部分:

在文件“\opencv\sources\modules\ml\src\inner_functions.cpp”中

#include "precomp.hpp"
//构造函数,对该类唯一的类成员进行赋值
CvStatModel::CvStatModel()
{
default_model_name = "my_stat_model";
}
//虚析构函数,调用虚函数clear()来执行不同的类的清理工作
CvStatModel::~CvStatModel()
{
clear();
}
void CvStatModel::clear(){}
//写函数,将数据写入到指定的文件中
void CvStatModel::save( const char* filename, const char* name ) const
{
//存储文件的指针初始化
CvFileStorage* fs = 0;
//
CV_FUNCNAME( "CvStatModel::save" ); __BEGIN__;
//打开传入该函数的文件
CV_CALL( fs = cvOpenFileStorage( filename, 0, CV_STORAGE_WRITE )); if( !fs )
CV_ERROR( CV_StsError, "Could not open the file storage. Check the path and permissions" );
//如果未传入模型的名字,则写入默认的模型名字
write( fs, name ? name : default_model_name ); __END__;
//释放指向文件的指针
cvReleaseFileStorage( &fs );
} //装载指定文件中的数据
void CvStatModel::load( const char* filename, const char* name )
{
CvFileStorage* fs = 0; CV_FUNCNAME( "CvStatModel::load" ); __BEGIN__; CvFileNode* model_node = 0; CV_CALL( fs = cvOpenFileStorage( filename, 0, CV_STORAGE_READ ));
if( !fs )
EXIT; if( name )
model_node = cvGetFileNodeByName( fs, 0, name );
else
{
CvFileNode* root = cvGetRootFileNode( fs );
if( root->data.seq->total > 0 )
model_node = (CvFileNode*)cvGetSeqElem( root->data.seq, 0 );
} read( fs, model_node ); __END__;
//释放指向文件的指针
cvReleaseFileStorage( &fs );
}
//写函数
void CvStatModel::write( CvFileStorage*, const char* ) const
{
OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::write", "" );
} void CvStatModel::read( CvFileStorage*, CvFileNode* )
{
OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::read", "" );
}

该文件中还有大量的数学计算函数,比如矩阵分解,从GMM上采样等等。

备注:好了这里就主要介绍下几个不存在于该类的函数。

1、模型训练函数

 bool CvStatModel::train(const Mat& train_data, [int tflag,] ..., const Mat& responses, ..., [const
Mat& var_idx,] ..., [const Mat& sample_idx,] ... [const Mat& var_type,] ...,
[const Mat& missing_mask,] <misc_training_alg_params> ... ) = 0

该函数是通过输入特征向量和对应的输出目标值(responses)来训练模型的。输入和输出的向量/值都是以矩阵的形式传递的。默认情况下输入特征向量是以train_data rows,也就是一个训练样本中所有的成分(特征)是连续存储的。不过一些算法是需要处理它们的转置形式的,只要当基于所有的输入集合中的特征都是连续存储的(个人:其实也就是存储成一个矩阵而不是链表).如果两种布局都支持的话,那么该方法将会有个tflag参数用来指定具体的情况。

• tflag=CV_ROW_SAMPLE 特征向量以行形式存储;

• tflag=CV_COL_SAMPLE 特征向量以列形式存储。

train_data 必须是 CV_32FC1 (32位浮点类型,单通道) 格式的. 而Responses通常存储成1D向量(一行或者一列)形式 ,格式有: CV_32SC1(只在分类的时候用); CV_32FC1, 其中一个输入向量对应着一个目标值.

对于分类问题来说, responses 是离散的标签;

对于回归问题来说,responses 是模型函数需要逼近的值。

一些算法只能用来分类;一些算法只能用来回归;还有一些能用在两方面。对于回归来说,输出变量的类型既可以是通过独立的参数传递也可以是var_type向量的最后一个元素:

• CV_VAR_CATEGORICAL 输出变量是离散的类别标签;

• CV_VAR_ORDERED(=CV_VAR_NUMERICAL) 输出的值是有序的,也就是说两个不同的值可以进行数值对比,当然这是一个回归问题。

输入变量的类型可以通过var_type指定。大多数算法只能处理有序的输入变量。

许多ML模型会在一个特征子集或者是训练集中样本子集上进行训练,为了能够容易的在不同状态间选择,该函数还包含了var_idx 和 sample_idx 这两个参数。前者是用来指定感兴趣的变量(特征);后者是用来指定感兴趣的样本。这两个向量都是整型向量 (CV_32SC1) ,(当然是基于0开始索引的)或者是基于激活的变量/样本的8位 (CV_8UC1)标记。当传递一个NULL指针给这两个参数时,也就意味着所有的变量/样本都会用来训练。

另外,许多算法可以处理缺失的值的情况,也就是说当某个具体的训练样本的特征的值是未知的(比如,忘记测量一个病人在礼拜一时候的体温)参数 missing_mask,是一个与train_data 具有相同size的8位的矩阵,它用来标记缺失的值(即该标记矩阵中非0值)

通常来说,在进入到训练阶段之前的模型的状态是需要调用CvStatModel::clear()来重置的 ;不过某些算法会让你选择是否使用新的训练数据来更新模型的状态而不是重置他们。

float CvStatModel::predict(const Mat& sample, ...) const

该函数用来对一个新的样本进行预测其response。在分类问题中,该方法返回一个类别标签;在回归问题上,盖方法返回一个函数值 。输入的样本必须与传递给train函数中train_data一样大的特征维度。如果var_idx 参数传递给了train,那么记得,也同时只提取必须的特征给该函数。后缀的const表示该预测函数不会影响到模型的内部状态,所以该方法可以安全的在不同的线程中被调用。

opencv7-ml之统计模型的更多相关文章

  1. 关于ML.NET v0.6的发布说明

    ML.NET 0.6版本提供了几项令人兴奋的新增功能: 用于构建和使用机器学习模型的新API 我们主要关注的是发布用于构建和使用模型的新ML.NET API的第一次迭代.这些新的,更灵活的API支持新 ...

  2. ML(1): 入门理论

    机器学习相关的文章太多,选取一篇本人认为最赞的,copy文章中部分经典供自己学习,摘抄至 http://www.cnblogs.com/subconscious/p/4107357.html#firs ...

  3. [ML] I'm back for Machine Learning

    Hi, Long time no see. Briefly, I plan to step into this new area, data analysis. In the past few yea ...

  4. ANN:ML方法与概率图模型

    一.ML方法分类:          产生式模型和判别式模型 假定输入x,类别标签y         -  产生式模型(生成模型)估计联合概率P(x,y),因可以根据联合概率来生成样本:HMMs   ...

  5. Spark2 ML 学习札记

    摘要: 1.pipeline 模式 1.1相关概念 1.2代码示例 2.特征提取,转换以及特征选择 2.1特征提取 2.2特征转换 2.3特征选择 3.模型选择与参数选择 3.1 交叉验证 3.2 训 ...

  6. [Machine Learning & Algorithm]CAML机器学习系列2:深入浅出ML之Entropy-Based家族

    声明:本博客整理自博友@zhouyong计算广告与机器学习-技术共享平台,尊重原创,欢迎感兴趣的博友查看原文. 写在前面 记得在<Pattern Recognition And Machine ...

  7. [Machine Learning & Algorithm]CAML机器学习系列1:深入浅出ML之Regression家族

    声明:本博客整理自博友@zhouyong计算广告与机器学习-技术共享平台,尊重原创,欢迎感兴趣的博友查看原文. 符号定义 这里定义<深入浅出ML>系列中涉及到的公式符号,如无特殊说明,符号 ...

  8. 机器学习 - ML

    CNCC - 2016 | 机器学习(原文链接) Machine Learning - ML,机器学习起源于人工智能,是AI的一个分支. 机器学习的理论基础:计算学习理论 - Computationa ...

  9. ML 基础知识

    A computer program is said to learn from experience E with respect to some task T and some performan ...

随机推荐

  1. jQuery中.bind() .live() .delegate() .on()区别

    $(selector).bind(event,data,function) $(selector).live(event,data,function)//jquery1.9版本以下支持,jquery1 ...

  2. phpstudy集成下Apache配置部署https安全证书

    一..先申请到安全证书.(腾讯云或者阿里云申请免费1年的安全证书),怎么申请这里也说下(以腾讯云为例): 1.登录腾讯云QQ或微信登录都行,第一次登录要通过实名认证,点击[产品]---[ss证书l] ...

  3. profile,bashrc,.bash_profile,.bash_login,.profile,.bashrc,.bash_logout浅析 Part 2

    profile,bashrc,.bash_profile,.bash_login,.profile,.bashrc,.bash_logout浅析 Part 2   by:授客 QQ:103355312 ...

  4. SQLServer 学习笔记之超详细基础SQL语句 Part 1

    Sqlserver 学习笔记 by:授客 QQ:1033553122 1创建数据库 格式: CREATE DATABASE database_name ON PRIMARY(在组文件组中指定文件) ( ...

  5. Flutter之搜索电影

    搜索使用的是豆瓣电影API https://developers.douban.com/wiki/?title=movie_v2#subject 效果 代码: https://github.com/z ...

  6. 利用HTML5和echarts开发大数据展示及大屏炫酷统计系统

    想这样的页面统计及展示系统都是通过echarts来发开的及ajax数据处理,echarts主要是案例,在案例上修改即可,填充数据 echarts的demo案例如下: http://echarts.ba ...

  7. AsyncTask 处理耗时操作&&显示进度条

    在Android中实现异步任务机制有两种,Handler和AsyncTask.优缺点自己百度,推荐使用AsyncTask. private ProgressDialog dialog; //新建一个对 ...

  8. MaterialRefreshLayout+ListView 下拉刷新 上拉加载

    效果图是这样的,有入侵式的,非入侵式的,带波浪效果的......就那几个属性,都给出来了,自己去试就行. 下拉刷新 上拉加载 关于下拉刷新-上拉加载的效果,有许许多多的实现方式,百度了一下竟然有几十种 ...

  9. 【Redis】Redis学习(一) Redis初步入门

    一.Redis基础知识 1.1 Redis简介 Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理.它支持字符串.哈希表.列表.集合.有序集合,位图,h ...

  10. Python基础知识之疑点难点

    一.标识符 (1) 标识符不能以数字开头:以下划线开头的标识符具有特殊的意义,使用时需要特别注意. 以单下划线开头(如_foo)的标识符代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用 “ ...