Sending a Mat object over socket from Java to Java

时间:2015-06-15 14:29:31

标签: java sockets opencv mat

I understand Sockets over Java and sending Int,String,bytes etc over it.

What i just want to know is that is there a way to decode a Mat object to byte array and then send it over java socket and then retrieve back the Mat object from the byte received?

Till Now this is What I have done

For Sending Mat over socket

//Sending Mat over Socket

Mat socketmat;      
long  nbytes = socketmat.total() * socketmat.elemSize();
byte[] bytes = new byte[ (int) nbytes ];
socketmat.get(0, 0,bytes);
mybytearray = bytes;

dos = new DataOutputStream(os);
dos.writeLong(nbytes);
dos.write(mybytearray, 0, mybytearray.length);  

dos.flush(); 

For Receiving Mat over Socket

//Receiving Mat over Socket

long len = clientData.readLong();  
byte[] data = new byte[ (int) len];
if (len > 0) {
    clientData.readFully(data);
}            
byte[] bytes_ = data;
result_mat.get(0, 0, bytes_ );

2 个答案:

答案 0 :(得分:0)

我认为使用JNI使用FileStorage类保存Mat。

以下代码可用于将Mat保存为文件存储

FileStorage storage("image.xml", FileStorage::WRITE);
storage << "img" << mat;
storage.release();

然后使用Socket发送文件,然后从File回溯Mat。

FileStorage fs("image.xml", FileStorage::READ);
Mat img;
fs >> img;

答案 1 :(得分:-1)

正如其他人指出的那样,您可以使用Serialization 解决问题。您应该让Mat类实现Serializable接口。

接下来,不是手动将对象转换为字节,而是直接编写对象,方法是将流包装在ObjectOutputStream

ObjectOutputStream oos = new ObjectOutputStream(outputStream);
oos.writeObject(mat);

在接收时,您可以以相同的方式提取对象。

ObjectInputStream ois = new ObjectInputStream(inputStream);
Mat mat = (Mat)(ois.readObject());

您可以通过更灵活的基于XML的通信替换上述内容,而不是使用byte进行通信。您可以让java使用{{3}为您创建XML (用于Xml绑定的Java体系结构),这非常简单,并且与序列化非常相似。

// for sender
JAXBContext jc = JAXBContext.newInstance(Mat.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(mat, outputStream);

// for receiver
JAXBContext jc = JAXBContext.newInstance(Mat.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Mat mat = unmarshaller.unmarshal(inputStream);

在您的情况下,您的对象具有原生参考。但对于这个问题,有一个简单的解决方案。只需通过创建包装类

来打破本机边界
import java.io.Serializable;

public class MatWrapper implements Serializable {
    int rows;
    int cols;
    int type;
    byte[] data;

    public MatWrapper() {
    }

    public MatWrapper(Mat mat)
    {
        if (mat.isContinuous()) {

            int elemSize = (int) mat.elemSize();
            rows = mat.rows();
            cols = mat.cols();
            type = mat.type();

            data = new byte[cols * rows * elemSize];
            mat.get(0, 0, data);
        }
    }

    public Mat toMat()
    {
        Mat mat = new Mat(rows, cols, type);
        mat.put(0, 0, data);
        return mat;
    }
}

用法:

// convert Mat object to a wrapper object
MatWrapper wrapper = new MatWrapper(mat);

// this wrapper object is serializable

// next on receiver-side
MatWrapper wrapper = (MatWrapper)(ois.readObject);
Mat mat = wrapper.toMat();