我试图序列化映射一对并获得如下例外:OpenCV的垫对象序列化在Java中
java.io.NotSerializableException: org.opencv.core.Mat
是否有某种方式序列化呢?
我试图序列化映射一对并获得如下例外:OpenCV的垫对象序列化在Java中
java.io.NotSerializableException: org.opencv.core.Mat
是否有某种方式序列化呢?
我从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;
}
不,不那么容易。
实际数据保存在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);
是否有其他简单的方法来制作类似数据库的东西,并在那里存储我拥有的所有Mat对象? – Araneo 2014-11-21 17:13:32
我改变了别人的代码,它似乎工作。 希望它可以帮助。
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());
下SO答案有关于得到一个'Mat'到Java原语,这当然是序列化的信息: https://stackoverflow.com/a/44089416/897007 – Dale 2017-05-23 14:41:41