在 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: terminating with uncaught exception of type
zmq::error_t: Interrupted system call
因为它发生在我 运行 我的客户项目时,我假设服务器接收到数据,但它要么已损坏,要么存在反序列化问题
我没有仔细阅读你的所有代码,但这是 100% 错误的:
std::string serialized = save(img);
// ...
zmq::message_t request (sizeof(serialized));
memcpy (request.data (), &serialized, sizeof(serialized));
sizeof(std::string)
与所持有的字符串的大小无关,您不能从 std::string
对象中进行 memcpy。你想要做的是:
zmq::message_t request (serialized.length());
memcpy (request.data (), serialized.c_str(), serialized.length());
也可能是其他错误,但这只是突出显示。
您好,我正在尝试使用 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: terminating with uncaught exception of type zmq::error_t: Interrupted system call
因为它发生在我 运行 我的客户项目时,我假设服务器接收到数据,但它要么已损坏,要么存在反序列化问题
我没有仔细阅读你的所有代码,但这是 100% 错误的:
std::string serialized = save(img);
// ...
zmq::message_t request (sizeof(serialized));
memcpy (request.data (), &serialized, sizeof(serialized));
sizeof(std::string)
与所持有的字符串的大小无关,您不能从 std::string
对象中进行 memcpy。你想要做的是:
zmq::message_t request (serialized.length());
memcpy (request.data (), serialized.c_str(), serialized.length());
也可能是其他错误,但这只是突出显示。