Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenCV VideoWriter帧速率问题_C++_Opencv_Video Capture - Fatal编程技术网

C++ OpenCV VideoWriter帧速率问题

C++ OpenCV VideoWriter帧速率问题,c++,opencv,video-capture,C++,Opencv,Video Capture,我正在尝试将1080p网络摄像头中的视频录制到一个文件中。我在视频中设置了一个计时器,在每次试验中,视频播放器报告的时间戳(我使用的是VLC)都与视频中的时间不同步。它总是在几秒钟内关闭(通常在视频中,计时器比播放机报告的时间快) 下边,我设置了C++程序,在一个线程中捕获视频,并在另一个线程中记录。这工作正常,因为我的CPU使用率约为200%(可能最大输出?)。我使用的是Macbook Air,带有10.8@1.8 GHz Intel Core i7操作系统 我尝试过将帧速率改为15fps,这

我正在尝试将1080p网络摄像头中的视频录制到一个文件中。我在视频中设置了一个计时器,在每次试验中,视频播放器报告的时间戳(我使用的是VLC)都与视频中的时间不同步。它总是在几秒钟内关闭(通常在视频中,计时器比播放机报告的时间快)

下边,我设置了C++程序,在一个线程中捕获视频,并在另一个线程中记录。这工作正常,因为我的CPU使用率约为200%(可能最大输出?)。我使用的是Macbook Air,带有10.8@1.8 GHz Intel Core i7操作系统

我尝试过将帧速率改为15fps,这会产生非常起伏/缓慢的视频。我还尝试将
CV\u CAP\u PROP\u FRAME\u WIDTH
CV\u CAP\u PROP\u FRAME\u HEIGHT
设置为较低的分辨率,这会导致视频速度变慢。看起来1080p@30fps可以产生稳定的视频,但它的播放速度总是比预期的要快。我还试着输入
waitKey(10)
记录>(*帧)之后;
}
}
int main(int,char**)
{
视频捕获(0);//打开默认摄像机
如果(!capture.isOpened()){
printf(“相机无法打开!\n”);
返回-1;
}
capture.set(CV_CAP_PROP_FPS,30);//将捕获速率设置为30fps
垫架;
捕获>>帧;//获取第一帧的大小
//初始化视频的录制
录像机记录(“test.avi”,CV_FOURCC('D','I','V','X'),30,frame.size(),true);
如果(!record.isOpened()){
printf(“VideoWriter无法打开!\n”);
返回-1;
}
boost::thread captureFunc,&frame,&capture);//启动捕获线程
sleep(1);//只是为了确保捕获线程已准备就绪
对于(;;)
{
//为录制的视频添加帧

record经过一点调试后,我解决了我的问题;这是因为VideoWriter对输入帧的速率很挑剔。

您需要同步读写函数。您的代码读得尽可能快,写得也尽可能快。您的输出视频可能看起来很慢,因为写入输出的速度很快这比读取输入要快得多(因为
capture>
正在等待您的相机),并且记录了几个相同的帧

不等待或同步的写作意味着您可能会多次编写相同的内容(我认为这里正在发生的事情),或者丢失帧

如果您想继续拥有线程,您可以这样做,但是您需要让您的写进程等待,直到有新的东西要写

同样,为了避免丢失帧或写入损坏的帧,您需要读取过程等待写入完成,以便可以安全地覆盖
frame

由于线程无论如何都需要彼此等待,因此线程没有什么意义

我宁愿推荐这种更简单的方法:

for (;;) {
    capture >> frame;
    process(frame);  // whatever smart you need
    record << frame;
}
(;;)的
{
捕获>>帧;
过程(框架);//你需要的任何智能

尝试使用不同的编解码器和不同的fps录制(25可能是一个不错的选择)。我尝试了25 fps,并使用XVID作为编解码器。对于大约1.5分钟的视频,它可以正常工作(某些部分快几秒,而其他部分慢几秒,所以它的平均值),但在任何更短或更长的时间内,VLC将播放比实际长3-6秒的视频(例如,视频中的计时器显示已过5分钟,但VLC将播放5分6秒)在我录制5分钟视频的测试中,时间是同步的,直到大约3分10秒之后。之后,间隔有时会达到6秒,最后以大约5秒的不同步结束。回答问题时再次+1。但我注意到,您的解决方案可能有竞争条件,因为摄像头获取线程可能会刷新垫子“frame”同时VideoWriter正在访问它。writeup很好,但是如果你能在这里写它并只给你的网站一个链接就更好了。如果你更改了url,信息就会丢失!如果链接消失,写出来的内容基本上就是你所期望的:VideoWriter“WriteName()"必须在初始化格式中指定的FPS间隔内调用。有意义。@JonathanLeaders这根本没有意义,如果我想制作一个两小时长的视频,我可以在10分钟内生成帧,那么我必须等待整整两小时才能得到输出?Veery wierd。这没有意义e、 的确如此。我认为问题在于,无论视频文件是否有新内容,都要将
frame
写入到视频文件中。结果是,输出中有多个视频帧是相同的,因为它们是从同一输入帧创建的。您需要的不是播放计时。您需要的是同步读取和播放写,这样你只有在有新的框架时才写。(你可以用线程来写,但最简单的方法是
capture>>frame;process(frame);记录这是正确的答案。正如Gauthier所写,显示的代码中没有任何机制来确保每次读取只有一次写入,因此每个帧i的写入次数不可预测。
for (;;) {
    capture >> frame;
    process(frame);  // whatever smart you need
    record << frame;
}