1. SVM介绍

占个坑,以后再说

2. OpenCV3.x下SVM接口介绍

官方文档

OpenCV3.x与OpenCV2.x中SVM的接口有了很大变化,在接口上使用了虚函数取代以前的定义。

下面介绍几个常用的接口,及其参数意义。

2.1 初始化函数

定义如下:

CV_WRAP static Ptr create();

2.2 参数设置函数

然后是一些设置SVM参数的函数:

CV_WRAP virtual int getType() const = 0;

CV_WRAP virtual void setType(int val) = 0;

CV_WRAP virtual double getGamma() const = 0;

CV_WRAP virtual void setGamma(double val) = 0;

CV_WRAP virtual double getDegree() const = 0;

CV_WRAP virtual void setDegree(double val) = 0;

CV_WRAP virtual double getC() const = 0;

CV_WRAP virtual void setC(double val) = 0;

CV_WRAP virtual double getNu() const = 0;

CV_WRAP virtual void setNu(double val) = 0;

CV_WRAP virtual double getP() const = 0;

CV_WRAP virtual void setP(double val) = 0;

CV_WRAP virtual cv::Mat getClassWeights() const = 0;

CV_WRAP virtual void setClassWeights(const cv::Mat &val) = 0;

CV_WRAP virtual cv::TermCriteria getTermCriteria() const = 0;

CV_WRAP virtual void setTermCriteria(const cv::TermCriteria &val) = 0;

CV_WRAP virtual int getKernelType() const = 0;

CV_WRAP virtual void setKernel(int kernelType) = 0;

具体的作用可以参考OpenCV文档,这里只介绍两个常用的函数:

//设置SVM类型

CV_WRAP virtual int getType() const = 0;

这个函数用于设置SVM类型,OpenCV提供了五种类型:

Types {

//C类支持向量分类机。 n类分组 (n≥2),容许用异常值处罚因子C进行不完全分类。

C_SVC =100,

//$v$类支持向量机

NU_SVC =101,

//单分类器,所有的练习数据提取自同一个类里,

//然后SVM建树了一个分界线以分别该类在特点空间

//中所占区域和其它类在特点空间中所占区域。

ONE_CLASS =102,

EPS_SVR =103,

NU_SVR =104

}

一般我们使用SVM进行二分类或者多分类任务,选择第一种SVM::C_SVC即可。

还有一个函数就是:

CV_WRAP virtual void setKernel(int kernelType) = 0;

这个函数用于设置SVM的核函数类型,我们知道,通过选择SVM的核函数可以使SVM处理高阶、非线性问题。OpenCV提供几种核函数:

enum KernelTypes {

/** Returned by SVM::getKernelType in case when custom kernel has been set */

CUSTOM=-1,

//线性核

LINEAR=0,

//多项式核

POLY=1,

//径向基核(高斯核)

RBF=2,

//sigmoid核

SIGMOID=3,

//指数核,与高斯核类似

CHI2=4,

//直方图核

INTER=5

};

一般情况下使用径向基核可以很好处理大部分情况。

2.3 训练函数

OpenCV3.x中SVM的提供了训练函数也与2.x不同,如下:

virtual bool trainAuto( const Ptr& data, int kFold = 10,

ParamGrid Cgrid = getDefaultGrid(C),

ParamGrid gammaGrid = getDefaultGrid(GAMMA),

ParamGrid pGrid = getDefaultGrid(P),

ParamGrid nuGrid = getDefaultGrid(NU),

ParamGrid coeffGrid = getDefaultGrid(COEF),

ParamGrid degreeGrid = getDefaultGrid(DEGREE),

bool balanced=false) = 0;

bool trainAuto (InputArray samples, int layout, InputArray responses,

int kFold=10, Ptr< ParamGrid > Cgrid=SVM::getDefaultGridPtr(SVM::C),

Ptr< ParamGrid > gammaGrid=SVM::getDefaultGridPtr(SVM::GAMMA),

Ptr< ParamGrid > pGrid=SVM::getDefaultGridPtr(SVM::P),

Ptr< ParamGrid > nuGrid=SVM::getDefaultGridPtr(SVM::NU),

Ptr< ParamGrid > coeffGrid=SVM::getDefaultGridPtr(SVM::COEF),

Ptr< ParamGrid > degreeGrid=SVM::getDefaultGridPtr(SVM::DEGREE),

bool balanced=false)

trainAuto可以在训练过程中自动优化2.2中的那些参数,而使用train函数时,参数被固定,所以推荐使用trainAuto函数。

在准备训练数据的时候,有下面几点需要注意,否则函数会报错

