boost asio ライブラリを使用して、OpenCV IplImage をサーバー (Ubuntu x64) からクライアント (Win7 x64) に送信しようとしています。
次のコードは、両方 (クライアントとサーバー) が同じオペレーティング システム上にある場合に正常に機能します。ただし、サーバーが Ubuntu 上にあり、クライアントが Win7 上にある場合は機能しません。画像ヘッダーは正しいですが、画像データに何か問題があります。
これは、2 つの OS のビット順序が異なるためだと思います。それは...ですか?この問題を解決するにはどうすればよいですか?
次に、このコードの送信は非常に遅いです。どうすれば速度を改善できますか?
クライアント:
#define _WIN32_WINNT 0x0601
#include <iostream>
#include <sstream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
using boost::asio::ip::tcp;
using namespace std;
char* splitImage(const string& str, const string& delim, vector<string>& parts) {
size_t start, end = 0;
int i = 0;
while (end < str.size() && i < 8) {
start = end;
while (start < str.size() && (delim.find(str[start]) != string::npos)) {
start++; // skip initial whitespace
}
end = start;
while (end < str.size() && (delim.find(str[end]) == string::npos)) {
end++; // skip to end of word
}
if (end-start != 0) { // just ignore zero-length strings.
parts.push_back(string(str, start, end-start));
}
i++;
}
int size = atoi(parts[6].c_str());
char *imgdata = new char[size];
memcpy(imgdata, string(str, end+1, size).c_str(), size);
return imgdata;
}
int main(int argc, char* argv[])
{
string header;
try
{
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query("localhost", "1234");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket.close();
socket.connect(*endpoint_iterator++, error);
}
if (error)
throw boost::system::system_error(error);
stringstream ss;
cout << "reading";
for (;;)
{
boost::array<char, 1024> buf;
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buf), error);
cout << ".";
if (error == boost::asio::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw boost::system::system_error(error); // Some other error.
ss.write(buf.data(), len);
header = ss.str();
}
cout << "done: data size: "<< header.size() << endl;
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
return 1;
}
vector<string> parts;
char* imgdata = splitImage(header,"#",parts);
IplImage img2;
img2.nSize = atoi(parts[0].c_str());
img2.ID = 0;
img2.nChannels = atoi(parts[1].c_str());
img2.depth = atoi(parts[2].c_str());
img2.dataOrder = atoi(parts[3].c_str());;
img2.height = atoi(parts[4].c_str());
img2.width = atoi(parts[5].c_str());
img2.roi = NULL;
img2.maskROI = NULL;
img2.imageId = NULL;
img2.tileInfo = NULL;
img2.imageSize = atoi(parts[6].c_str());
img2.widthStep = atoi(parts[7].c_str());
img2.imageData = imgdata;
cvNamedWindow("Image:",1);
cvShowImage("Image:",&img2);
cvWaitKey();
cvDestroyWindow("Image:");
delete[] imgdata;
return 0;
}
サーバ:
#define _WIN32_WINNT 0x0601
#define WIN32_LEAN_AND_MEAN
#include <string>
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <boost/asio.hpp>
#define DELIMITER "#"
using boost::asio::ip::tcp;
using namespace std;
IplImage *img;
string serializeImageHeader(){
stringstream ss;
ss << img->nSize << DELIMITER;
ss << img->nChannels << DELIMITER;
ss << img->depth << DELIMITER;
ss << img->dataOrder << DELIMITER;
ss << img->height << DELIMITER;
ss << img->width << DELIMITER;
ss << img->imageSize << DELIMITER;
ss << img->widthStep << DELIMITER;
return ss.str();
}
int main()
{
try
{
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 1234));
img = cvLoadImage("Test.bmp");
cout << "Server is running" << endl;
for (;;)
{
tcp::socket socket(io_service);
acceptor.accept(socket);
cout << "socket accepted" << endl;
string message = serializeImageHeader().append(img->imageData, img->imageSize);
boost::system::error_code ignored_error;
boost::asio::write(socket, boost::asio::buffer(message),
boost::asio::transfer_all(), ignored_error);
cout << "sent: size: "<< message.size() << endl;
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
cvReleaseImage(&img);
return 0;
}