Search code examples
androidc++opencvface-recognitionmat

Convert Mat to Blob and then back to Mat


Basically I am trying facial recognition using OpenCV Android. I need to convert a Mat image that is received during face detection via inputFrame.gray(); in CvCameraViewFrame into a blob that is a byte[] to save into an SQLite database. Then, during recognition, convert this byte[] back to a Mat file that can be used in .cpp files in the jni folder, as recognition code is native.


Solution

  • [edit]

    it turned out to be quite easy with androids onboard methods:

    import org.opencv.core.Mat;
    
    import android.content.Context;
    import android.content.ContentValues;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteDatabase.CursorFactory;
    import android.database.sqlite.SQLiteOpenHelper;
    
    class SqTable extends SQLiteOpenHelper {
        String table = "mydb";
    
        public SqlTable(Context context, String name, CursorFactory factory, int version) {
            super(context, name, factory, version);     
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("create table "+table+" (name TEXT UNIQUE, t INTEGER, w INTEGER, h INTEGER, pix BLOB);");
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
        }
        
        public void dbput(String name, Mat m) {
            long nbytes = m.total() * m.elemSize();
            byte[] bytes = new byte[ (int)nbytes ];
            m.get(0, 0,bytes);
            
            dbput(name, m.type(), m.cols(), m.rows(), bytes); 
        }
    
        public void dbput(String name, int t, int w, int h, byte[] bytes) {
            Log.d("dbput", name + " " + t + " " + w + "x" + h);
            SQLiteDatabase db = this.getWritableDatabase();
            ContentValues values = new ContentValues();
            values.put("name", name);
            values.put("t", t); 
            values.put("w", w); 
            values.put("h", h); 
            values.put("pix", bytes);
            db.insert(table, null, values);
            db.close();
        }
        
         public Mat dbget(String name) {
            SQLiteDatabase db = this.getReadableDatabase();
            String [] columns = {"t","w","h","pix"};
            Cursor cursor = db.query(table,columns," name = ?", 
                    new String[] { name }, // d. selections args
                    null, // e. group by
                    null, // f. having
                    null, // g. order by
                    null); // h. limit
         
            if (cursor != null)
                cursor.moveToFirst();
         
            int t = cursor.getInt(0);
            int w = cursor.getInt(1);
            int h = cursor.getInt(2);
            byte[] p = cursor.getBlob(3);
            Mat m = new Mat(h,w,t);
            m.put(0,0,p);
            Log.d("dbget("+name+")", m.toString());
            return m;
        }
    };
    
    // later use in your Activity:
    SqlTable sql = new SqlTable(this,"imgs",null,1);
    Mat m = new Mat(200,400, CvType.CV_8UC3,new Scalar(0,100,0));
    Core.putText(m, "world (~)", new Point(30,80), Core.FONT_HERSHEY_SCRIPT_SIMPLEX, 2.2, new          Scalar(200,200,200));
    sql.dbput("hello",m);
    // Mat m = sql.dbget("hello");