Linux下基于opencv的神经网络字符识别

运行环境:Linux Ubuntu12.04

    opencv 2.3.1


包含头文件、命名空间:


</pre><pre name="code" class="cpp">#include "mainwindow.h"
#include "ui_mainwindow.h"



#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/ml/ml.hpp>
#include <opencv2/opencv.hpp>
#include "qdebug.h"

using namespace std;
using namespace cv;


代码

    const string fileform = ".png";
    const string perfileReadPath = "../sourse";
    const string perfileSavePath = "../resize";

    const int sample_mun_perclass = 20;
    const int class_mun = 10;

    const int image_cols = 8;
    const int image_rows = 16;
    string  fileReadName,
            fileReadPath,
            fileSaveName,
            fileSavePath;
    char t[256];
    char temp[256];

    float trainingData[class_mun*sample_mun_perclass][image_rows*image_cols] = {{0}};
    float labels[class_mun*sample_mun_perclass][class_mun]={{0,0,0,0}};
    //Mat trainingDataMat;

    for(int i=0;i<=class_mun-1;++i)
    {

        sprintf(temp, "%d", i);
        fileReadPath = temp;
        fileSavePath = perfileSavePath+"/"+fileReadPath;
        fileReadPath = perfileReadPath+"/"+fileReadPath;

        for(int j=1;j<=sample_mun_perclass;++j)
        {

            sprintf(t, "%d", j);
            fileReadName = t;
            fileReadName  = fileReadName+fileform;//bug?

            //cout << fileReadPath+"/"+fileReadName<<endl;
            //cout << fileSavePath+"/"+fileReadName<<endl;

            Mat srcImage = imread(fileReadPath+"/"+fileReadName,CV_LOAD_IMAGE_GRAYSCALE);
            Mat resizeImage;
            if(srcImage.empty())
            {
                qDebug()<<"路径出错,找不到指定图像";
                return;
            }
            Mat result;

            //cvtColor( srcImage, srcImage, CV_BGR2GRAY );
            //cv::equalizeHist(srcImage,result);

            cv::resize(srcImage,resizeImage,Size(image_cols,image_rows),(0,0),(0,0),3);

            cv::threshold(resizeImage,resizeImage,0,255,CV_THRESH_BINARY|CV_THRESH_OTSU);

            imwrite(fileSavePath+"/"+fileReadName,resizeImage);

            // Set up training data

            Mat train_image = imread(fileSavePath+"/"+fileReadName,CV_LOAD_IMAGE_GRAYSCALE);

            for(int k = 0; k<image_rows*image_cols; ++k)
            {
                trainingData[i*sample_mun_perclass+(j-1)][k] = (float)train_image.at<unsigned char>((int)k/8,(int)k%8);//(float)train_image.data[k];
                //cout<<trainingData[i*sample_mun_perclass+(j-1)][k] <<" "<< (float)train_image.at<unsigned char>(k/8,k%8)<<endl;
            }
            //cout<<endl;
        }
    }
    Mat trainingDataMat(class_mun*sample_mun_perclass, image_rows*image_cols, CV_32FC1);

    for(int i =0;i < class_mun*sample_mun_perclass; ++i)
        for(int j =0;j < image_rows*image_cols; ++j)
        {
            trainingDataMat.at<float>(i,j) = (float)trainingData[i][j];
           // cout<<i<<" "<<j<<endl;
        }
    // memcpy(temp.data,trainingData,sizeof(float)*class_mun*sample_mun_perclass*image_rows*image_cols);
   //  trainingDataMat = temp;
/**/



