Convert a bitmap to mat and vice versa in OpenCV - android

I have an Android Bitmap in my code and I would like to run the
cvCanny method on it. However, it needs to be in a Mat first. How do I
convert the data to Mat, and how do I convert it back to Bitmap when
I'm done?

First import org.opencv.android.Utils
Then use:
Mat src = new Mat();
Utils.bitmapToMat(bitmap, src);
To perform edge detection:
Mat dest = new Mat();
Imgproc.Canny(src, dest, min, max);
Bitmap edgeBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dest, edgeBitmap);
//edgeBitmap is ready

Related

Getting java.lang.IllegalArgumentException: width and height must be > 0 error while initializing Mat in android

I am trying to initialize Mat and this is my code
Mat imgRgba = new Mat();
final Bitmap bitmap =
Bitmap.createBitmap(imgRgba.width(), imgRgba.height(), Bitmap.Config.RGB_565);
Utils.matToBitmap(imgRgba, bitmap);
I have tried this too
Bitmap.createBitmap(imgRgba.cols(), imgRgba.rows(), Bitmap.Config.RGB_565);
but when I am going to run my app I am getting crash and exception is this
Stack trace:
java.lang.IllegalArgumentException: width and height must be > 0
at android.graphics.Bitmap.createBitmap(Bitmap.java:969)
at android.graphics.Bitmap.createBitmap(Bitmap.java:948)
at android.graphics.Bitmap.createBitmap(Bitmap.java:915)
at com.jmr.agency.banking.ui.facerecognition.FRAddPersonPreviewActivity.onCameraFrame(FRAddPersonPreviewActivity.java:156)
Try either mat.create(int rows, int cols, int type) or some other constructor for Mat object, as currently it does not have a size.
You did new instance Mat for size. But it has no size.If you have bitmap or Mat data you can use your code like this:
private Bitmap getBitmap(Mat imgRgb){
final Bitmap bitmap =
Bitmap.createBitmap(imgRgba.width(), imgRgba.height(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(imgRgba, bitmap);
return bitmap;
}
Now you can call this method with your existing Mat data for convert your Mat data to bitmap.
Or you can convert your Bitmap to Mat:
private Bitmap getMat(Bitmap bitmap){
Mat mat = new Mat();
mat = Utils.bitmapToMat(bitmap,mat);
return mat;
}
Hope you understand.

Converting Bitmap To Mat through Utils.bitmapToMat changes its color [duplicate]

So I make a bitmap from a blob with the next code:
byte[] blob = contact.getMP();
ByteArrayInputStream inputStream = new ByteArrayInputStream(blob);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
Bitmap scalen = Bitmap.createScaledBitmap(bitmap, 320, 240, false);
and it gives back the next output, which is good
Then I do the following to make the bitmap into a Mat, but then my colors just change...
//Mat ImageMat = new Mat();
Mat ImageMat = new Mat(320, 240, CvType.CV_32F);
Utils.bitmapToMat(scalen, ImageMat);
I have no idea why, nor another way to make the bitmap into a Mat. What is wrong?
The format of color channels in Android Bitmap are RGB
But in opencv Mat, the channels are BGR by default.
So when you do Utils.bitmapToMat(), [B,G,R] values are stored in [R,G,B] channels. The red and blue channels are interchanged.
One possible solution is to apply cvtcolor on the opencv Mat you got as below:
Imgproc.cvtColor(ImageMat, ImageMat, Imgproc.COLOR_BGR2RGB);
It worked for me.

Android Image Processing using OpenCV

I am processing a camera frame using OpenCV. The functionality is working fine. However, it takes between 40~60 ms to process each frame. I am wondering if there is a possibility to improve the execution time. Following are the steps I take before I pass the mat to OpenCV cascade classifier.
mPixelBuf.rewind();
GLES20.glReadPixels(0, 0, mWidth, mHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPixelBuf);
Bitmap bmp = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
mPixelBuf.rewind();
bmp.copyPixelsFromBuffer(mPixelBuf);
// received inverted(upside-down) bitmap. Fixing it.
android.graphics.Matrix m = new android.graphics.Matrix();
m.preScale(1, -1);
Bitmap flipped = Bitmap.createBitmap(bmp, 0, 0, mWidth, mHeight, m, false);
Mat mat = new Mat();
// convert bitmap to mat
Utils.bitmapToMat(flipped, mat);
// apply gray scale
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_BGR2GRAY);
// pass the mat to cascade classifier...
I guess there could be some smart ways to avoid this extra processing or perhaps reduce the image resolution for faster image processing.

Convert Mat to Bitmap by opencv

I'm trying to convert Mat rectangle from onCameraFrame to bitmap then send the bitmap to ocr function because i need to make the ocr works on real-time on ROI according to rectangle. I tried these lines:
Mat mgray= inputFrame.gray();
Mat grayInnerWindow = mgray.submat(100, 100 +500, 150, 200 + 50);
Imgproc.cvtColor(mIntermediateMat, rgbaInnerWindow, Imgproc.COLOR_GRAY2BGRA, 4);
rgbaInnerWindow.release();
Size sizeGray = grayInnerWindow.size();
int rowss = (int) sizeGray.height;
int colss = (int) sizeGray.width;
Mat tmp = new Mat(colss, rowss, CvType.CV_8UC4);
Imgproc.cvtColor(rgbaInnerWindow, tmp, Imgproc.COLOR_RGBA2BGRA, 4);
Bitmap bmp = Bitmap.createBitmap(tmp.cols(), tmp.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(tmp, bmp);
ImageView Img = (ImageView)findViewById(R.id.image_manipulations_activity_surface_view);
Img.setImageBitmap(bmp);
but when i run it terminated.
you are releasing rgbaInnerWindow, then you re-use it as input to cvtColor.
yep, that will burn, rgbaInnerWindow is invalid/empty now..
also, why all those cvtColor calls ? can't you just pass an 8bit grayscale image to your ocr?
(converting a 4channel, all grayscale image from rgba to bgra is utterly useless)

Utils.bitmapToMat crashing app

I'm trying to convert a bmp file into a Mat, and then convert it to greyscale. But I'm having trouble getting it working. Here's what I've got:
String filename = "/mnt/sdcard/DCIM/01.bmp";
Bitmap bmp = BitmapFactory.decodeFile(filename);
Mat imgToProcess = null;
Utils.bitmapToMat(bmp, imgToProcess);
But whenever that final line is used, the app just crashes (the rest of the time it continues on just fine).
The rest of the code was going to be:
Imgproc.cvtColor(imgToProcess, imgToProcess, Imgproc.COLOR_BGR2GRAY);
Imgproc.cvtColor(imgToProcess, imgToProcess, Imgproc.COLOR_GRAY2RGBA, 4);
Utils.matToBitmap(imgToProcess, bmp);
I've no idea whether or not that works though, since I can't get the file converted to a Mat yet from the earlier part of the code. Looking at the documentation for Utils (found here) I'm using it correctly, but it's still not working.
Can anyone help me out here?
Change line:
Mat imgToProcess = null;
to this:
Mat imgToProcess = new Mat();
or this:
Mat imgToProcess = new Mat(bmp.getHeight(), bmp.getHeight(), CvType.CV_8UC4);
And why don't you just use Highgui.imread instead?
Mat imgToProcess = Highgui.imread(filename);

Categories

Resources