Artificial Neural Networks && FileStorage of OpenCV

来源:互联网 发布:老电视如何看网络电视 编辑:程序博客网 时间:2024/05/25 21:34

1. 文档简单介绍

参考【opencv2refman.pdf】



ANN原理及响应函数设置如上所述;

ANN与其他分类算法有一个不同点是,构建和训练分开进行;

2.OpenCV实现代码

2.1//XML文件载入训练数据和类别标签,并进行训练;

OCR::OCR(string trainFile){    DEBUG=false;    trained=false;    saveSegments=false;//字符块的宽高    charSize=20;    //Read file storage.    FileStorage fs;    fs.open("OCR.xml", FileStorage::READ);//新建两个矩阵,用于存储训练数据和类别标签;    Mat TrainingData;    Mat Classes;    fs["TrainingDataF15"] >> TrainingData;    fs["classes"] >> Classes;//10层ANN,训练    train(TrainingData, Classes, 10);}

2.2训练

void OCR::train(Mat TrainData, Mat classes, int nlayers){//矩阵,用于创建ANN;1行3列;训练数据的列数(特征属性),ANN的层数,字符数(类别标签);    Mat layers(1,3,CV_32SC1);    layers.at<int>(0)= TrainData.cols;    layers.at<int>(1)= nlayers;    layers.at<int>(2)= numCharacters;//使用sigmoid创建ANN    ann.create(layers, CvANN_MLP::SIGMOID_SYM, 1, 1);    //Prepare trainClases    //Create a mat with n trained data by m classes    Mat trainClasses;//TrainData.rows表示训练数据的数量;    trainClasses.create( TrainData.rows, numCharacters, CV_32FC1 );    for( int i = 0; i <  trainClasses.rows; i++ )    {        for( int k = 0; k < trainClasses.cols; k++ )        {            //If class of data i is same than a k class//trainClasses的第i个row存储第i个样本的标签类别,而此标签存储在class的第i个元素下;//class(numCharacters)-->trainClasses(TrainData.rows, numCharacters)矩阵转换;//(i,j),遍历j;在样本i对应标签位置置为1;//比如第5个样本对应第3个类别,则设置trainClasses(5,3)=1;            if( k == classes.at<int>(i) )                trainClasses.at<float>(i,k) = 1;            else                trainClasses.at<float>(i,k) = 0;        }    }//所有的训练样本权重都为1;    Mat weights( 1, TrainData.rows, CV_32FC1, Scalar::all(1) );if (DEBUG){//存储训练前的类别标签;FileStorage classBefore;classBefore.open("classBefore.xml", FileStorage::WRITE);classBefore << "before" << trainClasses;classBefore.release();}    //Learn classifier,训练数据,类别标签(大矩阵形式),权重;//类别标签并不会变化,此API仅训练ANN;    ann.train( TrainData, trainClasses, weights );if (DEBUG){//存储训练后的类别标签;FileStorage classAfter;classAfter.open("classAfter.xml", FileStorage::WRITE);classAfter << "after" << trainClasses;classAfter.release();}    trained=true;}

2.3 分类测试

ann.predict(f, output);

2.4 错误备注

在进行LED数字识别项目时,使用ANN和KNN对比,当然还是ANN的效果更好些;出现一些需要强调的错误:

2.4.1 训练类别需要使用整型 int

//set the class of train feature;vector<int> numberLabel;for (int colsIdx = 0; colsIdx<10; ++colsIdx)<span style="white-space:pre"></span>numberLabel.push_back(colsIdx);Mat(numberLabel).copyTo(ftrClass);
按上述方式新建类别矩阵;

2.4.2 矩阵copy时类型准确
for (int rowsIdx = 0, toFtrIdx = 0; rowsIdx < tempFtr.rows; ++rowsIdx)for (int colsIdx = 0; colsIdx < tempFtr.cols; ++colsIdx, ++toFtrIdx)ftrNumberTa.at<float>(nuIdex, toFtrIdx) = tempFtr.at<float>(rowsIdx, colsIdx);

矩阵copy取值时,一般将rows作为第一层,cols作为第二层;
也可不强制按照此模式,理解
MatName.at<dataType>(rowsIdx,colsIdx);
另外Mat新建
//cols即image的宽;rows即image的高Mat ftrNumberTa(cv::Size(ftrNumber_cols, ftrNumber_rows), CV_32F);

此文仅简单记载ANN识别在opencv中的使用流程;


0 0
原创粉丝点击