2

In the App I am developing I open the Camera using OpenCV4Android using CameraBridgeViewBase.CvCameraViewListener2 and when I touch the screen I set that frame as an image inside an ImageView as shown below in the code. the problem is the image set to the imageview is always of different color than the preview on the camera as shown in the picture. I believe that this issue has something to do with the conversion I made which is stated in the code below

My question is how to convert the Mat object to a Bitmap preserving the same color?

pic

enter image description here code:

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    Log.w(TAG, "onCameraFrame");
    if (mRGBT != null) {
        mRGBT.release();
    }

    mRGBT = inputFrame.rgba().t();
    Core.flip(mRGBT, mRGBT, 1);
    Imgproc.resize(mRGBT, mRGBT, inputFrame.rgba().size());

    if (touched) {
        touched = false;
        Imgproc.cvtColor(mRGBT, mRGBT, CvType.CV_8U);
        final Bitmap bitmap = Bitmap.createBitmap(mRGBT.cols(), mRGBT.rows(), Bitmap.Config.RGB_565);
        Utils.matToBitmap(mRGBT, bitmap);

        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mIV.setImageBitmap(bitmap);
            }
        });
    }

    return mRGBT;
}
Amrmsmb
  • 1
  • 27
  • 104
  • 226
  • OpenCV works with BGR images. You convert the frame to RGB. – Dan Mašek Oct 10 '16 at 12:14
  • As Dan has stated the colour order is incorrect your Red and Blue channels are in a different order – EdChum Oct 10 '16 at 12:15
  • @DanMašek do u mean this line: Bitmap.createBitmap(mRGBT.cols(), mRGBT.rows(), Bitmap.Config.RGB_565);..if that is what you mean, there is no option for BGR!! – Amrmsmb Oct 10 '16 at 12:16

2 Answers2

4

You are converting the image incorrectly.

If you want the bitmap to be a color image, you don't need the cvtColor. inputFrame.rgba() returns a RGBA Mat and that is the input you need for Utils.matToBitmap (See JavaDoc).

if (touched) {
    touched = false;
    final Bitmap bitmap = 
            Bitmap.createBitmap(mRGBT.cols(), mRGBT.rows(), Bitmap.Config.RGB_565);
    Utils.matToBitmap(mRGBT, bitmap);
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mIV.setImageBitmap(bitmap);
        }
    });
}

If you want the bitmap to be a gray image use Imgproc.COLOR_BGRA2GRAY:

if (touched) {
    touched = false;
    Imgproc.cvtColor(mRGBT, mRGBT, Imgproc.COLOR_BGRA2GRAY);
    final Bitmap bitmap = 
            Bitmap.createBitmap(mRGBT.cols(), mRGBT.rows(), Bitmap.Config.RGB_565);
    Utils.matToBitmap(mRGBT, bitmap);
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mIV.setImageBitmap(bitmap);
        }
    });
}

If you need to work with bitmaps Bitmap.Config.ARGB_8888 add true as a third parameter in Utils.matToBitmap, so the Mat is converted to alpha premultiplied format (See JavaDoc).

final Bitmap bitmap =
        Bitmap.createBitmap(mRGBT.cols(), mRGBT.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mRGBT, bitmap, true);
David Miguel
  • 12,154
  • 3
  • 66
  • 68
1

I am using this and it works fine:

Mat mat = inputFrame.rgba();
Bitmap bm = Bitmap.createBitmap(mat.cols(), mat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mat, bm);
Roman Samoilenko
  • 932
  • 12
  • 25