我有这个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),并在无限循环内进行所有操作。
有没有比编码和每次迭代发送每个帧更好的解决方案,更有效?
答案 0 :(得分:0)
从根本上说,视频流是按预定义顺序的一系列帧。
您可以简单地将帧作为图像发送,一个接一个。根本上没有错,但不一定是最优的(这也取决于您对最优的定义)。
在通信中,一方面是使传输的数据量最小化。只需将帧作为图像发送即可进行一些压缩(例如jpeg)。更好的视频压缩算法(例如mpeg)使用序列的时间属性。如果存在(主要是)静态框架,则可以限制自己发送有关零件变化的数据,并假定背景是相同的。这在通信的两端都进行了一些处理,但是可能会提高通信速度(假设链接是瓶颈)。这也将增加系统的复杂性,因此,请首先考虑潜在的优势(确定瓶颈)。
我不确定您的应用程序的使用情况,但是将视频流发送到stdout不一定是最好的主意。考虑使用管道或套接字代替(后者使您也很容易通过网络传输数据,这可能是一个不错的结果)。