Search code examples
opencvbitmapandroidcorner-detection

converting a Mat into Bitmap causes an error


I am working with OpenCV4Android version 2.4.11, and I am trying to detect cornrs in the image. For that purpose, I am using Harris corner detector.the problem i am facing is, after detecting the corners in the image as shown below in the code I want to display the image that contains the detected corners after converting it into Bitmap, but then i receive the below posted error.

step 1 and step 2 are executed without errors, but when i run step 3 i get the posted logcat error.

Please let mek know why i am receiving this error and how to solve it?

code:

//step 1
this.mMatGray = new Mat();
Imgproc.cvtColor(this.mMatInputFrame, this.mMatGray, Imgproc.COLOR_BGR2GRAY);

//step 2
Imgproc.cornerHarris(mMatGray,mMatGray,3,3,3,1);

//step 3
final Bitmap bitmap = Bitmap.createBitmap(mMatInputFrame.cols(), mMatInputFrame.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mMatGray, bitmap);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mIVEdges.setImageBitmap(bitmap);
    }
});

error:

OpenCV Error: Assertion failed (src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4) in void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean), file /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp, line 98
E/org.opencv.android.Utils: nMatToBitmap catched cv::Exception: /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp:98: error: (-215) src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4 in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)
E/AndroidRuntime: FATAL EXCEPTION: Thread-2477
Process: com.example.cornerdetection_00, PID: 22407
CvException [org.opencv.core.CvException: /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp:98: error: (-215) src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4 in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)
]
at org.opencv.android.Utils.nMatToBitmap2(Native Method)
at org.opencv.android.Utils.matToBitmap(Utils.java:123)
at org.opencv.android.Utils.matToBitmap(Utils.java:132)
at com.example.cornerdetection_00.FragOpenCVCam.cornerHarris(FragOpenCVCam.java:204)
at com.example.cornerdetection_00.FragOpenCVCam.onCameraFrame(FragOpenCVCam.java:159)
at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:387)
at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:346)

update1:

now after testing the following code provided by "MIkka Marmik" i recieve the errors below

code:

Mat mMatGray = new Mat();
Imgproc.cvtColor(mMatGray, mMatGray, Imgproc.COLOR_BGR2GRAY);
//step 2
Imgproc.cornerHarris(mMatGray,mMatGray,3,3,3,1);
//step 3
final Bitmap bitmap = Bitmap.createBitmap(mMatGray.cols(), mMatGray.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mMatGray, bitmap);

error:

OpenCV Error: Assertion failed (scn == 3 || scn == 4) in void cv::cvtColor(cv::InputArray, cv::OutputArray, int, int), file /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/imgproc/src/color.cpp, line 3739
E/org.opencv.imgproc: imgproc::cvtColor_11() caught cv::Exception: /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/imgproc/src/color.cpp:3739: error: (-215) scn == 3 || scn == 4 in function void cv::cvtColor(cv::InputArray, cv::OutputArray, int, int)
E/AndroidRuntime: FATAL EXCEPTION: Thread-4693

Solution

  • The createBitmap method is expecting an image which is either 1,3 or 4 channels. You must convert your output mMatGray to the format required for the createBitmap method. However, after checking the OpenCV documentation for the Harris corner algorithm, there are a few more steps involved to set up your image for corner detection. Try this out:

    Mat src_gray        = new Mat();
    Mat dst             = new Mat();
    Mat dst_norm        = new Mat();
    Mat dst_norm_scaled = new Mat();
    
    // Detector parameters
    int blockSize = 2;
    int apertureSize = 3;
    double k = 0.04;
    // Filter params
    int thresh = 200;
    int max_thresh = 255;
    
    // Detecting corner
    Imgproc.cvtColor(src, src_gray, Imgproc.COLOR_BGR2GRAY);
    Imgproc.cornerHarris(src_gray, dst, blockSize, apertureSize, k);
    
    // Normalizing
    Core.normalize(dst, dst_norm, 0, 255, Core.NORM_MINMAX);
    Core.convertScaleAbs(dst_norm, dst_norm_scaled);
    
    // Drawing a circle around corners
    for (int j = 0; j < dst_norm.rows(); j++) {
        for (int i = 0; i < dst_norm.cols(); i++) {
            if (dst_norm.get(j, i)[0] > thresh) {
                Core.circle(dst_norm_scaled, new Point(i, j), 5, new Scalar(255));
            }
        }
    }
    
    // Create bitmap
    final Bitmap bitmap = Bitmap.createBitmap(dst_norm_scaled.cols(), dst_norm_scaled.rows(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(dst_norm_scaled, bitmap);