SVM的训练函数是ROW_SAMPLE类型的,也就是说,送入SVM训练的特征需要reshape成一个行向量,所有训练数据全部保存在一个Mat中,一个训练样本就是Mat中的一行,最后还要讲这个Mat转换成CV_32F类型,例如,如果有\(k\)个样本,每个样本原本维度是\((h, w)\),则转换后Mat的维度为\((k, h * w)\)

对于多分类问题,label矩阵的行数要与样本数量一致,也就是每个样本要在label矩阵中有一个对应的标签,label的列数为1,因为对于一个样本,SVM输出一个值,我们在训练前需要做的就是设计这个值与样本的对应关系。对于有\(k\)个样本的情况,label的维度是\((k, 1)\)

2.4 预测函数

函数定义如下:

float predict(cv::InputArrat samples, cv::OutputArray results = noArray(), int flags = 0) const;

其中samples就是需要预测的样本,这里样本同样要转换成ROW_SAMPLE和CV_32F格式,对于单个测试样本的情况,预测结果直接通过函数返回值返回,而如果samples中有多个样本,就需要穿进result参数,预测结果以列向量的方式保存在result数组中。假如有\(k\)个样本,每个样本原本的维度为\((h, w)\),则samples的维度为\((k, h * w)\),最终预测结果result维度为\((k, 1)\)

3. 例程

下面上代码:

/*

* 把图片从vector格式转换成SVM的RAW_SAMPLE格式

*/

void transform(const vector &split, Mat &testData)

{

for (auto it = split.begin(); it != split.end(); it++){

Mat tmp;

resize(*it, tmp, Size(28, 28));

testData.push_back(tmp.reshape(0, 1));

}

testData.convertTo(testData, CV_32F);

}

/*

* 从文件list.txt中读取测试数据和标签,输出SVM的Mat格式

*/

void get_data(string path, Mat &trainData, Mat &trainLabels)

{

fstream io(path, ios::in);

if (!io.is_open()){

cout << "file open error in path : " << path << endl;

exit(0);

}

while (!io.eof())

{

string msg;

io >> msg;

trainData.push_back(imread(msg, 0).reshape(0, 1));

io >> msg;

int idx = msg[0] - '0';

//trainLabels.push_back(Mat_(1, 1) << idx); //用这种方式会报错,原因尚且不明

trainLabels.push_back(Mat(1, 1, CV_32S, &idx));

}

trainData.convertTo(trainData, CV_32F);

}

/*

* 训练SVM

*/

void svm_train(Ptr &model, Mat &trainData, Mat &trainLabels)

{

model->setType(SVM::C_SVC); //SVM类型

model->setKernel(SVM::LINEAR); //核函数,这里使用线性核

Ptr tData = TrainData::create(trainData, ROW_SAMPLE, trainLabels);

cout << "SVM: start train ..." << endl;

model->trainAuto(tData);

cout << "SVM: train success ..." << endl;

}

/*

* 利用训练好的SVM预测

*/

void svm_pridect(Ptr &model, Mat test)

{

Mat result;

float rst = model->predict(test, result);

for (auto i = 0; i < result.rows; i++){

cout << result.at(i, 0);

}

}

int main(int argc, const char** argv)

{

fstream io;

io.open("test_list.txt", ios::in);

string train_path = "train_list.txt";

vector test_set;

get_test(io, test_set);

Ptr model = SVM::create();

Mat trainData, trainLabels;

get_data(train_path, trainData, trainLabels);

svm_train(model, trainData, trainLabels);

Mat testData;

transform(test_set, testData);

svm_pridect(model, testData);

}

trian_list.txt文件格式是这样的:

D:\ImgPro\Project\for\char\code\beta00\train_data\0\0-1.jpg0

D:\ImgPro\Project\for\char\code\beta00\train_data\0\0-2.jpg0

每行前一段表示训练图片地址,最后的数字表示这个图片对应标签

test_list.txt中格式与train_list.txt差不多,只是没有了标签。

