Getting the time of actual screen refresh

Hi, I know that for displaying an image with opencv, I have to call the WaitKey function.
Supose I save a time variable just before and after displaying an image:

k = cv2.waitKey(500)

I also know that when you send a screen refresh instruction, yo have to wait for the next frame of the screen refresh rate to appear. Two quetsions rise:

  1. Is there any way that I can know the real timing of display
  2. Does WaitKey starts its internal time right away or it ‘waits’ for the onset of the display?

Supposing a 60 Hz screen, I may have to wait 16 ms aprox. at most. Ths meanes that after-before may give 516? Or WaitKey always starts independent of the internal rate of the screen, so that the actual time the screen is showing the image may be less that 500 ms?

not really, not with OpenCV. that’s information hidden inside whatever GUI toolkit is used at the moment.

I’ve managed to measure a kind of frame rate from measuring the time or iterations per second of waitKey/pollKey calls… but I don’t remember what I did there.

right away… usually. again, depends on GUI toolkit.

there are some calls inside of waitKey that sometimes wait until a screen refresh has happened. that can, in some situations, be disabled, and you could conceivably try to display thousands of images per second (of which maybe 60 will actually be displayed). same goes for pollKey(), which doesn’t wait at all, but just works on the event queue until it’s empty.

it also doesn’t care about refresh rate. you can do a waitKey(1) and it might wait upto 1 ms, or 10 ms, or 15.625 ms, which is all less than 60 fps would require.

in summary, do not, I repeat, DO NOT, rely on waitKey taking a specific amount of time. don’t. absolutely not. don’t even think about it.

if nothing else happens, it will take at least the specified time, because the operating system has a certain temporal resolution and it can’t do that any more precisely. if a key is pressed or all windows are closed, waitKey returns earlier.

you should have said that you want to display something at a fixed rate. that’s your goal, right? always say that. do not get lost in details of your own choosing. let others advise you. figuring out what you really want is a waste of time if you could just say that up front.

if you want a fixed rate display, take an initial time stamp, and increment a counter for every frame you want to show, and then calculate when that frame is due, and then calculate the difference from now until that time, and use that interval as an argument to waitKey, and when waitKey returns, check again if it’s time already, or not.


Thanks for you answer. I need two things to precisely synchronize data files from two different computers. First, analyze data already recorded in a “bad way”, and then, improve my code before re-executing my experiments to record better data.

For the first step, I need the time difference between the moment of code execution and actual screen refresh, because I already recorded data that way. In computer 1, a given line of code wrote to file a timestamp with absolute time, and the next line is cv2.waitKey(500) function. Later in time, the screen displays the image, while computer 2 detects the luminance change with a small photodiode (in the corner of the screen). So, in fact, I have to different delays. Delay 1 is the difference between 2 consecutive lines of code (unknown, but estimated in the 1-10 milisecond range). Delay 2 is the difference between the call to waitKey and the physical response of the monitor.
So, the point is that I have the photodiode signal in one computer, while controlled the screen and recorded timestamps with another. Specifically, I need to know when the timestamp of computer 1 matches in time with photodiode signal in computer 2.

I don’t need to display at a specific, constant rate, but I do need to know as precise as possible when the instruction for screen change was given, relative to the real response of the screen.

For step 2 I have no clue despite your advices, because there can always be a delay between a display function and the next frame of the screen.

see if, when waitKey returns, and then you take a timestamp, that timestamp indicates regular time intervals.

use time.perf_counter or other clock source that’s better than scheduler time slices.

calculate difference between timestamps. it might show that it’s “sticking” to screen refreshes/vsyncs, and be something like 1/60 seconds, more or less accurately.

use WINDOW_OPENGL flag for namedWindow.