number recognition using multi layer perceptron
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 ...
please put your error statement before your code explanation, so folks here know, what to look for.
i can't find:
ProjectedHistogram
I have made some changes ! thanks for commenting !
btw, the error msg is a bit misleading, it's all about your TrainClasses (the "output"), not about the TrainData.
btw, cv::reduce() does the same as your projection
is
Classes.cols == numCharacters
?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
I think I messed up all the things I have read :(
In
createDataForTraining
theclasses
variable in setted and save in the xml fileMaybe you want to talk about
TrainingClasses
and yesTrainingClasses.cols == numCharacters