Android OpenCV中MatOfKeyPoints转JSON字符串出错的问题咨询
I’ve run into this exact issue before with OpenCV on Android—MatOfKeyPoint is an OpenCV-specific native wrapper object, not a standard Java serializable type. JSON libraries like Gson or Jackson can’t automatically parse its internal structure, which is why you’re seeing that error. Here’s a straightforward fix:
Step 1: Convert MatOfKeyPoint to a standard Java list
OpenCV provides a built-in method to convert MatOfKeyPoint to a List<KeyPoint>, which is much easier to work with:
List<KeyPoint> keyPointList = refKeypoints.toList();
Step 2: Create a DTO for KeyPoint
Make a simple POJO (Plain Old Java Object) that mirrors the properties of OpenCV’s KeyPoint class. This acts as a bridge between OpenCV’s native object and JSON-serializable data:
public class KeyPointDTO { public float x; public float y; public float size; public float angle; public float response; public int octave; public int class_id; // Convert OpenCV KeyPoint to our DTO public KeyPointDTO(KeyPoint keyPoint) { this.x = keyPoint.pt.x; this.y = keyPoint.pt.y; this.size = keyPoint.size; this.angle = keyPoint.angle; this.response = keyPoint.response; this.octave = keyPoint.octave; this.class_id = keyPoint.class_id; } // Empty constructor for JSON deserialization (required by most libraries) public KeyPointDTO() {} }
Step 3: Serialize the DTO list to JSON
Using Gson (a widely used JSON library for Android), convert your list of DTOs to a JSON string. First, add Gson to your app-level build.gradle if you haven’t already:
dependencies { implementation 'com.google.code.gson:gson:2.10.1' }
Then run the conversion:
// Convert KeyPoint list to DTO list List<KeyPointDTO> keyPointDTOList = new ArrayList<>(); for (KeyPoint kp : keyPointList) { keyPointDTOList.add(new KeyPointDTO(kp)); } // Turn the DTO list into a JSON string Gson gson = new Gson(); String jsonString = gson.toJson(keyPointDTOList);
Step 4: (Optional) Deserialize JSON back to MatOfKeyPoint
If you need to convert the JSON string back to a MatOfKeyPoint later, use this code:
// Parse JSON back to DTO array KeyPointDTO[] dtoArray = gson.fromJson(jsonString, KeyPointDTO[].class); List<KeyPoint> restoredKeyPoints = new ArrayList<>(); // Convert DTOs back to OpenCV KeyPoint objects for (KeyPointDTO dto : dtoArray) { KeyPoint kp = new KeyPoint(); kp.pt = new Point(dto.x, dto.y); kp.size = dto.size; kp.angle = dto.angle; kp.response = dto.response; kp.octave = dto.octave; kp.class_id = dto.class_id; restoredKeyPoints.add(kp); } // Convert list back to MatOfKeyPoint MatOfKeyPoint restoredMatOfKeyPoint = new MatOfKeyPoint(); restoredMatOfKeyPoint.fromList(restoredKeyPoints);
This approach avoids direct serialization of OpenCV’s native objects, using plain Java types that JSON libraries can handle seamlessly.
内容的提问来源于stack exchange,提问作者Pradeepta Ranjan Choudhury

