0

I'm currently trying to serialize/deserialize descriptors found using the descriptorMatcher.compute() function. I'm using Gson's toJson and fromJason to do the serialization.

    MatOfKeyPoint kpFeatures = new MatOfKeyPoint();
    MatOfKeyPoint kpDescriptor = new MatOfKeyPoint();

    featureDetector.detect(sampleMat, kpFeatures);
    descriptorExtractor.compute(sampleMat, kpFeatures, kpDescriptor);

    //Serializing and deserializing the descriptors.
    //First convert the MatOfKeyPoint to an array for storage
    String serDescriptors = gson.toJson(kpDescriptor.toArray());
    MatOfKeyPoint deserDescriptors = new MatOfKeyPoint(gson.fromJson(serDescriptors, KeyPoint[].class));

    System.out.println("Original keypoint matrix: ");
    System.out.println(kpDescriptor);
    System.out.println("Deserialized keypoint matrix: ");
    System.out.println(deserDescriptors);

The output I get from this is:

Original keypoint matrix: 
Mat [ 1311*64*CV_32FC1, isCont=true, isSubmat=false, nativeObj=0xa30c010, dataAddr=0xa691660 ]
Deserialized keypoint matrix: 
Mat [ 83904*1*CV_32FC(7), isCont=true, isSubmat=false, nativeObj=0xa39b600, dataAddr=0x2b363a24d020 ]

My belief is that the matrix isn't getting deserialized correctly, so that running descriptorMatcher.compute() returns the following error:

OpenCV Error: Unsupported format or combination of formats (type=53 ) in buildIndex_, file /local/p4clients/pkgbuild-P1uGN/workspace/src/Opencv/build/private/src/modules/flann/src/miniflann.cpp, line 315 Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: /local/p4clients/pkgbuild-P1uGN/workspace/src/Opencv/build/private/src/modules/flann/src/miniflann.cpp:315: error: (-210) type=53 in function buildIndex_ ]

I've tried the solutions here and here but haven't had much luck as the deserialized matrix always has the wrong dimensions.

How can I reconstruct a CV_32FC1 matrix from an array of keypoints?

Maybe I'm just overlooking something dumb, but any input would be much appreciated!

Community
  • 1
  • 1
Sophie Li
  • 1
  • 2

1 Answers1

0

Rather than use Json, it is possible to go directly to Java primitives.

MatOfKeyPoint to float[] or even byte[]

Using the MatOfKeyPoint.get() method, you can get a populated float[]. Then using ByteBuffer.putFloat(), you can loop through all of your floats, finally getting a populated byte[] by using ByteBuffer.array().

You also need to save some attirbutes MatOfKeyPoint.rows(), MatOfKeyPoint.cols(), and MatOfKeyPoint.type().

float[] or byte[] to MatOfKeyPoint

To reconstitute your MatOfKeyPoint object, if you're coming from byte[], first you make a float[] out of that using ByteBuffer.wrap(blob), then runByteBuffer.asFloatBuffer(). If you're creating fromfloat[], useFloatBuffer.get()with a properly sized new emptyfloat[]` object.

Now that you have yourFloatArray you run MatOfKeyPoint.create(rows, cols, type), those three things you had to save earlier. Finally you run MatOfKeyPoint.put(0, 0, yourFloatArray).

There is a complete Android solution, with Java code which can be found in this StackOverflow Answer. It goes farther than what your question is about, since it goes into how to store the object in a database, but the OpenCv Mat object to primitive concept is demonstrated.

Dale
  • 5,520
  • 4
  • 43
  • 79