在 C++ 中通过 TCP 连接发送 Opencv Mat
Sending Opencv Mat through a TCP connection in C++
我正在尝试通过 TCP 连接发送 OpenCv Mat。到目前为止,我已经能够在 boost::asio tutorial.
之后建立一个简单的 TCP 连接
我想知道我是否可以简单地修改那个例子并在 tcp 连接对象中放置一个 cv::Mat image_ 来代替字符串 message_ ,或者我是否应该使用不同的策略来提供图像给客户。
既然您已经在使用 Boost,那么您不妨研究一下模块 serialization
。下面是一个将 cv::Mat
转换为 std::string
的示例:
#include <opencv2/core.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <cassert>
#include <string>
#include <vector>
BOOST_SERIALIZATION_SPLIT_FREE( cv::Mat )
namespace boost {
namespace serialization {
template <class Archive>
void save( Archive & ar, const cv::Mat & m, const unsigned int version )
{
size_t elemSize = m.elemSize();
size_t elemType = m.type();
ar & m.cols;
ar & m.rows;
ar & elemSize;
ar & elemType;
const size_t dataSize = m.cols * m.rows * m.elemSize();
for ( size_t i = 0; i < dataSize; ++i )
ar & m.data[ i ];
}
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, static_cast< int >( elemType ) );
const size_t dataSize = m.cols * m.rows * elemSize;
for (size_t i = 0; i < dataSize; ++i)
ar & m.data[ i ];
}
} // namespace serialization
} // namespace boost
std::string save( const cv::Mat & mat )
{
std::ostringstream oss;
boost::archive::text_oarchive toa( oss );
toa << mat;
return oss.str();
}
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( int argc, char ** argv )
{
cv::Mat eye = cv::Mat::eye( 3, 3, CV_32FC1 );
std::string serialized = save( eye );
std::cout << "serialized = " << serialized << std::endl;
cv::Mat deserialized;
load( deserialized, serialized.c_str() );
std::cout << "deserialized = \n\n" << deserialized << std::endl;
return 0;
}
试试这个来改进 cv::Mat
的序列化
template<class Archive>
void save(Archive & ar, const ::cv::Mat& m, const unsigned int version)
{
int cols = m.cols;
int rows = m.rows;
size_t elem_size = m.elemSize();
size_t elem_type = m.type();
ar & cols;
ar & rows;
ar & elem_size;
ar & elem_type;
const size_t data_size = m.cols * m.rows * elem_size;
boost::serialization::binary_object data(m.data, data_size);
ar & data;
}
/** Serialization support for cv::Mat */
template<class Archive>
void load(Archive & ar, ::cv::Mat& m, const unsigned int version)
{
int cols, rows;
size_t elem_size, elem_type;
ar & cols;
ar & rows;
ar & elem_size;
ar & elem_type;
m.create(rows, cols, elem_type);
size_t data_size = m.cols * m.rows * elem_size;
boost::serialization::binary_object data(m.data, data_size);
ar & data;
}
boost::serialization::binary_object 数据可以更好地处理二进制数据的序列化。
我正在尝试通过 TCP 连接发送 OpenCv Mat。到目前为止,我已经能够在 boost::asio tutorial.
之后建立一个简单的 TCP 连接我想知道我是否可以简单地修改那个例子并在 tcp 连接对象中放置一个 cv::Mat image_ 来代替字符串 message_ ,或者我是否应该使用不同的策略来提供图像给客户。
既然您已经在使用 Boost,那么您不妨研究一下模块 serialization
。下面是一个将 cv::Mat
转换为 std::string
的示例:
#include <opencv2/core.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <cassert>
#include <string>
#include <vector>
BOOST_SERIALIZATION_SPLIT_FREE( cv::Mat )
namespace boost {
namespace serialization {
template <class Archive>
void save( Archive & ar, const cv::Mat & m, const unsigned int version )
{
size_t elemSize = m.elemSize();
size_t elemType = m.type();
ar & m.cols;
ar & m.rows;
ar & elemSize;
ar & elemType;
const size_t dataSize = m.cols * m.rows * m.elemSize();
for ( size_t i = 0; i < dataSize; ++i )
ar & m.data[ i ];
}
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, static_cast< int >( elemType ) );
const size_t dataSize = m.cols * m.rows * elemSize;
for (size_t i = 0; i < dataSize; ++i)
ar & m.data[ i ];
}
} // namespace serialization
} // namespace boost
std::string save( const cv::Mat & mat )
{
std::ostringstream oss;
boost::archive::text_oarchive toa( oss );
toa << mat;
return oss.str();
}
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( int argc, char ** argv )
{
cv::Mat eye = cv::Mat::eye( 3, 3, CV_32FC1 );
std::string serialized = save( eye );
std::cout << "serialized = " << serialized << std::endl;
cv::Mat deserialized;
load( deserialized, serialized.c_str() );
std::cout << "deserialized = \n\n" << deserialized << std::endl;
return 0;
}
试试这个来改进 cv::Mat
的序列化template<class Archive>
void save(Archive & ar, const ::cv::Mat& m, const unsigned int version)
{
int cols = m.cols;
int rows = m.rows;
size_t elem_size = m.elemSize();
size_t elem_type = m.type();
ar & cols;
ar & rows;
ar & elem_size;
ar & elem_type;
const size_t data_size = m.cols * m.rows * elem_size;
boost::serialization::binary_object data(m.data, data_size);
ar & data;
}
/** Serialization support for cv::Mat */
template<class Archive>
void load(Archive & ar, ::cv::Mat& m, const unsigned int version)
{
int cols, rows;
size_t elem_size, elem_type;
ar & cols;
ar & rows;
ar & elem_size;
ar & elem_type;
m.create(rows, cols, elem_type);
size_t data_size = m.cols * m.rows * elem_size;
boost::serialization::binary_object data(m.data, data_size);
ar & data;
}
boost::serialization::binary_object 数据可以更好地处理二进制数据的序列化。