本文接着上一篇《自动车牌识别(ANPR)练习项目学习笔记3(基于opencv)》继续做笔记。
参考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$
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值。
到此完成了人工神经网络识别字符。
未完待续。