到目前为止,我看到的所有示例和书籍都建议使用waitKey(1)强制重绘OpenCV窗口。这看起来很奇怪,而且太hacky了。
有没有其他替代方法?我尝试过cv::updateWindow,但它似乎需要OpenGL,因此会崩溃。我在Windows上使用VC++。
到目前为止,我看到的所有示例和书籍都建议使用waitKey(1)强制重绘OpenCV窗口。这看起来很奇怪,而且太hacky了。
有没有其他替代方法?我尝试过cv::updateWindow,但它似乎需要OpenGL,因此会崩溃。我在Windows上使用VC++。
我查看了源代码,就像 @Dan Masek所说的那样,似乎没有其他的函数来处理Windows消息。 所以我最终编写了自己的小型DoEvents()函数用于VC++。以下是使用OpenCV逐帧显示视频帧并跳过所需帧数的完整源代码。
#include <windows.h>
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
bool DoEvents();
int main(int argc, char *argv[])
{
VideoCapture cap(argv[1]);
if (!cap.isOpened())
return -1;
namedWindow("tree", CV_GUI_EXPANDED | CV_WINDOW_AUTOSIZE);
double frnb(cap.get(CV_CAP_PROP_FRAME_COUNT));
std::cout << "frame count = " << frnb << endl;
for (double fIdx = 0; fIdx < frnb; fIdx += 50) {
Mat frame;
cap.set(CV_CAP_PROP_POS_FRAMES, fIdx);
bool success = cap.read(frame);
if (!success) {
cout << "Cannot read frame " << endl;
break;
}
imshow("tree", frame);
if (!DoEvents())
return 0;
}
return 0;
}
bool DoEvents()
{
MSG msg;
BOOL result;
while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
result = ::GetMessage(&msg, NULL, 0, 0);
if (result == 0) // WM_QUIT
{
::PostQuitMessage(msg.wParam);
return false;
}
else if (result == -1)
return true; //error occured
else
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
return true;
}
modules\highgui\src\window_w32.cpp
),它是一个相当简单的消息泵,你可以轻松地编写自己修改过的版本——去掉按键检查、睡眠等。 - Dan Mašek