Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the Mat object from the Byte[] in openCV android?

I am working with OpenCV library in Android. I have a class which implements PictureCallBack.

The override method onPictureTaken() is as given below,

     @Override
public void onPictureTaken(byte[] data, Camera camera) {
    Log.i(TAG, "Saving a bitmap to file");
    // The camera preview was automatically stopped. Start it again.
    mCamera.startPreview();
    mCamera.setPreviewCallback(this);

    // Write the image in a file (in jpeg format)
    try {
        FileOutputStream fos = new FileOutputStream(mPictureFileName);
        fos.write(data);
        fos.close();

    } catch (java.io.IOException e) {
        Log.e("PictureDemo", "Exception in photoCallback", e);
    }
}

As I want image data to be used further in image processing in stead of saving and reloading the image.

What is the most efficient way for getting the Mat object from the Byte array? I have already tried these approaches:

  1. Don't know what happened to the image.

    Mat m=new Mat(); m.put(0,0,data);

  2. Converting to Bitmap then use bitmapToMat() In this case , red color becomes blue .

I also don't have any problem in saving the image for future use,but this leads me an exception because the file not have been generated yet, when I am using the previously stored image.

like image 933
Ankur Gautam Avatar asked Jan 14 '14 12:01

Ankur Gautam


3 Answers

You have to specify width and height of the image/Mat and channels depth.

Mat mat = new Mat(width, height, CvType.CV_8UC3);
mat.put(0, 0, data);

Make sure you are using correct type of Mat. Maybe your data is not in 3 bytes RGB format and you should use another type e.g. CvType.CV_8UC1.
Good luck!

like image 168
lukk Avatar answered Nov 14 '22 11:11

lukk


The best and easiest way is like this:

byte[] bytes = FileUtils.readFileToByteArray(new File("aaa.jpg"));
Mat mat = Imgcodecs.imdecode(new MatOfByte(bytes), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED);
like image 40
Bahramdun Adil Avatar answered Nov 14 '22 10:11

Bahramdun Adil


opencv has a neat way to writing Mats to files - it can generate different formats based on the file extension provided. Here is a minimal example:

    public void writeImageToFile(Mat image, String filename) {

    File root = Environment.getExternalStorageDirectory();
    File file = new File(root, filename);

    Highgui.imwrite(file.getAbsolutePath(), image);

    if (DEBUG)
        Log.d(TAG,
                "writing: " + file.getAbsolutePath() + " (" + image.width()
                        + ", " + image.height() + ")");
}

if red and blue is swapped then it sounds like your byte data from onPictureTaken() is in BGRA format. You can swap it to RGBA using:

Imgproc.cvtColor(bgrImg, rgbImg, Imgproc.COLOR_BGR2RGB);

the format is actually device specific - on one device I had it comes through as YUV.

like image 1
timegalore Avatar answered Nov 14 '22 10:11

timegalore