繁体   English   中英

使用C ++中的zeromq将序列化的Mat对象发送到另一台计算机

[英]Sending serialized Mat object to another computer using zeromq in C++

您好,我正在尝试使用zeromq和boost将mat对象发送到另一台计算机。

这是我的serialization.h文件

#include <iostream>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/vector.hpp>

BOOST_SERIALIZATION_SPLIT_FREE(cv::Mat)
namespace boost {
    namespace serialization {

        /*** Mat ***/
        template<class Archive>
        void save(Archive & ar, const cv::Mat& m, const unsigned int version)
        {
            size_t elemSize = m.elemSize(), elemType = m.type();

            ar & m.cols;
            ar & m.rows;
            ar & elemSize;
            ar & elemType; // element type.
            size_t dataSize = m.cols * m.rows * m.elemSize();


            for (size_t dc = 0; dc < dataSize; ++dc) {
                ar & m.data[dc];
            }
        }

        template<class Archive>
        void load(Archive & ar, cv::Mat& m, const unsigned int version)
        {
            int cols, rows;
            size_t elemSize, elemType;

            ar & cols;
            ar & rows;
            ar & elemSize;
            ar & elemType;

            m.create(rows, cols, elemType);
            size_t dataSize = m.cols * m.rows * elemSize;

            //cout << "reading matrix data rows, cols, elemSize, type, datasize: (" << m.rows << "," << m.cols << "," << m.elemSize() << "," << m.type() << "," << dataSize << ")" << endl;

            for (size_t dc = 0; dc < dataSize; ++dc) {
                ar & m.data[dc];
            }
        }

    }
}

这就是我序列化Mat对象并发送它的方式。

#include <zmq.hpp>
#include <string>
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <fstream>
#include "Serialization.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

using namespace std;
using namespace cv;


std::string save( const cv::Mat & mat )
{
    std::ostringstream oss;
    boost::archive::text_oarchive toa( oss );
    toa << mat;

    return oss.str();
}



int main () {
    Mat img = imread("/Users/Rodrane/Downloads/barbara.pgm", 0);   // Read the file


    std::string serialized = save(img);


    //  Prepare our context and socket
    zmq::context_t context (1);
    zmq::socket_t socket (context, ZMQ_REQ);

    std::cout << "Connecting to hello world server…" << std::endl;
    socket.connect ("tcp://localhost:5555");

    //  Do 10 requests, waiting each time for a response
    for (int request_nbr = 0; request_nbr != 10; request_nbr++) {
        zmq::message_t request (sizeof(serialized));
        memcpy (request.data (), &serialized, sizeof(serialized));
        std::cout << "Sending Hello " << request_nbr << "…" << std::endl;
        socket.send (request);

        //  Get the reply.
        zmq::message_t reply;
        socket.recv (&reply);
        std::cout << "Received World " << request_nbr << std::endl;
    }
    return 0;



}

这就是我接收序列化对象并尝试显示它的方式。

#include <zmq.hpp>
#include <string>
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <fstream>
#include "Serialization.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

using namespace std;

void load( cv::Mat & mat, const char * data_str )
{
    std::stringstream ss;
    ss << data_str;

    boost::archive::text_iarchive tia( ss );
    tia >> mat;
}

int main () {
    zmq::context_t context (1);
    zmq::socket_t socket (context, ZMQ_REP);
    socket.bind ("tcp://*:5555");
    cv::Mat object;

    while (true) {
        zmq::message_t recivedData;
        socket.recv (&recivedData);
        std::string rpl = std::string(static_cast<char*>(recivedData.data()), recivedData.size());
        const char *cstr = rpl.c_str();
        load(object,cstr);
        imshow("asdasd",object);
        //  Send reply back to client
        zmq::message_t reply (8);
        memcpy (reply.data (), "Recieved", 8);
        socket.send (reply);
  }



}

当我运行这2个项目时,我检索到一个错误

libc ++ abi.dylib:以类型为zmq :: error_t的未捕获异常终止:系统调用中断

由于它发生在我运行客户端项目时,因此我假设服务器接收到数据,但是它已损坏或反序列化存在问题

我没有遍历您的所有代码,但这是100%错误的:

std::string serialized = save(img);
//  ...
zmq::message_t request (sizeof(serialized));
memcpy (request.data (), &serialized, sizeof(serialized));

sizeof(std::string)与所保存字符串的大小无关,因此您不能从std::string对象中进行存储。 您想要做的是:

zmq::message_t request (serialized.length());
memcpy (request.data (), serialized.c_str(), serialized.length());

也可能是其他错误,但这只是很明显。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM