java中的OpenCV Mat对象序列化

我试图序列化对的映射并获得如下exception:

java.io.NotSerializableException: org.opencv.core.Mat 

有什么方法可以序列化吗?

我从这里做了一些改进。 这里测试并运行了SerializationUtils类

 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(); int type = mat.type(); obj.addProperty("rows", rows); obj.addProperty("cols", cols); obj.addProperty("type", type); // We cannot set binary data to a json object, so: // Encoding data byte array to Base64. String dataString; if( type == CvType.CV_32S || type == CvType.CV_32SC2 || type == CvType.CV_32SC3 || type == CvType.CV_16S) { int[] data = new int[cols * rows * elemSize]; mat.get(0, 0, data); dataString = new String(Base64.encodeBase64(SerializationUtils.toByteArray(data))); } else if( type == CvType.CV_32F || type == CvType.CV_32FC2) { float[] data = new float[cols * rows * elemSize]; mat.get(0, 0, data); dataString = new String(Base64.encodeBase64(SerializationUtils.toByteArray(data))); } else if( type == CvType.CV_64F || type == CvType.CV_64FC2) { double[] data = new double[cols * rows * elemSize]; mat.get(0, 0, data); dataString = new String(Base64.encodeBase64(SerializationUtils.toByteArray(data))); } else if( type == CvType.CV_8U ) { byte[] data = new byte[cols * rows * elemSize]; mat.get(0, 0, data); dataString = new String(Base64.encodeBase64(data)); } else { throw new UnsupportedOperationException("unknown type"); } 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(); Mat mat = new Mat(rows, cols, type); String dataString = JsonObject.get("data").getAsString(); if( type == CvType.CV_32S || type == CvType.CV_32SC2 || type == CvType.CV_32SC3 || type == CvType.CV_16S) { int[] data = SerializationUtils.toIntArray(Base64.decodeBase64(dataString.getBytes())); mat.put(0, 0, data); } else if( type == CvType.CV_32F || type == CvType.CV_32FC2) { float[] data = SerializationUtils.toFloatArray(Base64.decodeBase64(dataString.getBytes())); mat.put(0, 0, data); } else if( type == CvType.CV_64F || type == CvType.CV_64FC2) { double[] data = SerializationUtils.toDoubleArray(Base64.decodeBase64(dataString.getBytes())); mat.put(0, 0, data); } else if( type == CvType.CV_8U ) { byte[] data = Base64.decodeBase64(dataString.getBytes()); mat.put(0, 0, data); } else { throw new UnsupportedOperationException("unknown type"); } return mat; } 

不,不那么容易。

实际数据保存在c ++ native中,所以你的serialize()不会达到。

能做什么:

 Mat mat = ... byte[] bytes = new byte[mat.total()*mat.elemSize()]; mat.get(0,0,bytes); // now somehow save mat.type(), mat.rows(), mat.cols() and the bytes, later restore it: Mat m2 = new Mat(rows,cols,type); m2.put(0,0, bytes); 

我改变了其他代码,看起来很有效。 希望它可以提供帮助。

  public static byte[] serializeMat(Mat mat) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { float[] data = new float[(int) mat.total() * mat.channels()]; mat.get(0, 0, data); ObjectOutput out = new ObjectOutputStream(bos); out.writeObject(data); out.close(); // Get the bytes of the serialized object byte[] buf = bos.toByteArray(); return buf; } catch (IOException ioe) { ioe.printStackTrace(); return null; } } 

您可以将内容转储到String一个序列化,如下所示:

 Mat mat = new Mat(); ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); String json = ow.writeValueAsString(mat.dump());