3

All examples and books I've seen so far recommends using waitKey(1) to force repaint OpenCV window. That looks weird and too hacky. Why wait for even 1ms when you don't have to?

Are there any alternatives? I tried cv::updateWindow but it seems to require OpenGL and therefore crashes. I'm using VC++ on Windows.

Shital Shah
  • 63,284
  • 17
  • 238
  • 185
  • 1
    According to the docs, it's the only method that does event processing. Looking at the code (`modules\highgui\src\window_w32.cpp`), it's a fairly straightforward message pump, you could easily write your own modified version -- drop the keypress checks, sleeping, etc. – Dan Mašek Mar 31 '16 at 23:50
  • this is fairly lousy. I'm using `opencv` for `python` - what's the alternative in this environment? – WestCoastProjects May 27 '19 at 20:14

1 Answers1

4

I looked in to source and as @Dan Masek said, there doesn't seem to be any other functions to process windows message. So I ended up writing my own little DoEvents() function for VC++. Below is the full source code that uses OpenCV to display video frame by frame while skipping desired number of frames.

#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;
}
Shital Shah
  • 63,284
  • 17
  • 238
  • 185