Android svm implementation error
I tried to implement svm in my android application but when i run my application i get errors.
// Creating Training Data
Mat trainData = new Mat();
Mat train_labels = new Mat();
for (int i = 0; i <549; i++) {
String path = Environment.getExternalStorageDirectory().toString()
+ "/Pictures/train/" + i + ".png";
Mat img = Imgcodecs.imread(path);
Log.i(TAG,"error"+i+img.empty());
img.convertTo(img, CvType.CV_32FC1); // Convert to float
Size dsize = new Size(25, 25);
Imgproc.resize(img, img, dsize);
img.convertTo(img, CvType.CV_32FC1);
Mat imgResized = img.reshape(1, 1); // make continuous
trainData.push_back(imgResized);
// add 1 item
train_labels
.push_back(new Mat(1, 1, CvType.CV_32FC1, new Scalar(i)));
}
Mat response = new Mat();
Mat tmp;
tmp = train_labels.reshape(1, 1); // make continuous
tmp.convertTo(response, CvType.CV_32FC1); // Convert to float
SVM svm = SVM.create();
TermCriteria criteria = new TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER,100,0.1);
svm.setKernel(SVM.LINEAR);
svm.setType(SVM.C_SVC);
svm.setGamma(0.5);
svm.setNu(0.5);
svm.setC(1);
svm.setTermCriteria(criteria);
svm.train(trainData, Ml.ROW_SAMPLE,train_labels);
// For Storing training data
File datasetFile = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "dataset.xml");
svm.save(datasetFile.getAbsolutePath());
And this is the error:
05-28 11:05:01.921: E/cv::error()(2252): OpenCV Error: Bad argument (in the case of classification problem the responses must be categorical; either specify varType when creating TrainData, or pass integer responses) in virtual bool cv::ml::SVMImpl::train(const cv::Ptr<cv::ml::traindata>&, int), file /home/maksim/workspace/android-pack/opencv/modules/ml/src/svm.cpp, line 1610 05-28 11:05:01.931: E/org.opencv.ml(2252): ml::train_10() caught cv::Exception: /home/maksim/workspace/android-pack/opencv/modules/ml/src/svm.cpp:1610: error: (-5) in the case of classification problem the responses must be categorical; either specify varType when creating TrainData, or pass integer responses in function virtual bool cv::ml::SVMImpl::train(const cv::Ptr<cv::ml::traindata>&, int)
Make labels of type
CV_32SC1
instead ofCV_32FC1
when i change type of label i got this error: 05-28 11:25:30.378: E/cv::error()(9388): OpenCV Error: Insufficient memory (Failed to allocate 1128195000 bytes) in void* cv::OutOfMemoryError(size_t), file /home/maksim/workspace/android-pack/opencv/modules/core/src/alloc.cpp, line 52 05-28 11:25:30.378: E/cv::error()(9388): OpenCV Error: Assertion failed (u != 0) in void cv::Mat::create(int, const int, int), file /home/maksim/workspace/android-pack/opencv/modules/core/src/matrix.cpp, line 411 05-28 11:25:30.388: E/org.opencv.ml(9388): ml::train_10() caught cv::Exception: /home/maksim/workspace/android-pack/opencv/modules/core/src/matrix.cpp:411: error: (-215) u != 0 in function void cv::Mat::create(int, const int, int)
That's another problem. Basically, you have not enough memory for training the SVM
here:
as said before , you need integer, not float labels (and don't convert them later) also you probably don't want
i
as the class label. this would mean, that you have 549 different classes with 1 train image each only, which is a terrible setup. (and very expensive memory-wise, since the SVM internally tries to split it into one SVM per class)last, you might want to train your SVM with tons of data on a beefy pc, not your phone ..
what are you actually trying to classify ?
In my application i should get images from data base and try to train them using opencv svm .Really i don't understand how to change i and how put my training data in classes
"Really i don't understand ..." - yes, that's obvious.
again, what is the classification problem ? apples vs pears ? person identification ? what is it ?
I have to recognize letters in an image .so i try to submat each letter from text extracted from image taken by phone camera and then i shoud recognize each letter (i can't use ocr because image is a latin manuscrit so letters aren't very clear) by refering to svm algorithm for opencv.So if i understand i should create for each letter a class ? but i don't know how
yes, each letter is a class,so a==1, b==2, ..etc. and you have to give those class numbers as labels, not
i
. later, when you try a prediction, you will get exactly those numbers back.when t tried to predict labels i got this error: OpenCV Error: Assertion failed (samples.cols == var_count && samples.type() == CV_32F) in virtual float cv::ml::SVMImpl::predict(cv::InputArray, cv::OutputArray, int) for (int i = 0; i < h; i++){