OpenCV如何有效地编码和发送网络摄像头视频流的数据?

时间:2019-06-21 14:26:05

标签: c++ opencv video-streaming

我有这个OpenCV C ++代码,它从凸轮获取图像,对其进行编码并将其发送到STDOUT。

#include <unistd.h> //STDOUT_FILENO
#include "opencv2/opencv.hpp"
#include <iostream>
#include <fcntl.h>
using namespace std;
using namespace cv;

#define BUFLEN 4096

int main(int argc, char *argv[])
{
    Mat frame;
    std::vector<uchar> buf;

    int bak, temp;

    //read image as grayscale
    namedWindow( "Camera", WINDOW_AUTOSIZE );
    //redirect stdout to NULL in order to avoid printing to STDOUT undesired stuff
    fflush(stdout);
    bak = dup(1);
    temp = open("/dev/null", O_WRONLY);
    dup2(temp, 1);
    close(temp  );
    VideoCapture cam(0 + CAP_V4L);
    cam>>frame;
    sleep(1);
    if (!cam.isOpened())
    {
        cout << "\nCould not open reference " << 0 << endl;
        return -1;
    }
    for (int i=0; i<5; i++)
    {
        cam>>frame;
    }
    /*Set the normal STDOUT back*/
    fflush(stdout);
    dup2(bak, 1);
    close(bak);

    //encode image and put data into the vector buf
    imencode(".png",frame, buf);
    //send the total size of vector to parent
    cout<<buf.size()<<endl;
    unsigned int written= 0;

    int i = 0;
    size_t toWrite = 0;
    //send until all bytes have been sent
    FILE * f = fdopen(STDOUT_FILENO, "w");
    while (written<buf.size())
    {
        //send the current block of data
        toWrite = BUFLEN < (buf.size()-written) ? BUFLEN : (buf.size()-written);
        //written += write(STDOUT_FILENO, buf.data()+written, toWrite);
        written += toWrite*fwrite ( buf.data()+written, toWrite, 1, f );
        i++;
    }
    return 0;
}

现在我想从凸轮上拍摄无限连续的视频,而不是图像。一种解决方案是在给定的几秒钟内拍摄一帧,对该帧进行编码并将其传输(将其打印到STDOUT),并在无限循环内进行所有操作。

有没有比编码和每次迭代发送每个帧更好的解决方案,更有效?

1 个答案:

答案 0 :(得分:0)

从根本上说,视频流是按预定义顺序的一系列帧。

您可以简单地将帧作为图像发送,一个接一个。根本上没有错,但不一定是最优的(这也取决于您对最优的定义)。

在通信中,一方面是使传输的数据量最小化。只需将帧作为图像发送即可进行一些压缩(例如jpeg)。更好的视频压缩算法(例如mpeg)使用序列的时间属性。如果存在(主要是)静态框架,则可以限制自己发送有关零件变化的数据,并假定背景是相同的。这在通信的两端都进行了一些处理,但是可能会提高通信速度(假设链接是瓶颈)。这也将增加系统的复杂性,因此,请首先考虑潜在的优势(确定瓶颈)。

我不确定您的应用程序的使用情况,但是将视频流发送到stdout不一定是最好的主意。考虑使用管道或套接字代替(后者使您也很容易通过网络传输数据,这可能是一个不错的结果)。