SVM训练模型时出错

豆子DXS 2019-03-12 08:44:51
VS2012+OPENCV3 程序运行到SVM_params->train(tData);出现中断
//********************************************用统计像素值的方法+SVM训练模型-产生.xml文件模型****************************
//**********************************************时间:2019年3月12日*******************************************************
//*********************************************VS2012+opencv3************************************************************
#include <stdio.h>
#include <time.h>
#include <opencv2/opencv.hpp>
#include <opencv/cv.h>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
#include <io.h> //查找文件相关函数

using namespace std;
using namespace cv;
using namespace ml;

ostringstream oss;//用于执行C风格的串流的输出操作,格式化字符串,避免申请大量的缓冲区,替代sprintf
int num = -1;
Mat dealimage;
Mat src;
Mat yangben_gray;
Mat yangben_thresh;

int main()
{
//核心思路://获取一张图片后会将图片特征写入到容器中, //训了样本图片与测试图片的尺寸应该一样
//紧接着会将标签写入另一个容器中,这样就保证了特征
// 和标签是一一对应的关系。
////===============================读取训练数据===============================////
const int classsum = 10;//图片共有10类,可修改
//const int imagesSum = 20;//每类有张图片,可修改,每个文件夹中图片不同,小小修改
const int imageRows =20;//图片尺寸
const int imageCols = 20;
//训练数据,每一行一个训练图片
Mat trainingData;
//训练样本标签
Mat labels;
//最终的训练样本标签
Mat clas;
//最终的训练数据
Mat traindata;
vector<Mat> input_images;
vector<String> input_images_name;
//////////////////////从指定文件夹下提取图片//////////////////
for (int p = 0; p < classsum; p++)//依次提取0到9文件夹中的图片
{
//oss << "E:/learn/graduate/C++/SVM/统计像素值训练模型/训练样本/";
oss << "E:/learn/graduate/C++/SVM/统计像素值训练模型/数字/";
num += 1;//num从0到9
int label = num;
oss << num << "/*.jpg";//图片名字后缀,oss可以结合数字与字符串,图片路径
string pattern = oss.str();//oss.str()输出oss字符串,并且赋给pattern
oss.str("");//每次循环后把oss字符串清空
glob(pattern, input_images_name, false);
//为false时,仅仅遍历指定文件夹内符合模式的文件,当为true时,会同时遍历指定文件夹的子文件夹
//此时input_images_name存放符合条件的图片地址
int all_num = input_images_name.size();//文件下总共有几个图片
//cout << num << ":总共有" << all_num << "个图片待测试" << endl;
//for (int i = 0; i < imagesSum; i++)//依次循环遍历每个文件夹中的图片,当不同文件夹中图片相同时
for (int i = 0; i < all_num; i++)//依次循环遍历每个文件夹中的图片,当不同文件夹中图片不相同时
{
cvtColor(imread(input_images_name[i]), yangben_gray, COLOR_BGR2GRAY);//灰度变换
threshold(yangben_gray, yangben_thresh, 0, 255, THRESH_OTSU);//二值化
//threshold(yangben_gray, yangben_thresh, 200, 255, CV_THRESH_BINARY);//固定阈值分割
input_images.push_back(yangben_thresh); //循环读取每张图片并且依次放在vector<Mat> input_images内
dealimage = input_images[i];
//注意:我们简单粗暴将整个图的所有像素作为了特征,因为我们关注更多的是整个的训练过程
//,所以选择了最简单的方式完成特征提取工作,除此中外,
//特征提取的方式有很多,比如LBP,HOG等等
//我们利用reshape()函数完成特征提取,
//reshape(1, 1)的结果就是原图像对应的矩阵将被拉伸成一个一行的向量,作为特征向量。
dealimage = dealimage.reshape(1, 1);//图片序列化
trainingData.push_back(dealimage);//序列化后的图片依次存入
labels.push_back(label);//把每个图片对应的标签依次存入
}
}
//图片数据和标签转变下
Mat(trainingData).copyTo(traindata);//复制
traindata.convertTo(traindata, CV_32FC1);//更改图片数据的类型,必要,不然会出错
Mat(labels).copyTo(clas);//复制
////===============================创建SVM模型===============================////
// 创建分类器并设置参数
Ptr<SVM> SVM_params = SVM::create();
SVM_params->setType(SVM::C_SVC);//C类支撑向量分类机。 n类分组 (n≥2),容许用异常值处罚因子C进行不完全分类
SVM_params->setKernel(SVM::LINEAR); //核函数,没有任何向映射至高维空间,线性区分(或回归)在原始特点空间中被完成,这是最快的选择

SVM_params->setDegree(0);//degree:内核函数(POLY)的参数degree
SVM_params->setGamma(1);//gamma:内核函数(POLY/ RBF/ SIGMOID)的参数
SVM_params->setCoef0(0);//内核函数(POLY/ SIGMOID)的参数coef0
SVM_params->setC(1);// SVM类型(C_SVC/ EPS_SVR/ NU_SVR)的参数C SVM最优问题参数
SVM_params->setNu(0);//SVM类型(NU_SVC/ ONE_CLASS/ NU_SVR)的参数 SVM最优问题参数
SVM_params->setP(0);//SVM类型(EPS_SVR)的参数 SVM最优问题参数
//结束条件,即训练1000次或者误差小于0.01结束
SVM_params->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, 0.01));// term_crit:SVM的迭代练习过程的中断前提,解决项目组受束缚二次最优题目
//训练数据和标签的结合
Ptr<TrainData> tData = TrainData::create(trainingData, ROW_SAMPLE, clas);
// 训练分类器
SVM_params->train(tData);//训练
//保存模型
SVM_params->save("E:/learn/graduate/C++/SVM/统计像素值训练模型/图片识别svm.xml");
cout << "训练好了!!!" << endl;
getchar();
return 0;
}

自动窗口显示:

+ SVM_params {owner=0x00c7de58 <无可用信息,未为 opencv_world300d.dll 加载任何符号> stored=0x03c52e00 <无可用信息,未为 opencv_world300d.dll 加载任何符号> } cv::Ptr<cv::ml::SVM>

+ clas {flags=1124024324 dims=2 rows=1441 ...} cv::Mat
+ tData {owner=0x00c7de18 <无可用信息,未为 opencv_world300d.dll 加载任何符号> stored=0x0308c2b0 <无可用信息,未为 opencv_world300d.dll 加载任何符号> } cv::Ptr<cv::ml::TrainData>
+ trainingData {flags=1124024320 dims=2 rows=1441 ...} cv::Mat

...全文
343 1 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
豆子DXS 2019-03-13
  • 打赏
  • 举报
回复
把 //Ptr<TrainData> tData = TrainData::create(trainingData, ROW_SAMPLE, clas);
//SVM_params->train(tData);//训练

改成
SVM_params->train(trainingData,ROW_SAMPLE, clas);

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