C++ OpenCV image sending through socket
Haris's answer is right and worked for me. However, instead of that server code (constructing image from uchar data), you can also use the shorter form:
int imgSize = img.total()*img.elemSize();
uchar sockData[imgSize];
for (int i = 0; i < imgSize; i += bytes) {
if ((bytes = recv(connectSock, sockData +i, imgSize - i, 0)) == -1)
quit("recv failed", 1);
}
// change the last loop to below statement
Mat img(Size(HEIGHT, WIDTH), CV_8UC3, socketData);
Buffer overflow. And I am not sure that format and sizes of image are the same -> you should serialize your Mat honestly, something like here.
Get Mat.data
and directly send to the socket, the data order is BGR BGR BGR.... On the receiving side assumes you know the size of image. After receiving just assign the received buffer(BGR BGR... array) to a Mat
.
Client:-
Mat frame;
frame = (frame.reshape(0,1)); // to make it continuous
int imgSize = frame.total()*frame.elemSize();
// Send data here
bytes = send(clientSock, frame.data, imgSize, 0))
Server:-
Mat img = Mat::zeros( height,width, CV_8UC3);
int imgSize = img.total()*img.elemSize();
uchar sockData[imgSize];
//Receive data here
for (int i = 0; i < imgSize; i += bytes) {
if ((bytes = recv(connectSock, sockData +i, imgSize - i, 0)) == -1) {
quit("recv failed", 1);
}
}
// Assign pixel value to img
int ptr=0;
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
img.at<cv::Vec3b>(i,j) = cv::Vec3b(sockData[ptr+ 0],sockData[ptr+1],sockData[ptr+2]);
ptr=ptr+3;
}
}
bytes = send(clientSock, frame.data, imgSize, 0));
This statement is giving error in Visual Studio 12.It say that.. ERROR: argument of type "uchar *" is incompatible with parameter of type "const char *" at ""frame.data"".