Search code examples
javajsonopencvmatopencv-features2d

OpenCV image descriptors to JSON


I want to store some image descriptors on a server so that when image matching on an android phone I can fetch the precomputed image descriptors rather then doing it on the fly. I have successfully created an application that can take an input image and output the best match but I am having some trouble with placing the image descriptor matrix into a JSON file.

Below I have placed some code that I have tried to adapt to perform the function I want but I run into an error with these lines:

mat.get(0, 0, data);

The error it gives is:

Mat data type is not compatible: 5

The descriptor matrix is of type CV_32FC1 but it treats it as CV_8SC1. Full code is underneath, the idea is that I will pass in descriptor matrix to matToJson and then store the output on the server and then use matFromJson to retrieve the contents of the JSON file. I also cannot resolve Base64.DEFAULT as it shows an error. Any help would be greatly appreciated.

    public static String matToJson(Mat mat){        
    JsonObject obj = new JsonObject();

    if(mat.isContinuous()){
        int cols = mat.cols();
        int rows = mat.rows();
        int elemSize = (int) mat.elemSize();    

        byte[] data = new byte[cols * rows * elemSize];

        mat.get(0, 0, data);

        obj.addProperty("rows", mat.rows()); 
        obj.addProperty("cols", mat.cols()); 
        obj.addProperty("type", mat.type());

        // We cannot set binary data to a json object, so:
        // Encoding data byte array to Base64.
        String dataString = new String(Base64.encode(data, Base64.DEFAULT)); //Error here as well .default does not exist

        obj.addProperty("data", dataString);            

        Gson gson = new Gson();
        String json = gson.toJson(obj);

        return json;
    } else {
        System.out.println("Mat not continuous.");
    }
    return "{}";
}

public static Mat matFromJson(String json){
    JsonParser parser = new JsonParser();
    JsonObject JsonObject = parser.parse(json).getAsJsonObject();

    int rows = JsonObject.get("rows").getAsInt();
    int cols = JsonObject.get("cols").getAsInt();
    int type = JsonObject.get("type").getAsInt();

    String dataString = JsonObject.get("data").getAsString();       
    byte[] data = Base64.decode(dataString.getBytes(), Base64.DEFAULT); 

    Mat mat = new Mat(rows, cols, type);
    mat.put(0, 0, data);

    return mat;
}

Solution

  • Found a solution to the issue here, the problem was being caused by using the incorrect data type in the array. rather than using byte it should have been float. however the solution I have linked above is much better in that it checks the data type prior to encoding the data.