Getting BeagleBone to capture a still frame using OpenCV

Chris picture Chris · Mar 6, 2013 · Viewed 7.6k times · Source

I've a BeagleBone running Ångström Linux 3.2.28, and I'm trying to capture a frame from my camera.

So I plug in my USB webcam, and check /dev to ensure it shows up.

It does, as video0 (bottom right). I know this is correct, because it disappears after I've unplugged the camera.

 (bo

So now I fire up Python and run the following:

root@beaglebone:/dev# python
Python 2.7.2 (default, Sep 11 2012, 16:15:43)
[GCC 4.5.4 20120305 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv
>>> capture=cv.CaptureFromCAM(-1)
>>> img=cv.QueryFrame(capture)
>>> type(capture)
<type 'cv2.Capture'>
>>> type(img)
<type 'NoneType'>

As you can see, I am able to create the capture object sufficiently, but I am unable to pull a frame from it. I have also tried this with different (or no) integer arguments for the camera ID (the -1 in the code above) to no avail.

For reference, running the same code on my laptop in IPython looks like this:

In [1]: import cv
In [2]: capture=cv.CaptureFromCAM(-1)
In [3]: img=cv.QueryFrame(capture)
In [4]: type(capture)
Out[4]: cv2.Capture
In [5]: type(img)
Out[5]: cv2.cv.iplimage

You can see that here I am indeed capturing an image. I am not sure exactly where to go from here.

UPDATE:

I've played around a bit with FFmpeg and am able to get the camera to respond (that is, its light goes on) by issuing the following command:

root@beaglebone:/# ffmpeg -f video4linux2 -i /dev/video0

Which is interesting because apparently CaptureFromCAM uses the V4L interface... I am not sure where to go from here.

Answer

karlphillip picture karlphillip · Mar 15, 2013

The very first thing you need to do is make sure CaptureFromCAM() succeeded:

import cv
capture = cv.CaptureFromCAM(-1)
if not capture:
    print "Unable to open device #-1"
    sys.exit(1) 

Sending -1 as argument tells OpenCV to open the default camera device. On some systems this doesn't work and you need to increase the number. Try passing 0, then 1 and later 2.

The second thing you need to do is make sure QueryFrame() returns something valid as well:

img = cv.QueryFrame(capture)
if not img:
    print "Unable to retrieve frame from the device"
    sys.exit(1) 

I've seen strange behaviors between OpenCV's Python API and the C (and even the C++) API. If none of the above help you fix the problem, I suggest you compile a C program (which has the most reliable API) using OpenCV to retrieve data from the camera. On some cases, OpenCV's C API work and the Python doesn't.

This C program retrieves frames from the camera and displays them in a window:

#include <stdio.h>
#include <highgui.h>
#include <cv.h>

int main() 
{
CvCapture* capture = NULL;
if ((capture = cvCaptureFromCAM(-1)) == NULL)
{
    fprintf(stderr, "ERROR: capture is NULL \n"); 
    return -1;
}

cvNamedWindow("mywindow", CV_WINDOW_AUTOSIZE);

cvQueryFrame(capture); // Sometimes needed to get correct data

while (1) 
{     
    IplImage* frame = cvQueryFrame(capture); // check return
    {
        fprintf( stderr, "ERROR: cvQueryFrame failed\n");
        break;
    }

    // At this point you already have the frame! There's no need to
    // repeat the thing 10x with cvGrabFrame and cvRetrieveFrame. 
    // You are probably sabotaging yourself doing this multiple times.

    cvShowImage("mywindow", frame); // Do not release the frame!

    int key = cvWaitKey(10);
    if (key  == 0x1b)
        break;
}    

cvReleaseCapture(&capture);   
cvDestroyWindow("mywindow");   

return 0;
}