What I'm attempting to do is take a thresholded image and perform findContours on it then draw it out to a rotation corrected image. The rotation corrected image and the thresholded image work as expected so I'm at a bit of a loss figuring out why this would crash. The thersholded image is a grey version of the rotation corrected image that has had a binary threshold applied to it.
public void findImageContours(Mat passedThreshInt, Mat passedRotatedInit)
{
/* Get Thresholded input image */
Mat initThresh = passedThreshInt.clone();
/* Get image to draw Contours on */
Mat initRotated = passedRotatedInit.clone();
/* Get contours from threshold image */
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(initThresh, contours, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
/* Draw Contours */
Scalar CONTOUR_COLOR = new Scalar(255,0,0,255);
Log.e(TAG, "Contours count: " + contours.size());
Imgproc.drawContours(initRotated, contours, -1, CONTOUR_COLOR);
/* Save Output */
contouredInit = initRotated.clone(); //ContouredInit is Global
Utils.matToBitmap(contouredInit, contouredBitmapInit); // contouredBitmapInit is Global
}
Error:
OpenCV Error: Assertion failed (src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols) 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 97
nMatToBitmap catched cv::Exception: /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)
And after that a JDI Dispatch Error.
Dimensions of Bitmap has to match the dimensions of OpenCV Mat. I suggest you create Bitmap as below.
Bitmap bitmapImg = Bitmap.createBitmap( matImg.cols(), matImg.rows(), Bitmap.Config.ARGB_8888 );
For future errors of these kind, a look into opencv github repository(1) might help you.
Related
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
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);
try this
Mat mMatGray = new Mat();
mMatGray = Highgui.imread(path);
Imgproc.cvtColor(mMatGray, mMatGray, Imgproc.COLOR_RGB2BGR);
Imgproc.cvtColor(mMatGray, mMatGray, Imgproc.COLOR_BGR2GRAY);
//step 2
Imgproc.cornerHarris(mMatGray,mMatGray,3,3,3,1);
Core.normalize(mMatGray, mMatGray, 0, 255, Core.NORM_MINMAX, CvType.CV_32FC1, new Mat());
Core.convertScaleAbs(mMatGray, mMatGray);
//step 3
final Bitmap bitmap = Bitmap.createBitmap(mMatGray.cols(), mMatGray.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mMatGray, bitmap);
The following are My Code for drawing border in openCV
Mat src = new Mat(imageChosen.getWidth(), imageChosen.getHeight(), CvType.CV_8UC3);
Utils.bitmapToMat(imageChosen, src);
Mat dst = new Mat(imageChosen.getWidth(), imageChosen.getHeight(), CvType.CV_8UC3);
Core.copyMakeBorder(src, dst, 10, 10, 10, 10, Core.BORDER_CONSTANT, new Scalar(0,0,0));
Bitmap b = Bitmap.createBitmap(imageChosen.getWidth()+20, imageChosen.getHeight()+20,Bitmap.Config.ARGB_8888);
Utils.matToBitmap(src, b);
and i don't know why it throw
E/cv::error(): OpenCV Error: Assertion failed (src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols) in void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean), file /Volumes/Linux/builds/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp, line 97
E/org.opencv.android.Utils: nMatToBitmap catched cv::Exception: /Volumes/Linux/builds/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)
Any help/ideas would be greatly appreciated, thanks.
If you take a look at the documentation of Mat, you can see that the constructor expects its params in the following order: rows, columns.
You're passing the width (columns) first and the height (rows) after.
Instead of the following:
Mat src = new Mat(imageChosen.getWidth(), imageChosen.getHeight(), CvType.CV_8UC3);
You should pass the height first:
Mat src = new Mat(imageChosen.getHeight(), imageChosen.getWidth(), CvType.CV_8UC3);
For both src and dst.
I have an application using A JavaCameraView from OpenCV for android that uses the following callback
CameraBridgeViewBase.CvCameraViewListener cvListener = new CameraBridgeViewBase.CvCameraViewListener() {
#Override
public void onCameraViewStarted(int width, int height) {
}
#Override
public void onCameraViewStopped() {
}
#Override
public Mat onCameraFrame(Mat inputFrame) {
Size newSize = new Size(400, 200);
Mat fit = new Mat(newSize, CvType.CV_8UC4);
Imgproc.resize(inputFrame,fit,newSize);
return fit;
}
};
However, when the resizing happens, an error occurs saying
E/CameraBridge: Utils.matToBitmap() throws an exception: /Volumes/Linux/builds/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)
E/cv::error(): OpenCV Error: Assertion failed (src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols) in void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean), file /Volumes/Linux/builds/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp, line 97
E/org.opencv.android.Utils: nMatToBitmap catched cv::Exception: /Volumes/Linux/builds/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)
E/CameraBridge: Mat type: Mat [ 244*432*CV_8UC4, isCont=true, isSubmat=false, nativeObj=0x1ade1b0, dataAddr=0x5dbc6010 ]
E/CameraBridge: Bitmap type: 240*160
Nothing happens in the actual UI. I'm not sure why I'm seeing this error, since I'm never calling Utils.bitmapToMat or Utils.matToBitmap. When I take out the Imgproc.resize(inputFrame,fit,newSize); and return the inputFrame, everything works as expected.
For onCameraFrame, I believe you have to return the Mat of the same size as your inputFrame. Since the resolution of the image obtained from your camera is
240*160 (refer this-> E/CameraBridge: Bitmap type: 240*160) you will need to resize your Mat fit back to 240*160 after you done your processing..
A simple fix:
#Override
public Mat onCameraFrame(Mat inputFrame) {
Size newSize = new Size(400, 200);
Mat fit = new Mat(newSize, CvType.CV_8UC4);
Imgproc.resize(inputFrame,fit,newSize);
/**Your processing code */
Imgproc.resize(fit,fit,inputFrame.size()); <- Add this line
return fit;
}
To change the size of the image you receive from camera, you have to call mOpenCvCameraView.setMaxFrameSize(width, height); but the resolution will be chosen from the list of resolutions supported by the camera hardware. To know more why you can't set an arbitrary value for the resolution you'll need to read on Android Camera API, since that's what OpenCV uses to grab the images at the back :)
Can anybody tell me what am I doing wrong or give me example how to create AND DISPLAY histogram from grayscale mat in OpenCV4 Android? There is my code...
Vector<Mat> bgr_planes = new Vector<Mat>();
Core.split(cleanFaceMatGRAY, bgr_planes);
MatOfInt histSize = new MatOfInt(256);
final MatOfFloat histRange = new MatOfFloat(0f, 256f);
boolean accumulate = false;
Mat b_hist = new Mat();
Imgproc.calcHist(bgr_planes, new MatOfInt(0),new Mat(), b_hist, histSize, histRange, accumulate);
And then I try to set it to Image view to see it:
ivPickedPhoto.setImageBitmap(AppTools.createBitmapFromMat(b_hist, Bitmap.Config.ARGB_8888));
Method for display was created on my own:
public class AppTools {
public static Bitmap createBitmapFromMat(Mat mat, Bitmap.Config config) {
Bitmap bmp2 = null;
bmp2 = Bitmap.createBitmap(mat.cols(), mat.rows(), config);
Utils.matToBitmap(mat, bmp2);
return bmp2;
}
This gives me an error in the ivPickedPhoto(...) lane:
12-10 21:12:59.910: E/AndroidRuntime(10301): Caused by: CvException [org.opencv.core.CvException: /home/reports/ci/slave_desktop/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)
I guess my problem is with the way I want to display the histogram... prolly I cant convert it to bmp. What is a good way to show histogram?
The OpenCV Java Documentation states that the Mat object you are passing should be of type CV_8UC1, CV_8UC3 or CV_8UC4. The documentation of calcHist doesn't really specify which type you should expect your b_Hist to be, but since it is complaining about the Mat type:
error: (-215) src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4
you should probably convert it to either of the three above formats.
In android i am trying to scale my mat using following code.
Mat destMat = new Mat();
Size newSize=new Size(output.width()/6.0f, output.height()/6.0f);
Imgproc.resize(output, destMat, newSize, 0, 0, Imgproc.INTER_CUBIC);
When it try to execute the resize method i get following exception. My code is in onCameraFrame().
MatToBitmap catched cv::Exception:
/home/reports/ci/slave_desktop/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp:97:
error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows &&
info.width == (uint32_t)src.cols in function void
Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong,
jobject, jboolean)
Where the variable 'newSize' is, you actually want the original size of destMat. You can scale it down by using the fx and fy parameters. From the javadocs:
The function resize resizes the image src down to or up to the
specified size.Note that the initial dst type or size are not taken
into account. Instead, the size and type are derived from the
src,dsize,fx, and fy.
Later on:
// explicitly specify dsize=dst.size(); fx and fy will be computed
from that.