P.Andrews
P.Andrews

Reputation: 73

How to transfer opencv Mat over network?

I have just started working on a Robot controller,however I haven't got the camera part working. I want to receive webcam stream over tcp from a server, which sends Mat[s], then display this information on the client side.

Either the server sends wrong information, potentially as a result of the cast, or the client interprets this information wrong, also potentially as a result of the cast. Either way I'm not sure how to resolve this issue.

So far my server.cpp looks like this :

#include "opencv2/opencv.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>

using namespace cv;
int main(int argc, char** argv)
{
    int socket_desc , client_sock , c , read_size;
    struct sockaddr_in server , client;

    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 1111 );

    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
        //print the error message
        perror("bind failed. Error");
        return 1;
    }
    puts("bind done");

    //Listen
    listen(socket_desc , 3);

    //Accept and incoming connection
    puts("Waiting for incoming connections...");
    c = sizeof(struct sockaddr_in);

    //accept connection from an incoming client
    client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
    if (client_sock < 0)
    {
        perror("accept failed");
        return 1;
    }
    puts("Connection accepted");

    VideoCapture cap;
    // open the default camera, use something different from 0 otherwise;
    // Check VideoCapture documentation.
    if(!cap.open(0))
        return 0;
    for(;;)
    {
          Mat frame;
          cap >> frame;
          if( frame.empty() ) break; // end of video stream
          //imshow("Input :)", frame);
          write(client_sock,(char *)frame.data,strlen((char *)frame.data));
          if( waitKey(1) == 27 ) break; // stop capturing by pressing ESC 
    }
    // the camera will be closed automatically upon exit
    // cap.close();
    return 0;
}

And my client looks like this :

#include "opencv2/opencv.hpp"
#include <SFML/Network.hpp>
using namespace cv;
int main() {
    sf::TcpSocket socket;
    sf::Socket::Status status = socket.connect("127.0.0.1", 1111);
    if (status != sf::Socket::Done)
    {
        puts("Bye\n");
        return 0; 
    }
    while(true) {
        Mat frame;
        char data[1000000]; //strlen gave me around 930000 when I was debugging. 
        std::size_t received;

        // TCP socket:
        if (socket.receive(data, 1000000, received) != sf::Socket::Done)
        {
            continue;
        }else {
            frame.data = (unsigned char *)data;
            imshow("Hello",frame); //Error occurs here, not sure what causes it 
        }
    }

}

Error

OpenCV Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /build/opencv-SviWsf/opencv-2.4.9.1+dfsg/modules/highgui/src/window.cpp, line 269
terminate called after throwing an instance of 'cv::Exception'
  what():  /build/opencv-SviWsf/opencv-2.4.9.1+dfsg/modules/highgui/src/window.cpp:269: error: (-215) size.width>0 && size.height>0 in function imshow

Aborted

Upvotes: 0

Views: 1638

Answers (1)

La bla bla
La bla bla

Reputation: 8708

I'm guessing it's because you only send the Mat's data. A Mat object contains header, which include, among other, the Mat size.

I'd suggest at the very least to also transmit the Size and Type of the Mat and then using it to create a new Mat

Mat frame(receivedSize, receivedType)

I'm not sure if that's would be enough, but that's a start.

Also, is there a reason you only send the data instead of (char *)&frame and then casting it back to Mat?

Upvotes: 3

Related Questions