I'm still new to OpenCV, but already learned a lot. I am however stuck on the K-NN Algorithm. I'm writing some software to read energy meters and I already succesfully wrote the image processing part. When the processing is finished, I end up with digits like this:
For the K-NN part (training and etc), I used almost all code from this OpenCV question. However, when running the following code (and doing the nescessary training in advance):
Mat one_feature = Imgcodecs.imread("/Users/jeremyk/Desktop/output/digits/digit0.png", 0);
Imgproc.resize(one_feature, one_feature, new Size(20, 20));
Mat res = new Mat();
one_feature.convertTo(one_feature, CvType.CV_32F);
one_feature.reshape(1,1);
float p = knn.findNearest(one_feature, 1, res);
I'm getting this nasty error:
OpenCV Error: Assertion failed (test_samples.type() == 5 && test_samples.cols == samples.cols) in cv::ml::BruteForceImpl::findNearest, file C:\build\master_winpack-bindings-win64-vc14-static\opencv\modules\ml\src\knearest.cpp, line 325
Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: C:\build\master_winpack-bindings-win64-vc14-static\opencv\modules\ml\src\knearest.cpp:325: error: (-215) test_samples.type() == 5 && test_samples.cols == samples.cols in function cv::ml::BruteForceImpl::findNearest]
I can't seem to find any solution to this.. Anyone got a clue?
Thanks in advance!
Edit: import as grayscale and resize image added to one_feature in an attempt to solve the error.
Edit 2: Here's the training/testing code that I'm using
Edit 3: Here's the updated training/test code that I'm using
for (int c = 0; c< numberOfTrainingDigits; c++) {
// crop out 1 digit:
digit = Imgcodecs.imread("/Users/jeremyk/Desktop/training/digit" + c + ".png");
Mat num = new Mat();
Imgproc.resize(digit, num, new Size(60, 110));
// we need float data for knn:
num.convertTo(num, CvType.CV_32F);
// for opencv ml, each feature has to be a single row:
trainData.push_back(num.reshape(1,1));
trainLabs.add(c);
}
}
// Add test
digit
image
Mat testDigit = Imgcodecs.imread("/Users/jeremyk/Desktop/testdigit.png", 0);
Mat num =
testDigit.submat(new Rect(0,0,60,110));
new Mat();
Imgproc.resize(testDigit, num, new Size(60, 110));
// we need float data for knn:
num.convertTo(num, CvType.CV_32F);
testData.push_back(num.reshape(1,1));
// Add label for test digit
testLabs.add(6);
// make a Mat of the train labels, and train knn:
KNearest knn = KNearest.create();
knn.train(trainData, Ml.ROW_SAMPLE, Converters.vector_int_to_Mat(trainLabs));
// now test predictions:
for (int j=0; j<testData.rows(); j++)
{
Mat one_feature = testData.row(j);
int testLabel = testLabs.get(j);
Mat res = new Mat();
float p = knn.findNearest(one_feature, 1, res);
System.out.println(testLabel + " " + p + " " + res.dump());
}