OpenCV的machine learning模块使用
来源:互联网 发布:零点微网络是什么 编辑:程序博客网 时间:2024/06/08 08:02
opencv中提供的了较为完善的machine learning 模块,包含多种ml算法,极大了简化了实验过程。然而目前网上大部分的资料(包括官方文档)中关于ml模块的使用均是针对1.0风格的旧代码的,这对我们的学习造成了极大的困扰。本文将简单介绍一下如何使用opencv的ml模块进行实验。
首先,准备实验数据,我这里使用的是《模式分类》一书中第二章上机习题的部分数据,旨在进行一个简单的调用过程进行实验。实验数据如下表所示,在实际实验过程中,使用txt文档保存数据,并且没有文件头信息(实际上opencv提供了从csv文档读取数据的功能,这里简化实验没有使用该函数)。
实验思路如下:
- 读取数据,并构造训练样本的特征矩阵,标记矩阵(这里使用1和-1进行标记);
- 使用合适的分类器进行训练;
- 使用训练好的分类器进行分类(这里直接使用训练样本进行测试,便于直观看出测试结果,同时简化实验)
实验代码如下所示:
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
using namespace cv;
using namespace cv::ml;
void svm_classifier(Mat &training_data_mat, Mat &label_mat);
void bayes_classifier(Mat &training_data_mat, Mat &label_mat);
int main()
{
const int class_num = 2;
const int feature_num = 3;
ifstream file("E:\\programs\\Dec\\bayes_opencv\\data.txt");
float value;
vector<float> data_vec;
while (!file.eof())
{
file >> value;
data_vec.push_back(value);
}
Mat data(data_vec);
data = data.reshape(0, 20);
Mat training_data_mat = data.colRange(1, data.cols);
Mat lable_mat(data.col(0));
lable_mat.convertTo(lable_mat, CV_32SC1);
cout << "bayes classifier" << endl;
bayes_classifier(training_data_mat, lable_mat);
cout << "svm classifier" << endl;
svm_classifier(training_data_mat, lable_mat);
return 0;
}
void svm_classifier(Mat &training_data_mat, Mat &lable_mat)
{
SVM::Params params;
params.svmType = SVM::C_SVC;
params.kernelType = SVM::LINEAR;
params.termCrit = TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6);
Ptr<SVM> svm = StatModel::train<SVM>(training_data_mat, ROW_SAMPLE, lable_mat, params);
for (size_t i = 0; i != training_data_mat.rows; ++i)
{
Mat test_mat = training_data_mat.row(i);
float response = svm->predict(test_mat);
cout << i + 1 << ":\t" << response << flush;
MatIterator_<float> it, end;
for (it = test_mat.begin<float>(), end = test_mat.end<float>(); it != end; ++it)
{
cout << '\t' << *it << flush;
}
cout << endl;
}
}
void bayes_classifier(Mat &training_data_mat, Mat &lable_mat)
{
NormalBayesClassifier::Params params;
Ptr<TrainData> train_data = TrainData::create(training_data_mat, ROW_SAMPLE, lable_mat);
Ptr<NormalBayesClassifier> bayes = StatModel::train<NormalBayesClassifier>(train_data, params, 0);
for (size_t i = 0; i != training_data_mat.rows; ++i)
{
Mat test_mat = training_data_mat.row(i);
float response = bayes->predict(test_mat);
cout << i + 1 << ":\t" << response << flush;
MatIterator_<float> it, end;
for (it = test_mat.begin<float>(), end = test_mat.end<float>(); it != end; ++it)
{
cout << '\t' << *it << flush;
}
cout << endl;
}
}
代码运行结果如图所示:
从上述代码可以看出,实验使用了SVM和normal baysian classifier两个分类器,两分类器具有相同结构的使用方式,不同的是SVM使用前需要设置合适的参数,而贝叶斯分类器不需要。实验主要使用了两个函数:
//训练
Ptr<SVM> svm = StatModel::train<SVM>(training_data_mat, ROW_SAMPLE, lable_mat, params);
Ptr<NormalBayesClassifier> bayes = StatModel::train<NormalBayesClassifier>(train_data, params, 0);
//测试
float response = svm->predict(test_mat);
float response = bayes->predict(test_mat);
这里训练svm和bayes时使用了两个不同的函数,这是因为分类器类SVM和NormalBayesClassifier均继承自StatModel这个类别,它提供了两个重载的静态函数进行训练。从源代码可以看出:
template<typename _Tp> static Ptr<_Tp> train(const Ptr<TrainData>& data, const typename _Tp::Params& p, int flags=0)
{
Ptr<_Tp> model = _Tp::create(p);
return !model.empty() && model->train(data, flags) ? model : Ptr<_Tp>();
}
template<typename _Tp> static Ptr<_Tp> train(InputArray samples, int layout, InputArray responses,
const typename _Tp::Params& p, int flags=0)
{
Ptr<_Tp> model = _Tp::create(p);
return !model.empty() && model->train(TrainData::create(samples, layout, responses), flags) ? model : Ptr<_Tp>();
}
所以,实际上第二个函数使用的时候根据输入的参数samples, layout和response构造了TrainData类对象,并调用了第一个函数。这里的TrainData类即保存ml算法使用数据的类,这里不做详细分析(后期会写相关文章,分析其源代码)。samples是训练样本特征的矩阵,layout参数有ROW_SAMPLE和COL_SMAPLE两个选择,说明了样本矩阵中一行还是一列代表一个样本,response矩阵和samples矩阵相对应,说明了样本的标记,本例中为1和-1.
从上面的代码中可以看出ml算法的使用方法,实际上opencv的ml模块提供的所有分类器均继承自StatModel这个抽象类,他们的使用方法均和SVM和NormalBayesClassifier类似。其包含的所有ml算法如下:
- NormalBayesClassifier (贝叶斯分类器~~~符合正态分布的)
- KNearest (KNN算法)
- SVM
- EM
- DTrees (决策树)
- RTrees (随机森林)
- Boost (boosted tree classifer)
- ANN_MLP (人工神经网络)
后续内容:本文是使用opencv学习ml算法的初次尝试,后面还会介绍更多的相关内容,包括opencv的源码学习,更多的machine learning算法介绍,如何对图像进行分类等,敬请期待。
- OpenCV的machine learning模块使用
- OpenCV的machine learning模块使用
- Machine Learning with OpenCV
- Java使用OpenCV类库实现简单的KNN Machine Learning.
- machine learning 的测试数据
- 《Machine learning for OpenCV》 Windows下的Anaconda+OpenCV的环境配置
- OpenCV: Machine Learning Overview翻译心得
- Machine learning for openCV 学习笔记 day1
- Machine learning for OpenCV 学习笔记 day2
- Machine learning for OpenCV 学习笔记 day4
- Machine learning for OpenCV 学习笔记 day5
- Machine learning for OpenCV 学习笔记 day6
- 【Machine Learning】OpenCV中的K-means聚类
- machine learning(4) --SVM 在opencv 中的使用及SVM与HOG联合
- opencv 收费模块的使用
- OpenCV Machine Learning 之正态贝叶斯分类器(Normal Bayes Classifier)的用法实例
- OpenCV Machine Learning 之 K最近邻分类器的应用 K-Nearest Neighbors
- OpenCV Machine Learning 之正态贝叶斯分类器(Normal Bayes Classifier)的用法实例
- UVALive 3708 Graveyard
- 学会使用Mingw.4.9.1来静态编译Qt5.4.0
- (下拉框系列4)通过学习下拉框系列,自己写的下拉框
- 第二周编程作业1-信号报告
- 彭姓女孩名字大全最新女宝宝名字
- OpenCV的machine learning模块使用
- 易语言隔行扫描算法 支持库
- 网站迁移服务器
- File类中的list方法
- linux之SQL语句简明教程---DROP TRUNCATE
- IBM Watson的Question Answering系统采用了何种技术--笔记
- 软件工程中的数据流图
- Oracle数据库date类型与Java中Date的联系与转化 .
- 第16周项目1-数组的排序