如何通过网络传输opencv Mat?

时间:2016-09-13 11:04:07

标签: c++ opencv stream

我刚刚开始研究机器人控制器,但我没有让相机部件工作。我想从服务器通过tcp接收网络摄像头流,服务器发送Mat [s],然后在客户端显示此信息。

服务器发送错误信息,可能是由于强制转换,或者客户端将此信息解释错误,也可能是由于强制转换。无论哪种方式,我都不确定如何解决这个问题。

到目前为止,我的server.cpp看起来像这样:

#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;
}

我的客户看起来像这样:

#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 
        }
    }

}

错误

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

1 个答案:

答案 0 :(得分:2)

我猜是因为你只发送了Mat的数据。 Mat对象包含标题,其中包括Mat大小。

我建议至少也传输Mat的SizeType,然后使用它来创建新的Mat

Mat frame(receivedSize, receivedType)

我不确定这是否足够,但这是一个开始。

此外,您是否有理由仅发送data而不是(char *)&frame,然后将其转发回Mat