2014-11-21 43 views
0

我试图序列化映射一对并获得如下例外:OpenCV的垫对象序列化在Java中

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

是否有某种方式序列化呢?

+0

下SO答案有关于得到一个'Mat'到Java原语,这当然是序列化的信息: https://stackoverflow.com/a/44089416/897007 – Dale 2017-05-23 14:41:41

回答

1

我从here做了一些改进措施。测试和工作 SerializationUtils类here

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; 
} 
+0

对图像的base64编码很粗糙。 – berak 2015-03-27 11:12:52

+0

其实这不是图像,功能。 – Joker 2015-03-27 12:05:42

+0

感谢您的代码。转换为json似乎对我来说很好 – Araneo 2015-04-13 11:03:06

0

不,不那么容易。

实际数据保存在C++本机内部,所以你的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); 
+0

是否有其他简单的方法来制作类似数据库的东西,并在那里存储我拥有的所有Mat对象? – Araneo 2014-11-21 17:13:32

0

我改变了别人的代码,它似乎工作。 希望它可以帮助。

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; 
      } 
     } 
0

你可以转储内容为String一个序列化,像这样:

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