2
votes

I'm using OpenCV 3.1, I try to run a simple code as the following one (main function):

 cv::VideoCapture cam;
cv::Mat matTestingNumbers;

cam.open(0);

if (!cam.isOpened()) { printf("--(!)Error opening video capture\n"); return -1; }

while (cam.read(matTestingNumbers))
{
    cv::imshow("matTestingNumbers", matTestingNumbers);
    cv::waitKey(5000);
}

When I move the camera it seems that the code does not capture and show the current frame but shows all the captured frames from the previous position and only then from the new one.

So when I capture the wall it shows the correct frames (the wall itself) in the correct delay, but, when I twist the camera to my computer, I first see about 3 frames of the wall and only then the computer, it seems that the frames are stuck.

I've tried to use videoCapture.set() functions and set the FPS to 1, and I tried to switch the method of capturing to cam >> matTestingNumbers (and the rest of the main function according to this change) but nothing helped, I still got "stuck" frames.

BTW, These are the solutions I found on web.

What can I do to fix this problem?

Thank you, Dan.

EDIT:

I tried to retrieve frames as the following:

#include "opencv2/opencv.hpp"

using namespace cv;

int main(int, char**)
{
    VideoCapture cap(0); // open the default camera
    if(!cap.isOpened())  // check if we succeeded
        return -1;

    Mat frame;
    namedWindow("edges",1);

    for(;;)
    {
        cap.grab();

        if (waitKey(11) >= 0)
        {
            cap.retrieve(frame);
            imshow("edges", frame);
        }

    }
    return 0;
}

But, it gave the result (when I pointed the camera on one spot and pressed a key it showed one more of the previous frames that were captured of the other point).

It is just like you're trying to picture one person then another but when you picture the second you get the photo of the first person what doesn't make sense.

Then, I tried the following:

#include "opencv2/opencv.hpp"

using namespace cv;

int main(int, char**)
{
    VideoCapture cap(0); // open the default camera
    if(!cap.isOpened())  // check if we succeeded
        return -1;

    Mat frame;
    namedWindow("edges",1);

    for(;;)
    {
        cap >> frame;

        if (waitKey(33) >= 0)

            imshow("edges", frame);

    }
    return 0;
}

And it worked as expected.

1
still not sure whether this is a buffering in the camera/driver/openCV but you cant be sure that a captured frame is the most up-to-date one... you should read all frames without long sleep or waitKey and/or adjust the capturing framerate to your target fps. - Micka
As I wrote in the question, I tried to do that (set() function) but the result was still not changed, I definitely need a delay in this program so I can't comment the long delay out. - Danaro
what about multi threading with one capturing thread (updates without any waiting time) and a processing thread (waits some time and then processes the latest captured image)? - Micka

1 Answers

0
votes

One of the problems is that you are not calling cv::waitKey(X) to properly freeze the window for X amount of milliseconds. Get rid of usleep()!