Getting BeagleBone to capture a still frame using OpenCV

7.7k Views Asked by At

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.

3

There are 3 best solutions below

5
On

I am not sure whether this can be an answer. Do try out the following.

I guess, the camera driver is not supported. Connect the camera onto the board and type 'dmesg' in the terminal, and see whether the camera manufacturers name is detected in it.

If the manufacturers name is not present anywhere in the message, the camera driver is to be installed from the terminal:

opkg update
opkg install kernel-module-uvcvideo
modprobe uvcvideo

If the above steps doesn't help you, try installing VLC media player or any other player which supports video input from a camera, and try whether it's working. :)

2
On

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;
}
0
On
  1. Try to use any V4L2 application and try to test the camera without using any code. There is Qt V4L2 software that you can download and test the camera with.
  2. If step one fails, then there are problems with your camera driver, and it is not supported.
  3. If step one succeeds then check your code and try to use gstreamer or any ready V4L2 capture samples.

I have faced problems that the camera can be recognized, but the driver has bugs, so check first if the camera's driver is really supported by your kernel. Mentioning your camera model is also good. What kind of interface is it, MIPI or USB? I suspect that that's a driver problem.