简体   繁体   English

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

[英]OpenCV how to encode and send data of webcam video stream efficiently?

I have this OpenCV C++ code which is taking an image from the cam, encoding it and sending it to the STDOUT. 我有这个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;
}

Now instead of an image I would like to take an infinite continuous video from the cam. 现在,而不是图像,我想从凸轮拍摄无限连续视频。 One solution would be to take a frame any given seconds, encode the frame and transmit it (print it to STDOUT), all actions inside an infinite loop. 一种解决方案是在任何给定的秒内采用帧,对帧进行编码并将其传输(将其打印到STDOUT),所有动作都在无限循环内。

Is there a better solution, more efficient than encoding and send each frame at each iteration? 是否有更好的解决方案,比编码更有效,并在每次迭代时发送每个帧?

Fundamentally, a video stream is a sequence of frames in a predefined order. 基本上,视频流是预定义顺序的帧序列。

You could simply send the frames as images, one after another. 您可以简单地将帧作为图像一个接一个地发送。 There is nothing fundamentally wrong with that, but is not necessarily optimal (which also depends on your definition of optimal). 这没有什么根本性的错误,但不一定是最优的(这也取决于你对最优的定义)。

In communication, one of the aspects is to minimize the amount of data transferred. 在通信中,其中一个方面是最小化传输的数据量。 Simply sending the frames as images allows you to do some compression (eg jpeg). 只需将帧作为图像发送即可进行一些压缩(例如jpeg)。 Better compression algorithms for video (eg mpeg) use the temporal properties of the sequence. 用于视频的更好的压缩算法(例如mpeg)使用序列的时间属性。 If there is a (mostly) static frame, you can limit yourself sending data about the changing parts and assume the background is the same. 如果存在(大多数)静态帧,则可以限制自己发送有关更改部分的数据并假设背景相同。 This goes with some processing at both ends of the communication, but might increase the communication speed (assuming the link is the bottleneck). 这与通信两端的一些处理有关,但可能会提高通信速度(假设链路是瓶颈)。 This would also add a lot of complexity to the system, so think about the potential advantages first (identify the bottlenecks). 这也会给系统增加很多复杂性,因此首先考虑潜在的优势(找出瓶颈)。

I am not sure about the usage of your application, but sending the video stream to stdout might not necessarily be the best idea. 我不确定您的应用程序的用途,但将视频流发送到stdout可能不一定是最好的主意。 Consider using a pipe or a socket instead (the latter allows you quite easily to transfer data over the network as well, which might be a nice outcome). 考虑使用管道或套接字(后者允许您很容易通过网络传输数据,这可能是一个很好的结果)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM