I try to transmit an OpenCV IplImage from a Server (Ubuntu x64) to a Client (Win7 x64)
The following code works fine if both (Client and Server) are on the same operating system. But when the server is on Ubuntu and the client on Win7 it doesn't work. The image header is correct, but something with the image data is wrong.
I think this is because of the different bit-order between the two OS. How can I resolve this problem?
And second: The transmission with this code is slow as hell :D .
How can I improve the speed?
Client:
#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;
//192.168.0.162
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;
}
Server:
#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;
}