20x20 Mat gets reshaped to 1x1200, expected 1x400 for kNearest [closed]

asked 2020-01-03 17:14:26 -0600

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 ...

(more)
edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by berak
close date 2020-01-04 07:37:17.798338

Comments

since 1200 = 400 * 3 i guess, you load your train images as bgr, where grayscale is expected

berak gravatar imageberak ( 2020-01-04 02:39:07 -0600 )edit

Thank 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.

JWKowns gravatar imageJWKowns ( 2020-01-04 03:47:21 -0600 )edit

again, type and cols must match. we cannot check from here.

berak gravatar imageberak ( 2020-01-04 03:53:29 -0600 )edit

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?

JWKowns gravatar imageJWKowns ( 2020-01-04 04:01:22 -0600 )edit

test image should not be isSubMat after the resize(). can it be you use different code, than you show above ?

berak gravatar imageberak ( 2020-01-04 05:30:14 -0600 )edit

Sorry, I'm not sure wha you mean by "different code", can I check that somehow or convert it?

JWKowns gravatar imageJWKowns ( 2020-01-04 05:41:59 -0600 )edit

different program

berak gravatar imageberak ( 2020-01-04 05:48:04 -0600 )edit

Oh I thought you were refering to something opencv related. No that is the exact code I'm using.

JWKowns gravatar imageJWKowns ( 2020-01-04 06:11:26 -0600 )edit
1

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.

JWKowns gravatar imageJWKowns ( 2020-01-04 06:12:19 -0600 )edit