我正在尝试用 OpenCV 阅读C++视频,但是当视频显示时,帧速率非常慢,例如原始帧速率的 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可以毫无问题地播放这两个视频。
提前谢谢。
尝试减少waitKey
帧等待时间。您实际上是在等待帧速率时间(即 33 毫秒),以及抓取帧并显示帧所需的所有时间。这意味着,如果捕获帧并显示它需要超过 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 毫秒,因为 OpenCV 需要调用 waitKey
在那里获取和处理事件,并且调用值 <= 0 的 waitKey
告诉它无限等待用户输入,我们也不希望(在这种情况下)