/**/     Mat mm(image_rows,image_cols,CV_8UC1);

    for(int n=0;n < sample_mun_perclass*class_mun;n++)
    {
     for(int m=0;m < image_rows*image_cols;m++)
         mm.at<uchar>(m/8,m%8) = trainingDataMat.at<float>(n,m);//(uchar)(int)trainingData[0][m];
     //imshow("check",mm);
     //waitKey(100);
    }

    // Set up lable data

    for(int i=0;i<=class_mun-1;++i)
    {
        for(int j=0;j<=sample_mun_perclass-1;++j)
        {
            for(int k = 0;k<class_mun;++k)
            {
                if(k==i)
                    labels[i*sample_mun_perclass + j][k] = 1;
                else labels[i*sample_mun_perclass + j][k] = 0;
            }
        }
    }
    Mat labelsMat(class_mun*sample_mun_perclass, class_mun, CV_32FC1,labels);
    for(int i=0;i<=class_mun-1;++i)
    {
        for(int j=0;j<=sample_mun_perclass-1;++j)
        {
            for(int k = 0;k<class_mun;++k)
            {
                labelsMat.data[i*sample_mun_perclass + j+k] = labels[i*sample_mun_perclass + j][k];
                //cout<<(float)labelsMat.data[i*sample_mun_perclass + j+k];
                //cout<<labels[i*sample_mun_perclass + j][k];
            }
            //cout<<endl;
        }
    }

    /*
     *训练代码
    */
    CvANN_MLP bp;
    //if(0)
    {
    cout<<"training start...."<<endl;


    // Set up BPNetwork's parameters
    CvANN_MLP_TrainParams params;
    params.train_method=CvANN_MLP_TrainParams::BACKPROP;
    params.bp_dw_scale=0.001;
    params.bp_moment_scale=0.1;
    params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,10000,0.0001);  //设置结束条件
    //params.train_method=CvANN_MLP_TrainParams::RPROP;
    //params.rp_dw0 = 0.1;
    //params.rp_dw_plus = 1.2;
    //params.rp_dw_minus = 0.5;
    //params.rp_dw_min = FLT_EPSILON;
    //params.rp_dw_max = 50.;

    //Setup the BPNetwork
    Mat layerSizes=(Mat_<int>(1,5) << 128,128,128,128,class_mun);
    bp.create(layerSizes,CvANN_MLP::SIGMOID_SYM,1.0,1.0);//CvANN_MLP::SIGMOID_SYM
                                               //CvANN_MLP::GAUSSIAN
                                               //CvANN_MLP::IDENTITY
    cout<<"training...."<<endl;
    bp.train(trainingDataMat, labelsMat, Mat(),Mat(), params);

    bp.save("../bpcharModel.xml"); //save classifier
    cout<<"bpModel1.xml saved training finish..."<<endl;
    }

    /*
    *测试代码
    */
    //if(0)
    int err = 0;
    for(int i=0;i<=class_mun-1;++i)
    {

        sprintf(temp, "%d", i);
        fileReadPath = temp;
        fileSavePath = perfileSavePath+"/"+fileReadPath;
        for(int j=sample_mun_perclass+1;j<=10+2*sample_mun_perclass;++j)
        {
            sprintf(t, "%d", j);
            fileReadName = t;
            fileReadName  = fileReadName+fileform;//bug?
            cout << fileSavePath+"/"+fileReadName<<endl;

            {
            Mat test_image = imread(fileSavePath+"/"+fileReadName,CV_LOAD_IMAGE_GRAYSCALE);
            if(test_image.empty())
            {
                qDebug()<<"路径出错,找不到指定图像";
                return;
            }
            Mat_<float>sampleMat(1,image_rows*image_cols);
            for(int i = 0; i<image_rows*image_cols; ++i)
            {
                sampleMat.at<float>(0,i) = (float)test_image.at<uchar>(i/8,i%8);
                //cout<<((sampleMat.at<float>(0,i))>0?1:0)<<"  ";
                //if(i%8==7)
                //    cout<<endl;
            }
            imshow("1",test_image);
            //Mat sampleMat = ( << 10,501);
            Mat responseMat;
            bp.predict(sampleMat,responseMat);
            float* p=responseMat.ptr<float>(0);

            //cout<<(float)(*p)<<" "<<(float)(*(p+1))<<" "<<(float)(*(p+2))<<" "<<(float)(*(p+3))<<endl;

            float max= -1,min =0;
            int index = 0;
            for(int k=0;k<class_mun;++k)
            {
                cout<<(float)(*(p+k))<<" ";
                if(k==class_mun-1)
                    cout<<endl;
                //max = (*p)
                if((float)(*(p+k))>max)
                {
                    min = max;
                    max = (float)(*(p+k));
                    index = k;
                }
                else
                {
                    if(min < (float)(*(p+k)))
                        min = (float)(*(p+k));
                }
            }
            cout<<"识别结果:"<<index<<endl<<"识别置信度:"<<(((max-min)*100) > 100 ? 100:((max-min)*100))<<endl;
            if(index!=i)
            {
                //if(max-min)<
                err++;
                cout<<"识别出错: "<<err<<endl;
            }
            cout<<"识别出错: "<<err<<endl;
           // if((max-min)<0.2)
            {

            }
            }
        }
    }

特征采用8*16的二值化图像构成的128维向量作为输入层,3层128维的隐藏层,10维的输出层。输出用{1,0,0,0,0,...0}{0,1,0,0,0,...0}{0,0,1,0,0,...0}......{0,0,0,0,0,...1}表示

识别率95%左右

测试图像来源:http://www.cnblogs.com/ronny/p/opencv_road_more_01.html ,

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值