How to transfer cv::VideoCapture frames through socket in client-server model (OpenCV C++)?

前端 未结 2 1703
执笔经年
执笔经年 2021-01-17 02:02

I translate video through socket and I see video stream in other side but I cant receive video. My video file is empty. I am thinking the problem can be wrong convert video

相关标签:
2条回答
  • 2021-01-17 02:42

    Env: OpenCV 3.3, G++5.4, Ubuntu 16.04


    If you want to save the video, you should set CV_FOURCE to MJPG

    VideoWriter outputVideo;
    Size S = Size((int) 640,(int) 480);
    outputVideo.open("receive.avi", CV_FOURCC('M','J','P','G'), 30, S, true);
    

    This is my result:

    Code as follow:

    客户端(Client.cpp):

    //!2017.12.19 19:19:01 CST
    //!2017.12.19 22:19:38 CST
    //!2017.12.19 22:39:37 CST
    // 客户端
    // 使用 OpenCV 读取视频(并处理),然后使用 SOCKET 上传到服务器。
    
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <string>
    #include <vector>
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    int main()
    {
        int sock;
        struct sockaddr_in addr;
    
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if(sock < 0){
            perror("socket");
            exit(1);
        }
    
        addr.sin_family = AF_INET;
        addr.sin_port = htons(3425);
        addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    
        if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0){
            perror("connect");
            exit(2);
        }
    
        int bbytee;
        cout << "before open the cam" << endl;
    
        VideoCapture cap(0);
    
        if(!cap.isOpened()) {
            cout<< "Could not open the camera" <<  endl;
            close(sock);
            return -1;
        }
    
        Mat frame;
        frame = Mat::zeros(480, 640, CV_8UC3);
        int imgSize = frame.cols*frame.rows*3;
    
        int cnt=0;
        //Mat frame;
        while(1) {
            cap >> frame;
            if(frame.empty()) {
                cerr<<"[client] VideoCapture(0) error!"<<endl;
            }
    
            cout<< ++cnt << ":"<< frame.isContinuous()<<"," <<frame.size()<<endl;;
    
            if( (bbytee = send(sock, frame.data, imgSize, 0)) < 0 ) {
                cerr<< "bytes = " << bbytee << endl;
                break;
            }
    
            cv::imshow("client", frame);
            if(cv::waitKey(100) == 'q') {
                break;
            }
        }
        close(sock);
        return 0;
    }
    

    服务端(Server.cpp):

    //!2017.12.19 19:19:01 CST
    //!2017.12.19 22:19:38 CST
    //!2017.12.19 22:39:37 CST
    // 服务器
    // 监听客户端请求,读取视频流(并处理),保存。
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <string>
    #include <vector>
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    int main()
    {
        int sock, listener;
        struct sockaddr_in addr;
    
        if( (listener = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
            perror("[server] socket() failed");
            exit(1);
        }
    
        addr.sin_family = AF_INET;
        addr.sin_port = htons(3425);
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
        if(bind(listener, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
            perror("[server] binding faild!");
            exit(2);
        }
    
        listen(listener, 1);
    
    
        int num_of_recv_bytes;
        VideoWriter outputVideo;
        Size S = Size((int) 640,(int) 480);
        outputVideo.open("receive.avi", CV_FOURCC('M','J','P','G'), 30, S, true);
    
        int imgSize = 480*640*3;
        Mat frame = Mat::zeros(480, 640, CV_8UC3);
        uchar *iptr = frame.data;
        int key;
    
        int cnt=0;
        while(1){
            cout << ++cnt<<endl;
            sock = accept(listener, NULL, NULL);
            if(sock < 0){
                perror("[server] accept() faild!");
                exit(3);
            }
    
            while(key != 'q') {
                if( num_of_recv_bytes = recv(sock, iptr, imgSize, MSG_WAITALL) == -1 ) {
                    cerr << "recv failed, received bytes = " << num_of_recv_bytes << endl;
                }
    
                outputVideo<< frame;
                imshow("server", frame);
                if (key = waitKey(100) >= 0) break;
            }
            outputVideo.release();
            close(sock);
            break;
        }
        return 0;
    }
    
    0 讨论(0)
  • 2021-01-17 02:42

    Uh,I am also a newbie about opencv. But i can do this in opencv and Gstreamer. There are lots of solutions i'm not sure the FFmpeg can do it, you can try.

    Here is the Gstremer documetion.Hope it will help you.And you can also search some project in github. This project help me but it is not my project, hope it will help you.

    0 讨论(0)
提交回复
热议问题