我正在尝试使用C ++中的OpenCV读取视频,但是当显示视频时,帧速率非常慢,就像原始帧速率的10%一样。
整个代码在这里:
// g++ `pkg-config --cflags --libs opencv` play-video.cpp -o play-video
// ./play-video [video filename]
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
// video filename should be given as an argument
if (argc == 1) {
cerr << "Please give the video filename as an argument" << endl;
exit(1);
}
const string videofilename = argv[1];
// we open the video file
VideoCapture capture(videofilename);
if (!capture.isOpened()) {
cerr << "Error when reading video file" << endl;
exit(1);
}
// we compute the frame duration
int FPS = capture.get(CV_CAP_PROP_FPS);
cout << "FPS: " << FPS << endl;
int frameDuration = 1000 / FPS; // frame duration in milliseconds
cout << "frame duration: " << frameDuration << " ms" << endl;
// we read and display the video file, image after image
Mat frame;
namedWindow(videofilename, 1);
while(true)
{
// we grab a new image
capture >> frame;
if(frame.empty())
break;
// we display it
imshow(videofilename, frame);
// press 'q' to quit
char key = waitKey(frameDuration); // waits to display frame
if (key == 'q')
break;
}
// releases and window destroy are automatic in C++ interface
}
我尝试使用GoPro Hero 3+的视频,以及MacBook网络摄像头的视频,这两个视频同样存在问题。 VLC都可以毫无问题地播放这两个视频。
提前致谢。
答案 0 :(得分:2)
尝试缩短waitKey
帧等待时间。您实际上正在等待帧速率时间(即33 ms),以及获取帧并显示它所需的所有时间。这意味着如果捕获帧并显示它需要超过0毫秒(它确实如此),您将保证等待太长时间。或者,如果你真的想要准确,你可以计算该部分需要多长时间,并等待剩下的部分,例如类似的东西:
while(true)
{
auto start_time = std::chrono::high_resolution_clock::now();
capture >> frame;
if(frame.empty())
break;
imshow(videofilename, frame);
auto end_time = std::chrono::high_resolution_clock::now();
int elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
//make sure we call waitKey with some value > 0
int wait_time = std::max(1, elapsed_time);
char key = waitKey(wait_time); // waits to display frame
if (key == 'q')
break;
}
整个int wait_time = std::max(1, elapsed_time);
行只是为了确保我们等待至少1 ms,因为OpenCV需要在那里调用waitKey
来获取和处理事件,并调用{{1使用值&lt; = 0告诉它等待无穷大的用户输入,我们也不想要(在这种情况下)