20x20 Mat gets reshaped to 1x1200, expected 1x400 for kNearest [closed]
I train my Model like this:
// Prepare Training Data
Mat trainData = new Mat();
int numWidth = 20;
for (int i = 0; i < digits.size().height; i += numWidth ) {
for (int j = 0; j < digits.size().width; j += numWidth) {
//Mat num = digits.submat(new Rect(j * numWidth, i * numWidth, numWidth, numWidth));
Mat num = new Mat(digits, new Rect(j, i, numWidth, numWidth));
// Convert to float data, needed for KNearest
num.convertTo(num, CvType.CV_32F);
num = num.reshape(1, 1);
trainData.push_back(num);
}
}
// Train Model
model = KNearest.create();
model.train(trainData, Ml.ROW_SAMPLE, Converters.vector_int_to_Mat(trainLabels));
And later I try to predict like this:
Mat number = new Mat(square, new Rect(bounds.x, bounds.y, bounds.width, bounds.height));
Imgproc.resize(number, number, new Size(20, 20));
saveImage("digit.png", number, context);
number.convertTo(number, CvType.CV_32F);
number = number.reshape(1, 1);
Mat res = new Mat();
float p = model.findNearest(number, 1, res);
But I get this Exception:
E/cv::error(): OpenCV(3.4.3) Error: Assertion failed (test_samples.type() == CV_32F && test_samples.cols == samples.cols) in virtual float cv::ml::BruteForceImpl::findNearest(cv::InputArray, int, cv::OutputArray, cv::OutputArray, cv::OutputArray) const, file /build/3_4_pack-android/opencv/modules/ml/src/knearest.cpp, line 312 E/org.opencv.ml: ml::findNearest_12() caught cv::Exception: OpenCV(3.4.3) /build/3_4_pack-android/opencv/modules/ml/src/knearest.cpp:312: error: (-215:Assertion failed) test_samples.type() == CV_32F && test_samples.cols == samples.cols in function 'virtual float cv::ml::BruteForceImpl::findNearest(cv::InputArray, int, cv::OutputArray, cv::OutputArray, cv::OutputArray) const' E/MethodChannel#openCV: Failed to handle method call CvException [org.opencv.core.CvException: cv::Exception: OpenCV(3.4.3) /build/3_4_pack-android/opencv/modules/ml/src/knearest.cpp:312: error: (-215:Assertion failed) test_samples.type() == CV_32F && test_samples.cols == samples.cols in function 'virtual float cv::ml::BruteForceImpl::findNearest(cv::InputArray, int, cv::OutputArray, cv::OutputArray, cv::OutputArray) const' ] at org.opencv.ml.KNearest.findNearest_2(Native Method) at org.opencv.ml.KNearest.findNearest(KNearest.java:79) at com.wallmann.flutter_sudoku_solver.SudokuSolver.readNumbers(SudokuSolver.java:291) at com.wallmann.flutter_sudoku_solver.SudokuSolver.solveChallenge(SudokuSolver.java:46) at com.wallmann.flutter_sudoku_solver.MainActivity.lambda$configureFlutterEngine$0$MainActivity(MainActivity.java:48) at com.wallmann.flutter_sudoku_solver.-$$Lambda$MainActivity$g3xDyIoaci2vBR5JzA2Kry58MDg.onMethodCall(Unknown Source:2) at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:231) at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:93) at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:642) at android.os.MessageQueue.nativePollOnce(Native Method) at android.os.MessageQueue.next(MessageQueue.java:325) at android.os.Looper.loop(Looper.java:142) at android.app.ActivityThread.main(ActivityThread.java:6710) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770) E/flutter: [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(error, cv::Exception: OpenCV(3.4.3) /build/3_4_pack-android/opencv/modules/ml/src/knearest.cpp:312: error: (-215:Assertion failed) test_samples.type() == CV_32F && test_samples.cols ...
since
1200 = 400 * 3
i guess, you load your train images as bgr, where grayscale is expectedThank you, that was indeed the reason why my training mats were 1x1200, I converted it tp greyscale and now it has the Size 1x400 but unfortunatly, that still didn't fix my issue, I still get the same exception.
again, type and cols must match. we cannot check from here.
They do match, both cols are 400 and type is 5 which is CV_32F. The only difference I can see is when prediction, for the mat isSubmat is true while for training its false. Could that be the issue?
test image should not be isSubMat after the resize(). can it be you use different code, than you show above ?
Sorry, I'm not sure wha you mean by "different code", can I check that somehow or convert it?
different program
Oh I thought you were refering to something opencv related. No that is the exact code I'm using.
I found my issue thank you so much for helping me! The color thing was my initial error, after that I screwed up and overwrote the reference for my model.