4

I am working on a project where I need to use opencv to get image data in python from the pi camera module. I have seen the tutorials on how to do this with C++ but not too much in python. I did find this link which had me install the official kernel V4L2 driver bcm2835-v4l2. Once I did this I was able to capture the stream from the pi but the stream shows up tiny...probably about 5x5 pixels. I couldn't find anyone else who has encountered this problem. Any ideas?

Below is the simple code I am using for the capture:

import cv2
import numpy as np

cap = cv2.VideoCapture(-1)

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

EDIT: I also forgot to mention that when I run the script, I get this error before the window shows up. I am assuming it occurs when cap is created.

VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument
VIDIOC_QUERYMENU: Invalid argument

1 Answer 1

2

You may find you need to use v4l2-ctl to configure the camera module as detailed in this forum thread (you could do this before running your script, or have your script call it via subprocess.call).

An alternative (given that OpenCV's image format is simply a numpy array in BGR order), is to use the unencoded capture feature in picamera (based on your code and the RGB capture recipe from the picamera 1.8 docs):

import cv2
import picamera
import picamera.array

with picamera.PiCamera() as camera:
    with picamera.array.PiRGBArray(camera) as stream:
        camera.resolution = (320, 240)

        while True:
            camera.capture(stream, 'bgr', use_video_port=True)
            # stream.array now contains the image data in BGR order
            cv2.imshow('frame', stream.array)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
            # reset the stream before the next capture
            stream.seek(0)
            stream.truncate()

        cv2.destroyAllWindows()
3
  • Thanks! I ended up going with the alternative solution and things seem to be working great. Is one method superior to the other? For my purposes the more efficient the better and it would be great if the capture is non-blocking.
    – TooMuchDog
    Nov 4, 2014 at 21:36
  • I suspect both are similar in terms of speed as both picamera and the official V4L2 driver use the MMAL layer to control the camera. The latter is probably faster (simply because it's written in C) but most of the capture time is spent in the camera's firmware rather than the calling code.
    – Dave Jones
    Nov 5, 2014 at 10:15
  • Capture (in MMAL) is actually non-blocking, but the picamera code waits on the background thread for capture to finish (primarily to keep the interface simple, given it's an educational platform). If you have a look at the capture method's implementation you might be able to come up with a non-blocking version, but I can't say it's only my todo list at the moment!
    – Dave Jones
    Nov 5, 2014 at 10:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.