waveform80 / picamera

A pure Python interface to the Raspberry Pi camera module
https://picamera.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
1.57k stars 357 forks source link

Unable to run example transform from documentation... #417

Open byronformwalt opened 7 years ago

byronformwalt commented 7 years ago

I am wondering if anyone else has had success or failure executing the cross-hairs sample code from the online documentation (See attached file for Python3-compatible tweaks.)

In addition to a sporadic frame rate less than 1 FPS, I get repeated instances of the following error messages for my configuration:

pi@desk:~/scratch $ python3 camera_transform_experiment.py 
Traceback (most recent call last):
  File "_ctypes/callbacks.c", line 277, in 'calling callback function'
  File "/usr/lib/python3/dist-packages/picamera/mmalobj.py", line 1227, in wrapper
    self._pool.send_buffer(block=False)
  File "/usr/lib/python3/dist-packages/picamera/mmalobj.py", line 1931, in send_buffer
    super(MMALPortPool, self).send_buffer(port, block, timeout)
  File "/usr/lib/python3/dist-packages/picamera/mmalobj.py", line 1881, in send_buffer
    raise PiCameraMMALError(mmal.MMAL_EAGAIN, 'no buffers available')
picamera.exc.PiCameraMMALError: no buffers available: Resource temporarily unavailable; try again later

Below are what I think are all the relevant aspects of my system's configuration:

Parameter/Expression Value/Result
Board RPi3 Model B, (Mfg by Embest in Q12016)
cat /proc/cpuinfo \|grep -E '(Hardware\|Revision)' Hardware: BCM2835, Revision a22082
Camera Module V1
python3 -c 'from picamera import PiCamera as pc; print(pc().revision)' ov5647
uname -a Linux wd 4.9.24-v7+ #993 SMP Wed Apr 26 18:01:23 BST 2017 armv7l GNU/Linux
free -h Total: 859 MB, Used: 209 MB, Free: 650 MB
grep 'gpu_mem' /boot/config.txt gpu_mem=128
python3 --version Python 3.4.2
pip3 show picamera Version: 1.13

Has anyone else attempted to run this example? I get the same error message and result when running the analog clock example from the same section of the documentation. It may be worth pointing out that I am able to use MMAL to get 30 FPS at 1080p resolution when directly connecting the preview component to output[0] on the MMAL camera object. I am also able to get the MJPEG stream examples to work at an acceptable frame rate. When I comment out the buffer modification from the __handle_frame() callback I am still confronted with the same performance issue. My first thought was that the problem may be related to the buffer format, but I am unable to find a format that makes this example work.

Byron

byronformwalt commented 7 years ago

The file wouldn't upload with a .py extension. So you might download this one and change its extension to .py. Here is the source: camera_transform_experiment.py.txt

from picamera import mmal, mmalobj as mo, PiCameraPortDisabled
from PIL import Image, ImageDraw
from signal import pause

class Crosshair(mo.MMALPythonComponent):
    def __init__(self):
        super(Crosshair, self).__init__(name='py.crosshair')
        self._crosshair = None
        self.inputs[0].supported_formats = mmal.MMAL_ENCODING_I420

    def _handle_frame(self, port, buf):
        # If we haven't drawn the crosshair yet, do it now and cache the
        # result so we don't bother doing it again
        if self._crosshair is None:
            self._crosshair = Image.new('L', port.framesize)
            draw = ImageDraw.Draw(self._crosshair)
            draw.line([
                (port.framesize.width // 2, 0),
                (port.framesize.width // 2, port.framesize.height)],
                fill=255, width=1)
            draw.line([
                (0, port.framesize.height // 2),
                (port.framesize.width , port.framesize.height // 2)],
                fill=255, width=1)
        # buf is the buffer containing the frame from our input port. First
        # we try and grab a buffer from our output port
        try:
            out = self.outputs[0].get_buffer(False)
        except PiCameraPortDisabled:
            # The port was disabled; that probably means we're shutting down so
            # return True to indicate we're all done and the component should
            # be disabled
            return True
        else:
            if out:
                # We've got a buffer (if we don't get a buffer here it most
                # likely means things are going too slow downstream so we'll
                # just have to skip this frame); copy the input buffer to the
                # output buffer
                out.copy_from(buf)
                # now grab a locked reference to the buffer's data by using
                # "with"
                with out as data:
                    # Construct a PIL Image over the Y plane at the front of
                    # the data and tell PIL the buffer is writeable
                    img = Image.frombuffer('L', port.framesize, data, 'raw', 'L', 0, 1)
                    img.readonly = False
                    img.paste(self._crosshair, (0, 0), mask=self._crosshair)
                # Send the output buffer back to the output port so it can
                # continue onward to whatever's downstream
                try:
                    self.outputs[0].send_buffer(out)
                except PiCameraPortDisabled:
                    # The port was disabled; same as before this probably means
                    # we're shutting down so return True to indicate we're done
                    return True
            # Return False to indicate that we want to continue processing
            # frames. If we returned True here, the component would be
            # disabled and no further buffers would be processed
            return False

camera = mo.MMALCamera()
preview = mo.MMALRenderer()
transform = Crosshair()

camera.outputs[0].framesize = '720p'
camera.outputs[0].framerate = 30
camera.outputs[0].commit()

transform.connect(camera)
preview.connect(transform)

transform.connection.enable()
preview.connection.enable()

preview.enable()
transform.enable()
camera.enable()

pause()
jcormier commented 7 years ago

Same here

PlanetaryGear commented 4 years ago

I am also getting the same errors while attempting to run the next example with the analog clock overlay. It drops frames after getting those errors.