Ask Your Question
0

How to get around camera lag

asked 2017-01-20 19:32:18 -0600

blue32 gravatar image

Disclaimer: I am new to OpenCV and fairly new to Computer Science in general

I'm currently using OpenCV 3.2 on both Windows (with Visual Studio 2016) and Linux (via Virtual Machine) and I am having trouble with the camera. More specifically, I am having trouble opening and closing the camera on my computer. I am running fairly simple code (snippet below) that involves opening the camera, displaying frames, pressing esc to take a picture, saving the picture, and then closing the camera. When I close the camera, the terminal says that the camera is closed, but the frame stays open and says "not responding". Eventually it closes itself (after a good minute or two) and moves on with my code. However, when I try to relaunch the camera again, it won't relaunch. Furthermore, it brings up the last frame that it hung on and continues to say "not responding". It hangs for a while, never opens, and then continues with my code. My question is this: Is there some known way to get around this? Is there a special command for relaunching a camera that is different than the command you use to open the camera for the first time? Are there other ways to prevent the camera (and the computer for that matter) from hanging?

Things I have tried:

-Adding a sleep function after loading a new frame to help do less computation per second (to improve the lag)
-Using two different names for the video capture when launching the camera (cap and cap2)
-Using the exact same code twice in a row
-Simplifying the program to be just the task of opening, closing, and reopening

I have tried snooping around on Google, but my searching abilities have failed me. Is there anyone who has had this problem and/or knows how to solve this?

Code snippet:

...
VideoCapture cap;
if (!cap.open(0)) {
    return 0;}
for (;;)
{
    cap >> frame;
    if (frame.empty()) break; // end of video stream
    imshow("Smile! Press esc to take picture", frame);
    if (waitKey(1) == 27)
    {
        imwrite("../image.png", frame);
        testSample = frame;
        testLabel = -1;
        break; // stop capturing by pressing ESC 
    }
}

// the camera will be closed automatically upon exit
cap.release(); 

    ...

VideoCapture cap2;
if (!cap2.open(0))
{
    cout << "Cap isn't open. Terminating..." << endl;
    return -1;
}
cout << "Smile! Press esc to take picture" << endl;
for (;;)
{
    cap2 >> frame;
    if (frame.empty()) cout << "frame empty. terminating..." << endl;  break; // end of video stream
    imshow("Smile! :)", frame);
            ...
     }

    ...

cap2.release();

     ...
edit retag flag offensive close merge delete

Comments

i do not understand, why you even try to close / reopen the capture, after taking an image, -- you want to take more than one image during the lifetime of your program, right ?

it seems you duplicated your whole program, while it could be a single (but smarter) for-loop there.

berak gravatar imageberak ( 2017-01-21 02:46:21 -0600 )edit

maybe unrelated, but i see useful to mention here vpisarev's comment on

if (waitKey(1) == 27)

"such a small delay may cause the program to process the same frame many times, because cameras do not usually capture video at 1000fps and we are not able to process it in 1ms"

sturkmen gravatar imagesturkmen ( 2017-01-21 05:09:20 -0600 )edit

berak: The actual program this comes from is much much longer than what I put up. The first loop happens toward the beginning of the program and the second toward the end under specific conditions. In some cases, the second loop doesn't even operate. In most though, for the purposes of testing, it will.

blue32 gravatar imageblue32 ( 2017-01-23 19:39:41 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
1

answered 2017-01-21 02:37:29 -0600

LBerger gravatar image

updated 2017-01-21 02:48:08 -0600

Second capture loop is wrong. you forgot some {. If you want to close a windows you have to use DestroyWindow. Close a capture is not close window

 VideoCapture cap;
if (!cap.open(0)) {
    return 0;
}
Mat frame;
for (;;)
{
    cap >> frame;
    if (frame.empty()) break; // end of video stream
    imshow("Smile! Press esc to take picture", frame);
    if (waitKey(1) == 27)
    {
        break; // stop capturing by pressing ESC 
    }
}

// the camera will be closed automatically upon exit
cap.release();


    VideoCapture cap2;
if (!cap2.open(0))
{
    cout << "Cap isn't open. Terminating..." << endl;
    return -1;
}
cout << "Smile! Press esc to take picture" << endl;
for (;;)
{
    cap2 >> frame;
    if (frame.empty())
    { // ADD
        cout << "frame empty. terminating..." << endl;  break; // end of video stream

    }// ADD
    imshow("Smile! :)", frame);
    if (waitKey(1) == 27) // waitkey after imshow to avoid a lag  (small)
    {
        break; // stop capturing by pressing ESC 
    }
}

    cap2.release();

Visual studio 2016 ? VS 2015 or VS2017 RC

edit flag offensive delete link more
0

answered 2017-01-21 03:02:28 -0600

berak gravatar image

updated 2017-01-21 03:06:54 -0600

closing and re-opening a capture is usually a bad idea (slow/memory intensive), so i'd rather change the logic / code-flow in your program: have 1 button to take a picture, and another to quit.

int imagesTaken=0;
VideoCapture cap;
if (!cap.open(0)) {
    return 0;}
for (;;)
{
    cap >> frame;
    if (frame.empty()) break; // end of video stream
    imshow("Smile! Press space to take a picture, esc to stop.", frame);
    int k = waitKey(1);
    if (k == ' ') // space
    {
        imwrite(format("../image%04d.png", imagesTaken), frame); // try unique name
        imagesTaken++;
    }
    if (k == 27) // escape
    {
        break; // stop capturing by pressing ESC 
    }
}
// the camera will be closed automatically upon exit
edit flag offensive delete link more

Comments

I remember some problems about this comment "About slow/memory intensive" Now I test it there is no problem with VS 2015 windows 10 opencv 3.2

   for (int i = 0; i < 100; i++)
    {
    VideoCapture cap;
    if (!cap.open(0)) 
        return 0;
     Mat frame;
    for (;;)
    {
        cap >> frame;
        if (frame.empty()) break; // end of video stream
        imshow(format("Smile! Press esc to take picture %d",i), frame);
        if (waitKey(1) == 27)
        {
            break; // stop capturing by pressing ESC 
        }
    }
    cap.release();

    }
LBerger gravatar imageLBerger ( 2017-01-21 03:16:26 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-01-20 19:32:18 -0600

Seen: 6,359 times

Last updated: Jan 21 '17