美文网首页
Opencv手写数字识别

Opencv手写数字识别

作者: zjh3029 | 来源:发表于2017-09-15 21:39 被阅读0次
/*
Created by Jinhua Zhao,2017.09.15.
Contact:3210513029@qq.com
*/

#include<opencv2\opencv.hpp>

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

int main()
{
    Mat resizeImage, trainImage;

    const int sample_num = 20;//set the every character number.  
    const int clas_num = 10;//set the class of the number.

    const int cols = 16;//set the width.
    const int rows = 16;//set the height

    float trainingData[sample_num*clas_num][cols*rows] = { {0} };
    float labels[sample_num*clas_num][clas_num] = { { 0 } };//means the sign.
    for (int i = 0; i < clas_num; i++)//the different class of the photo
    {
        for (int j = 1; j <=sample_num; j++)
        {
            Mat img = imread("./" + to_string(i) + "/" + to_string(j) + ".png", CV_LOAD_IMAGE_GRAYSCALE);
            resize(img, resizeImage, Size(cols, rows), (0, 0), (0, 0), CV_INTER_AREA);
            threshold(resizeImage, trainImage, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

            for (int k = 0; k < cols*rows; k++)
            {
                trainingData[i*sample_num + (j - 1)][k] = (float)trainImage.data[k];//get the training data.
            }
        }
    }

    Mat trainingDataMat(clas_num*sample_num, cols*rows, CV_32FC1, trainingData);//transfrom the data into the Mat.
    cout << "TrainingDataMat has been OK!" << endl << "-----------------------" << endl;


    for (int i = 0; i < clas_num; i++)
    {
        for (int j = 0; j < sample_num; j++)
        {
            for (int k = 0; k < clas_num; k++)
            {
                if (k == i)
                    labels[i*sample_num + j][k] = 1;
                else
                    labels[i*sample_num + j][k] = 0;
            }
        }
    }

    Mat labelsMat(clas_num*sample_num, clas_num, CV_32FC1, labels);
    cout << "LabelsMat:" << endl << labelsMat << endl << "LabelsMat is OK!" << endl << "-----------------------" << endl;

    cout << "train start..." << endl;

    Ptr<ANN_MLP>bp = ANN_MLP::create();
    Mat layerSizes = (Mat_<int>(1, 5) << cols*rows, 256, 256, 256, clas_num);
    bp->setLayerSizes(layerSizes);
    //It is so important that you must be careful!!!
    //If you can not get  the result, you ought to choose the proper params.
    bp->setActivationFunction(ANN_MLP::SIGMOID_SYM,3.0,1.0);
    bp->setTrainMethod(ANN_MLP::BACKPROP);
    bp->setBackpropWeightScale(0.001);
    bp->setBackpropMomentumScale(0.1);
    bp->setRpropDW0(0.1);
    bp->setRpropDWMax(50);
    bp->setRpropDWMin(FLT_EPSILON);
    bp->setRpropDWMinus(0.5);
    bp->setRpropDWPlus(1.2);
    bp->setTermCriteria(TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10000, 0.0001));
    cout << "training..." << endl;
    Ptr<TrainData>tData = TrainData::create(trainingDataMat, ROW_SAMPLE, labelsMat);
    bp->train(tData);

    bp->save("bp_reco_char.xml");
    cout << "Training has been over!" << endl;


    cout << "Strat testing..." << endl;
    Mat img_test = imread("7.png", CV_LOAD_IMAGE_GRAYSCALE);
    Mat img_temp;
    cout << "Warning: required a photo of 16x16 pixels!!!" << endl;
    resize(img_test, img_temp, Size(cols, rows), (0, 0), (0, 0), CV_INTER_AREA);
    threshold(img_temp, img_temp, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

    vector<float>sampleMat;
    for (int i = 0; i < cols*rows; i++)
    {
        sampleMat.push_back((float)img_temp.data[i]);
    }
    cout << "Loading the photo...Successed!" << endl;

    Mat responseMat;
    bp->predict(sampleMat, responseMat);
    cout << "Predicted:" << responseMat << endl;
    Point maxLoc;
    double maxVal = 0;
    minMaxLoc(responseMat, NULL, &maxVal, NULL, &maxLoc);

    cout << "Result of the recognize: " << maxLoc.x << endl << "Similarity degree:" << maxVal*100 << "%" << endl;
    imshow("test", img_test);
    waitKey(0);
    return 0;
}     

相关文章

网友评论

      本文标题:Opencv手写数字识别

      本文链接:https://www.haomeiwen.com/subject/nvmesxtx.html