自动车牌识别(ANPR)练习项目学习笔记4(基于opencv)

本文接着上一篇《自动车牌识别(ANPR)练习项目学习笔记3(基于opencv)》继续做笔记。

E.  OCR分类中使用到的人工神经网络

参考opencv手册学习ANN函数的使用方法。再看下OCR::train() 函数:

// 671*265   671*1   10
void OCR::train(Mat TrainData, Mat classes, int nlayers){            
    Mat layers(1,3,CV_32SC1);                  //[265 10 30]
    layers.at<int>(0)= TrainData.cols;
    layers.at<int>(1)= nlayers;
    layers.at<int>(2)= numCharacters;
    ann.create(layers, CvANN_MLP::SIGMOID_SYM, 1, 1);

    //Prepare trainClases
    //Create a mat with n trained data by m classes
    Mat trainClasses;
    trainClasses.create( TrainData.rows, numCharacters, CV_32FC1 );  //[671 30] 
    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
            if( k == classes.at<int>(i) )
                trainClasses.at<float>(i,k) = 1;
            else
                trainClasses.at<float>(i,k) = 0;
        }
    }
    Mat weights( 1, TrainData.rows, CV_32FC1, Scalar::all(1) );
    
    //Learn classifier
    ann.train( TrainData, trainClasses, weights );
    trained=true;
}
以"TrainingDataF15"为例,TrainData : 671 * 265,   classes : 671 * 1

 设置Mat layers=[265, 10, 30]  第一列为特征数,第二列为隐藏层的隐藏神经元数,第三列为样本类数。

ann.create(layers, CvANN_MLP::SIGMOID_SYM, 1, 1);
函数原型:

C++: void CvANN_MLP::create(const Mat& layerSizes, int activateFunc=CvANN_MLP::SIGMOID_SYM,
double fparam1=0, double fparam2=0 )
layerSizes: 整型向量,指定每一层的神经元数目,包括输入层和输出层。

activateFunc: 指定每一个神经元的激励函数,以下三种中的一种:CvAnn_MLP::IDENTITY, CvANN_MLP::SIGMOID_SYM, CvANN_MLP::GAUSSIAN

fparam1, fparam2 分别表示激励函数中的参数$\alpha$  $\beta$

自动车牌识别(ANPR)练习项目学习笔记4(基于opencv)_第1张图片
这里使用的就是SIGMOID函数。

trainClasses : 671 * 30  行表示671个样本,列表示30种分类,如果i 行样本属于第k个分类,则trainClasses(i,k)==1,否则=0;


权重矩阵 Mat  weights(1, 671, CV_32FC1, Scalar::all(1)); 列数是样本数671,权重值相同都为1。这里的权重是为了指定哪些样本更重要些。

准备好数据之后,执行 ann.train( TrainData, trainClasses, weights );

C++: int CvANN_MLP::train(const Mat& inputs, const Mat& outputs, const Mat& sampleWeights,
const Mat& sampleIdx=Mat(), CvANN_MLP_TrainParams params=CvANN_MLP_TrainParams(), int flags=0 )
用训练好的神经网络将特征向量分类:

int OCR::classify(Mat f){
    int result=-1;
    Mat output(1, numCharacters, CV_32FC1);
    ann.predict(f, output);
    Point maxLoc;
    double maxVal;
    minMaxLoc(output, 0, &maxVal, 0, &maxLoc);
    //We need know where in output is the max val, the x (cols) is the class.

    return maxLoc.x;
}
与SVM返回一个值不同,ANN的 predict 返回一个行向量,大小为类的数量,该向量的每个元素反应了输入样本属于每个类的概率。

使用minMaxLoc() 函数获得向量中的最大值及最大值的索引值,字符类别为变量maxLoc.x值。
到此完成了人工神经网络识别字符。

未完待续。




你可能感兴趣的:(C++,opencv,ann,ANPR)