number recognition using multi layer perceptron

asked 2016-09-28 13:22:41 -0500

BenNG gravatar image

updated 2016-09-30 06:16:14 -0500

Eduardo gravatar image

Hi all !

I think I am more than close to finish my project which is a sudoku grabber After using tesseract, I realised that it was to slow and not enough accurate so I try an other solution I try to use an Artificial Neural Network and more precisely a Multi-Layer Perceptron

I'm stuck with this error:

Bad argument (output training data should be a floating-point matrix with the number of rows equal to the number of training samples and the number of columns equal to the size of last (output) layer)

and this error is related to :

 Ptr<TrainData> trainingData = TrainData::create(TrainingData, ROW_SAMPLE, TrainingClasses);

Here is some details:

I have 126 training images which represent number. those images have normalized size (25,25)

I have a feature function which extract some information about the cell image:

Mat features(Mat in, int sizeData) {
int HORIZONTAL = 1;
int VERTICAL = 0;

//Histogram features
Mat vhist = ProjectedHistogram(in, VERTICAL);
Mat hhist = ProjectedHistogram(in, HORIZONTAL);

//Low data feature
Mat lowData;
resize(in, lowData, Size(sizeData, sizeData));

//Last 10 is the number of moments components
int numCols = vhist.cols + hhist.cols + lowData.cols * lowData.cols;

Mat out = Mat::zeros(1, numCols, CV_32F);
//Asign values to feature
int j = 0;
for (int i = 0; i < vhist.cols; i++) {
    out.at<float>(j) = vhist.at<float>(i);
    j++;
}
for (int i = 0; i < hhist.cols; i++) {
    out.at<float>(j) = hhist.at<float>(i);
    j++;
}
for (int x = 0; x < lowData.cols; x++) {
    for (int y = 0; y < lowData.rows; y++) {
        out.at<float>(j) = (float) lowData.at < unsigned
        char > (x, y);
        j++;
    }
}
return out;
}

 Mat ProjectedHistogram(Mat img, int t) {
int sz = (t) ? img.rows : img.cols;
Mat mhist = Mat::zeros(1, sz, CV_32F);
for (int j = 0; j < sz; j++) {
    Mat data = (t) ? img.row(j) : img.col(j);
    mhist.at<float>(j) = countNonZero(data);
}
//Normalize histogram
double min, max;
minMaxLoc(mhist, &min, &max);
if (max > 0)
    mhist.convertTo(mhist, -1, 1.0f / max, 0);
return mhist;
}

I also have a function called createDataForTraining which take all my input picture and transform these to a matrix of features called TrainingData. so in TrainingData each row represents a image and each row has 275 cols. For now TrainingClasses are (1, 275)

void createDataForTraining() {

char *path = "./training/";

Mat classes;
Mat trainingDataf5;
Mat trainingDataf10;
Mat trainingDataf15;
Mat trainingDataf20;

vector<int> trainingLabels;
for (int i = 0; i < numCharacters; i++) {
    int numFiles = numFilesChars[i];
    for (int j = 1; j <= numFiles; j++) {
        // cout << "Character "<< strCharacters[i] << " file: " << j << "\n";
        stringstream ss(stringstream::in | stringstream::out);
        ss << path << strCharacters[i] << "/" << j << ".jpg";
        string filename = ss.str();
        // cout << filename << endl;
        Mat img = imread(ss.str(), 0);
        Mat f5 = features(img, 5);
        Mat f10 = features(img, 10);
        Mat f15 = features(img, 15);
        Mat f20 = features(img, 20);

        trainingDataf5.push_back(f5);
        trainingDataf10.push_back(f10);
        trainingDataf15.push_back(f15);
        trainingDataf20.push_back(f20);
        trainingLabels.push_back(i);
    }
}

trainingDataf5.convertTo(trainingDataf5, CV_32F);
trainingDataf10.convertTo(trainingDataf10, CV_32F);
trainingDataf15.convertTo(trainingDataf15, CV_32F);
trainingDataf20.convertTo(trainingDataf20, CV_32F);
Mat(trainingLabels).copyTo(classes ...
(more)
edit retag flag offensive close merge delete

Comments

please put your error statement before your code explanation, so folks here know, what to look for.

berak gravatar imageberak ( 2016-09-28 13:38:16 -0500 )edit

i can't find: ProjectedHistogram

berak gravatar imageberak ( 2016-09-28 13:40:23 -0500 )edit

I have made some changes ! thanks for commenting !

BenNG gravatar imageBenNG ( 2016-09-29 02:48:34 -0500 )edit
1

btw, the error msg is a bit misleading, it's all about your TrainClasses (the "output"), not about the TrainData.

berak gravatar imageberak ( 2016-09-29 02:52:07 -0500 )edit

btw, cv::reduce() does the same as your projection

berak gravatar imageberak ( 2016-09-29 02:54:01 -0500 )edit

is Classes.cols == numCharacters ?

berak gravatar imageberak ( 2016-09-29 03:02:01 -0500 )edit

No, Classes.rows = 126 and Classes.cols = 1, each row represents an cell image and the column data is a index of the related char. I wanted to be concise but here is the code

BenNG gravatar imageBenNG ( 2016-09-29 03:15:58 -0500 )edit

I think I messed up all the things I have read :(

BenNG gravatar imageBenNG ( 2016-09-29 03:16:25 -0500 )edit

In createDataForTraining the classes variable in setted and save in the xml file

BenNG gravatar imageBenNG ( 2016-09-29 03:19:25 -0500 )edit

Maybe you want to talk about TrainingClasses and yes TrainingClasses.cols == numCharacters

BenNG gravatar imageBenNG ( 2016-09-29 04:44:54 -0500 )edit