How can I get the most current frame in OpenCV?

I’m trying to take and display the most current frame on any key event. It is important for me that the photo will be taken only once (without using infinity loop). I have a problem because displayed photo is the previous one not the most current. It looks like some buffor with captured frames in VideoCapture object.

I’m using OpenCV 4.6.0 and laptop camera.

#include <iostream>
#include <opencv2/opencv.hpp>

int main() {
    cv::VideoCapture cap0(0);

    cv::Mat frame0;
    for (;;)
    {
        cap0.read(frame0);
        if (!frame0.empty())
        {
            imshow("cap0", frame0);
        }
        cv::waitKey(0);
    }
    return 0;
}

Is it possible to get and display current photo without doing infinity loop whenever I click any key?

crosspost:

Hello Piter217,
this might not be the best or smartest solution but you can capture 4 frames before calling imshow(). This will clear the old frames and leave you with the most current frame. You can do this by calling cap0.read(frame0); multiple times.

note that that number is arbitrary and not justified by any technical fact. there are some hacks to flush the queue, such as setting buffer size to 0 or 1 or something else small that works. the usual way is to run capture in a separate thread and keep a reference to the last captured frame, for the rest of the program to access whenever needed.

the initial post should simply not use waitKey(0) but instead waitKey(1) or pollKey(). all of this was already discussed on Stack Overflow

Thank you for clarifying, I was under the impression that the buffer size defaulted to store 4 frames.

Another way of getting the most current frame from camera might be measuring time of grabing. Usual grab times for web cameras are 20 - 40 ms. If grabbing is faster than this time, you can assume that the frame was copied from buffer, so you can grab again unitil the grabbing time is more than threshold: ~20 ms (50 FPS).

Make sure that the actual grab time is more than the threshold, your code might end up in infinite loop.