到目前为止,我看到的所有示例和书籍都建议使用waitKey(1)来强制重新绘制OpenCV窗口。这看起来很奇怪,也太古怪了。既然不需要,为什么还要等1毫秒?
有其他选择吗?我尝试了cv::updateWindow,但它似乎需要OpenGL,因此崩溃了。我在Windows上使用VC++。
我查看了源代码,正如@Dan Masek所说,似乎没有任何其他函数可以处理windows消息。因此,我最终为VC++编写了自己的DoEvents()函数。以下是使用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;
}