0

I want to serialize OpenCv Mat(https://docs.opencv.org/3.4.3/javadoc/index.html) to save in Preference(https://developer.android.com/reference/android/preference/Preference) and then deserialize it.

Heres how I serialize it.

        Mat cameraMatrix = {put some Mat value here};
        Gson gson = new Gson();
        String json;

        // serialize
        json = gson.toJson(Double.toString(cameraMatrix));

        // deserialize          
        cameraMatrix = gson.fromJson(json, Mat.class);

Unfortunately, it doesnt work as Java Mat stores nativeObject instead of real Mat values.

How do I serialize and deserialize Mat in Java?

Syaiful Nizam Yahya
  • 4,196
  • 11
  • 51
  • 71
  • What is `Mat`? Maybe at least put a link to that in your question. And: what makes you think that this Mat class supports such operations? – GhostCat Nov 16 '18 at 08:07
  • Could you store the key information and reconstruct it at runtime? – MeetTitan Nov 16 '18 at 08:09
  • @GhostCat Mat is OpenCv Mat. Updated my question. – Syaiful Nizam Yahya Nov 16 '18 at 08:34
  • Similar with this: [How to read image from database(sqlite Django) not local file?](https://stackoverflow.com/questions/53124921/how-to-read-image-from-databasesqlite-django-not-local-file/53138304#53138304) – Kinght 金 Nov 16 '18 at 08:38

2 Answers2

2

I got it working for my use case. Here are the serialization/deserialization class. I use the table here for reference. http://ninghang.blogspot.com/2012/11/list-of-mat-type-in-opencv.html

import com.google.gson.Gson;

import org.opencv.core.Mat;

class CommonUtility
{
//  Serialization/deserialization utility
    public static String SerializeFromMat(Mat mat)
    {
        SerializedMat serializedMat = new SerializedMat();
        serializedMat.setType(mat.type());
        serializedMat.setRows(mat.rows());
        serializedMat.setCols(mat.cols());

        if (serializedMat.getType()==0||
                serializedMat.getType()==8||
                serializedMat.getType()==16||
                serializedMat.getType()==24)
        {
            serializedMat.setBytes(new byte[(int)(mat.total()*mat.elemSize())]);
            mat.get(0,0,serializedMat.bytes);
        }
        else if (serializedMat.getType()==1||
            serializedMat.getType()==9||
            serializedMat.getType()==17||
            serializedMat.getType()==25)
        {
            serializedMat.setBytes(new byte[(int)(mat.total()*mat.elemSize())]);
            mat.get(0,0,serializedMat.bytes);
        }
        else if (serializedMat.getType()==2||
                serializedMat.getType()==10||
                serializedMat.getType()==18||
                serializedMat.getType()==26)
        {
            serializedMat.setShorts(new short[(int)(mat.total()*mat.elemSize())]);
            mat.get(0,0,serializedMat.shorts);
        }
        else if (serializedMat.getType()==3||
                serializedMat.getType()==11||
                serializedMat.getType()==19||
                serializedMat.getType()==27)
        {
            serializedMat.setShorts(new short[(int)(mat.total()*mat.elemSize())]);
            mat.get(0,0,serializedMat.shorts);
        }
        else if (serializedMat.getType()==4||
                serializedMat.getType()==12||
                serializedMat.getType()==20||
                serializedMat.getType()==28)
        {
            serializedMat.setInts(new int[(int)(mat.total()*mat.elemSize())]);
            mat.get(0,0,serializedMat.ints);
        }
        else if (serializedMat.getType()==5||
                serializedMat.getType()==13||
                serializedMat.getType()==21||
                serializedMat.getType()==29)
        {
            serializedMat.setFloats(new float[(int)(mat.total()*mat.elemSize())]);
            mat.get(0,0,serializedMat.floats);
        }
        else if (serializedMat.getType()==6||
                serializedMat.getType()==14||
                serializedMat.getType()==22||
                serializedMat.getType()==30)
        {
            serializedMat.setDoubles(new double[(int)(mat.total()*mat.elemSize())]);
            mat.get(0,0,serializedMat.doubles);
        }

        Gson gson = new Gson();
        return gson.toJson(serializedMat);
    }

    public static Mat DeserializeToMat(String json)
    {
        Gson gson = new Gson();
        SerializedMat serializedMat = gson.fromJson(json, SerializedMat.class);
        Mat mat = new Mat(serializedMat.getRows(),serializedMat.getCols(),serializedMat.getType());

        if (serializedMat.getType()==0||
                serializedMat.getType()==8||
                serializedMat.getType()==16||
                serializedMat.getType()==24)
        {
            mat.put(0,0,serializedMat.getBytes());
        }
        else if (serializedMat.getType()==1||
                serializedMat.getType()==9||
                serializedMat.getType()==17||
                serializedMat.getType()==25)
        {
            mat.put(0,0,serializedMat.getBytes());
        }
        else if (serializedMat.getType()==2||
                serializedMat.getType()==10||
                serializedMat.getType()==18||
                serializedMat.getType()==26)
        {
            mat.put(0,0,serializedMat.getShorts());
        }
        else if (serializedMat.getType()==3||
                serializedMat.getType()==11||
                serializedMat.getType()==19||
                serializedMat.getType()==27)
        {
            mat.put(0,0,serializedMat.getShorts());
        }
        else if (serializedMat.getType()==4||
                serializedMat.getType()==12||
                serializedMat.getType()==20||
                serializedMat.getType()==28)
        {
            mat.put(0,0,serializedMat.getInts());
        }
        else if (serializedMat.getType()==5||
                serializedMat.getType()==13||
                serializedMat.getType()==21||
                serializedMat.getType()==29)
        {
            mat.put(0,0,serializedMat.getFloats());
        }
        else if (serializedMat.getType()==6||
                serializedMat.getType()==14||
                serializedMat.getType()==22||
                serializedMat.getType()==30)
        {
            mat.put(0,0,serializedMat.getDoubles());
        }

        return mat;
    }

    private static class SerializedMat
    {
        byte[] bytes;
        short[] shorts;
        int[] ints;
        float[] floats;
        double[] doubles;

        int type;
        int rows;
        int cols;

        byte[] getBytes()
        {
            return bytes;
        }

        void setBytes(byte[] bytes)
        {
            this.bytes = bytes;
        }

        short[] getShorts()
        {
            return shorts;
        }

        void setShorts(short[] shorts)
        {
            this.shorts = shorts;
        }

        int[] getInts()
        {
            return ints;
        }

        void setInts(int[] ints)
        {
            this.ints = ints;
        }

        float[] getFloats()
        {
            return floats;
        }

        void setFloats(float[] floats)
        {
            this.floats = floats;
        }

        double[] getDoubles()
        {
            return doubles;
        }

        void setDoubles(double[] doubles)
        {
            this.doubles = doubles;
        }

        int getType()
        {
            return type;
        }

        void setType(int type)
        {
            this.type = type;
        }

        int getRows()
        {
            return rows;
        }

        void setRows(int rows)
        {
            this.rows = rows;
        }

        int getCols()
        {
            return cols;
        }

        void setCols(int cols)
        {
            this.cols = cols;
        }

        SerializedMat()
        {
        }
    }
}
Syaiful Nizam Yahya
  • 4,196
  • 11
  • 51
  • 71
1

Mat cannot directly be serialized as the pixels are stored natively. Here's what you can do:

  • Convert Mat to Bitmap.
  • Get pixels array from bitmap or compress the bitmap to byte array.
  • Serialize pixels array or byte array to JSON or Base64 as required.

Do the reverse for deserialization.

Nabin Bhandari
  • 15,949
  • 6
  • 45
  • 59