Pagorn Petchara Pagorn Petchara - 1 month ago 6
Android Question

How to use threshold on CameraFrame android + openCV

I try to use threshold in openCV sample code "ColorBlobDetection". But I found some error.

The error.

11-13 20:10:03.798 28032-30391/app.heng.opencv E/cv::error()﹕ OpenCV Error: Assertion failed (src.type() == CV_8UC1) in double cv::threshold(cv::InputArray, cv::OutputArray, double, double, int), file /home/reports/ci/slave_desktop/50-SDK/opencv/modules/imgproc/src/thresh.cpp, line 719
11-13 20:10:03.828 28032-30391/app.heng.opencv E/org.opencv.imgproc﹕ imgproc::threshold_10() caught cv::Exception: /home/reports/ci/slave_desktop/50-SDK/opencv/modules/imgproc/src/thresh.cpp:719: error: (-215) src.type() == CV_8UC1 in function double cv::threshold(cv::InputArray, cv::OutputArray, double, double, int)
11-13 20:10:03.858 28032-30391/app.heng.opencv E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-10693
CvException [org.opencv.core.CvException: cv::Exception: /home/reports/ci/slave_desktop/50-SDK/opencv/modules/imgproc/src/thresh.cpp:719: error: (-215) src.type() == CV_8UC1 in function double cv::threshold(cv::InputArray, cv::OutputArray, double, double, int)
]
at org.opencv.imgproc.Imgproc.threshold_0(Native Method)
at org.opencv.imgproc.Imgproc.threshold(Imgproc.java:9180)
at app.heng.opencv.ColorBlobDetectionActivity.onCameraFrame(ColorBlobDetectionActivity.java:241)
at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:387)
at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:328)
at java.lang.Thread.run(Thread.java:841)


Here sample picture before use threshold.
Here sample picture before use threshold

Here sample picture after use threshold that I want.
Here sample picture after use threshold that I want

The openCV sample code

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba(); // mRbga = input frame with color
MatOfPoint2f approxCurve = new MatOfPoint2f();

if (mIsColorSelected) {
mDetector.process(mRgba);
final List<MatOfPoint> contours = mDetector.getContours(); //contour info is ready in detector
Log.e(TAG, "Contours count: " + contours.size());

Core.putText(mRgba, ""+contours.size(), new Point(mRgba.cols()/2, mRgba.rows()/2), 3, 1, new Scalar(255, 255, 255, 255), 2);

//green contous and size=5
Imgproc.drawContours(mRgba, contours, -1, new Scalar(0, 255, 0), 3);



Imgproc.threshold(mRgba, mRgba, 0, 255, Imgproc.THRESH_OTSU);



Mat colorLabel = mRgba.submat(4, 68, 4, 68);
colorLabel.setTo(mBlobColorRgba);
Mat spectrumLabel = mRgba.submat(4, 4 + mSpectrum.rows(), 70, 70 + mSpectrum.cols());
mSpectrum.copyTo(spectrumLabel);
}

return mRgba;
}


This is original source code Here

Answer

As the docs says:

public static double threshold(Mat src, Mat dst, double thresh, double maxval, int type)

Parameters:

  • src - Source array (single-channel, 8-bit or 32-bit floating point).
  • dst - Destination array of the same size and type as src.
  • thresh - Threshold value.
  • maxval - Maximum value to use with the THRESH_BINARY and THRESH_BINARY_INV thresholding types.
  • type - Thresholding type (see the details below).

You need to convert mRgba to single-channel Mat.

cvtColor: Imgproc.cvtColor(input, output, Imgproc.COLOR_BGRA2GRAY, 1);