svm图片多分类python代码_[OpenCV随笔]-OpenCV3.x中SVM多分类使用(代码篇)相关推荐

  1. Python基础_第3章_Python中的循环结构

    Python基础_第3章_Python中的循环结构 文章目录 Python基础_第3章_Python中的循环结构 Python中的循环结构 一.回顾分支练习题 1.判断是否为一个合法三角形 2.求世界 ...

  2. Python基础_第5章_Python中的数据序列

    Python基础_第5章_Python中的数据序列 文章目录 Python基础_第5章_Python中的数据序列 Python中的数据序列 一.字典--Python中的==查询==神器 1.为什么需要 ...

  3. maven引用公共包_使用github作为maven仓库存放发布自己的jar包依赖 实现多个项目公共部分代码的集中,避免团队中多个项目之间代码的复制粘贴...

    使用github作为maven仓库存放发布自己的jar包依赖 实现多个项目公共部分代码的集中,避免团队中多个项目之间代码的复制粘贴. 1.首先在本地maven位置的配置文件setting.xml(没有 ...

  4. 猿编程python怎么样_猿编程怎么练习编程 让你提前熟悉代码

    猿编程作为一款专业的少儿编程学习软件,它能够正确引导想要学习编程的孩子,帮助学生更加有效的学习编程思维,为他的学习之路打下坚实的基础,很多用户在开始操作时不知道如何练习编程,想知道的赶快来看看下面的教 ...

  5. tensorflow 语义slam_研究《视觉SLAM十四讲从理论到实践第2版》PDF代码+《OpenCV+TensorFlow深度学习与计算机视觉实战》PDF代码笔记...

    我们知道随着人工神经网络和深度学习的发展,通过模拟视觉所构建的卷积神经网络模型在图像识别和分类上取得了非常好的效果,借助于深度学习技术的发展,使用人工智能去处理常规劳动,理解语音语义,帮助医学诊断和支 ...

  6. 有趣的html代码_千万别惹程序员,否则会在代码注释里,告诉这家公司有多坑...

    Python现在非常火,语法简单而且功能强大,很多同学都想学Python!所以小的给各位看官们准备了高价值Python学习视频教程及相关电子版书籍,都放在了文章结尾,欢迎前来领取! 每个程序员敲代码都 ...

  7. 深度学习分类类别不平衡_如何应对深度学习中的数据分布不平衡问题

    对数据不平衡的应对 在比赛中经常会遇到数据不平衡的问题,各个类别之间的数据量不平衡容易导致模型对数据量少的类别的检测性能较低.数据不平衡问题可以分为以下两种情况: 大数据分布不均衡.这种情况下整体数据 ...

  8. tfs管理java代码_使用Intellij Idea连接Team Foundation Server (TFS)实现代码版本管理

    Intellij Idea是一个Java项目开发工具,支持Windows,MAC OS和Linux的跨平台开发环境,具备良好和智能的用户界面,在欧洲市场拥有很多粉丝.https://www.jetbr ...

  9. 运算阶乘的代码_【必修1】2.4可以复用的代码

    学习目标 ★了解函数的作用. ★学会函数的定义和调用方法,并能熟练使用函数解决问题. ★学会发布共享代码的常见方法,并能熟练使用模块解决问题. 本课要点 任务一  用自定义函数实现火柴摆数字问题 活动 ...

  10. php 工商银行公众号支付代码_微信支付PHP SDK之微信公众号支付代码详解

    这里假设你已经申请完微信支付 1. 微信后台配置  如图 我们先进行测试,所以先把测试授权目录和 测试白名单添加上.测试授权目录是你要发起微信请求的哪个文件所在的目录. 例如jsapi 发起请求一般是 ...

最新文章

  1. [SpringBoot]全局异常处理
  2. android 模块不编译错误,Android 编译出错版本匹配问题解决办法
  3. C++开发WPF,开发环境配置
  4. 【项目管理】CMM能力成熟度模型
  5. 第9章 项目人力资源管理
  6. pandas创建和文件读取笔记(一)
  7. Oracle的一些资料
  8. 爱不释手(Typingfaster)1.82beta ,请试用并反馈,谢谢
  9. 惊,Java 字符串拼接竟然有这么多玩法!| CSDN 原力计划
  10. note 2 运算符和表达式
  11. 一个小型的无线路由器 Linux 系统OpenWRT
  12. 航模入门经典教材:航空模型教材
  13. Altium Designed导出Gerber,Gerber文件所对应的层
  14. mysql排序order by asc | desc
  15. macbook_我如何学会不再担心并热爱Macbook
  16. 广州大学人工智能原理实验三:产生式系统推理
  17. 计算机教育学研究方法,广西师大 教育学 孙杰远《教育研究方法》知识点笔记1.pdf...
  18. SVN客户端TortoiseSVN基本使用方法步骤-初人指南
  19. Python3.6 安装PIL
  20. 自称中本聪的他被法官怒怼:你的证词毫无可信度!

热门文章

  1. 淘宝店铺装修全屏海报代码怎么用的设置方法
  2. 求推荐民法论文选题?
  3. GBDT算法原理以及实例理解
  4. 基于R语言的Meta分析(全流程、不确定性分析)方法与Meta机器学习
  5. 笨方法学python 习题41
  6. PHP校园食堂系统描述
  7. 2019年11月~2020年7月CCF会议列表-计算机视觉计算机图形学
  8. 2020软件测试学科全套上课视频教程网盘免费分享
  9. [转] eclipse安装subversive插件
  10. eclipse 每次打开 提示 subversive svn connectors