OpenCV, как эффективно кодировать и отправлять данные видеопотока с веб-камеры? - PullRequest
0 голосов
/ 21 июня 2019

У меня есть этот код 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 голосов
/ 21 июня 2019

По сути, видеопоток - это последовательность кадров в предварительно определенном порядке.

Вы можете просто отправлять кадры в виде изображений, один за другим.В этом нет ничего принципиально неправильного, но это не обязательно является оптимальным (что также зависит от вашего определения оптимального).

В общении одним из аспектов является минимизация объема передаваемых данных.Простая отправка кадров в виде изображений позволяет выполнить некоторое сжатие (например, JPEG).Лучшие алгоритмы сжатия для видео (например, MPEG) используют временные свойства последовательности.Если есть (в основном) статическая рамка, вы можете ограничить себя отправкой данных об изменяющихся деталях и предположить, что фон остается тем же.Это идет с некоторой обработкой на обоих концах связи, но может увеличить скорость связи (предполагая, что канал является узким местом).Это также усложнит систему, поэтому сначала подумайте о потенциальных преимуществах (определите узкие места).

Я не уверен в использовании вашего приложения, но отправка видеопотока на стандартный вывод можетне обязательно быть лучшей идеей.Попробуйте вместо этого использовать канал или сокет (последний позволяет довольно легко передавать данные по сети, что может быть хорошим результатом).

...