To install picamera on Raspbian, it is best to use the system‚Äôs package
manager: apt. This will ensure that picamera is easy to keep up to date, and
easy to remove should you wish to do so. It will also make picamera available
for all users on the system. To install picamera using apt simply run:

On distributions other than Raspbian, it is probably simplest to install system
wide using Python‚Äôs pip tool:

$ sudo pip install picamera

If you wish to use the classes in the picamera.array module then specify
the ‚Äúarray‚ÄĚ option which will pull in numpy as a dependency:

$ sudo pip install "picamera[array]"

Warning

Be warned that older versions of pip will attempt to build numpy from
source. This will take a very long time on a Pi (several hours on slower
models). Modern versions of pip will download and install a pre-built
numpy ‚Äúwheel‚ÄĚ instead which is much faster.

The behaviour of the Pi‚Äôs camera module is dictated by the Pi‚Äôs firmware. Over
time, considerable work has gone into fixing bugs and extending the
functionality of the Pi‚Äôs camera module through new firmware releases. Whilst
the picamera library attempts to maintain backward compatibility with older Pi
firmwares, it is only tested against the latest firmware at the time of
release, and not all functionality may be available if you are running an older
firmware. As an example, the annotate_text attribute relies
on a recent firmware; older firmwares lacked the functionality.

You can determine the revision of your current firmware with the following
command:

On Raspbian, the standard upgrade procedure should keep your firmware
up to date:

$ sudo apt-get update
$ sudo apt-get upgrade

Warning

Previously, these documents have suggested using the rpi-update utility
to update the Pi‚Äôs firmware; this is now discouraged. If you have
previously used the rpi-update utility to update your firmware, you can
switch back to using apt to manage it with the following commands:

Please note that the PiTFT screen (and similar GPIO-driven screens)
requires a custom firmware for operation. This firmware lags behind the
official firmware and at the time of writing lacks several features
including long exposures and text overlays.

Make sure your Pi is off while installing the camera module. Although it is
possible to install the camera while the Pi is on, this isn‚Äôt good practice
(if the camera is active when removed, it‚Äôs possible to damage it).

Connect your camera module to the CSI port on your Raspberry Pi; this is the
long thin port adjacent to the HDMI socket. Gently lift the collar on top of
the CSI port (if it comes off, don‚Äôt worry, you can push it back in but try to
be more gentle in future!). Slide the ribbon cable of the camera module into
the port with the blue side facing the Ethernet port (or where the Ethernet
port would be if you‚Äôve got a model A/A+).

Once the cable is seated in the port, press the collar back down to lock the
cable in place. If done properly you should be able to easily lift the Pi by
the camera‚Äôs cable without it falling out. The following illustrations show
a well-seated camera cable with the correct orientation:

Make sure the camera module isn‚Äôt sat on anything conductive (e.g. the Pi‚Äôs
USB ports or its GPIO pins).

Remove the existing camera module‚Äôs cable by gently lifting the collar on
the camera module and pulling the cable out.

Next, insert the wider end of the adapter cable with the conductors facing
in the same direction as the camera‚Äôs lens.

Finally, attach the adapter to the Pi Zero by gently lifting the collar at
the edge of the board (be careful with this as they are more delicate than
the collars on the regular CSI ports) and inserting the smaller end of the
adapter with the conductors facing the back of the Pi Zero.

Now, apply power to your Pi. Once booted, start the Raspberry Pi Configuration
utility and enable the camera module:

You will need to reboot after doing this (but this is one-time setup so you
won‚Äôt need to do it again unless you re-install your operating system or switch
SD cards). Once rebooted, start a terminal and try the following command:

raspistill -o image.jpg

If everything is working correctly, the camera should start, a preview from the
camera should appear on the display and, after a 5 second delay it should
capture an image (storing it as image.jpg) before shutting down the camera.
Proceed to the Basic Recipes.

If something else happens, read any error message displayed and try any
recommendations suggested by such messages. If your Pi reboots as soon as you
run this command, your power supply is insufficient for running your Pi plus
the camera module (and whatever other peripherals you have attached).

The following recipes should be reasonably accessible to Python programmers of
all skill levels. Please feel free to suggest enhancements or additional
recipes.

Warning

When trying out these scripts do not name your file picamera.py.
Naming scripts after existing Python modules will cause errors when you
try and import those modules (because Python checks the current directory
before checking other paths).

Capturing an image to a file-like object (a socket(), a
io.BytesIO stream, an existing open file object, etc.) is as simple as
specifying that object as the output of whatever capture()
method you‚Äôre using:

Note that the format is explicitly specified in the case above. The
BytesIO object has no filename, so the camera can‚Äôt automatically
figure out what format to use.

One thing to bear in mind is that (unlike specifying a filename), the stream is
not automatically closed after capture; picamera assumes that since it didn‚Äôt
open the stream it can‚Äôt presume to close it either. However, if the object has
a flush method, this will be called prior to capture returning. This should
ensure that once capture returns the data is accessible to other processes
although the object still needs to be closed:

fromtimeimportsleepfrompicameraimportPiCamera# Explicitly open a new file called my_image.jpgmy_file=open('my_image.jpg','wb')camera=PiCamera()camera.start_preview()sleep(2)camera.capture(my_file)# At this point my_file.flush() has been called, but the file has# not yet been closedmy_file.close()

Note that in the case above, we didn‚Äôt have to specify the format as the camera
interrogated the my_file object for its filename (specifically, it looks
for a name attribute on the provided object). As well as using stream
classes built into Python (like BytesIO) you can also construct
your own custom outputs.

This is a variation on Capturing to a stream. First we‚Äôll capture an image to a
BytesIO stream (Python‚Äôs in-memory stream class), then we‚Äôll
rewind the position of the stream to the start, and read the stream into a
PIL Image object:

fromioimportBytesIOfromtimeimportsleepfrompicameraimportPiCamerafromPILimportImage# Create the in-memory streamstream=BytesIO()camera=PiCamera()camera.start_preview()sleep(2)camera.capture(stream,format='jpeg')# "Rewind" the stream to the beginning so we can read its contentstream.seek(0)image=Image.open(stream)

Sometimes, particularly in scripts which will perform some sort of analysis or
processing on images, you may wish to capture smaller images than the current
resolution of the camera. Although such resizing can be performed using
libraries like PIL or OpenCV, it is considerably more efficient to have the
Pi‚Äôs GPU perform the resizing when capturing the image. This can be done with
the resize parameter of the capture() methods:

You may wish to capture a sequence of images all of which look the same in
terms of brightness, color, and contrast (this can be useful in timelapse
photography, for example). Various attributes need to be used in order to
ensure consistency across multiple shots. Specifically, you need to ensure that
the camera‚Äôs exposure time, white balance, and gains are all fixed:

To fix exposure time, set the shutter_speed attribute to a
reasonable value.

To fix white balance, set the awb_mode to 'off', then
set awb_gains to a (red, blue) tuple of gains.

It can be difficult to know what appropriate values might be for these
attributes. For iso, a simple rule of thumb is that 100 and
200 are reasonable values for daytime, while 400 and 800 are better for low
light. To determine a reasonable value for shutter_speed you
can query the exposure_speed attribute. For exposure gains,
it‚Äôs usually enough to wait until analog_gain is greater than
1 before exposure_mode is set to 'off'. Finally, to
determine reasonable values for awb_gains simply query the
property while awb_mode is set to something other than
'off'. Again, this will tell you the camera‚Äôs white balance gains as
determined by the auto-white-balance algorithm.

The following script provides a brief example of configuring these settings:

fromtimeimportsleepfrompicameraimportPiCameracamera=PiCamera(resolution=(1280,720),framerate=30)# Set ISO to the desired valuecamera.iso=100# Wait for the automatic gain control to settlesleep(2)# Now fix the valuescamera.shutter_speed=camera.exposure_speedcamera.exposure_mode='off'g=camera.awb_gainscamera.awb_mode='off'camera.awb_gains=g# Finally, take several photos with the fixed settingscamera.capture_sequence(['image%02d.jpg'%iforiinrange(10)])

The simplest way to capture long time-lapse sequences is with the
capture_continuous() method. With this method, the camera
captures images continually until you tell it to stop. Images are automatically
given unique names and you can easily control the delay between captures. The
following example shows how to capture images with a 5 minute delay between
each shot:

However, you may wish to capture images at a particular time, say at the start
of every hour. This simply requires a refinement of the delay in the loop (the
datetime module is slightly easier to use for calculating dates and
times; this example also demonstrates the timestamp template in the
captured filenames):

fromtimeimportsleepfrompicameraimportPiCamerafromdatetimeimportdatetime,timedeltadefwait():# Calculate the delay to the start of the next hournext_hour=(datetime.now()+timedelta(hour=1)).replace(minute=0,second=0,microsecond=0)delay=(next_hour-datetime.now()).secondssleep(delay)camera=PiCamera()camera.start_preview()wait()forfilenameincamera.capture_continuous('img{timestamp:%Y-%m-%d-%H-%M}.jpg'):print('Captured %s'%filename)wait()

Using similar tricks to those in Capturing consistent images, the Pi‚Äôs camera can
capture images in low light conditions. The primary objective is to set a high
gain, and a long exposure time to allow the camera to gather as much light as
possible. However, the shutter_speed attribute is constrained
by the camera‚Äôs framerate so the first thing we need to do is
set a very slow framerate. The following script captures an image with a 6
second exposure time (the maximum the Pi‚Äôs V1 camera module is capable of; the
V2 camera module can manage 10 second exposures):

frompicameraimportPiCamerafromtimeimportsleepfromfractionsimportFraction# Force sensor mode 3 (the long exposure mode), set# the framerate to 1/6fps, the shutter speed to 6s,# and ISO to 800 (for maximum gain)camera=PiCamera(resolution=(1280,720),framerate=Fraction(1,6),sensor_mode=3)camera.shutter_speed=6000000camera.iso=800# Give the camera a good long time to set gains and# measure AWB (you may wish to use fixed AWB instead)sleep(30)camera.exposure_mode='off'# Finally, capture an image with a 6s exposure. Due# to mode switching on the still port, this will take# longer than 6 secondscamera.capture('dark.jpg')

In anything other than dark conditions, the image produced by this script will
most likely be completely white or at least heavily over-exposed.

Note

The Pi‚Äôs camera module uses a rolling shutter. This means that moving
subjects may appear distorted if they move relative to the camera. This
effect will be exaggerated by using longer exposure times.

When using long exposures, it is often preferable to use
framerate_range instead of framerate. This
allows the camera to vary the framerate on the fly and use shorter framerates
where possible (leading to shorter capture delays). This hasn‚Äôt been used in
the script above as the shutter speed is forced to 6 seconds (the maximum
possible on the V1 camera module) which would make a framerate range pointless.

This is a variation of Capturing timelapse sequences. Here we have two scripts: a
server (presumably on a fast machine) which listens for a connection from the
Raspberry Pi, and a client which runs on the Raspberry Pi and sends a continual
stream of images to the server. We‚Äôll use a very simple protocol for
communication: first the length of the image will be sent as a 32-bit integer
(in Little Endian format), then this will be followed by the bytes of image
data. If the length is 0, this indicates that the connection should be closed
as no more images will be forthcoming. This protocol is illustrated below:

Firstly the server script (which relies on PIL for reading JPEGs, but you could
replace this with any other suitable graphics library, e.g. OpenCV or
GraphicsMagick):

importioimportsocketimportstructfromPILimportImage# Start a socket listening for connections on 0.0.0.0:8000 (0.0.0.0 means# all interfaces)server_socket=socket.socket()server_socket.bind(('0.0.0.0',8000))server_socket.listen(0)# Accept a single connection and make a file-like object out of itconnection=server_socket.accept()[0].makefile('rb')try:whileTrue:# Read the length of the image as a 32-bit unsigned int. If the# length is zero, quit the loopimage_len=struct.unpack('<L',connection.read(struct.calcsize('<L')))[0]ifnotimage_len:break# Construct a stream to hold the image data and read the image# data from the connectionimage_stream=io.BytesIO()image_stream.write(connection.read(image_len))# Rewind the stream, open it as an image with PIL and do some# processing on itimage_stream.seek(0)image=Image.open(image_stream)print('Image is %dx%d'%image.size)image.verify()print('Image is verified')finally:connection.close()server_socket.close()

Now for the client side of things, on the Raspberry Pi:

importioimportsocketimportstructimporttimeimportpicamera# Connect a client socket to my_server:8000 (change my_server to the# hostname of your server)client_socket=socket.socket()client_socket.connect(('my_server',8000))# Make a file-like object out of the connectionconnection=client_socket.makefile('wb')try:camera=picamera.PiCamera()camera.resolution=(640,480)# Start a preview and let the camera warm up for 2 secondscamera.start_preview()time.sleep(2)# Note the start time and construct a stream to hold image data# temporarily (we could write it directly to connection but in this# case we want to find out the size of each capture first to keep# our protocol simple)start=time.time()stream=io.BytesIO()forfooincamera.capture_continuous(stream,'jpeg'):# Write the length of the capture to the stream and flush to# ensure it actually gets sentconnection.write(struct.pack('<L',stream.tell()))connection.flush()# Rewind the stream and send the image data over the wirestream.seek(0)connection.write(stream.read())# If we've been capturing for more than 30 seconds, quitiftime.time()-start>30:break# Reset the stream for the next capturestream.seek(0)stream.truncate()# Write a length of zero to the stream to signal we're doneconnection.write(struct.pack('<L',0))finally:connection.close()client_socket.close()

The server script should be run first to ensure there‚Äôs a listening socket
ready to accept a connection from the client script.

Note that we use wait_recording() in the example above instead
of time.sleep() which we‚Äôve been using in the image capture recipes
above. The wait_recording() method is similar in that it will
pause for the number of seconds specified, but unlike time.sleep() it
will continually check for recording errors (e.g. an out of disk space
condition) while it is waiting. If we had used time.sleep() instead, such
errors would only be raised by the stop_recording() call (which
could be long after the error actually occurred).

Here, we‚Äôve set the quality parameter to indicate to the encoder the level
of image quality that we‚Äôd like it to try and maintain. The camera‚Äôs H.264
encoder is primarily constrained by two parameters:

bitrate limits the encoder‚Äôs output to a certain number of bits per second.
The default is 17000000 (17Mbps), and the maximum value is 25000000 (25Mbps).
Higher values give the encoder more ‚Äúfreedom‚ÄĚ to encode at higher qualities.
You will likely find that the default doesn‚Äôt constrain the encoder at all
except at higher recording resolutions.

quality tells the encoder what level of image quality to maintain. Values
can be between 1 (highest quality) and 40 (lowest quality), with typical
values providing a reasonable trade-off between bandwidth and quality being
between 20 and 25.

As well as using stream classes built into Python (like BytesIO)
you can also construct your own custom outputs. This is
particularly useful for video recording, as discussed in the linked recipe.

This is similar to Recording video to a stream but uses a special kind of in-memory
stream provided by the picamera library. The PiCameraCircularIO class
implements a ring buffer based stream, specifically for video recording.
This enables you to keep an in-memory stream containing the last n seconds of
video recorded (where n is determined by the bitrate of the video recording
and the size of the ring buffer underlying the stream).

A typical use-case for this sort of storage is security applications where one
wishes to detect motion and only record to disk the video where motion was
detected. This example keeps 20 seconds of video in memory until the
write_now function returns True (in this implementation this is random
but one could, for example, replace this with some sort of motion detection
algorithm). Once write_now returns True, the script waits 10 more
seconds (so that the buffer contains 10 seconds of video from before the event,
and 10 seconds after) and writes the resulting video to disk before going back
to waiting:

In the above script we use the special copy_to()
method to copy the stream to a disk file. This automatically handles details
like finding the start of the first key-frame in the circular buffer, and
also provides facilities like writing a specific number of bytes or seconds.

Note

Note that at least 20 seconds of video are in the stream. This is an
estimate only; if the H.264 encoder requires less than the specified
bitrate (17Mbps by default) for recording the video, then more than 20
seconds of video will be available in the stream.

This is similar to Recording video to a stream but instead of an in-memory stream like
BytesIO, we will use a file-like object created from a
socket(). Unlike the example in Capturing to a network stream we don‚Äôt
need to complicate our network protocol by writing things like the length of
images. This time we‚Äôre sending a continual stream of video frames (which
necessarily incorporates such information, albeit in a much more efficient
form), so we can simply dump the recording straight to the network socket.

Firstly, the server side script which will simply read the video stream and
pipe it to a media player for display:

importsocketimportsubprocess# Start a socket listening for connections on 0.0.0.0:8000 (0.0.0.0 means# all interfaces)server_socket=socket.socket()server_socket.bind(('0.0.0.0',8000))server_socket.listen(0)# Accept a single connection and make a file-like object out of itconnection=server_socket.accept()[0].makefile('rb')try:# Run a viewer with an appropriate command line. Uncomment the mplayer# version if you would prefer to use mplayer instead of VLCcmdline=['vlc','--demux','h264','-']#cmdline = ['mplayer', '-fps', '25', '-cache', '1024', '-']player=subprocess.Popen(cmdline,stdin=subprocess.PIPE)whileTrue:# Repeatedly read 1k of data from the connection and write it to# the media player's stdindata=connection.read(1024)ifnotdata:breakplayer.stdin.write(data)finally:connection.close()server_socket.close()player.terminate()

Note

If you run this script on Windows you will probably need to provide a
complete path to the VLC or mplayer executable. If you run this script
on Mac OS X, and are using Python installed from MacPorts, please ensure
you have also installed VLC or mplayer from MacPorts.

You will probably notice several seconds of latency with this setup. This is
normal and is because media players buffer several seconds to guard against
unreliable network streams. Some media players (notably mplayer in this case)
permit the user to skip to the end of the buffer (press the right cursor key in
mplayer), reducing the latency by increasing the risk that delayed / dropped
network packets will interrupt the playback.

Now for the client side script which simply starts a recording over a file-like
object created from the network socket:

importsocketimporttimeimportpicamera# Connect a client socket to my_server:8000 (change my_server to the# hostname of your server)client_socket=socket.socket()client_socket.connect(('my_server',8000))# Make a file-like object out of the connectionconnection=client_socket.makefile('wb')try:camera=picamera.PiCamera()camera.resolution=(640,480)camera.framerate=24# Start a preview and let the camera warm up for 2 secondscamera.start_preview()time.sleep(2)# Start recording, sending the output to the connection for 60# seconds, then stopcamera.start_recording(connection,format='h264')camera.wait_recording(60)camera.stop_recording()finally:connection.close()client_socket.close()

It should also be noted that the effect of the above is much more easily
achieved (at least on Linux) with a combination of netcat and the
raspivid executable. For example:

However, this recipe does serve as a starting point for video streaming
applications. It‚Äôs also possible to reverse the direction of this recipe
relatively easily. In this scenario, the Pi acts as the server, waiting for a
connection from the client. When it accepts a connection, it starts streaming
video over it for 60 seconds. Another variation (just for the purposes of
demonstration) is that we initialize the camera straight away instead of
waiting for a connection to allow the streaming to start faster on connection:

importsocketimporttimeimportpicameracamera=picamera.PiCamera()camera.resolution=(640,480)camera.framerate=24server_socket=socket.socket()server_socket.bind(('0.0.0.0',8000))server_socket.listen(0)# Accept a single connection and make a file-like object out of itconnection=server_socket.accept()[0].makefile('wb')try:camera.start_recording(connection,format='h264')camera.wait_recording(60)camera.stop_recording()finally:connection.close()server_socket.close()

One advantage of this setup is that no script is needed on the client side - we
can simply use VLC with a network URL:

vlc tcp/h264://my_pi_address:8000/

Note

VLC (or mplayer) will not work for playback on a Pi. Neither is
(currently) capable of using the GPU for decoding, and thus they attempt to
perform video decoding on the Pi‚Äôs CPU (which is not powerful enough for
the task). You will need to run these applications on a faster machine
(though ‚Äúfaster‚ÄĚ is a relative term here: even an Atom powered netbook
should be quick enough for the task at non-HD resolutions).

The camera preview system can operate multiple layered renderers
simultaneously. While the picamera library only permits a single renderer to
be connected to the camera‚Äôs preview port, it does permit additional renderers
to be created which display a static image. These overlaid renderers can be
used to create simple user interfaces.

Note

Overlay images will not appear in image captures or video recordings. If
you need to embed additional information in the output of the camera,
please refer to Overlaying text on the output.

One difficulty of working with overlay renderers is that they expect unencoded
RGB input which is padded up to the camera‚Äôs block size. The camera‚Äôs block
size is 32x16 so any image data provided to a renderer must have a width which
is a multiple of 32, and a height which is a multiple of 16. The specific RGB
format expected is interleaved unsigned bytes. If all this sounds complicated,
don‚Äôt worry; it‚Äôs quite simple to produce in practice.

The following example demonstrates loading an arbitrary size image with PIL,
padding it to the required size, and producing the unencoded RGB data for the
call to add_overlay():

importpicamerafromPILimportImagefromtimeimportsleepcamera=picamera.PiCamera()camera.resolution=(1280,720)camera.framerate=24camera.start_preview()# Load the arbitrarily sized imageimg=Image.open('overlay.png')# Create an image padded to the required size with# mode 'RGB'pad=Image.new('RGB',(((img.size[0]+31)//32)*32,((img.size[1]+15)//16)*16,))# Paste the original image into the padded onepad.paste(img,(0,0))# Add the overlay with the padded image as the source,# but the original image's dimensionso=camera.add_overlay(pad.tobytes(),size=img.size)# By default, the overlay is in layer 0, beneath the# preview (which defaults to layer 2). Here we make# the new overlay semi-transparent, then move it above# the previewo.alpha=128o.layer=3# Wait indefinitely until the user terminates the scriptwhileTrue:sleep(1)

Alternatively, instead of using an image file as the source, you can produce an
overlay directly from a numpy array. In the following example, we construct
a numpy array with the same resolution as the screen, then draw a white cross
through the center and overlay it on the preview as a simple cross-hair:

importtimeimportpicameraimportnumpyasnp# Create an array representing a 1280x720 image of# a cross through the center of the display. The shape of# the array must be of the form (height, width, color)a=np.zeros((720,1280,3),dtype=np.uint8)a[360,:,:]=0xffa[:,640,:]=0xffcamera=picamera.PiCamera()camera.resolution=(1280,720)camera.framerate=24camera.start_preview()# Add the overlay directly into layer 3 with transparency;# we can omit the size parameter of add_overlay as the# size is the same as the camera's resolutiono=camera.add_overlay(np.getbuffer(a),layer=3,alpha=64)try:# Wait indefinitely until the user terminates the scriptwhileTrue:time.sleep(1)finally:camera.remove_overlay(o)

Given that overlaid renderers can be hidden (by moving them below the preview‚Äôs
layer which defaults to 2), made semi-transparent (with the
alpha property), and resized so that they don‚Äôt fillthescreen, they can be used to construct simple user
interfaces.

The camera includes a rudimentary annotation facility which permits up to 255
characters of ASCII text to be overlaid on all output (including the preview,
image captures and video recordings). To achieve this, simply assign a string
to the annotate_text attribute:

importpicameraimporttimecamera=picamera.PiCamera()camera.resolution=(640,480)camera.framerate=24camera.start_preview()camera.annotate_text='Hello world!'time.sleep(2)# Take a picture including the annotationcamera.capture('foo.jpg')

With a little ingenuity, it‚Äôs possible to display longer strings:

importpicameraimporttimeimportitertoolss="This message would be far too long to display normally..."camera=picamera.PiCamera()camera.resolution=(640,480)camera.framerate=24camera.start_preview()camera.annotate_text=' '*31forcinitertools.cycle(s):camera.annotate_text=camera.annotate_text[1:31]+ctime.sleep(0.1)

And of course, it can be used to display (and embed) a timestamp in recordings
(this recipe also demonstrates drawing a background behind the timestamp for
contrast with the annotate_background attribute):

In certain circumstances, you may find the V1 camera module‚Äôs red LED a
hindrance (the V2 camera module lacks an LED). For example, in the case of
automated close-up wild-life photography, the LED may scare off animals. It can
also cause unwanted reflected red glare with close-up subjects.

One trivial way to deal with this is simply to place some opaque covering on
the LED (e.g. blue-tack or electricians tape). Another method is to use the
disable_camera_led option in the boot configuration.

However, provided you have the RPi.GPIO package installed, and provided your
Python process is running with sufficient privileges (typically this means
running as root with sudopython), you can also control the LED via the
led attribute:

importpicameracamera=picamera.PiCamera()# Turn the camera's LED offcamera.led=False# Take a picture while the LED remains offcamera.capture('foo.jpg')

Note

The camera LED cannot currently be controlled when the module is attached
to a Raspberry Pi 3 Model B as the GPIO that controls the LED has moved to
a GPIO expander not directly accessible to the ARM processor.

Warning

Be aware when you first use the LED property it will set the GPIO library
to Broadcom (BCM) mode with GPIO.setmode(GPIO.BCM) and disable warnings
with GPIO.setwarnings(False). The LED cannot be controlled when the
library is in BOARD mode.

The following recipes involve advanced techniques and may not be ‚Äúbeginner
friendly‚ÄĚ. Please feel free to suggest enhancements or additional recipes.

Warning

When trying out these scripts do not name your file picamera.py.
Naming scripts after existing Python modules will cause errors when you
try and import those modules (because Python checks the current directory
before checking other paths).

Since 1.11, picamera can capture directly to any object which supports Python‚Äôs
buffer protocol (including numpy‚Äôs ndarray). Simply pass the
object as the destination of the capture and the image data will be written
directly to the object. The target object must fulfil various requirements
(some of which are dependent on the version of Python you are using):

The buffer object must be writeable (e.g. you cannot capture to a
bytes object as it is immutable).

The buffer object must be large enough to receive all the image data.

(Python 2.x only) The buffer object must be 1-dimensional.

(Python 2.x only) The buffer object must have byte-sized items.

For example, to capture directly to a three-dimensional numpy
ndarray (Python 3.x only):

It is also important to note that when outputting to unencoded formats, the
camera rounds the requested resolution. The horizontal resolution is rounded up
to the nearest multiple of 32 pixels, while the vertical resolution is rounded
up to the nearest multiple of 16 pixels. For example, if the requested
resolution is 100x100, the capture will actually contain 128x112 pixels worth
of data, but pixels beyond 100x100 will be uninitialized.

So, to capture a 100x100 image we first need to provide a 128x112 array,
then strip off the uninitialized pixels afterward. The following example
demonstrates this along with the re-shaping necessary under Python 2.x:

This is a variation on Capturing to a numpy array. OpenCV uses numpy arrays as
images and defaults to colors in planar BGR. Hence, the following is all that‚Äôs
required to capture an OpenCV compatible image:

If you want images captured without loss of detail (due to JPEG‚Äôs lossy
compression), you are probably better off exploring PNG as an alternate image
format (PNG uses lossless compression). However, some applications
(particularly scientific ones) simply require the image data in numeric form.
For this, the 'yuv' format is provided:

The specific YUV format used is YUV420 (planar). This means that the Y
(luminance) values occur first in the resulting data and have full resolution
(one 1-byte Y value for each pixel in the image). The Y values are followed by
the U (chrominance) values, and finally the V (chrominance) values. The UV
values have one quarter the resolution of the Y components (4 1-byte Y values
in a square for each 1-byte U and 1-byte V value). This is illustrated in the
diagram below:

It is also important to note that when outputting to unencoded formats, the
camera rounds the requested resolution. The horizontal resolution is rounded up
to the nearest multiple of 32 pixels, while the vertical resolution is rounded
up to the nearest multiple of 16 pixels. For example, if the requested
resolution is 100x100, the capture will actually contain 128x112 pixels worth
of data, but pixels beyond 100x100 will be uninitialized.

Given that the YUV420 format contains 1.5 bytes worth of data for each pixel
(a 1-byte Y value for each pixel, and 1-byte U and V values for every 4 pixels),
and taking into account the resolution rounding, the size of a 100x100 YUV
capture will be:

The first 14336 bytes of the data (128*112) will be Y values, the next 3584
bytes () will be U values, and the final 3584
bytes will be the V values.

The following code demonstrates capturing YUV image data, loading the data into
a set of numpy arrays, and converting the data to RGB format in an efficient
manner:

from__future__importdivisionimporttimeimportpicameraimportnumpyasnpwidth=100height=100stream=open('image.data','w+b')# Capture the image in YUV formatwithpicamera.PiCamera()ascamera:camera.resolution=(width,height)camera.start_preview()time.sleep(2)camera.capture(stream,'yuv')# Rewind the stream for readingstream.seek(0)# Calculate the actual image size in the stream (accounting for rounding# of the resolution)fwidth=(width+31)//32*32fheight=(height+15)//16*16# Load the Y (luminance) data from the streamY=np.fromfile(stream,dtype=np.uint8,count=fwidth*fheight).\
reshape((fheight,fwidth))# Load the UV (chrominance) data from the stream, and double its sizeU=np.fromfile(stream,dtype=np.uint8,count=(fwidth//2)*(fheight//2)).\
reshape((fheight//2,fwidth//2)).\
repeat(2,axis=0).repeat(2,axis=1)V=np.fromfile(stream,dtype=np.uint8,count=(fwidth//2)*(fheight//2)).\
reshape((fheight//2,fwidth//2)).\
repeat(2,axis=0).repeat(2,axis=1)# Stack the YUV channels together, crop the actual resolution, convert to# floating point for later calculations, and apply the standard biasesYUV=np.dstack((Y,U,V))[:height,:width,:].astype(np.float)YUV[:,:,0]=YUV[:,:,0]-16# Offset Y by 16YUV[:,:,1:]=YUV[:,:,1:]-128# Offset UV by 128# YUV conversion matrix from ITU-R BT.601 version (SDTV)# Y U VM=np.array([[1.164,0.000,1.596],# R[1.164,-0.392,-0.813],# G[1.164,2.017,0.000]])# B# Take the dot product with the matrix to produce RGB output, clamp the# results to byte range and convert to bytesRGB=YUV.dot(M.T).clip(0,255).astype(np.uint8)

Note

You may note that we are using open() in the code above instead of
io.open() as in the other examples. This is because numpy‚Äôs
numpy.fromfile() method annoyingly only accepts ‚Äúreal‚ÄĚ file objects.

This recipe is now encapsulated in the PiYUVArray class in the
picamera.array module, which means the same can be achieved as follows:

importtimeimportpicameraimportpicamera.arraywithpicamera.PiCamera()ascamera:withpicamera.array.PiYUVArray(camera)asstream:camera.resolution=(100,100)camera.start_preview()time.sleep(2)camera.capture(stream,'yuv')# Show size of YUV dataprint(stream.array.shape)# Show size of RGB converted dataprint(stream.rgb_array.shape)

As of 1.11 you can also capture directly to numpy arrays (see
Capturing to a numpy array). Due to the difference in resolution of the Y and UV
components, this isn‚Äôt directly useful (if you need all three components,
you‚Äôre better off using PiYUVArray as this rescales the UV
components for convenience). However, if you only require the Y plane you can
provide a buffer just large enough for this plane and ignore the error that
occurs when writing to the buffer (picamera will deliberately write as much as
it can to the buffer before raising an exception to support this use-case):

importtimeimportpicameraimportpicamera.arrayimportnumpyasnpwithpicamera.PiCamera()ascamera:camera.resolution=(100,100)time.sleep(2)y_data=np.empty((112,128),dtype=np.uint8)try:camera.capture(y_data,'yuv')exceptIOError:passy_data=y_data[:100,:100]# y_data now contains the Y-plane only

Capturing so-called ‚Äúraw‚ÄĚ formats ('yuv', 'rgb', etc.) does not
provide the raw bayer data from the camera‚Äôs sensor. Rather, it provides
access to the image data after GPU processing, but before format encoding
(JPEG, PNG, etc). Currently, the only method of accessing the raw bayer
data is via the bayer parameter to the capture() method.
See Raw Bayer data captures for more information.

Changed in version 1.0: The raw_format attribute is now deprecated, as is the
'raw' format specification for the capture() method.
Simply use the 'yuv' format instead, as shown in the code above.

The RGB format is rather larger than the YUV format discussed in the section
above, but is more useful for most analyses. To have the camera produce output
in RGB format, you simply need to specify 'rgb' as the format for the
capture() method instead:

The size of RGB data can be calculated similarly to YUV captures.
Firstly round the resolution appropriately (see Unencoded image capture (YUV format) for the
specifics), then multiply the number of pixels by 3 (1 byte of red, 1 byte of
green, and 1 byte of blue intensity). Hence, for a 100x100 capture, the amount
of data produced is:

The resulting RGB data is interleaved. That is to say that the red, green
and blue values for a given pixel are grouped together, in that order. The
first byte of the data is the red value for the pixel at (0, 0), the second
byte is the green value for the same pixel, and the third byte is the blue
value for that pixel. The fourth byte is the red value for the pixel at (1, 0),
and so on.

As the planes in RGB data are all equally sized (in contrast to YUV420)
it is trivial to capture directly into a numpy array (Python 3.x only; see
Capturing to a numpy array for Python 2.x instructions):

RGB captures from the still port do not work at the full resolution of the
camera (they result in an out of memory error). Either use YUV captures, or
capture from the video port if you require full resolution.

Changed in version 1.0: The raw_format attribute is now deprecated, as is the
'raw' format specification for the capture() method.
Simply use the 'rgb' format instead, as shown in the code above.

All methods in the picamera library which accept a filename also accept
file-like objects. Typically, this is only used with actual file objects, or
with memory streams (like io.BytesIO). However, building a custom
output object is extremely easy and in certain cases very useful. A file-like
object (as far as picamera is concerned) is simply an object with a write
method which must accept a single parameter consisting of a byte-string, and
which can optionally return the number of bytes written. The object can
optionally implement a flush method (which has no parameters), which will
be called at the end of output.

Custom outputs are particularly useful with video recording as the custom
output‚Äôs write method will be called (at least) once for every frame that
is output, allowing you to implement code that reacts to each and every frame
without going to the bother of a full custom encoder.
However, one should bear in mind that because the write method is called so
frequently, its implementation must be sufficiently rapid that it doesn‚Äôt stall
the encoder (it must perform its processing and return before the next write is
due to arrive if you wish to avoid dropping frames).

The following trivial example demonstrates an incredibly simple custom output
which simply throws away the output while counting the number of bytes that
would have been written and prints this at the end of the output:

importpicameraclassMyOutput(object):def__init__(self):self.size=0defwrite(self,s):self.size+=len(s)defflush(self):print('%d bytes would have been written'%self.size)withpicamera.PiCamera()ascamera:camera.resolution=(640,480)camera.framerate=60camera.start_recording(MyOutput(),format='h264')camera.wait_recording(10)camera.stop_recording()

The following example shows how to use a custom output to construct a crude
motion detection system. We construct a custom output object which is used as
the destination for motion vector data (this is particularly simple as motion
vector data always arrives as single chunks; frame data by contrast sometimes
arrives in several separate chunks). The output object doesn‚Äôt actually write
the motion data anywhere; instead it loads it into a numpy array and analyses
whether there are any significantly large vectors in the data, printing a
message to the console if there are. As we are not concerned with keeping the
actual video output in this example, we use /dev/null as the
destination for the video data:

from__future__importdivisionimportpicameraimportnumpyasnpmotion_dtype=np.dtype([('x','i1'),('y','i1'),('sad','u2'),])classMyMotionDetector(object):def__init__(self,camera):width,height=camera.resolutionself.cols=(width+15)//16self.cols+=1# there's always an extra columnself.rows=(height+15)//16defwrite(self,s):# Load the motion data from the string to a numpy arraydata=np.fromstring(s,dtype=motion_dtype)# Re-shape it and calculate the magnitude of each vectordata=data.reshape((self.rows,self.cols))data=np.sqrt(np.square(data['x'].astype(np.float))+np.square(data['y'].astype(np.float))).clip(0,255).astype(np.uint8)# If there're more than 10 vectors with a magnitude greater# than 60, then say we've detected motionif(data>60).sum()>10:print('Motion detected!')# Pretend we wrote all the bytes of sreturnlen(s)withpicamera.PiCamera()ascamera:camera.resolution=(640,480)camera.framerate=30camera.start_recording(# Throw away the video data, but make sure we're using H.264'/dev/null',format='h264',# Record motion data to our custom output objectmotion_output=MyMotionDetector(camera))camera.wait_recording(30)camera.stop_recording()

You may wish to investigate the classes in the picamera.array module
which implement several custom outputs for analysis of data with numpy. In
particular, the PiMotionAnalysis class can be used to remove
much of the boiler plate code from the recipe above:

importpicameraimportpicamera.arrayimportnumpyasnpclassMyMotionDetector(picamera.array.PiMotionAnalysis):defanalyse(self,a):a=np.sqrt(np.square(a['x'].astype(np.float))+np.square(a['y'].astype(np.float))).clip(0,255).astype(np.uint8)# If there're more than 10 vectors with a magnitude greater# than 60, then say we've detected motionif(a>60).sum()>10:print('Motion detected!')withpicamera.PiCamera()ascamera:camera.resolution=(640,480)camera.framerate=30camera.start_recording('/dev/null',format='h264',motion_output=MyMotionDetector(camera))camera.wait_recording(30)camera.stop_recording()

The simplest of these, the filename, hides a certain amount of complexity. It
can be important to understand exactly how picamera treats files, especially
when dealing with ‚Äúunconventional‚ÄĚ files (e.g. pipes, FIFOs, etc.)

When given a filename, picamera does the following:

Opens the specified file with the 'wb' mode, i.e. open for writing,
truncating the file first, in binary mode.

The file is opened with a larger-than-normal buffer size, specifically 64Kb.
A large buffer size is utilized because it improves performance and system
load with the majority use-case, i.e. sequentially writing video to the
disk.

The requested data (image captures, video recording, etc.) is written to the
open file.

Finally, the file is flushed and closed. Note that this is the only
circumstance in which picamera will presume to close the output for you,
because picamera opened the output for you.

As noted above, this fits the majority use case (sequentially writing video to
a file) very well. However, if you are piping data to another process via a
FIFO (which picamera will simply treat as any other file), you may wish to
avoid all the buffering. In this case, you can simply open the output yourself
with no buffering. As noted above, you will then be responsible for closing the
output when you are finished with it (you opened it, so the responsibility for
closing it is yours as well).

The camera is capable of capturing a sequence of images extremely rapidly by
utilizing its video-capture capabilities with a JPEG encoder (via the
use_video_port parameter). However, there are several things to note about
using this technique:

When using video-port based capture only the video recording area is
captured; in some cases this may be smaller than the normal image capture
area (see discussion in Sensor Modes).

No Exif information is embedded in JPEG images captured through the
video-port.

Captures typically appear ‚Äúgrainier‚ÄĚ with this technique. Captures from the
still port use a slower, more intensive denoise algorithm.

All capture methods support the use_video_port option, but the methods differ
in their ability to rapidly capture sequential frames. So, whilst
capture() and capture_continuous() both support
use_video_port, capture_sequence() is by far the fastest
method (because it does not re-initialize an encoder prior to each capture).
Using this method, the author has managed 30fps JPEG captures at a resolution
of 1024x768.

By default, capture_sequence() is particularly suited to
capturing a fixed number of frames rapidly, as in the following example which
captures a ‚Äúburst‚ÄĚ of 5 images:

However, this still doesn‚Äôt let us capture an arbitrary number of frames until
some condition is satisfied. To do this we need to use a generator function to
provide the list of filenames (or more usefully, streams) to the
capture_sequence() method:

The major issue with capturing this rapidly is firstly that the Raspberry Pi‚Äôs
IO bandwidth is extremely limited and secondly that, as a format, JPEG is
considerably less efficient than the H.264 video format (which is to say that,
for the same number of bytes, H.264 will provide considerably better quality
over the same number of frames). At higher resolutions (beyond 800x600) you are
likely to find you cannot sustain 30fps captures to the Pi‚Äôs SD card for very
long (before exhausting the disk cache).

If you are intending to perform processing on the frames after capture, you may
be better off just capturing video and decoding frames from the resulting file
rather than dealing with individual JPEG captures. Thankfully this is
relatively easy as the JPEG format has a simple magic number (FFD8).
This means we can use a custom output to separate the
frames out of an MJPEG video recording by inspecting the first two bytes of
each buffer:

importioimporttimeimportpicameraclassSplitFrames(object):def__init__(self):self.frame_num=0self.output=Nonedefwrite(self,buf):ifbuf.startswith(b'\xff\xd8'):# Start of new frame; close the old one (if any) and# open a new outputifself.output:self.output.close()self.frame_num+=1self.output=io.open('image%02d.jpg'%self.frame_num,'wb')self.output.write(buf)withpicamera.PiCamera(resolution='720p',framerate=30)ascamera:camera.start_preview()# Give the camera some warm-up timetime.sleep(2)output=SplitFrames()start=time.time()camera.start_recording(output,format='mjpeg')camera.wait_recording(2)camera.stop_recording()finish=time.time()print('Captured %d frames at %.2ffps'%(output.frame_num,output.frame_num/(finish-start)))

So far, we‚Äôve just saved the captured frames to disk. This is fine if you‚Äôre
intending to process later with another script, but what if we want to perform
all processing within the current script? In this case, we may not need to
involve the disk (or network) at all. We can set up a pool of parallel threads
to accept and process image streams as captures come in:

importioimporttimeimportthreadingimportpicameraclassImageProcessor(threading.Thread):def__init__(self,owner):super(ImageProcessor,self).__init__()self.stream=io.BytesIO()self.event=threading.Event()self.terminated=Falseself.owner=ownerself.start()defrun(self):# This method runs in a separate threadwhilenotself.terminated:# Wait for an image to be written to the streamifself.event.wait(1):try:self.stream.seek(0)# Read the image and do some processing on it#Image.open(self.stream)#...#...# Set done to True if you want the script to terminate# at some point#self.owner.done=Truefinally:# Reset the stream and eventself.stream.seek(0)self.stream.truncate()self.event.clear()# Return ourselves to the available poolwithself.owner.lock:self.owner.pool.append(self)classProcessOutput(object):def__init__(self):self.done=False# Construct a pool of 4 image processors along with a lock# to control access between threadsself.lock=threading.Lock()self.pool=[ImageProcessor(self)foriinrange(4)]self.processor=Nonedefwrite(self,buf):ifbuf.startswith(b'\xff\xd8'):# New frame; set the current processor going and grab# a spare oneifself.processor:self.processor.event.set()withself.lock:ifself.pool:self.processor=self.pool.pop()else:# No processor's available, we'll have to skip# this frame; you may want to print a warning# here to see whether you hit this caseself.processor=Noneifself.processor:self.processor.stream.write(buf)defflush(self):# When told to flush (this indicates end of recording), shut# down in an orderly fashion. First, add the current processor# back to the poolifself.processor:withself.lock:self.pool.append(self.processor)self.processor=None# Now, empty the pool, joining each thread as we gowhileTrue:withself.lock:try:proc=self.pool.pop()exceptIndexError:pass# pool is emptyproc.terminated=Trueproc.join()withpicamera.PiCamera(resolution='VGA')ascamera:camera.start_preview()time.sleep(2)output=ProcessOutput()camera.start_recording(output,format='mjpeg')whilenotoutput.done:camera.wait_recording(1)camera.stop_recording()

Just as unencoded RGB data can be captured as images, the Pi‚Äôs camera module
can also capture an unencoded stream of RGB (or YUV) video data. Combining this with
the methods presented in Custom outputs (via the classes from
picamera.array), we can produce a fairly rapid color detection script:

importpicameraimportnumpyasnpfrompicamera.arrayimportPiRGBAnalysisfrompicamera.colorimportColorclassMyColorAnalyzer(PiRGBAnalysis):def__init__(self,camera):super(MyColorAnalyzer,self).__init__(camera)self.last_color=''defanalyze(self,a):# Convert the average color of the pixels in the middle boxc=Color(r=int(np.mean(a[30:60,60:120,0])),g=int(np.mean(a[30:60,60:120,1])),b=int(np.mean(a[30:60,60:120,2])))# Convert the color to hue, saturation, lightnessh,l,s=c.hlsc='none'ifs>1/3:ifh>8/9orh<1/36:c='red'elif5/9<h<2/3:c='blue'elif5/36<h<4/9:c='green'# If the color has changed, update the displayifc!=self.last_color:self.camera.annotate_text=cself.last_color=cwithpicamera.PiCamera(resolution='160x90',framerate=24)ascamera:# Fix the camera's white-balance gainscamera.awb_mode='off'camera.awb_gains=(1.4,1.5)# Draw a box over the area we're going to watchcamera.start_preview(alpha=128)box=np.zeros((96,160,3),dtype=np.uint8)box[30:60,60:120,:]=0x80camera.add_overlay(memoryview(box),size=(160,90),layer=3,alpha=64)# Construct the analysis output and start recording data to itwithMyColorAnalyzer(camera)asanalyzer:camera.start_recording(analyzer,'rgb')try:whileTrue:camera.wait_recording(1)finally:camera.stop_recording()

Following on from Rapid capture and processing, we can combine the video capture
technique with Capturing to a network stream. The server side script doesn‚Äôt change
(it doesn‚Äôt really care what capture technique is being used - it just reads
JPEGs off the wire). The changes to the client side script can be minimal at
first - just set use_video_port to True in the
capture_continuous() call:

importioimportsocketimportstructimporttimeimportpicameraclient_socket=socket.socket()client_socket.connect(('my_server',8000))connection=client_socket.makefile('wb')try:withpicamera.PiCamera()ascamera:camera.resolution=(640,480)camera.framerate=30time.sleep(2)start=time.time()count=0stream=io.BytesIO()# Use the video-port for captures...forfooincamera.capture_continuous(stream,'jpeg',use_video_port=True):connection.write(struct.pack('<L',stream.tell()))connection.flush()stream.seek(0)connection.write(stream.read())count+=1iftime.time()-start>30:breakstream.seek(0)stream.truncate()connection.write(struct.pack('<L',0))finally:connection.close()client_socket.close()finish=time.time()print('Sent %d images in %d seconds at %.2ffps'%(count,finish-start,count/(finish-start)))

Using this technique, the author can manage about 19fps of streaming at
640x480. However, utilizing the MJPEG splitting demonstrated in
Rapid capture and processing we can manage much faster:

importioimportsocketimportstructimporttimeimportpicameraclassSplitFrames(object):def__init__(self,connection):self.connection=connectionself.stream=io.BytesIO()self.count=0defwrite(self,buf):ifbuf.startswith(b'\xff\xd8'):# Start of new frame; send the old one's length# then the datasize=self.stream.tell()ifsize>0:self.connection.write(struct.pack('<L',size))self.connection.flush()self.stream.seek(0)self.connection.write(self.stream.read(size))self.count+=1self.stream.seek(0)self.stream.write(buf)client_socket=socket.socket()client_socket.connect(('my_server',8000))connection=client_socket.makefile('wb')try:output=SplitFrames(connection)withpicamera.PiCamera(resolution='VGA',framerate=30)ascamera:time.sleep(2)start=time.time()camera.start_recording(output,format='mjpeg')camera.wait_recording(30)camera.stop_recording()# Write the terminating 0-length to the connection to let the# server know we're doneconnection.write(struct.pack('<L',0))finally:connection.close()client_socket.close()finish=time.time()print('Sent %d images in %d seconds at %.2ffps'%(output.count,finish-start,output.count/(finish-start)))

Streaming video over the web is surprisingly complicated. At the time of
writing, there are still no video standards that are universally supported by
all web browsers on all platforms. Furthermore, HTTP was originally designed as
a one-shot protocol for serving web-pages. Since its invention, various
additions have been bolted on to cater for its ever increasing use cases (file
downloads, resumption, streaming, etc.) but the fact remains there‚Äôs no
‚Äúsimple‚ÄĚ solution for video streaming at the moment.

If you want to have a play with streaming a ‚Äúreal‚ÄĚ video format (specifically,
MPEG1) you may want to have a look at the pistreaming demo. However, for the
purposes of this recipe we‚Äôll be using a much simpler format: MJPEG. The
following script uses Python‚Äôs built-in http.server module to make a
simple video streaming server:

The camera is capable of capturing still images while it is recording video.
However, if one attempts this using the stills capture mode, the resulting
video will have dropped frames during the still image capture. This is because
images captured via the still port require a mode change, causing the dropped
frames (this is the flicker to a higher resolution that one sees when capturing
while a preview is running).

However, if the use_video_port parameter is used to force a video-port based
image capture (see Rapid capture and processing) then the mode change does not occur,
and the resulting video should not have dropped frames, assuming the image can
be produced before the next video frame is due:

The above code should produce a 20 second video with no dropped frames, and a
still frame from 10 seconds into the video. Higher resolutions or non-JPEG
image formats may still cause dropped frames (only JPEG encoding is hardware
accelerated).

The camera is capable of recording multiple streams at different resolutions
simultaneously by use of the video splitter. This is probably most useful for
performing analysis on a low-resolution stream, while simultaneously recording
a high resolution stream for storage or viewing.

The following simple recipe demonstrates using the splitter_port parameter of
the start_recording() method to begin two simultaneous
recordings, each with a different resolution:

There are 4 splitter ports in total that can be used (numbered 0, 1, 2, and 3).
The video recording methods default to using splitter port 1, while the image
capture methods default to splitter port 0 (when the use_video_port parameter
is also True). A splitter port cannot be simultaneously used for video
recording and image capture so you are advised to avoid splitter port 0 for
video recordings unless you never intend to capture images whilst recording.

The Pi‚Äôs camera is capable of outputting the motion vector estimates that the
camera‚Äôs H.264 encoder calculates while generating compressed video. These can
be directed to a separate output file (or file-like object) with the
motion_output parameter of the start_recording() method. Like
the normal output parameter this accepts a string representing a filename, or
a file-like object:

Motion data is calculated at the macro-block level (an MPEG macro-block
represents a 16x16 pixel region of the frame), and includes one extra column of
data. Hence, if the camera‚Äôs resolution is 640x480 (as in the example above)
there will be 41 columns of motion data (), in 30 rows
().

Motion data values are 4-bytes long, consisting of a signed 1-byte x vector, a
signed 1-byte y vector, and an unsigned 2-byte SAD (Sum of Absolute
Differences) value for each macro-block. Hence in the example above, each
frame will generate 4920 bytes of motion data ().
Assuming the data contains 300 frames (in practice it may contain a few more)
the motion data should be 1,476,000 bytes in total.

The following code demonstrates loading the motion data into a
three-dimensional numpy array. The first dimension represents the frame, with
the latter two representing rows and finally columns. A structured data-type
is used for the array permitting easy access to x, y, and SAD values:

from__future__importdivisionimportnumpyasnpwidth=640height=480cols=(width+15)//16cols+=1# there's always an extra columnrows=(height+15)//16motion_data=np.fromfile('motion.data',dtype=[('x','i1'),('y','i1'),('sad','u2'),])frames=motion_data.shape[0]//(cols*rows)motion_data=motion_data.reshape((frames,rows,cols))# Access the data for the first framemotion_data[0]# Access just the x-vectors from the fifth framemotion_data[4]['x']# Access SAD values for the tenth framemotion_data[9]['sad']

You can calculate the amount of motion the vector represents simply by
calculating the magnitude of the vector with Pythagoras‚Äô theorem. The SAD
(Sum of Absolute Differences) value can be used to determine how well the
encoder thinks the vector represents the original reference frame.

The following code extends the example above to use PIL to produce a PNG image
from the magnitude of each frame‚Äôs motion vectors:

The following command line can be used to generate an animation from the
generated PNGs with ffmpeg (this will take a very long time on the Pi so you
may wish to transfer the images to a faster machine for this step):

Finally, as a demonstration of what can be accomplished with motion vectors,
here‚Äôs a gesture detection system:

importosimportnumpyasnpimportpicamerafrompicamera.arrayimportPiMotionAnalysisclassGestureDetector(PiMotionAnalysis):QUEUE_SIZE=10# the number of consecutive frames to analyzeTHRESHOLD=4.0# the minimum average motion required in either axisdef__init__(self,camera):super(GestureDetector,self).__init__(camera)self.x_queue=np.zeros(self.QUEUE_SIZE,dtype=np.float)self.y_queue=np.zeros(self.QUEUE_SIZE,dtype=np.float)self.last_move=''defanalyze(self,a):# Roll the queues and overwrite the first element with a new# mean (equivalent to pop and append, but faster)self.x_queue[1:]=self.x_queue[:-1]self.y_queue[1:]=self.y_queue[:-1]self.x_queue[0]=a['x'].mean()self.y_queue[0]=a['y'].mean()# Calculate the mean of both queuesx_mean=self.x_queue.mean()y_mean=self.y_queue.mean()# Convert left/up to -1, right/down to 1, and movement below# the threshold to 0x_move=(''ifabs(x_mean)<self.THRESHOLDelse'left'ifx_mean<0.0else'right')y_move=(''ifabs(y_mean)<self.THRESHOLDelse'down'ify_mean<0.0else'up')# Update the displaymovement=('%s%s'%(x_move,y_move)).strip()ifmovement!=self.last_move:self.last_move=movementifmovement:print(movement)withpicamera.PiCamera(resolution='VGA',framerate=24)ascamera:withGestureDetector(camera)asdetector:camera.start_recording(os.devnull,format='h264',motion_output=detector)try:whileTrue:camera.wait_recording(1)finally:camera.stop_recording()

Within a few inches of the camera, move your hand up, down, left, and right,
parallel to the camera and you should see the direction displayed on the
console.

This example builds on the one in Recording to a circular stream and the one in
Capturing images whilst recording to demonstrate the beginnings of a security
application. As before, a PiCameraCircularIO instance is used to keep
the last few seconds of video recorded in memory. While the video is being
recorded, video-port-based still captures are taken to provide a motion
detection routine with some input (the actual motion detection algorithm is
left as an exercise for the reader).

Once motion is detected, the last 10 seconds of video are written to disk, and
video recording is split to another disk file to proceed until motion is no
longer detected. Once motion is no longer detected, we split the recording back
to the in-memory ring-buffer:

importioimportrandomimportpicamerafromPILimportImageprior_image=Nonedefdetect_motion(camera):globalprior_imagestream=io.BytesIO()camera.capture(stream,format='jpeg',use_video_port=True)stream.seek(0)ifprior_imageisNone:prior_image=Image.open(stream)returnFalseelse:current_image=Image.open(stream)# Compare current_image to prior_image to detect motion. This is# left as an exercise for the reader!result=random.randint(0,10)==0# Once motion detection is done, make the prior image the currentprior_image=current_imagereturnresultwithpicamera.PiCamera()ascamera:camera.resolution=(1280,720)stream=picamera.PiCameraCircularIO(camera,seconds=10)camera.start_recording(stream,format='h264')try:whileTrue:camera.wait_recording(1)ifdetect_motion(camera):print('Motion detected!')# As soon as we detect motion, split the recording to# record the frames "after" motioncamera.split_recording('after.h264')# Write the 10 seconds "before" motion to disk as wellstream.copy_to('before.h264',seconds=10)stream.clear()# Wait until motion is no longer detected, then split# recording back to the in-memory circular bufferwhiledetect_motion(camera):camera.wait_recording(1)print('Motion stopped!')camera.split_recording(stream)finally:camera.stop_recording()

This example also demonstrates using the seconds parameter of the
copy_to() method to limit the before file to 10
seconds of data (given that the circular buffer may contain considerably more
than this).

You can override and/or extend the encoder classes used during image or video
capture. This is particularly useful with video capture as it allows you to run
your own code in response to every frame, although naturally whatever code runs
within the encoder‚Äôs callback has to be reasonably quick to avoid stalling the
encoder pipeline.

Writing a custom encoder is quite a bit harder than writing a custom
output and in most cases there‚Äôs little benefit. The only
thing a custom encoder gives you that a custom output doesn‚Äôt is access to the
buffer header flags. For many output formats (MJPEG and YUV for example), these
won‚Äôt tell you anything interesting (i.e. they‚Äôll simply indicate that the
buffer contains a full frame and nothing else). Currently, the only format
where the buffer header flags contain useful information is H.264. Even then,
most of the information (I-frame, P-frame, motion information, etc.) would be
accessible from the frame attribute which you could access
from your custom output‚Äôs write method.

The encoder classes defined by picamera form the following hierarchy (dark
classes are actually instantiated by the implementation in picamera, light
classes implement base functionality but aren‚Äôt technically ‚Äúabstract‚ÄĚ):

The following table details which PiCamera methods use which encoder
classes, and which method they call to construct these encoders:

It is recommended, particularly in the case of the image encoder classes, that
you familiarize yourself with the specific function of these classes so that
you can determine the best class to extend for your particular needs. You may
find that one of the intermediate classes is a better basis for your own
modifications.

In the following example recipe we will extend the
PiCookedVideoEncoder class to store how many I-frames and P-frames are
captured (the camera‚Äôs encoder doesn‚Äôt use B-frames):

importpicameraimportpicamera.mmalasmmal# Override PiVideoEncoder to keep track of the number of each type of frameclassMyEncoder(picamera.PiCookedVideoEncoder):defstart(self,output,motion_output=None):self.parent.i_frames=0self.parent.p_frames=0super(MyEncoder,self).start(output,motion_output)def_callback_write(self,buf):# Only count when buffer indicates it's the end of a frame, and# it's not an SPS/PPS header (..._CONFIG)if((buf.flags&mmal.MMAL_BUFFER_HEADER_FLAG_FRAME_END)andnot(buf.flags&mmal.MMAL_BUFFER_HEADER_FLAG_CONFIG)):ifbuf.flags&mmal.MMAL_BUFFER_HEADER_FLAG_KEYFRAME:self.parent.i_frames+=1else:self.parent.p_frames+=1# Remember to return the result of the parent method!returnsuper(MyEncoder,self)._callback_write(buf)# Override PiCamera to use our custom encoder for video recordingclassMyCamera(picamera.PiCamera):def__init__(self):super(MyCamera,self).__init__()self.i_frames=0self.p_frames=0def_get_video_encoder(self,camera_port,output_port,format,resize,**options):returnMyEncoder(self,camera_port,output_port,format,resize,**options)withMyCamera()ascamera:camera.start_recording('foo.h264')camera.wait_recording(10)camera.stop_recording()print('Recording contains %d I-frames and %d P-frames'%(camera.i_frames,camera.p_frames))

Please note that the above recipe is flawed: PiCamera is capable of
initiating multiple simultaneous recordings. If this
were used with the above recipe, then each encoder would wind up incrementing
the i_frames and p_frames attributes on the MyCamera instance
leading to incorrect results.

The bayer parameter of the capture() method causes the raw
Bayer data recorded by the camera‚Äôs sensor to be output as part of the image
meta-data.

Note

The bayer parameter only operates with the JPEG format, and only
for captures from the still port (i.e. when use_video_port is False,
as it is by default).

Raw Bayer data differs considerably from simple unencoded captures; it is the
data recorded by the camera‚Äôs sensor prior to any GPU processing including
auto white balance, vignette compensation, smoothing, down-scaling,
etc. This also means:

Bayer data is always full resolution, regardless of the camera‚Äôs output
resolution and any resize parameter.

Bayer data occupies the last 6,404,096 bytes of the output file for the V1
module, or the last 10,270,208 bytes for the V2 module. The first 32,768
bytes of this is header data which starts with the string 'BRCM'.

Bayer data consists of 10-bit values, because this is the sensitivity of the
OV5647 and IMX219 sensors used in the Pi‚Äôs camera modules. The 10-bit
values are organized as 4 8-bit values, followed by the low-order 2-bits of
the 4 values packed into a fifth byte.

Bayer data is organized in a BGGR pattern (a minor variation of the common
Bayer CFA). The raw data therefore has twice as many green pixels as red
or blue and if viewed ‚Äúraw‚ÄĚ will look distinctly strange (too dark, too
green, and with zippering effects along any straight edges).

To make a ‚Äúnormal‚ÄĚ looking image from raw Bayer data you will need to
perform de-mosaicing at the very least, and probably some form of
color balance.

This (heavily commented) example script causes the camera to capture an image
including the raw Bayer data. It then proceeds to unpack the Bayer data into a
3-dimensional numpy array representing the raw RGB data and finally performs
a rudimentary de-mosaic step with weighted averages. A couple of numpy tricks
are used to improve performance but bear in mind that all processing is
happening on the CPU and will be considerably slower than normal image
captures:

from__future__import(unicode_literals,absolute_import,print_function,division,)importioimporttimeimportpicameraimportnumpyasnpfromnumpy.lib.stride_tricksimportas_stridedstream=io.BytesIO()withpicamera.PiCamera()ascamera:# Let the camera warm up for a couple of secondstime.sleep(2)# Capture the image, including the Bayer datacamera.capture(stream,format='jpeg',bayer=True)ver={'RP_ov5647':1,'RP_imx219':2,}[camera.exif_tags['IFD0.Model']]# Extract the raw Bayer data from the end of the stream, check the# header and strip if off before converting the data into a numpy arrayoffset={1:6404096,2:10270208,}[ver]data=stream.getvalue()[-offset:]assertdata[:4]=='BRCM'data=data[32768:]data=np.fromstring(data,dtype=np.uint8)# For the V1 module, the data consists of 1952 rows of 3264 bytes of data.# The last 8 rows of data are unused (they only exist because the maximum# resolution of 1944 rows is rounded up to the nearest 16).## For the V2 module, the data consists of 2480 rows of 4128 bytes of data.# There's actually 2464 rows of data, but the sensor's raw size is 2466# rows, rounded up to the nearest multiple of 16: 2480.## Likewise, the last few bytes of each row are unused (why?). Here we# reshape the data and strip off the unused bytes.reshape,crop={1:((1952,3264),(1944,3240)),2:((2480,4128),(2464,4100)),}[ver]data=data.reshape(reshape)[:crop[0],:crop[1]]# Horizontally, each row consists of 10-bit values. Every four bytes are# the high 8-bits of four values, and the 5th byte contains the packed low# 2-bits of the preceding four values. In other words, the bits of the# values A, B, C, D and arranged like so:## byte 1 byte 2 byte 3 byte 4 byte 5# AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD AABBCCDD## Here, we convert our data into a 16-bit array, shift all values left by# 2-bits and unpack the low-order bits from every 5th byte in each row,# then remove the columns containing the packed bitsdata=data.astype(np.uint16)<<2forbyteinrange(4):data[:,byte::5]|=((data[:,4::5]>>((4-byte)*2))&0b11)data=np.delete(data,np.s_[4::5],1)# Now to split the data up into its red, green, and blue components. The# Bayer pattern of the OV5647 sensor is BGGR. In other words the first# row contains alternating green/blue elements, the second row contains# alternating red/green elements, and so on as illustrated below:## GBGBGBGBGBGBGB# RGRGRGRGRGRGRG# GBGBGBGBGBGBGB# RGRGRGRGRGRGRG## Please note that if you use vflip or hflip to change the orientation# of the capture, you must flip the Bayer pattern accordinglyrgb=np.zeros(data.shape+(3,),dtype=data.dtype)rgb[1::2,0::2,0]=data[1::2,0::2]# Redrgb[0::2,0::2,1]=data[0::2,0::2]# Greenrgb[1::2,1::2,1]=data[1::2,1::2]# Greenrgb[0::2,1::2,2]=data[0::2,1::2]# Blue# At this point we now have the raw Bayer data with the correct values# and colors but the data still requires de-mosaicing and# post-processing. If you wish to do this yourself, end the script here!## Below we present a fairly naive de-mosaic method that simply# calculates the weighted average of a pixel based on the pixels# surrounding it. The weighting is provided by a byte representation of# the Bayer filter which we construct first:bayer=np.zeros(rgb.shape,dtype=np.uint8)bayer[1::2,0::2,0]=1# Redbayer[0::2,0::2,1]=1# Greenbayer[1::2,1::2,1]=1# Greenbayer[0::2,1::2,2]=1# Blue# Allocate an array to hold our output with the same shape as the input# data. After this we define the size of window that will be used to# calculate each weighted average (3x3). Then we pad out the rgb and# bayer arrays, adding blank pixels at their edges to compensate for the# size of the window when calculating averages for edge pixels.output=np.empty(rgb.shape,dtype=rgb.dtype)window=(3,3)borders=(window[0]-1,window[1]-1)border=(borders[0]//2,borders[1]//2)rgb=np.pad(rgb,[(border[0],border[0]),(border[1],border[1]),(0,0),],'constant')bayer=np.pad(bayer,[(border[0],border[0]),(border[1],border[1]),(0,0),],'constant')# For each plane in the RGB data, we use a nifty numpy trick# (as_strided) to construct a view over the plane of 3x3 matrices. We do# the same for the bayer array, then use Einstein summation on each# (np.sum is simpler, but copies the data so it's slower), and divide# the results to get our weighted average:forplaneinrange(3):p=rgb[...,plane]b=bayer[...,plane]pview=as_strided(p,shape=(p.shape[0]-borders[0],p.shape[1]-borders[1])+window,strides=p.strides*2)bview=as_strided(b,shape=(b.shape[0]-borders[0],b.shape[1]-borders[1])+window,strides=b.strides*2)psum=np.einsum('ijkl->ij',pview)bsum=np.einsum('ijkl->ij',bview)output[...,plane]=psum//bsum# At this point output should contain a reasonably "normal" looking# image, although it still won't look as good as the camera's normal# output (as it lacks vignette compensation, AWB, etc).## If you want to view this in most packages (like GIMP) you'll need to# convert it to 8-bit RGB data. The simplest way to do this is by# right-shifting everything by 2-bits (yes, this makes all that# unpacking work at the start rather redundant...)output=(output>>2).astype(np.uint8)withopen('image.data','wb')asf:output.tofile(f)

An enhanced version of this recipe (which also handles different bayer orders
caused by flips and rotations) is also encapsulated in the
PiBayerArray class in the picamera.array
module, which means the same can be achieved as follows:

importtimeimportpicameraimportpicamera.arrayimportnumpyasnpwithpicamera.PiCamera()ascamera:withpicamera.array.PiBayerArray(camera)asstream:camera.capture(stream,'jpeg',bayer=True)# Demosaic data and write to output (just use stream.array if you# want to skip the demosaic step)output=(stream.demosaic()>>2).astype(np.uint8)withopen('image.data','wb')asf:output.tofile(f)

The device tree source contains a number of sections enclosed in curly braces,
which form a hierarchy of definitions. The section to edit will depend on which
revision of Raspberry Pi you have (check the silk-screen writing on the board
for the revision number if you are unsure):

Model

Section

Raspberry Pi Model B rev 1

/videocore/pins_rev1

Raspberry Pi Model A and
Model B rev 2

/videocore/pins_rev2

Raspberry Pi Model A+

/videocore/pins_aplus

Raspberry Pi Model B+ rev 1.1

/videocore/pins_bplus1

Raspberry Pi Model B+ rev 1.2

/videocore/pins_bplus2

Raspberry Pi 2 Model B rev 1.0

/videocore/pins_2b1

Raspberry Pi 2 Model B rev 1.1
and rev 1.2

/videocore/pins_2b2

Raspberry Pi 3 Model B rev 1.0

/videocore/pins_3b1

Raspberry Pi 3 Model B rev 1.2

/videocore/pins_3b2

Raspberry Pi Zero rev 1.2 and
rev 1.3

/videocore/pins_pi0

Under the section for your particular model of Pi you will find pin_config
and pin_defines sections. Under the pin_config section you need to
configure the GPIO pins you want to use for the flash and privacy indicator as
using pull down termination. Then, under the pin_defines section you need
to associate those pins with the FLASH_0_ENABLE and FLASH_0_INDICATOR
pins.

For example, to configure GPIO 17 as the flash pin, leaving the privacy
indicator pin absent, on a Raspberry Pi 2 Model B rev 1.1 you would add the
following line under the /videocore/pins_2b2/pin_config section:

pin@p17 { function = "output"; termination = "pull_down"; };

Please note that GPIO pins will be numbered according to the Broadcom pin
numbers (BCM mode in the RPi.GPIO library, not BOARD mode). Then change the
following section under /videocore/pins_2b2/pin_defines. Specifically,
change the type from ‚Äúabsent‚ÄĚ to ‚Äúinternal‚ÄĚ, and add a number property defining
the flash pin as GPIO 17:

pin_define@FLASH_0_ENABLE {
type = "internal";
number = <17>;
};

With the device tree source updated, you now need to compile it into a binary
blob for the firmware to read. This is done with the following command line:

$ dtc -q -I dts -O dtb dt-blob.dts -o dt-blob.bin

Dissecting this command line, the following components are present:

dtc - Execute the device tree compiler

-Idts - The input file is in device tree source format

-Odtb - The output file should be produced in device tree binary format

dt-blob.dts - The first anonymous parameter is the input filename

-odt-blob.bin - The output filename

This should output nothing. If you get lots of warnings, you‚Äôve forgotten the
-q switch; you can ignore the warnings. If anything else is output, it will
most likely be an error message indicating you have made a mistake in the
device tree source. In this case, review your edits carefully (note that
sections and properties must be semi-colon terminated for example), and try
again.

Now the device tree binary blob has been produced, it needs to be placed on the
first partition of the SD card. In the case of non-NOOBS Raspbian installs,
this is generally the partition mounted as /boot:

$ sudo cp dt-blob.bin /boot/

However, in the case of NOOBS Raspbian installs, this is the recovery
partition, which is not mounted by default:

Please note that the filename and location are important. The binary blob must
be named dt-blob.bin (all lowercase), and it must be placed in the root
directory of the first partition on the SD card. Once you have rebooted the Pi
(to activate the new device tree configuration) you can test the flash with the
following simple script:

You should see your flash LED blink twice during the execution of the script.

Warning

The GPIOs only have a limited current drive which is insufficient for
powering the sort of LEDs typically used as flashes in mobile phones. You
will require a suitable drive circuit to power such devices, or risk
damaging your Pi. One developer on the Pi forums notes:

For reference, the flash driver chips we have used on mobile phones
will often drive up to 500mA into the LED. If you‚Äôre aiming for that,
then please think about your power supply too.

If you wish to experiment with the flash driver without attaching anything to
the GPIO pins, you can also reconfigure the camera‚Äôs own LED to act as the
flash LED. Obviously this is no good for actual flash photography but it can
demonstrate whether your configuration is good. In this case you need not add
anything to the pin_config section (the camera‚Äôs LED pin is already defined
to use pull down termination), but you do need to set CAMERA_0_LED to
absent, and FLASH_0_ENABLE to the old CAMERA_0_LED definition (this
will be pin 5 in the case of pins_rev1 and pins_rev2, and pin 32 in the
case of everything else). For example, change:

You‚Äôve named your script picamera.py (or you‚Äôve named some other script
picamera.py. If you name a script after a system or third-party package you
will break imports for that system or third-party package. Delete or rename
that script (and any associated .pyc files), and try again.

No. The camera module‚Äôs preview system is quite crude: it simply tells the GPU
to overlay the preview on the Pi‚Äôs video output. The preview has no knowledge
(or interaction with) the X-Windows environment (incidentally, this is why the
preview works quite happily from the command line, even without anyone logged
in).

That said, the preview area can be resized and repositioned via the
window attribute of the preview object.
If your program can respond to window repositioning and sizing events you can
‚Äúcheat‚ÄĚ and position the preview within the borders of the target window.
However, there‚Äôs currently no way to allow anything to appear on top of the
preview so this is an imperfect solution at best.

As mentioned above, the preview is simply an overlay over the Pi‚Äôs video
output. If you start a preview you may therefore discover you can‚Äôt see your
console anymore and there‚Äôs no obvious way of getting it back. If you‚Äôre
confident in your typing skills you can try calling
stop_preview() by typing ‚Äúblindly‚ÄĚ into your hidden console.
However, the simplest way of getting your display back is usually to hit
Ctrl+D to terminate the Python process (which should also shut down the
camera).

When starting a preview, you may want to set the alpha parameter of the
start_preview() method to something like 128. This should
ensure that when the preview is displayed, it is partially transparent so you
can still see your console.

The camera‚Äôs preview system directly overlays the Pi‚Äôs output on the HDMI or
composite video ports. At this time, it will not operate with GPIO-driven
displays like the PiTFT. Some projects, like the Adafruit Touchscreen Camera
project, have approximated a preview by rapidly capturing unencoded images
and displaying them on the PiTFT instead.

The camera requires 250mA when running. Note that simply creating a
PiCamera object means the camera is running (due to the hidden preview
that is started to allow the auto-exposure algorithm to run). If you are
running your Pi from batteries, you should close() (or destroy)
the instance when the camera is not required in order to conserve power. For
example, the following code captures 60 images over an hour, but leaves the
camera running all the time:

If you are experiencing lockups or reboots when the camera is active, your
power supply may be insufficient. A practical minimum is 1A for running a Pi
with an active camera module; more may be required if additional peripherals
are attached.

The picamera library relies on the setuptools package for installation
services. You can use the setuptools pkg_resources API to query which
version of picamera is available in your Python environment like so:

If you have multiple versions installed (e.g. from pip and apt-get)
they will not show up in the list returned by the require method. However,
the first entry in the list will be the version that importpicamera will
import.

If you receive the error ‚ÄúNo module named pkg_resources‚ÄĚ, you need to install
the pip utility. This can be done with the following command in Raspbian:

If you are using Raspbian, firstly check that you haven‚Äôt got both a PyPI
(pip) and an apt (apt-get) installation of picamera installed
simultaneously. If you have, one will be taking precedence and it may not be
the most up to date version.

Secondly, please understand that while the PyPI release process is entirely
automated (so as soon as a new picamera release is announced, it will be
available on PyPI), the release process for Raspbian packages is semi-manual.
There is typically a delay of a few days after a release before updated
picamera packages become accessible in the Raspbian repository.

Users desperate to try the latest version may choose to uninstall their apt
based copy (uninstall instructions are provided in the installation
instructions, and install using pip instead. However, be aware that keeping a PyPI based
installation up to date is a more manual process (sticking with apt ensures
everything gets upgraded with a simple sudoapt-getupgrade command).

The first thing to understand is that streaming latency has little to do with
the encoding or sending end of things (i.e. the Pi), and much more to do with
the playing or receiving end. If the Pi weren‚Äôt capable of encoding a frame
before the next frame arrived, it wouldn‚Äôt be capable of recording video at all
(because its internal buffers would rapidly become filled with unencoded
frames).

So, why do players typically introduce several seconds worth of latency? The
primary reason is that most players (e.g. VLC) are optimized for playing
streams over a network. Such players allocate a large (multi-second) buffer and
only start playing once this is filled to guard against possible future packet
loss.

A secondary reason that all such players allocate at least a couple of frames
worth of buffering is that the MPEG standard includes certain frame types that
require it:

I-frames (intra-frames, also known as ‚Äúkey frames‚ÄĚ). These frames contain a
complete picture and thus are the largest sort of frames. They occur at the
start of playback and at periodic points during the stream.

P-frames (predicted frames). These frames describe the changes from the prior
frame to the current frame, therefore one must have successfully decoded the
prior frame in order to decode a P-frame.

B-frames (bi-directional predicted frames). These frames describe the changes
from the next frame to the current frame, therefore one must have
successfully decoded the next frame in order to decode the current B-frame.

B-frames aren‚Äôt produced by the Pi‚Äôs camera (or, as I understand it, by most
real-time recording cameras) as it would require buffering yet-to-be-recorded
frames before encoding the current one. However, most recorded media (DVDs,
Blu-rays, and hence network video streams) do use them, so players must support
them. It is simplest to write such a player by assuming that any source may
contain B-frames, and buffering at least 2 frames worth of data at all times to
make decoding them simpler.

As for the network in between, a slow wifi network may introduce a frame‚Äôs
worth of latency, but not much more than that. Check the ping time across your
network; it‚Äôs likely to be less than 30ms in which case your network cannot
account for more than a frame‚Äôs worth of latency.

TL;DR: the reason you‚Äôve got lots of latency when streaming video is nothing to
do with the Pi. You need to persuade your video player to reduce or forgo its
buffering.

Read the note at the bottom of the Recording to a circular stream recipe. When you set
the number of seconds for the circular stream you are setting a lower bound
for a given bitrate (which defaults to 17Mbps - the same as the video recording
default). If the recorded scene has low motion or complexity the stream can
store considerably more than the number of seconds specified.

If you need to copy a specific number of seconds from the stream, see the
seconds parameter of the copy_to() method (which
was introduced in release 1.11).

Finally, if you specify a different bitrate limit for the stream and the
recording, the seconds limit will be inaccurate.

The camera‚Äôs H264 encoder doesn‚Äôt output a full MP4 file (which would contain
frames-per-second meta-data). Instead it outputs an H264 NAL stream which just
has frame-size and a few other details (but not FPS).

Most players (like VLC) default to 24, 25, or 30 fps. Hence, recordings at
12fps will appear ‚Äúfast‚ÄĚ, while recordings as 60fps will appear ‚Äúslow‚ÄĚ. Your
playback client needs to be told what fps to use when playing back (assuming it
supports such an option).

For those wondering why the camera doesn‚Äôt output a full MP4 file, consider
that the Pi camera‚Äôs heritage is mobile phone cameras. In these devices you
only want the camera to output the H264 stream so you can mux it with, say, an
AAC stream recorded from the microphone input and wrap the result into a full
MP4 file.

To convert the H264 NAL stream to a full MP4 file, there are a couple of
options. The simplest is to use the MP4Box utility from the gpac
package on Raspbian. Unfortunately this only works with files; it cannot accept
redirected streams:

$ sudo apt-get install gpac
...$ MP4Box -add input.h264 output.mp4

Alternatively you can use the console version of VLC to handle the conversion.
This is a more complex command line, but a lot more powerful (it‚Äôll handle
redirected streams and can be used with a vast array of outputs including
HTTP, RTP, etc.):

The camera firmware is designed to be used by a single process at a time.
Attempting to use the camera from multiple processes simultaneously will fail
in a variety of ways (from simple errors to the process locking up).

Python‚Äôs multiprocessing module creates multiple copies of a Python
process (usually via os.fork()) for the purpose of parallel processing.
Whilst you can use multiprocessing with picamera, you must ensure that
only a single process creates a PiCamera instance at any given time.

The following script demonstrates an approach with one process that owns the
camera, which handles disseminating captured frames to other processes via a
Queue:

importosimportioimporttimeimportmultiprocessingasmpfromqueueimportEmptyimportpicamerafromPILimportImageclassQueueOutput(object):def__init__(self,queue,finished):self.queue=queueself.finished=finishedself.stream=io.BytesIO()defwrite(self,buf):ifbuf.startswith(b'\xff\xd8'):# New frame, put the last frame's data in the queuesize=self.stream.tell()ifsize:self.stream.seek(0)self.queue.put(self.stream.read(size))self.stream.seek(0)self.stream.write(buf)defflush(self):self.queue.close()self.queue.join_thread()self.finished.set()defdo_capture(queue,finished):withpicamera.PiCamera(resolution='VGA',framerate=30)ascamera:output=QueueOutput(queue,finished)camera.start_recording(output,format='mjpeg')camera.wait_recording(10)camera.stop_recording()defdo_processing(queue,finished):whilenotfinished.wait(0.1):try:stream=io.BytesIO(queue.get(False))exceptEmpty:passelse:stream.seek(0)image=Image.open(stream)# Pretend it takes 0.1 seconds to process the frame; on a quad-core# Pi this gives a maximum processing throughput of 40fpstime.sleep(0.1)print('%d: Processing image with size %dx%d'%(os.getpid(),image.size[0],image.size[1]))if__name__=='__main__':queue=mp.Queue()finished=mp.Event()capture_proc=mp.Process(target=do_capture,args=(queue,finished))processing_procs=[mp.Process(target=do_processing,args=(queue,finished))foriinrange(4)]forprocinprocessing_procs:proc.start()capture_proc.start()forprocinprocessing_procs:proc.join()capture_proc.join()

MJPEG is a particularly ill-defined format (see ‚ÄúDisadvantages‚ÄĚ) which
results in compatibility issues between software that purports to produce MJPEG
files, and software that purports to play MJPEG files. This is one such case:
the Pi‚Äôs camera firmware produces an MJPEG file which simply consists of
concatenated JPEGs; this is reasonably common on other devices and webcams, and
is a nice simple format which makes parsing particularly easy (see
Web streaming for an example).

Unfortunately, VLC doesn‚Äôt recognize this as a valid MJPEG file: it thinks it‚Äôs
a single JPEG image and doesn‚Äôt bother reading the rest of the file (which is
also a reasonable interpretation in the absence of any other information).
Thankfully, extra command line switches can be provided to give it a hint that
there‚Äôs more to read in the file:

Many questions I receive regarding picamera are based on misunderstandings of
how the camera works. This chapter attempts to correct those misunderstandings
and gives the reader a basic description of the operation of the camera. The
chapter deliberately follows a lie-to-children model, presenting first a
technically inaccurate but useful model of the camera‚Äôs operation, then
refining it closer to the truth later on.

The Pi‚Äôs camera module is basically a mobile phone camera module. Mobile phone
digital cameras differ from larger, more expensive, cameras (DSLRs) in a
few respects. The most important of these, for understanding the Pi‚Äôs camera,
is that many mobile cameras (including the Pi‚Äôs camera module) use a rolling
shutter to capture images. When the camera needs to capture an image, it
reads out pixels from the sensor a row at a time rather than capturing all
pixel values at once.

In fact, the ‚Äúglobal shutter‚ÄĚ on DSLRs typically also reads out pixels a row at
a time. The major difference is that a DSLR will have a physical shutter that
covers the sensor. Hence in a DSLR the procedure for capturing an image is to
open the shutter, letting the sensor ‚Äúview‚ÄĚ the scene, close the shutter, then
read out each line from the sensor.

The notion of ‚Äúcapturing an image‚ÄĚ is thus a bit misleading as what we actually
mean is ‚Äúreading each row from the sensor in turn and assembling them back into
an image‚ÄĚ.

The notion that the camera is effectively idle until we tell it to capture a
frame is also misleading. Don‚Äôt think of the camera as a still image camera.
Think of it as a video camera. Specifically one that, as soon as it is
initialized, is constantly streaming frames (or rather rows of frames) down the
ribbon cable to the Pi for processing.

The camera may seem idle, and your script may be doing nothing with the camera,
but still numerous tasks are going on in the background (automatic gain
control, exposure time, white balance, and several other tasks which we‚Äôll
cover later on).

This background processing is why most of the picamera example scripts seen in
prior chapters include a sleep(2) line after initializing the camera. The
sleep(2) statement pauses your script for a couple of seconds. During this
pause, the camera‚Äôs firmware continually receives rows of frames from the
camera and adjusts the sensor‚Äôs gain and exposure times to make the frame look
‚Äúnormal‚ÄĚ (not over- or under-exposed, etc).

So when we request the camera to ‚Äúcapture a frame‚ÄĚ what we‚Äôre really requesting
is that the camera give us the next complete frame it assembles, rather than
using it for gain and exposure then discarding it (as happens constantly in the
background otherwise).

What does the camera sensor actually detect? It detects photon counts; the
more photons that hit the sensor elements, the more those elements increment
their counters. As our camera has no physical shutter (unlike a DSLR) we can‚Äôt
prevent light falling on the elements and incrementing the counts. In fact we
can only perform two operations on the sensor: reset a row of elements, or read
a row of elements.

To understand a typical frame capture, let‚Äôs walk through the capture of a
couple of frames of data with a hypothetical camera sensor, with only 8x8
pixels and no Bayer filter. The sensor is sat in bright light, but as it‚Äôs
just been initialized, all the elements start off with a count of 0. The
sensor‚Äôs elements are shown on the left, and the frame buffer, that we‚Äôll read
values into, is on the right:

Sensor elements

‚Äď>

Frame 1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

The first line of data is reset (in this case that doesn‚Äôt change the state of
any of the sensor elements). Whilst resetting that line, light is still
falling on all the other elements so they increment by 1:

Sensor elements

‚Äď>

Frame 1

0

0

0

0

0

0

0

0

Rst

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

The second line of data is reset (this time some sensor element states change).
All other elements increment by 1. We‚Äôve not read anything yet, because we want
to leave a delay for the first row to ‚Äúsee‚ÄĚ enough light before we read it:

Sensor elements

‚Äď>

Frame 1

1

1

1

1

1

1

1

1

0

0

0

0

0

0

0

0

Rst

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

2

The third line of data is reset. Again, all other elements increment by 1:

Sensor elements

‚Äď>

Frame 1

2

2

2

2

2

2

2

2

1

1

1

1

1

1

1

1

0

0

0

0

0

0

0

0

Rst

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

Now the camera starts reading and resetting. The first line is read and the
fourth line is reset:

Sensor elements

‚Äď>

Frame 1

3

3

3

3

3

3

3

3

‚Äď>

3

3

3

3

3

3

3

3

2

2

2

2

2

2

2

2

1

1

1

1

1

1

1

1

0

0

0

0

0

0

0

0

Rst

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

The second line is read whilst the fifth line is reset:

Sensor elements

‚Äď>

Frame 1

4

4

4

4

4

4

4

4

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

‚Äď>

3

3

3

3

3

3

3

3

2

2

2

2

2

2

2

2

1

1

1

1

1

1

1

1

0

0

0

0

0

0

0

0

Rst

5

5

5

5

5

5

5

5

5

5

5

5

5

5

5

5

5

5

5

5

5

5

5

5

At this point it should be fairly clear what‚Äôs going on, so let‚Äôs fast-forward
to the point where the final line is reset:

Sensor elements

‚Äď>

Frame 1

7

7

7

7

7

7

7

7

3

3

3

3

3

3

3

3

6

6

6

6

6

6

6

6

3

3

3

3

3

3

3

3

5

5

5

5

5

5

5

5

3

3

3

3

3

3

3

3

4

4

4

4

4

4

4

4

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

‚Äď>

3

3

3

3

3

3

3

3

2

2

2

2

2

2

2

2

1

1

1

1

1

1

1

1

0

0

0

0

0

0

0

0

Rst

At this point, the camera can start resetting the first line again while
continuing to read the remaining lines from the sensor:

Sensor elements

‚Äď>

Frame 1

0

0

0

0

0

0

0

0

Rst

3

3

3

3

3

3

3

3

7

7

7

7

7

7

7

7

3

3

3

3

3

3

3

3

6

6

6

6

6

6

6

6

3

3

3

3

3

3

3

3

5

5

5

5

5

5

5

5

3

3

3

3

3

3

3

3

4

4

4

4

4

4

4

4

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

‚Äď>

3

3

3

3

3

3

3

3

2

2

2

2

2

2

2

2

1

1

1

1

1

1

1

1

Let‚Äôs fast-forward to the state where the last row has been read. Our first
frame is now complete:

Sensor elements

‚Äď>

Frame 1

2

2

2

2

2

2

2

2

3

3

3

3

3

3

3

3

1

1

1

1

1

1

1

1

3

3

3

3

3

3

3

3

0

0

0

0

0

0

0

0

Rst

3

3

3

3

3

3

3

3

7

7

7

7

7

7

7

7

3

3

3

3

3

3

3

3

6

6

6

6

6

6

6

6

3

3

3

3

3

3

3

3

5

5

5

5

5

5

5

5

3

3

3

3

3

3

3

3

4

4

4

4

4

4

4

4

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

3

‚Äď>

3

3

3

3

3

3

3

3

At this stage, Frame 1 would be sent off for post-processing and Frame 2 would
be read into a new buffer:

Sensor elements

‚Äď>

Frame 2

3

3

3

3

3

3

3

3

‚Äď>

3

3

3

3

3

3

3

3

2

2

2

2

2

2

2

2

1

1

1

1

1

1

1

1

0

0

0

0

0

0

0

0

Rst

7

7

7

7

7

7

7

7

6

6

6

6

6

6

6

6

5

5

5

5

5

5

5

5

4

4

4

4

4

4

4

4

From the example above it should be clear that we can control the exposure time
of a frame by varying the delay between resetting a line and reading it (reset
and read don‚Äôt really happen simultaneously, but they are synchronized which is
all that matters for this process).

There are naturally limits to the minimum exposure time: reading out a line of
elements must take a certain minimum time. For example, if there are 500 rows
on our hypothetical sensor, and reading each row takes a minimum of 20ns then
it will take a minimum of to read
a full frame. This is the minimum exposure time of our hypothetical sensor.

The framerate is the number of frames the camera can capture per second.
Depending on the time it takes to capture one frame, the exposure time, we can
only capture so many frames in a specific amount of time. For example, if it
takes 10ms to read a full frame, then we cannot capture more
than frames in a second. Hence the maximum framerate of our hypothetical 500
row sensor is 100fps.

This can be expressed in the word equation:
from which we can see the inverse relationship. The lower the minimum
exposure time, the larger the maximum framerate and vice versa.

To maximise the exposure time we need to capture as few frames as possible per
second, i.e. we need a very low framerate. Therefore the maximum exposure
time is determined by the camera‚Äôs minimum framerate. The minimum framerate
is largely determined by how slow the sensor can be made to read lines (at the
hardware level this is down to the size of registers for holding things like
line read-out times).

This can be expressed in the word equation:

If we imagine that the minimum framerate of our hypothetical sensor is ¬Ĺfps
then the maximum exposure time will be .

More generally, the framerate setting of the camera limits
the maximum exposure time of a given frame. For example, if we set the
framerate to 30fps, then we cannot spend more than capturing any given frame.

Therefore, the exposure_speed attribute, which reports the
exposure time of the last processed frame (which is really a multiple of
the sensor‚Äôs line read-out time) is limited by the camera‚Äôs
framerate.

Note

Tiny framerate adjustments, done with framerate_delta,
are achieved by reading extra ‚Äúdummy‚ÄĚ lines at the end of a frame. I.e
reading a line but then discarding it.

The other important factor influencing sensor element counts, aside from line
read-out time, is the sensor‚Äôs gain. Specifically, the gain given by the
analog_gain attribute (the corresponding
digital_gain is simply post-processing which we‚Äôll cover
later). However, there‚Äôs an obvious issue: how is this gain ‚Äúanalog‚ÄĚ if we‚Äôre
dealing with digital photon counts?

Time to reveal the first lie: the sensor elements are not simple digital
counters but are in fact analog components that build up charge as more photons
hit them. The analog gain influences how this charge is built-up. An
analog-to-digital converter (ADC) is used to convert the analog charge to a
digital value during line read-out (in fact the ADC‚Äôs speed is a large portion
of the minimum line read-out time).

Note

Camera sensors also tend to have a border of non-sensing pixels (elements
that are covered from light). These are used to determine what level of
charge represents ‚Äúoptically black‚ÄĚ.

The camera‚Äôs elements are affected by heat (thermal radiation, after all,
is just part of the electromagnetic spectrum close to the visible
portion). Without the non-sensing pixels you would get different black
levels at different ambient temperatures.

The analog gain cannot be directly controlled in picamera, but various
attributes can be used to ‚Äúinfluence‚ÄĚ it.

Setting exposure_mode to 'off' locks the analog (and
digital) gains at their current values and doesn‚Äôt allow them to adjust at
all, no matter what happens to the scene, and no matter what other camera
attributes may be adjusted.

Setting exposure_mode to values other than 'off'
permits the gains to ‚Äúfloat‚ÄĚ (change) according to the auto-exposure mode
selected. Where possible, the camera firmware prefers to adjust the analog
gain rather than the digital gain, because increasing the digital gain
produces more noise. Some examples of the adjustments made for different
auto-exposure modes include:

'sports' reduces motion blur by preferentially increasing gain rather
than exposure time (i.e. line read-out time).

'night' is intended as a stills mode, so it permits very long exposure
times while attempting to keep gains low.

The iso attribute effectively represents another set of
auto-exposure modes with specific gains:

With the V1 camera module, ISO 100 attempts to use an overall gain of 1.0.
ISO 200 attempts to use an overall gain of 2.0, and so on.

With the V2 camera module, ISO 100 produces an overall gain of ~1.84. ISO
60 produces overall gain of 1.0, and ISO 800 of 14.72 (the V2 camera module
was calibrated against the ISO film speed standard).

Hence, one might be tempted to think that iso provides a
means of fixing the gains, but this isn‚Äôt entirely true: the
exposure_mode setting takes precedence (setting the
exposure mode to 'off' will fix the gains no matter what ISO is later
set, and some exposure modes like 'spotlight' also override ISO-adjusted
gains).

At this point, a reader familiar with operating system theory may be
questioning how a non real-time operating system (non-RTOS) like Linux could
possibly be reading lines from the sensor? After all, to ensure each line is
read in exactly the same amount of time (to ensure a constant exposure over the
whole frame) would require extremely precise timing, which cannot be achieved
in a non-RTOS.

Time to reveal the second lie: lines are not actively ‚Äúread‚ÄĚ from the sensor.
Rather, the sensor is configured (via its registers) with a time per line and
number of lines to read. Once started, the sensor simply reads lines, pushing
the data out to the Pi at the configured speed.

That takes care of how each line‚Äôs read-out time is kept constant, but it still
doesn‚Äôt answer the question of how we can guarantee that Linux is actually
listening and ready to accept each line of data? The answer is quite simply
that Linux doesn‚Äôt. The CPU doesn‚Äôt talk to the camera directly. In fact,
none of the camera processing occurs on the CPU (running Linux) at all.
Instead, it is done on the Pi‚Äôs GPU (VideoCore IV) which is running its own
real-time OS (VCOS).

Note

This is another lie: VCOS is actually an abstraction layer on top of an
RTOS running on the GPU (ThreadX at the time of writing). However, given
that RTOS has changed in the past (hence the abstraction layer), and that
the user doesn‚Äôt directly interact with it anyway, it is perhaps simpler to
think of the GPU as running something called VCOS (without thinking too
much about what that actually is).

The following diagram illustrates that the BCM2835 system on a chip (SoC) is
comprised of an ARM Cortex CPU running Linux (under which is running
myscript.py which is using picamera), and a VideoCore IV GPU running VCOS.
The VideoCore Host Interface (VCHI) is a message passing system provided to
permit communication between these two components. The available RAM is split
between the two components (128Mb is a typical GPU memory split when using the
camera). Finally, the camera module is shown above the SoC. It is connected to
the SoC via a CSI-2 interface (providing 2Gbps of bandwidth).

The scenario depicted is as follows:

The camera‚Äôs sensor has been configured and is continually streaming frame
lines over the CSI-2 interface to the GPU.

The GPU is assembling complete frame buffers from these lines and performing
post-processing on these buffers (we‚Äôll go into further detail about this
part in the next section).

Meanwhile, over on the CPU, myscript.py makes a capture call using
picamera.

The picamera library in turn uses the MMAL API to enact this request
(actually there‚Äôs quite a lot of MMAL calls that go on here but for the sake
of simplicity we represent all this with a single arrow).

The MMAL API sends a message over VCHI requesting a frame capture (again,
in reality there‚Äôs a lot more activity than a single message).

In response, the GPU initiates a DMA transfer of the next complete frame
from its portion of RAM to the CPU‚Äôs portion.

Finally, the GPU sends a message back over VCHI that the capture is
complete.

This causes an MMAL thread to fire a callback in the picamera library, which
in turn retrieves the frame (in reality, this requires more MMAL and VCHI
activity).

We‚Äôve alluded briefly to some of the GPU processing going on in the sections
above (gain control, exposure time, white balance, frame encoding, etc). Time
to reveal the final lie: the GPU is not, as depicted in the prior section, one
discrete component. Rather it is composed of numerous components each of which
play a role in the camera‚Äôs operation.

The diagram below depicts a more accurate representation of the GPU side of the
BCM2835 SoC. From this we get our first glimpse of the frame processing
‚Äúpipeline‚ÄĚ and why it is called such. In the diagram, an H264 video is being
recorded. The components that data passes through are as follows:

Starting at the camera module, some minor processing happens. Specifically,
flips (horizontal and vertical), line skipping, and pixel binning are
configured on the sensor‚Äôs registers. Pixel binning actually happens on the
sensor itself, prior to the ADC to improve signal-to-noise ratios. See
hflip, vflip, and
sensor_mode.

As described previously, frame lines are streamed over the CSI-2 interface
to the GPU. There, it is received by the Unicam component which writes the
line data into RAM.

Transposition: If any rotation has been requested, the input is
transposed to rotate the image (rotation is always implemented by some
combination of transposition and flips).

Black level compensation: Use the non-light sensing elements
(typically in a covered border) to determine what level of charge
represents ‚Äúoptically black‚ÄĚ.

Lens shading: The camera firmware includes a table that corrects for
chromatic distortion from the standard module‚Äôs lens. This is one reason
why third party modules incorporating different lenses may show
non-uniform color across a frame.

Distortion: The distortion introduced by the camera‚Äôs lens is
corrected. At present this stage does nothing as the stock lens isn‚Äôt a
fish-eye lens; it exists as an option should a future sensor require
it.

Resizing: At this point, the frame is resized to the requested output
resolution (all prior stages have been performed on ‚Äúfull‚ÄĚ frame data
at whatever resolution the sensor is configured to produce). See
resolution.

Some of these steps can be controlled directly (e.g. brightness, noise
reduction), others can only be influenced (e.g. analog and digital gain),
and the remainder are not user-configurable at all (e.g. demosaic and lens
shading).

At this point the frame is effectively ‚Äúcomplete‚ÄĚ.

If you are producing ‚Äúunencoded‚ÄĚ output (YUV, RGB, etc.) the pipeline ends
at this point, with the frame data getting copied over to the CPU via
DMA. The ISP might be used to convert to RGB, but that‚Äôs all.

If you are producing encoded output (H264, MJPEG, MPEG2, etc.)
the next step is one of the encoding blocks, the H264 block in this case.
The encoding blocks are specialized hardware designed specifically to
produce particular encodings. For example, the JPEG block will include
hardware for performing lots of parallel discrete cosine transforms
(DCTs), while the H264 block will include hardware for performing motion
estimation.

Coordinating these components is the VPU, the general purpose component in
the GPU running VCOS (ThreadX). The VPU configures and controls the other
components in response to messages from VCHI. Currently the most complete
documentation of the VPU is available from the videocoreiv repository.

There are a couple of feedback loops running within the pipeline described
above. When exposure_mode is not 'off', automatic gain
control (AGC) gathers statistics from each frame (prior to the de-mosaic phase
in the ISP). It tweaks the analog and digital gains, and the exposure time
(line read-out time) attempting to nudge subsequent frames towards a target Y
(luminance) value.

Likewise, when awb_mode is not 'off', automatic white
balance (AWB) gathers statistics from frames (again, prior to de-mosaic).
Typically AWB analysis only occurs on 1 out of every 3 streamed frames as it is
computationally expensive. It adjusts the red and blue gains
(awb_gains) attempting to nudge subsequent frames towards the
expected color balance.

You can observe the effect of the AGC loop quite easily during daylight.
Ensure the camera module is pointed at something bright like the sky or the
view through a window, and query the camera‚Äôs analog gain and exposure time:

Force the camera to use a higher gain by setting iso to 800.
If you have the preview running, you‚Äôll see very little difference in the
scene. However, if you subsequently query the exposure time you‚Äôll find the
firmware has drastically reduced it to compensate for the higher sensor gain:

>>> camera.iso=800>>> camera.exposure_speed198

You can force a longer exposure time with the shutter_speed
attribute at which point the scene will become quite washed out (because both
the gain and exposure time are now fixed). If you let the gain float again by
setting iso back to automatic (0) you should find the gain
reduces accordingly and the scene returns more or less to normal:

The camera‚Äôs AGC loop attempts to produce a scene with a target Y
(luminance) value (or values) within the constraints set by things like ISO,
shutter speed, and so forth. The target Y‚Äô value can be adjusted with the
exposure_compensation attribute which is measured in
increments of 1/6th of an f-stop. So if, whilst the exposure time is fixed,
you increase the luminance that the camera is aiming for by a couple of stops,
then wait a few seconds you should find that the gain has increased
accordingly:

If you allow the exposure time to float once more (by setting
shutter_speed back to 0), then wait a few seconds, you should
find the analog gain decreases back to 1.0, but the exposure time increases to
maintain the deliberately over-exposed appearance of the scene:

The Pi‚Äôs camera modules have a discrete set of modes that they can use to
output data to the GPU. On the V1 module these are as follows:

#

Resolution

Aspect Ratio

Framerates

Video

Image

FoV

Binning

1

1920x1080

16:9

1 < fps <= 30

x

Partial

None

2

2592x1944

4:3

1 < fps <= 15

x

x

Full

None

3

2592x1944

4:3

1/6 <= fps <= 1

x

x

Full

None

4

1296x972

4:3

1 < fps <= 42

x

Full

2x2

5

1296x730

16:9

1 < fps <= 49

x

Full

2x2

6

640x480

4:3

42 < fps <= 60

x

Full

4x4

7

640x480

4:3

60 < fps <= 90

x

Full

4x4

On the V2 module, these are:

#

Resolution

Aspect Ratio

Framerates

Video

Image

FoV

Binning

1

1920x1080

16:9

1/10 <= fps <= 30

x

Partial

None

2

3280x2464

4:3

1/10 <= fps <= 15

x

x

Full

None

3

3280x2464

4:3

1/10 <= fps <= 15

x

x

Full

None

4

1640x1232

4:3

1/10 <= fps <= 40

x

Full

2x2

5

1640x922

16:9

1/10 <= fps <= 40

x

Full

2x2

6

1280x720

16:9

40 < fps <= 90

x

Partial

2x2

7

640x480

4:3

40 < fps <= 90

x

Partial

2x2

Note

These are not the set of possible output resolutions or framerates. These
are merely the set of resolutions and framerates that the sensor can
output directly to the GPU. The GPU‚Äôs ISP block will resize to any
requested resolution (within reason). Read on for details of mode
selection.

Note

Sensor mode 3 on the V2 module appears to be a duplicate, but this is
deliberate. The sensor modes of the V2 module were designed to mimic the
closest equivalent sensor modes of the V1 module. Long exposures on the
V1 module required a separate sensor mode; this wasn‚Äôt required on the V2
module leading to the duplication of mode 2.

Modes with full field of view (FoV) capture from the whole area of the
camera‚Äôs sensor (2592x1944 pixels for the V1 camera, 3280x2464 for the V2
camera). Modes with partial FoV capture from the center of the sensor. The
combination of FoV limiting, and binning is used to achieve the requested
resolution.

The image below illustrates the difference between full and partial field of
view for the V1 camera:

While the various fields of view for the V2 camera are illustrated in the
following image:

The sensor‚Äôs mode can be forced with the sensor_mode parameter in the
PiCamera constructor (using one of the values from the # column in the
tables above). This parameter defaults to 0 indicating that the mode should be
selected automatically based on the requested resolution and
framerate. The rules governing which sensor mode is selected
are as follows:

The capture mode must be acceptable. All modes can be used for video
recording, or for image captures from the video port (i.e. when
use_video_port is True in calls to the various capture methods). Image
captures when use_video_port is False must use an image mode (of which
only two exist, both with the maximum resolution).

The closer the requested resolution is to the mode‚Äôs
resolution the better, but downscaling from a higher sensor resolution to a
lower output resolution is preferable to upscaling from a lower sensor
resolution.

The requested framerate should be within the range of the
sensor mode.

The closer the aspect ratio of the requested resolution to
the mode‚Äôs resolution, the better. Attempts to set resolutions with aspect
ratios other than 4:3 or 16:9 (which are the only ratios directly supported
by the modes in the tables above) will choose the mode which maximizes the
resulting field of view (FoV).

A few examples are given below to clarify the operation of this heuristic (note
these examples assume the V1 camera module):

If you set the resolution to 1024x768 (a 4:3 aspect ratio),
and framerate to anything less than 42fps, the 1296x972
mode (4) will be selected, and the GPU will downscale the result to
1024x768.

If you set the resolution to 1280x720 (a 16:9 wide-screen
aspect ratio), and framerate to anything less than 49fps,
the 1296x730 mode (5) will be selected and downscaled appropriately.

Setting resolution to 1920x1080 and
framerate to 30fps exceeds the resolution of both the
1296x730 and 1296x972 modes (i.e. they would require upscaling), so the
1920x1080 mode (1) is selected instead, despite it having a reduced FoV.

A resolution of 800x600 and a framerate
of 60fps will select the 640x480 60fps mode, even though it requires
upscaling because the algorithm considers the framerate to take precedence in
this case.

Any attempt to capture an image without using the video port will
(temporarily) select the 2592x1944 mode while the capture is performed (this
is what causes the flicker you sometimes see when a preview is running while
a still image is captured).

The are additional limits imposed by the GPU hardware that performs all
image and video processing:

The maximum resolution for MJPEG recording depends partially on GPU
memory. If you get ‚ÄúOut of resource‚ÄĚ errors with MJPEG recording at high
resolutions, try increasing gpu_mem in /boot/config.txt.

The maximum horizontal resolution for default H264 recording is 1920 (this is
a limit of the H264 block in the GPU). Any attempt to record H264 video at
higher horizontal resolutions will fail.

The maximum resolution of the V2 camera may require additional GPU memory
when operating at low framerates (<1fps). Increase gpu_mem in
/boot/config.txt if you encounter ‚Äúout of resources‚ÄĚ errors when
attempting long-exposure captures with a V2 module.

The maximum resolution of the V2 camera can also cause issues with previews.
Currently, picamera runs previews at the same resolution as captures
(equivalent to -fp in raspistill). You may need to increase
gpu_mem in /boot/config.txt to achieve full resolution operation with
the V2 camera module, or configure the preview to use a lower
resolution than the camera itself.

The maximum framerate of the camera depends on several factors. With
overclocking, 120fps has been achieved on a V2 module but 90fps is the
maximum supported framerate.

The maximum exposure time is currently 6 seconds on the V1 camera
module, and 10 seconds on the V2 camera module. Remember that exposure
time is limited by framerate, so you need to set an extremely slow
framerate before setting
shutter_speed.

The MMAL layer below picamera provides a greatly simplified interface to the
camera firmware running on the GPU. Conceptually, it presents the camera with
three ‚Äúports‚ÄĚ: the still port, the video port, and the preview port. The
following sections describe how these ports are used by picamera and how they
influence the camera‚Äôs behaviour.

Firstly, the still port. Whenever this is used to capture images, it (briefly)
forces the camera‚Äôs mode to one of the two supported still modes (see
Sensor Modes) so that images are captured using the full area of the
sensor. It also uses a strong noise reduction algorithm on captured images so
that they appear higher quality.

The still port is used by the various capture() methods when
their use_video_port parameter is False (which it is by default).

The video port is somewhat simpler in that it never changes the camera‚Äôs mode.
The video port is used by the start_recording() method (for
recording video), and is also used by the various capture()
methods when their use_video_port parameter is True. Images captured from
the video port tend to have a ‚Äúgrainy‚ÄĚ appearance, much more akin to a video
frame than the images captured by the still port (this is due to the still port
using the stronger noise reduction algorithm).

The preview port operates more or less identically to the video port. The
preview port is always connected to some form of output to ensure that the
auto-gain algorithm can run. When an instance of PiCamera is
constructed, the preview port is initially connected to an instance of
PiNullSink. When start_preview() is called, this null
sink is destroyed and the preview port is connected to an instance of
PiPreviewRenderer. The reverse occurs when
stop_preview() is called.

This section attempts to provide detail of what MMAL pipelines picamera
constructs in response to various method calls.

The firmware provides various encoders which can be attached to the still and
video ports for the purpose of producing output (e.g. JPEG images or H.264
encoded video). A port can have a single encoder attached to it at any given
time (or nothing if the port is not in use).

Encoders are connected directly to the still port. For example, when capturing
a picture using the still port, the camera‚Äôs state conceptually moves through
these states:

As you have probably noticed in the diagram above, the video port is a little
more complex. In order to permit simultaneous video recording and image capture
via the video port, a ‚Äúsplitter‚ÄĚ component is permanently connected to the
video port by picamera, and encoders are in turn attached to one of its four
output ports (numbered 0, 1, 2, and 3). Hence, when recording video the
camera‚Äôs setup looks like this:

And when simultaneously capturing images via the video port whilst recording,
the camera‚Äôs configuration moves through the following states:

When the resize parameter is passed to one of the aforementioned methods, a
resizer component is placed between the camera‚Äôs ports and the encoder, causing
the output to be resized before it reaches the encoder. This is particularly
useful for video recording, as the H.264 encoder cannot cope with full
resolution input (the GPU hardware can only handle frame widths up to 1920
pixels). Hence, when performing full frame video recording, the camera‚Äôs setup
looks like this:

Finally, when performing unencoded captures an encoder is (naturally) not
required. Instead data is taken directly from the camera‚Äôs ports. However,
various firmware limitations require acrobatics in the pipeline to achieve
requested encodings.

For example, in older firmwares the camera‚Äôs still port cannot be configured
for RGB output (due to a faulty buffer size check). However, they can be
configured for YUV output so in this case picamera configures the still port
for YUV output, attaches as resizer (configured with the same input and output
resolution), then configures the resizer‚Äôs output for RGBA (the resizer doesn‚Äôt
support RGB for some reason). It then runs the capture and strips the redundant
alpha bytes off the data.

Recent firmwares fix the buffer size check, so with these picamera will
simply configure the still port for RGB output (since 1.11):

The ports used to connect MMAL components together pass image data around in
particular encodings. Often, this is the YUV420 encoding (this is the
‚Äúpreferred‚ÄĚ internal format for the pipeline). On rare occasions, it is RGB
(RGB is a large and rather inefficient format). However, another format
sometimes used is the ‚ÄúOPAQUE‚ÄĚ encoding.

‚ÄúOPAQUE‚ÄĚ is the most efficient encoding to use when connecting MMAL components
as it simply passes pointers around under the hood rather than full frame data
(as such it‚Äôs not really an encoding at all, but it‚Äôs treated as such by the
MMAL framework). However, not all OPAQUE encodings are equivalent:

The preview port‚Äôs OPAQUE encoding contains a single image.

The video port‚Äôs OPAQUE encoding contains two images (used for motion
estimation by various encoders).

The MJPEG video encoder does not accept the OPAQUE strips format, only
the single and dual image variants provided by the preview or video ports.

The H264 video encoder in older firmwares only accepts the dual image
OPAQUE format (it will accept full-frame YUV input instead though). In newer
firmwares it now accepts the single image OPAQUE format too (presumably
constructing the second image itself for motion estimation).

The splitter accepts single or dual image OPAQUE input, but only outputs
single image OPAQUE input (or YUV; in later firmwares it also
supports RGB or BGR output).

The VPU resizer (MMALResizer) theoretically
accepts OPAQUE input (though the author hasn‚Äôt managed to get this working at
the time of writing) but will only produce YUV, RGBA, and BGRA output, not
RGB or BGR.

The ISP resizer (MMALISPResizer, not currently
used by picamera‚Äôs high level API, but available from the
mmalobj layer) accepts OPAQUE input, and will produce almost
any unencoded output (including YUV, RGB, BGR, RGBA, and BGRA) but not
OPAQUE.

The mmalobj layer introduced in picamera 1.11 is aware of
these OPAQUE encoding differences and attempts to configure connections between
components using the most efficient formats possible. However, it is not aware
of firmware revisions so if you‚Äôre playing with MMAL components via this layer
be prepared to do some tinkering to get your pipeline working.

Please note that the description above is MMAL‚Äôs greatly simplified
presentation of the imaging pipeline. This is far removed from what actually
happens at the GPU‚Äôs ISP level (described roughly in earlier sections).
However, as MMAL is the API under-pinning the picamera library (along with the
official raspistill and raspivid applications) it is worth
understanding.

In other words, by using picamera you are passing through (at least) two
abstraction layers which necessarily obscure (but hopefully simplify) the
‚Äútrue‚ÄĚ operation of the camera.

Anyone is more than welcome to open tickets to discuss bugs, new features, or
just to ask usage questions (I find this useful for gauging what questions
ought to feature in the FAQ, for example).

For anybody wishing to hack on the project, I would strongly recommend reading
through the PiCamera class‚Äô source, to get a handle on using the
mmalobj layer. This is a layer introduced in picamera 1.11 to
ease the usage of libmmal (the underlying library that picamera,
raspistill, and raspivid all rely upon).

Beneath mmalobj is a ctypes translation of the
libmmal headers but my hope is that most developers will never need to deal
with this directly (thus, a working knowledge of C is hopefully no longer
necessary to hack on picamera).

Even if you don‚Äôt feel up to hacking on the code, I‚Äôd love to hear suggestions
from people of what you‚Äôd like the API to look like (even if the code itself
isn‚Äôt particularly pythonic, the interface should be)!

If you wish to develop picamera itself, it is easiest to obtain the source by
cloning the GitHub repository and then use the ‚Äúdevelop‚ÄĚ target of the Makefile
which will install the package as a link to the cloned repository allowing
in-place development (it also builds a tags file for use with vim/emacs with
Exuberant‚Äôs ctags utility). The following example demonstrates this method
within a virtual Python environment:

If you wish to build the docs, you‚Äôll need a few more dependencies. Inkscape
is used for conversion of SVGs to other formats, Graphviz is used for rendering
certain charts, and TeX Live is required for building PDF output. The following
command should install all required dependencies:

If you wish to run the picamera test suite, follow the instructions in
Development installation above and then make the ‚Äútest‚ÄĚ target within the sandbox:

$ workon picamera
(picamera) $cd ~/picamera
(picamera) $ make test

Warning

The test suite takes a very long time to execute (at least 1 hour on an
overclocked Pi 3). Depending on configuration, it can also lockup the
camera requiring a reboot to reset, so ensure you are familiar with SSH or
using alternate TTYs to access a command line in the event you need to
reboot.

The picamera library is (at the time of writing) nearly a year old and has
grown quite rapidly in this time. Occasionally, when adding new functionality
to the library, the API is obvious and natural (e.g.
start_recording() and stop_recording()). At
other times, it‚Äôs been less obvious (e.g. unencoded captures) and my initial
attempts have proven to be less than ideal. In such situations I‚Äôve endeavoured
to improve the API without breaking backward compatibility by introducing new
methods or attributes and deprecating the old ones.

This means that, as of release 1.8, there‚Äôs quite a lot of deprecated
functionality floating around the library which it would be nice to tidy up,
partly to simplify the library for debugging, and partly to simplify it for new
users. To assuage any fears that I‚Äôm imminently going to break backward
compatibility: I intend to leave a gap of at least a year between deprecating
functionality and removing it, hopefully providing ample time for people to
migrate their scripts.

Furthermore, to distinguish any release which is backwards incompatible, I
would increment the major version number in accordance with semantic
versioning. In other words, the first release in which currently deprecated
functionality would be removed would be version 2.0, and as of the release of
1.8 it‚Äôs at least a year away. Any future 1.x releases will include all
currently deprecated functions.

Of course, that still means people need a way of determining whether their
scripts use any deprecated functionality in the picamera library. All
deprecated functionality is documented, and the documentation includes pointers
to the intended replacement functionality (see raw_format for
example). However, Python also provides excellent methods for determining
automatically whether any deprecated functionality is being used via the
warnings module.

As of release 1.8, all deprecated functionality will raise
DeprecationWarning when used. By default, the Python interpreter
suppresses these warnings (as they‚Äôre only of interest to developers, not
users) but you can easily configure different behaviour.

Despite using deprecated functionality the script runs happily (and silently)
with picamera 1.8. To discover what deprecated functions are being used, we add
a couple of lines to tell the warnings module that we want ‚Äúdefault‚ÄĚ handling
of DeprecationWarning; ‚Äúdefault‚ÄĚ handling means that the first time an
attempt is made to raise this warning at a particular location, the warning‚Äôs
details will be printed to the console. All future invocations from the same
location will be ignored. This saves flooding the console with warning details
from tight loops. With this change, the script looks like this:

This tells us which pieces of deprecated functionality are being used in our
script, but it doesn‚Äôt tell us where in the script they were used. For this,
it is more useful to have warnings converted into full blown exceptions. With
this change, each time a DeprecationWarning would have been printed, it
will instead cause the script to terminate with an unhandled exception and a
full stack trace:

Traceback (most recent call last):
File "test_deprecated.py", line 10, in <module>camera.framerate=(24,1)
File "/usr/share/pyshared/picamera/camera.py", line 1888, in _set_frameraten,d=to_rational(value)
File "/usr/share/pyshared/picamera/camera.py", line 149, in to_rational"Setting framerate or gains as a tuple is deprecated; "DeprecationWarning: Setting framerate or gains as a tuple is deprecated; please use one of Python's many numeric classes like int, float, Decimal, or Fraction instead

This tells us that line 10 of our script is using deprecated functionality, and
provides a hint of how to fix it. We change line 10 to use an int instead of a
tuple for the framerate. Now we run again, and this time get the following:

The script now runs to completion, so we can be confident it‚Äôs no longer using
any deprecated functionality and will run happily even when this functionality
is removed in release 2.0. At this point, you may wish to remove the
filterwarnings line as well (or at least comment it out).

For convenience, all currently deprecated functionality is detailed below. You
may wish to skim this list to check whether you‚Äôre currently using deprecated
functions, but I would urge users to take advantage of the warnings system
documented in the prior section as well.

In very early versions of picamera, unencoded captures were created by
specifying the 'raw' format with the capture() method, with
the raw_format attribute providing the actual encoding. The
attribute is deprecated, as is usage of the value 'raw' with the format
parameter of all the capture methods.

The deprecated method of taking unencoded captures looks like this:

camera.raw_format='rgb'camera.capture('output.data',format='raw')

In such cases, simply remove references to raw_format and
place the required format directly within the capture() call:

The quantization parameter for start_recording() and
record_sequence() is deprecated in favor of the quality
parameter; this change was made to keep the recording methods consistent with
the capture methods, and to make the meaning of the parameter more obvious to
newcomers. The values of the parameter remain the same (i.e. 1-100 for MJPEG
recordings with higher values indicating higher quality, and 1-40 for H.264
recordings with lower values indicating higher quality).

The deprecated method of setting recording quality looks like this:

camera.start_recording('foo.h264',quantization=25)

Simply replace the quantization parameter with the quality parameter
like so:

Several attributes in picamera expect rational (fractional) values. In early
versions of picamera, these values could only be specified as a tuple expressed
as (numerator,denominator). In later versions, support was expanded to
accept any of Python‚Äôs numeric types.

The following code illustrates the deprecated usage of a tuple representing
a rational value:

camera.framerate=(24,1)

Such cases can be replaced with any of Python‚Äôs numeric types, including
int, float,
Decimal, and Fraction. All the following
examples are functionally equivalent to the deprecated example above:

These attributes return a Fraction instance as well, but
one modified to permit access as a tuple in order to maintain backward
compatibility. This is also deprecated behaviour. The following example
demonstrates accessing the framerate attribute as a tuple:

n,d=camera.framerateprint('The framerate is %d/%d fps'%(n,d))

In such cases, use the standard numerator and
denominator attributes of the returned fraction
instead:

Release 1.8 introduced rather sweeping changes to the preview system to
incorporate the ability to create multiple static overlays on top of the
preview. As a result, the preview system is no longer incorporated into the
PiCamera class. Instead, it is represented by the
preview attribute which is a separate
PiPreviewRenderer instance when the preview is active.

Unfortuantely, this simple change is not possible when preview attributes are
altered before the preview has been activated, as the
preview attribute is None when the preview is not active.
To accomodate this use-case, optional parameters were added to
start_preview() to provide initial settings for the preview
renderer. The following example illustrates the deprecated method of setting
preview related attribtues prior to activating the preview:

Remove the lines setting the attributes, and use the corresponding keyword
parameters of the start_preview() method instead:

camera.start_preview(alpha=128,fullscreen=False,window=(0,0,640,480))

Finally, the previewing attribute is now obsolete (and thus
deprecated) as its functionality can be trivially obtained by checking the
preview attribute. The following example illustrates the
deprecated method of checking whether the preview is activate:

ifcamera.previewing:print('The camera preview is running')else:print('The camera preview is not running')

In release 1.8, the base PiArrayOutput class was changed to
derive from io.BytesIO in order to add support for seeking, and to
improve performance. The prior implementation had been non-seekable, and
therefore to accommodate re-use of the stream between captures the
truncate() method had an unusual side-effect not
seen with regular Python streams: after truncation, the position of the stream
was set to the new length of the stream. In all other Python streams, the
truncate method doesn‚Äôt affect the stream position. The method is
overridden in 1.8 to maintain its unusual behaviour, but this behaviour is
nonetheless deprecated.

The following snippet illustrates the method of truncating an array stream
in picamera versions 1.7 and older:

Unfortunately, this will not work if your script needs to work with prior
versions of picamera as well (since such streams were non-seekable in prior
versions). In this case, call seekable() to determine the
correct course of action:

In release 1.8, the crop attribute was renamed to
zoom; the old name was retained as a deprecated alias for
backward compatibility. This change was made as crop was a thoroughly
misleading name for the attribute (which actually sets the ‚Äúregion of interest‚ÄĚ
for the sensor), leading to numerous support questions.

Over time, several capabilities were added to the H.264 encoder in the GPU
firmware. This expanded the number of possible frame types from a simple
key-frame / non-key-frame affair, to a multitude of possibilities (P-frame,
I-frame, SPS/PPS header, motion vector data, and who knows in future). Rather
than keep adding more and more boolean fields to the PiVideoFrame
named tuple, release 1.5 introduced the PiVideoFrameType enumeration
used by the frame_type attribute and deprecated the
keyframe and header attributes.

The following code illustrates usage of the deprecated boolean fields:

In release 1.10, the annotate_background attribute was
enhanced to support setting the background color of annotation text. Older
versions of picamera treated this attribute as a bool (False for no
background, True to draw a black background).

In order to provide the new functionality while maintaining a certain amount of
backward compatibility, the new attribute accepts None for no background
and a Color instance for a custom background color. It is worth
noting that the truth values of None and False are equivalent, as are
the truth values of a Color instance and True. Hence, naive tests
against the attribute value will continue to work.

The following example illustrates the deprecated behaviour of setting the
attribute as a boolean:

camera.annotate_background=Falsecamera.annotate_background=True

In such cases, replace False with None, and True with a
Color instance of your choosing. Bear in mind that older Pi firmwares
can only produce a black background, so you may wish to stick with black to
ensure equivalent behaviour:

The picamera library contains numerous classes, but the primary one that all
users are likely to interact with is PiCamera, documented below.
With the exception of the contents of the picamera.array module, all
classes in picamera are accessible from the package‚Äôs top level namespace.
In other words, the following import is sufficient to import everything in
the library (excepting the contents of picamera.array):

Upon construction, this class initializes the camera. The camera_num
parameter (which defaults to 0) selects the camera module that the instance
will represent. Only the Raspberry Pi compute module currently supports
more than one camera.

The sensor_mode, resolution, framerate, framerate_range, and
clock_mode parameters provide initial values for the sensor_mode,
resolution, framerate, framerate_range, and
clock_mode attributes of the class (these attributes are all
relatively expensive to set individually, hence setting them all upon
construction is a speed optimization). Please refer to the attribute
documentation for more information and default values.

The stereo_mode and stereo_decimate parameters configure dual cameras
on a compute module for sterescopic mode. These parameters can only be set
at construction time; they cannot be altered later without closing the
PiCamera instance and recreating it. The stereo_mode parameter
defaults to 'none' (no stereoscopic mode) but can be set to
'side-by-side' or 'top-bottom' to activate a stereoscopic mode. If
the stereo_decimate parameter is True, the resolution of the two
cameras will be halved so that the resulting image has the same dimensions
as if stereoscopic mode were not being used.

The led_pin parameter can be used to specify the GPIO pin which should be
used to control the camera‚Äôs LED via the led attribute. If this is
not specified, it should default to the correct value for your Pi platform.
You should only need to specify this parameter if you are using a custom
DeviceTree blob (this is only typical on the Compute Module platform).

No preview or recording is started automatically upon construction. Use
the capture() method to capture images, the start_recording()
method to begin recording video, or the start_preview() method to
start live display of the camera‚Äôs input.

Several attributes are provided to adjust the camera‚Äôs configuration. Some
of these can be adjusted while a recording is running, like
brightness. Others, like resolution, can only be adjusted
when the camera is idle.

When you are finished with the camera, you should ensure you call the
close() method to release the camera resources:

camera=PiCamera()try:# do something with the camerapassfinally:camera.close()

The class supports the context manager protocol to make this particularly
easy (upon exiting the with statement, the close() method
is automatically called):

withPiCamera()ascamera:# do something with the camerapass

Changed in version 1.8: Added stereo_mode and stereo_decimate parameters.

Changed in version 1.9: Added resolution, framerate, and sensor_mode parameters.

Changed in version 1.10: Added led_pin parameter.

Changed in version 1.11: Added clock_mode parameter, and permitted setting of resolution as
appropriately formatted string.

This method creates a new static overlay using the same rendering
mechanism as the preview. Overlays will appear on the Pi‚Äôs video
output, but will not appear in captures or video recordings. Multiple
overlays can exist; each call to add_overlay() returns a new
PiOverlayRenderer instance representing the overlay.

The source must be an object that supports the buffer protocol in one of the supported unencoded formats: 'yuv',
'rgb', 'rgba', 'bgr', or 'bgra'. The format can
specified explicitly with the optional format parameter. If not
specified, the method will attempt to guess the format based on the
length of source and the size (assuming 3 bytes per pixel for RGB,
and 4 bytes for RGBA).

The optional size parameter specifies the size of the source image as
a (width,height) tuple. If this is omitted or None then the
size is assumed to be the same as the camera‚Äôs current
resolution.

The length of source must take into account that widths are rounded
up to the nearest multiple of 32, and heights to the nearest multiple
of 16. For example, if size is (1280,720), and format is
'rgb', then source must be a buffer with length 1280 √ó 720 √ó 3
bytes, or 2,764,800 bytes (because 1280 is a multiple of 32, and 720 is
a multiple of 16 no extra rounding is required). However, if size is
(97,57), and format is 'rgb' then source must be a buffer
with length 128 √ó 64 √ó 3 bytes, or 24,576 bytes (pixels beyond column
97 and row 57 in the source will be ignored).

New overlays default to layer 0, whilst the preview defaults to layer
2. Higher numbered layers obscure lower numbered layers, hence new
overlays will be invisible (if the preview is running) by default. You
can make the new overlay visible either by making any existing preview
transparent (with the alpha property) or by moving
the overlay into a layer higher than the preview (with the
layer property).

All keyword arguments captured in options are passed onto the
PiRenderer constructor. All camera properties except
resolution and framerate can be modified while overlays
exist. The reason for these exceptions is that the overlay has a static
resolution and changing the camera‚Äôs mode would require resizing of the
source.

Warning

If too many overlays are added, the display output will be disabled
and a reboot will generally be required to restore the display.
Overlays are composited ‚Äúon the fly‚ÄĚ. Hence, a real-time constraint
exists wherein for each horizontal line of HDMI output, the content
of all source layers must be fetched, resized, converted, and
blended to produce the output pixels.

If enough overlays exist (where ‚Äúenough‚ÄĚ is a number dependent on
overlay size, display resolution, bus frequency, and several other
factors making it unrealistic to calculate in advance), this
process breaks down and video output fails. One solution is to add
dispmanx_offline=1 to /boot/config.txt to force the use of
an off-screen buffer. Be aware that this requires more GPU memory
and may reduce the update rate.

If output is a string, it will be treated as a filename for a new
file which the image will be written to. If output is not a string,
but is an object with a write method, it is assumed to be a
file-like object and the image data is appended to it (the
implementation only assumes the object has a write method - no
other methods are required but flush will be called at the end of
capture if it is present). If output is not a string, and has no
write method it is assumed to be a writeable object implementing
the buffer protocol. In this case, the image data will be written
directly to the underlying buffer (which must be large enough to accept
the image data).

If format is None (the default), the method will attempt to guess
the required image format from the extension of output (if it‚Äôs a
string), or from the name attribute of output (if it has one). In
the case that the format cannot be determined, a
PiCameraValueError will be raised.

If format is not None, it must be a string specifying the format
that you want the image output in. The format can be a MIME-type or
one of the following strings:

'jpeg' - Write a JPEG file

'png' - Write a PNG file

'gif' - Write a GIF file

'bmp' - Write a Windows bitmap file

'yuv' - Write the raw image data to a file in YUV420 format

'rgb' - Write the raw image data to a file in 24-bit RGB format

'rgba' - Write the raw image data to a file in 32-bit RGBA format

'bgr' - Write the raw image data to a file in 24-bit BGR format

'bgra' - Write the raw image data to a file in 32-bit BGRA format

'raw' - Deprecated option for raw captures; the format is taken
from the deprecated raw_format attribute

The use_video_port parameter controls whether the camera‚Äôs image or
video port is used to capture images. It defaults to False which
means that the camera‚Äôs image port is used. This port is slow but
produces better quality pictures. If you need rapid capture up to the
rate of video frames, set this to True.

When use_video_port is True, the splitter_port parameter
specifies the port of the video splitter that the image encoder will be
attached to. This defaults to 0 and most users will have no need to
specify anything different. This parameter is ignored when
use_video_port is False. See MMAL for more information
about the video splitter.

If resize is not None (the default), it must be a two-element
tuple specifying the width and height that the image should be resized
to.

Warning

If resize is specified, or use_video_port is True, Exif
metadata will not be included in JPEG output. This is due to an
underlying firmware limitation.

Certain file formats accept additional options which can be specified
as keyword arguments. Currently, only the 'jpeg' encoder accepts
additional options, which are:

quality - Defines the quality of the JPEG encoder as an integer
ranging from 1 to 100. Defaults to 85. Please note that JPEG quality
is not a percentage and definitions of quality vary widely.

restart - Defines the restart interval for the JPEG encoder as a
number of JPEG MCUs. The actual restart interval used will be a
multiple of the number of MCUs per row in the resulting image.

thumbnail - Defines the size and quality of the thumbnail to embed
in the Exif metadata. Specifying None disables thumbnail
generation. Otherwise, specify a tuple of (width,height,quality). Defaults to (64,48,35).

bayer - If True, the raw bayer data from the camera‚Äôs sensor
is included in the Exif metadata.

Note

The so-called ‚Äúraw‚ÄĚ formats listed above ('yuv', 'rgb',
etc.) do not represent the raw bayer data from the camera‚Äôs sensor.
Rather they provide access to the image data after GPU processing,
but before format encoding (JPEG, PNG, etc). Currently, the only
method of accessing the raw bayer data is via the bayer parameter
described above.

Changed in version 1.0: The resize parameter was added, and raw capture formats can now
be specified directly

Changed in version 1.3: The splitter_port parameter was added, and bayer was added as
an option for the 'jpeg' format

This method returns an infinite iterator of images captured
continuously from the camera. If output is a string, each captured
image is stored in a file named after output after substitution of
two values with the format() method. Those two values are:

{counter} - a simple incrementor that starts at 1 and increases
by 1 for each image taken

Note that because timestamp‚Äôs default output includes colons (:),
the resulting filenames are not suitable for use on Windows. For
this reason (and the fact the default contains spaces) it is
strongly recommended you always specify a format when using
{timestamp}.

You can use both {timestamp} and {counter} in a single
format string (multiple times too!) although this tends to be
redundant.

If output is not a string, but has a write method, it is assumed
to be a file-like object and each image is simply written to this
object sequentially. In this case you will likely either want to write
something to the object between the images to distinguish them, or
clear the object between iterations. If output is not a string, and
has no write method, it is assumed to be a writeable object
supporting the buffer protocol; each image is simply written to the
buffer sequentially.

The format, use_video_port, splitter_port, resize, and
options parameters are the same as in capture().

If use_video_port is False (the default), the burst parameter
can be used to make still port captures faster. Specifically, this
prevents the preview from switching resolutions between captures which
significantly speeds up consecutive captures from the still port. The
downside is that this mode is currently has several bugs; the major
issue is that if captures are performed too quickly some frames will
come back severely underexposed. It is recommended that users avoid the
burst parameter unless they absolutely require it and are prepared to
work around such issues.

For example, to capture 60 images with a one second delay between them,
writing the output to a series of JPEG files named image01.jpg,
image02.jpg, etc. one could do the following:

Alternatively, to capture JPEG frames as fast as possible into an
in-memory stream, performing some processing on each stream until
some condition is satisfied:

importioimporttimeimportpicamerawithpicamera.PiCamera()ascamera:stream=io.BytesIO()forfooincamera.capture_continuous(stream,format='jpeg'):# Truncate the stream to the current position (in case# prior iterations output a longer image)stream.truncate()stream.seek(0)ifprocess(stream):break

Changed in version 1.0: The resize parameter was added, and raw capture formats can now
be specified directly

This method accepts a sequence or iterator of outputs each of which
must either be a string specifying a filename for output, or a
file-like object with a write method, or a writeable buffer object.
For each item in the sequence or iterator of outputs, the camera
captures a single image as fast as it can.

The format, use_video_port, splitter_port, resize, and
options parameters are the same as in capture(), but format
defaults to 'jpeg'. The format is not derived from the
filenames in outputs by this method.

If use_video_port is False (the default), the burst parameter
can be used to make still port captures faster. Specifically, this
prevents the preview from switching resolutions between captures which
significantly speeds up consecutive captures from the still port. The
downside is that this mode is currently has several bugs; the major
issue is that if captures are performed too quickly some frames will
come back severely underexposed. It is recommended that users avoid the
burst parameter unless they absolutely require it and are prepared to
work around such issues.

After successfully constructing a PiCamera object, you should
ensure you call the close() method once you are finished with the
camera (e.g. in the finally section of a try..finally block).
This method stops all recording and preview activities and releases all
resources associated with the camera; this is necessary to prevent GPU
memory leaks.

This method accepts a sequence or iterator of outputs each of which
must either be a string specifying a filename for output, or a
file-like object with a write method.

The method acts as an iterator itself, yielding each item of the
sequence in turn. In this way, the caller can control how long to
record to each item by only permitting the loop to continue when ready
to switch to the next output.

The format, splitter_port, resize, and options parameters are
the same as in start_recording(), but format defaults to
'h264'. The format is not derived from the filenames in
outputs by this method.

For example, to record 3 consecutive 10-second video clips, writing the
output to a series of H.264 files named clip01.h264, clip02.h264, and
clip03.h264 one could use the following:

importpicamerawithpicamera.PiCamera()ascamera:forfilenameincamera.record_sequence(['clip01.h264','clip02.h264','clip03.h264']):print('Recording to %s'%filename)camera.wait_recording(10)

Alternatively, a more flexible method of writing the previous example
(which is easier to expand to a large number of output files) is by
using a generator expression as the input sequence:

importpicamerawithpicamera.PiCamera()ascamera:forfilenameincamera.record_sequence('clip%02d.h264'%iforiinrange(3)):print('Recording to %s'%filename)camera.wait_recording(10)

More advanced techniques are also possible by utilising infinite
sequences, such as those generated by itertools.cycle(). In the
following example, recording is switched between two in-memory streams.
Whilst one stream is recording, the other is being analysed. The script
only stops recording when a video recording meets some criteria defined
by the process function:

When called, the video encoder running on the specified splitter_port
will attempt to produce a key-frame (full-image frame) as soon as
possible. The splitter_port defaults to 1. Valid values are
between 0 and 3 inclusive.

Note

This method is only meaningful for recordings encoded in the H264
format as MJPEG produces full frames for every frame recorded.
Furthermore, there‚Äôs no guarantee that the next frame will be
a key-frame; this is simply a request to produce one as soon as
possible after the call.

Continue the recording in the specified output; close existing output.

When called, the video encoder will wait for the next appropriate
split point (an inline SPS header), then will cease writing to the
current output (and close it, if it was specified as a filename), and
continue writing to the newly specified output.

The output parameter is treated as in the start_recording()
method (it can be a string, a file-like object, or a writeable
buffer object).

The motion_output parameter can be used to redirect the output of the
motion vector data in the same fashion as output. If motion_output
is None (the default) then motion vector data will not be
redirected and will continue being written to the output specified by
the motion_output parameter given to start_recording().
Alternatively, if you only wish to redirect motion vector data, you can
set output to None and given a new value for motion_output.

The splitter_port parameter specifies which port of the video
splitter the encoder you wish to change outputs is attached to. This
defaults to 1 and most users will have no need to specify anything
different. Valid values are between 0 and 3 inclusive.

Note that unlike start_recording(), you cannot specify format or
other options as these cannot be changed in the middle of recording.
Only the new output (and motion_output) can be specified.
Furthermore, the format of the recording is currently limited to H264,
and inline_headers must be True when start_recording() is
called (this is the default).

This method starts a camera preview as an overlay on the Pi‚Äôs primary
display (HDMI or composite). A PiRenderer instance (more
specifically, a PiPreviewRenderer) is constructed with the
keyword arguments captured in options, and is returned from the
method (this instance is also accessible from the preview
attribute for as long as the renderer remains active). By default, the
renderer will be opaque and fullscreen.

This means the default preview overrides whatever is currently visible
on the display. More specifically, the preview does not rely on a
graphical environment like X-Windows (it can run quite happily from a
TTY console); it is simply an overlay on the Pi‚Äôs video output. To stop
the preview and reveal the display again, call stop_preview().
The preview can be started and stopped multiple times during the
lifetime of the PiCamera object.

All other camera properties can be modified ‚Äúlive‚ÄĚ while the preview is
running (e.g. brightness).

Note

Because the default preview typically obscures the screen, ensure
you have a means of stopping a preview before starting one. If the
preview obscures your interactive console you won‚Äôt be able to
Alt+Tab back to it as the preview isn‚Äôt in a window. If you are in
an interactive Python session, simply pressing Ctrl+D usually
suffices to terminate the environment, including the camera and its
associated preview.

If output is a string, it will be treated as a filename for a new
file which the video will be written to. If output is not a string,
but is an object with a write method, it is assumed to be a
file-like object and the video data is appended to it (the
implementation only assumes the object has a write() method - no
other methods are required but flush will be called at the end of
recording if it is present). If output is not a string, and has no
write method it is assumed to be a writeable object implementing
the buffer protocol. In this case, the video frames will be written
sequentially to the underlying buffer (which must be large enough to
accept all frame data).

If format is None (the default), the method will attempt to guess
the required video format from the extension of output (if it‚Äôs a
string), or from the name attribute of output (if it has one). In
the case that the format cannot be determined, a
PiCameraValueError will be raised.

If format is not None, it must be a string specifying the format
that you want the video output in. The format can be a MIME-type or
one of the following strings:

'h264' - Write an H.264 video stream

'mjpeg' - Write an M-JPEG video stream

'yuv' - Write the raw video data to a file in YUV420 format

'rgb' - Write the raw video data to a file in 24-bit RGB format

'rgba' - Write the raw video data to a file in 32-bit RGBA format

'bgr' - Write the raw video data to a file in 24-bit BGR format

'bgra' - Write the raw video data to a file in 32-bit BGRA format

If resize is not None (the default), it must be a two-element
tuple specifying the width and height that the video recording should
be resized to. This is particularly useful for recording video using
the full resolution of the camera sensor (which is not possible in
H.264 without down-sizing the output).

The splitter_port parameter specifies the port of the built-in
splitter that the video encoder will be attached to. This defaults to
1 and most users will have no need to specify anything different.
If you wish to record multiple (presumably resized) streams
simultaneously, specify a value between 0 and 3 inclusive for
this parameter, ensuring that you do not specify a port that is
currently in use.

Certain formats accept additional options which can be specified
as keyword arguments. The 'h264' format accepts the following
additional options:

profile - The H.264 profile to use for encoding. Defaults to
‚Äėhigh‚Äô, but can be one of ‚Äėbaseline‚Äô, ‚Äėmain‚Äô, ‚Äėextended‚Äô, ‚Äėhigh‚Äô, or
‚Äėconstrained‚Äô.

level - The H.264 level to use for encoding. Defaults to ‚Äė4‚Äô,
but can be any H.264 level up to ‚Äė4.2‚Äô.

intra_period - The key frame rate (the rate at which I-frames are
inserted in the output). Defaults to None, but can be any 32-bit
integer value representing the number of frames between successive
I-frames. The special value 0 causes the encoder to produce a single
initial I-frame, and then only P-frames subsequently. Note that
split_recording() will fail in this mode.

intra_refresh - The key frame format (the way in which I-frames
will be inserted into the output stream). Defaults to None, but
can be one of ‚Äėcyclic‚Äô, ‚Äėadaptive‚Äô, ‚Äėboth‚Äô, or ‚Äėcyclicrows‚Äô.

inline_headers - When True, specifies that the encoder should
output SPS/PPS headers within the stream to ensure GOPs (groups of
pictures) are self describing. This is important for streaming
applications where the client may wish to seek within the stream, and
enables the use of split_recording(). Defaults to True if
not specified.

sei - When True, specifies the encoder should include
‚ÄúSupplemental Enhancement Information‚ÄĚ within the output stream.
Defaults to False if not specified.

sps_timing - When True the encoder includes the camera‚Äôs
framerate in the SPS header. Defaults to False if not specified.

motion_output - Indicates the output destination for motion vector
estimation data. When None (the default), motion data is not
output. Otherwise, this can be a filename string, a file-like object,
or a writeable buffer object (as with the output parameter).

All encoded formats accept the following additional options:

bitrate - The bitrate at which video will be encoded. Defaults to
17000000 (17Mbps) if not specified. The maximum value depends on the
selected H.264 level and profile. Bitrate 0 indicates the encoder
should not use bitrate control (the encoder is limited by the quality
only).

quality - Specifies the quality that the encoder should attempt
to maintain. For the 'h264' format, use values between 10 and 40
where 10 is extremely high quality, and 40 is extremely low (20-25 is
usually a reasonable range for H.264 encoding). For the mjpeg
format, use JPEG quality values between 1 and 100 (where higher
values are higher quality). Quality 0 is special and seems to be
a ‚Äúreasonable quality‚ÄĚ default.

quantization - Deprecated alias for quality.

Changed in version 1.0: The resize parameter was added, and 'mjpeg' was added as a
recording format

Changed in version 1.3: The splitter_port parameter was added

Changed in version 1.5: The quantization parameter was deprecated in favor of quality,
and the motion_output parameter was added.

If start_preview() has previously been called, this method shuts
down the preview display which generally results in the underlying
display becoming visible again. If a preview is not currently running,
no exception is raised - the method will simply do nothing.

After calling this method the video encoder will be shut down and
output will stop being written to the file-like object specified with
start_recording(). If an error occurred during recording and
wait_recording() has not been called since the error then this
method will raise the exception.

The splitter_port parameter specifies which port of the video
splitter the encoder you wish to stop is attached to. This defaults to
1 and most users will have no need to specify anything different.
Valid values are between 0 and 3 inclusive.

It is recommended that this method is called while recording to check
for exceptions. If an error occurs during recording (for example out of
disk space) the recording will stop, but an exception will only be
raised when the wait_recording() or stop_recording()
methods are called.

If timeout is 0 (the default) the function will immediately return
(or raise an exception if an error has occurred).

The splitter_port parameter specifies which port of the video
splitter the encoder you wish to wait on is attached to. This
defaults to 1 and most users will have no need to specify anything
different. Valid values are between 0 and 3 inclusive.

When queried, this property returns the analog gain currently being
used by the camera. The value represents the analog gain of the sensor
prior to digital conversion. The value is returned as a
Fraction instance.

The annotate_background attribute specifies if a background
will be drawn behind the annotationtext and,
if so, what color it will be. The value is specified as a
Color or None if no background should be drawn. The
default is None.

Note

For backward compatibility purposes, the value False will be
treated as None, and the value True will be treated as the
color black. The ‚Äútruthiness‚ÄĚ of the values returned by the
attribute are backward compatible although the values themselves
are not.

New in version 1.8.

Changed in version 1.10: In prior versions this was a bool value with True representing
a black background.

The annotate_foreground attribute specifies, partially, the
color of the annotation text. The value is specified as a
Color. The default is white.

Note

The underlying firmware does not directly support setting all
components of the text color, only the Y‚Äô component of a Y‚ÄôUV
tuple. This is roughly (but not precisely) analogous to the
‚Äúbrightness‚ÄĚ of a color, so you may choose to think of this as
setting how bright the annotation text will be relative to its
background. In order to specify just the Y‚Äô component when setting
this attribute, you may choose to construct the
Color instance as follows:

When queried, the annotate_text property returns the current
annotation (if no annotation has been set, this is simply a blank
string).

When set, the property immediately applies the annotation to the
preview (if it is running) and to any future captures or video
recording. Strings longer than 255 characters, or strings containing
non-ASCII characters will raise a PiCameraValueError. The
default value is ''.

Changed in version 1.8: Text annotations can now be 255 characters long. The prior limit
was 32 characters.

When queried, this attribute returns a tuple of values representing
the (red, blue) balance of the camera. The red and blue values
are returned Fraction instances. The values will
be between 0.0 and 8.0.

When set, this attribute adjusts the camera‚Äôs auto-white-balance gains.
The property can be specified as a single value in which case both red
and blue gains will be adjusted equally, or as a (red, blue) tuple.
Values can be specified as an int, float or Fraction and each gain must be
between 0.0 and 8.0. Typical values for the gains are between 0.9 and
1.9. The property can be set while recordings or previews are in
progress.

Note

This attribute only has an effect when awb_mode is set to
'off'. Also note that even with AWB disabled, some attributes
(specifically still_stats and drc_strength) can
cause AWB re-calculations.

Changed in version 1.6: Prior to version 1.6, this attribute was write-only.

When queried, the awb_mode property returns a string
representing the auto white balance setting of the camera. The possible
values can be obtained from the PiCamera.AWB_MODES attribute, and
are as follows:

'off'

'auto'

'sunlight'

'cloudy'

'shade'

'tungsten'

'fluorescent'

'incandescent'

'flash'

'horizon'

When set, the property adjusts the camera‚Äôs auto-white-balance mode.
The property can be set while recordings or previews are in progress.
The default value is 'auto'.

Note

AWB mode 'off' is special: this disables the camera‚Äôs automatic
white balance permitting manual control of the white balance via
the awb_gains property. However, even with AWB disabled,
some attributes (specifically still_stats and
drc_strength) can cause AWB re-calculations.

When queried, the brightness property returns the brightness
level of the camera as an integer between 0 and 100. When set, the
property adjusts the brightness of the camera. Brightness can be
adjusted while previews or recordings are in progress. The default
value is 50.

This is an advanced property which can be used to control the nature of
the frame timestamps available from the frame property. When
this is ‚Äúreset‚ÄĚ (the default) each frame‚Äôs timestamp will be relative
to the start of the recording. When this is ‚Äúraw‚ÄĚ, each frame‚Äôs
timestamp will be relative to the last initialization of the camera.

The initial value of this property can be specified with the
clock_mode parameter in the PiCamera constructor, and will
default to ‚Äúreset‚ÄĚ if not specified.

When queried, the color_effects property either returns
None which indicates that the camera is using normal color
settings, or a (u,v) tuple where u and v are integer
values between 0 and 255.

When set, the property changes the color effect applied by the camera.
The property can be set while recordings or previews are in progress.
For example, to make the image black and white set the value to (128,128). The default value is None.

When queried, the contrast property returns the contrast level
of the camera as an integer between -100 and 100. When set, the
property adjusts the contrast of the camera. Contrast can be adjusted
while previews or recordings are in progress. The default value is 0.

When queried, this property returns the digital gain currently being
used by the camera. The value represents the digital gain the camera
applies after conversion of the sensor‚Äôs analog output. The value is
returned as a Fraction instance.

By default several Exif tags are automatically applied to any images
taken with the capture() method: IFD0.Make (which is set to
RaspberryPi), IFD0.Model (which is set to RP_OV5647), and
three timestamp tags: IFD0.DateTime, EXIF.DateTimeOriginal, and
EXIF.DateTimeDigitized which are all set to the current date and
time just before the picture is taken.

If you wish to set additional Exif tags, or override any of the
aforementioned tags, simply add entries to the exif_tags map before
calling capture(). For example:

The Exif standard mandates ASCII encoding for all textual values, hence
strings containing non-ASCII characters will cause an encoding error to
be raised when capture() is called. If you wish to set binary
values, use a bytes() value:

Binary Exif values are currently ignored; this appears to be a
libmmal or firmware bug.

You may also specify datetime values, integer, or float values, all of
which will be converted to appropriate ASCII strings (datetime values
are formatted as YYYY:MM:DDHH:MM:SS in accordance with the Exif
standard).

When queried, the exposure_compensation property returns an
integer value between -25 and 25 indicating the exposure level of the
camera. Larger values result in brighter images.

When set, the property adjusts the camera‚Äôs exposure compensation
level. Each increment represents 1/6th of a stop. Hence setting the
attribute to 6 increases exposure by 1 stop. The property can be set
while recordings or previews are in progress. The default value is 0.

When queried, the exposure_mode property returns a string
representing the exposure setting of the camera. The possible values
can be obtained from the PiCamera.EXPOSURE_MODES attribute, and
are as follows:

'off'

'auto'

'night'

'nightpreview'

'backlight'

'spotlight'

'sports'

'snow'

'beach'

'verylong'

'fixedfps'

'antishake'

'fireworks'

When set, the property adjusts the camera‚Äôs exposure mode. The
property can be set while recordings or previews are in progress. The
default value is 'auto'.

Note

Exposure mode 'off' is special: this disables the camera‚Äôs
automatic gain control, fixing the values of digital_gain
and analog_gain.

Please note that these properties are not directly settable
(although they can be influenced by setting isoprior to
fixing the gains), and default to low values when the camera is
first initialized. Therefore it is important to let them settle on
higher values before disabling automatic gain control otherwise all
frames captured will appear black.

When queried, this property returns the shutter speed currently being
used by the camera. If you have set shutter_speed to a non-zero
value, then exposure_speed and shutter_speed should be
equal. However, if shutter_speed is set to 0 (auto), then you
can read the actual shutter speed being used from this attribute. The
value is returned as an integer representing a number of microseconds.
This is a read-only property.

When queried, the flash_mode property returns a string
representing the flash setting of the camera. The possible values can
be obtained from the PiCamera.FLASH_MODES attribute, and are as
follows:

'off'

'auto'

'on'

'redeye'

'fillin'

'torch'

When set, the property adjusts the camera‚Äôs flash mode. The property
can be set while recordings or previews are in progress. The default
value is 'off'.

Note

You must define which GPIO pins the camera is to use for flash and
privacy indicators. This is done within the Device Tree
configuration which is considered an advanced topic.
Specifically, you need to define pins FLASH_0_ENABLE and
optionally FLASH_0_INDICATOR (for the privacy indicator). More
information can be found in this recipe.

Retrieves information about the current frame recorded from the camera.

When video recording is active (after a call to
start_recording()), this attribute will return a
PiVideoFrame tuple containing information about the current
frame that the camera is recording.

If multiple video recordings are currently in progress (after multiple
calls to start_recording() with different values for the
splitter_port parameter), which encoder‚Äôs frame information is
returned is arbitrary. If you require information from a specific
encoder, you will need to extract it from _encoders explicitly.

Querying this property when the camera is not recording will result in
an exception.

Note

There is a small window of time when querying this attribute will
return None after calling start_recording(). If this
attribute returns None, this means that the video encoder has
been initialized, but the camera has not yet returned any frames.

Retrieves or sets the framerate at which video-port based image
captures, video recordings, and previews will run.

When queried, the framerate property returns the rate at which
the camera‚Äôs video and preview ports will operate as a
Fraction instance (which can be easily converted to
an int or float). If framerate_range has been
set, then framerate will be 0 which indicates that a dynamic
range of framerates is being used.

Note

For backwards compatibility, a derivative of the
Fraction class is actually used which permits
the value to be treated as a tuple of (numerator,denominator).

Setting and retrieving framerate as a (numerator,denominator)
tuple is deprecated and will be removed in 2.0. Please use a
Fraction instance instead (which is just as
accurate and also permits direct use with math operators).

When set, the property configures the camera so that the next call to
recording and previewing methods will use the new framerate. Setting
this property implicitly sets framerate_range so that the low
and high values are equal to the new framerate. The framerate can be
specified as an int, float,
Fraction, or a (numerator,denominator) tuple.
For example, the following definitions are all equivalent:

The camera must not be closed, and no recording must be active when the
property is set.

Note

This attribute, in combination with resolution, determines
the mode that the camera operates in. The actual sensor framerate
and resolution used by the camera is influenced, but not directly
set, by this property. See sensor_mode for more
information.

The initial value of this property can be specified with the
framerate parameter in the PiCamera constructor, and will
default to 30 if not specified.

Retrieves or sets a fractional amount that is added to the camera‚Äôs
framerate for the purpose of minor framerate adjustments.

When queried, the framerate_delta property returns the amount
that the camera‚Äôs framerate has been adjusted. This defaults
to 0 (so the camera‚Äôs framerate is the actual framerate used).

When set, the property adjusts the camera‚Äôs framerate on the fly. The
property can be set while recordings or previews are in progress. Thus
the framerate used by the camera is actually framerate +
framerate_delta.

Note

Framerates deltas can be fractional with adjustments as small as
1/256th of an fps possible (finer adjustments will be rounded).
With an appropriately tuned PID controller, this can be used to
achieve synchronization between the camera framerate and other
devices.

If the new framerate demands a mode switch (such as moving between a
low framerate and a high framerate mode), currently active recordings
may drop a frame. This should only happen when specifying quite large
deltas, or when framerate is at the boundary of a sensor mode (e.g.
49fps).

The framerate delta can be specified as an int,
float, Fraction or a
(numerator,denominator) tuple. For example, the following
definitions are all equivalent:

This property is implicitly reset to 0 when framerate or
framerate_range is set. When framerate is 0
(indicating that framerate_range is set), this property
cannot be used. (there would be little point in making fractional
adjustments to the framerate when the framerate itself is
variable).

Retrieves or sets a range between which the camera‚Äôs framerate is
allowed to float.

When queried, the framerate_range property returns a
namedtuple() derivative with low and high
components (index 0 and 1 respectively) which specify the limits of the
permitted framerate range.

When set, the property configures the camera so that the next call to
recording and previewing methods will use the new framerate range.
Setting this property will implicitly set the framerate
property to 0 (indicating that a dynamic range of framerates is in use
by the camera).

Note

Use of this property prevents use of framerate_delta (there
would be little point in making fractional adjustments to the
framerate when the framerate itself is variable).

The low and high framerates can be specified as int, float, or
Fraction values. For example, the following
definitions are all equivalent:

The camera must not be closed, and no recording must be active when the
property is set.

Note

This attribute, like framerate, determines the mode that
the camera operates in. The actual sensor framerate and resolution
used by the camera is influenced, but not directly set, by this
property. See sensor_mode for more information.

Retrieves or sets whether the camera‚Äôs output is horizontally flipped.

When queried, the hflip property returns a boolean indicating
whether or not the camera‚Äôs output is horizontally flipped. The
property can be set while recordings or previews are in progress. The
default value is False.

When queried, the image_effect property returns a string
representing the effect the camera will apply to captured video. The
possible values can be obtained from the PiCamera.IMAGE_EFFECTS
attribute, and are as follows:

'none'

'negative'

'solarize'

'sketch'

'denoise'

'emboss'

'oilpaint'

'hatch'

'gpen'

'pastel'

'watercolor'

'film'

'blur'

'saturation'

'colorswap'

'washedout'

'posterise'

'colorpoint'

'colorbalance'

'cartoon'

'deinterlace1'

'deinterlace2'

When set, the property changes the effect applied by the camera. The
property can be set while recordings or previews are in progress, but
only certain effects work while recording video (notably 'negative'
and 'solarize'). The default value is 'none'.

When queried, the image_effect_params property either returns
None (for effects which have no configurable parameters, or if no
parameters have been configured), or a tuple of numeric values up to
six elements long.

When set, the property changes the parameters of the current
effect as a sequence of numbers, or a single
number. Attempting to set parameters on an effect which does not
support parameters, or providing an incompatible set of parameters for
an effect will raise a PiCameraValueError exception.

The effects which have parameters, and what combinations those
parameters can take is as follows:

Effect

Parameters

Description

'solarize'

yuv,
x0, y1,
y2, y3

yuv controls whether data is
processed as RGB (0) or YUV(1). Input
values from 0 to x0 - 1 are remapped
linearly onto the range 0 to y0.
Values from x0 to 255 are remapped
linearly onto the range y1 to y2.

quadrant specifies which quadrant
of the U/V space to retain chroma
from: 0=green, 1=red/yellow, 2=blue,
3=purple. There is no default; this
effect does nothing until parameters
are set.

'colorbalance'

lens,
r, g, b,
u, v

lens specifies the lens shading
strength (0.0 to 256.0, where 0.0
indicates lens shading has no effect).
r, g, b are multipliers for their
respective color channels (0.0 to
256.0). u and v are offsets added
to the U/V plane (0 to 255).

lens,
r, g, b

Same as above but u are defaulted
to 0.

lens,
r, b

Same as above but g also defaults to
to 1.0.

'colorswap'

dir

If dir is 0, swap RGB to BGR. If
dir is 1, swap RGB to BRG.

'posterise'

steps

Control the quantization steps for the
image. Valid values are 2 to 32, and
the default is 4.

'blur'

size

Specifies the size of the kernel. Valid
values are 1 or 2.

'film'

strength,
u, v

strength specifies the strength of
effect. u and v are offsets added
to the U/V plane (0 to 255).

When queried, the iso property returns the ISO setting of the
camera, a value which represents the sensitivity of the camera to
light. Lower values (e.g. 100) imply less sensitivity than higher
values (e.g. 400 or 800). Lower sensitivities tend to produce less
‚Äúnoisy‚ÄĚ (smoother) images, but operate poorly in low light conditions.

When set, the property adjusts the sensitivity of the camera (by
adjusting the analog_gain and digital_gain). Valid
values are between 0 (auto) and 1600. The actual value used when iso is
explicitly set will be one of the following values (whichever is
closest): 100, 200, 320, 400, 500, 640, 800.

On the V2 camera module, ISO 100 attempts to produce overall gain of
~1.84, and ISO 800 attempts to produce overall gain of ~14.72 (the V2
camera module was calibrated against the ISO film speed standard).

The attribute can be adjusted while previews or recordings are in
progress. The default value is 0 which means automatically determine a
value according to image-taking conditions.

Note

Some users on the Pi camera forum have noted that higher ISO values
than 800 (specifically up to 1600) can be achieved in certain
conditions with exposure_mode set to 'sports' and
iso set to 0. It doesn‚Äôt appear to be possible to manually
request an ISO setting higher than 800, but the picamera library
will permit settings up to 1600 in case the underlying firmware
permits such settings in particular circumstances.

If a GPIO library is available (only RPi.GPIO is currently supported),
and if the python process has the necessary privileges (typically this
means running as root via sudo), this property can be used to set the
state of the camera‚Äôs LED as a boolean value (True is on, False
is off).

Note

This is a write-only property. While it can be used to control the
camera‚Äôs LED, you cannot query the state of the camera‚Äôs LED using
this property.

Note

At present, the camera‚Äôs LED cannot be controlled on the Pi 3
(the GPIOs used to control the camera LED were re-routed to GPIO
expander on the Pi 3).

Warning

There are circumstances in which the camera firmware may override
an existing LED setting. For example, in the case that the firmware
resets the camera (as can happen with a CSI-2 timeout), the LED may
also be reset. If you wish to guarantee that the LED remain off at
all times, you may prefer to use the disable_camera_led option
in config.txt (this has the added advantage that sudo privileges
and GPIO access are not required, at least for LED control).

When set, the property adjusts the camera‚Äôs metering mode. All modes
set up two regions: a center region, and an outer region. The major
difference between each mode is the size of the center region. The
'backlit' mode has the largest central region (30% of the width),
while 'spot' has the smallest (10% of the width).

The property can be set while recordings or previews are in progress.
The default value is 'average'. All possible values for the
attribute can be obtained from the PiCamera.METER_MODES attribute.

If no overlays are current active, overlays will return an
empty iterable. Otherwise, it will return an iterable of
PiRenderer instances which are currently acting as overlays.
Note that the preview renderer is an exception to this: it is not
included as an overlay despite being derived from PiRenderer.

If no preview is currently active, preview will return
None. Otherwise, it will return the instance of
PiRenderer which is currently connected to the camera‚Äôs
preview port for rendering what the camera sees. You can use the
attributes of the PiRenderer class to configure the appearance
of the preview. For example, to make the preview semi-transparent:

Retrieves or sets the resolution at which image captures, video
recordings, and previews will be captured.

When queried, the resolution property returns the resolution at
which the camera will operate as a tuple of (width,height)
measured in pixels. This is the resolution that the capture()
method will produce images at, and the resolution that
start_recording() will produce videos at.

When set, the property configures the camera so that the next call to
these methods will use the new resolution. The resolution can be
specified as a (width,height) tuple, as a string formatted
'WIDTHxHEIGHT', or as a string containing a commonly recognized
display resolution name (e.g. ‚ÄúVGA‚ÄĚ, ‚ÄúHD‚ÄĚ, ‚Äú1080p‚ÄĚ, etc). For
example, the following definitions are all equivalent:

The camera must not be closed, and no recording must be active when the
property is set.

Note

This attribute, in combination with framerate, determines
the mode that the camera operates in. The actual sensor framerate
and resolution used by the camera is influenced, but not directly
set, by this property. See sensor_mode for more
information.

The initial value of this property can be specified with the
resolution parameter in the PiCamera constructor, and will
default to the display‚Äôs resolution or 1280x720 if the display has
been disabled (with tvservice-o).

Changed in version 1.11: Resolution permitted to be set as a string. Preview resolution
added as separate property.

When queried, the saturation property returns the color
saturation of the camera as an integer between -100 and 100. When set,
the property adjusts the saturation of the camera. Saturation can be
adjusted while previews or recordings are in progress. The default
value is 0.

This is an advanced property which can be used to control the camera‚Äôs
sensor mode. By default, mode 0 is used which allows the camera to
automatically select an input mode based on the requested
resolution and framerate. Valid values are currently
between 0 and 7. The set of valid sensor modes (along with the
heuristic used to select one automatically) are detailed in the
Sensor Modes section of the documentation.

Note

At the time of writing, setting this property does nothing unless
the camera has been initialized with a sensor mode other than 0.
Furthermore, some mode transitions appear to require setting the
property twice (in a row). This appears to be a firmware
limitation.

The initial value of this property can be specified with the
sensor_mode parameter in the PiCamera constructor, and will
default to 0 if not specified.

When queried, the sharpness property returns the sharpness
level of the camera (a measure of the amount of post-processing to
reduce or increase image sharpness) as an integer between -100 and 100.
When set, the property adjusts the sharpness of the camera. Sharpness
can be adjusted while previews or recordings are in progress. The
default value is 0.

When queried, the shutter_speed property returns the shutter
speed of the camera in microseconds, or 0 which indicates that the
speed will be automatically determined by the auto-exposure algorithm.
Faster shutter times naturally require greater amounts of illumination
and vice versa.

When set, the property adjusts the shutter speed of the camera, which
most obviously affects the illumination of subsequently captured
images. Shutter speed can be adjusted while previews or recordings are
running. The default value is 0 (auto).

Note

You can query the exposure_speed attribute to determine the
actual shutter speed being used when this attribute is set to 0.
Please note that this capability requires an up to date firmware
(#692 or later).

Note

In later firmwares, this attribute is limited by the value of the
framerate attribute. For example, if framerate is set to
30fps, the shutter speed cannot be slower than 33,333¬Ķs (1/fps).

Retrieves or sets whether statistics will be calculated from still
frames or the prior preview frame.

When queried, the still_stats property returns a boolean value
indicating when scene statistics will be calculated for still captures
(that is, captures where the use_video_port parameter of
capture() is False). When this property is False (the
default), statistics will be calculated from the preceding preview
frame (this also applies when the preview is not visible). When True,
statistics will be calculated from the captured image itself.

When set, the propetry controls when scene statistics will be
calculated for still captures. The property can be set while recordings
or previews are in progress. The default value is False.

The advantages to calculating scene statistics from the captured image
are that time between startup and capture is reduced as only the AGC
(automatic gain control) has to converge. The downside is that
processing time for captures increases and that white balance and gain
won‚Äôt necessarily match the preview.

The camera‚Äôs timestamp is a 64-bit integer representing the number of
microseconds since the last system boot. When the camera‚Äôs
clock_mode is 'raw' the values returned by this attribute
are comparable to those from the frametimestamp attribute.

Retrieves or sets whether the camera‚Äôs output is vertically flipped.

When queried, the vflip property returns a boolean indicating
whether or not the camera‚Äôs output is vertically flipped. The property
can be set while recordings or previews are in progress. The default
value is False.

When queried, the zoom property returns a (x,y,w,h)
tuple of floating point values ranging from 0.0 to 1.0, indicating the
proportion of the image to include in the output (this is also known as
the ‚ÄúRegion of Interest‚ÄĚ or ROI). The default value is (0.0,0.0,1.0,1.0) which indicates that everything should be included. The
property can be set while recordings or previews are in progress.

This class is a namedtuple() derivative used to store
information about a video frame. It is recommended that you access the
information stored by this class by attribute name rather than position
(for example: frame.index rather than frame[0]).

Returns the zero-based number of the frame. This is a monotonic counter
that is simply incremented every time the camera starts outputting a
new frame. As a consequence, this attribute cannot be used to detect
dropped frames. Nor does it necessarily represent actual frames; it
will be incremented for SPS headers and motion data buffers too.

Returns the size in bytes of the current frame. If a frame is written
in multiple chunks, this value will increment while index
remains static. Query complete to determine whether the frame
has been completely output yet.

Returns the size in bytes of the entire video up to this frame. Note
that this is unlikely to match the size of the actual file/stream
written so far. This is because a stream may utilize buffering which
will cause the actual amount written (e.g. to disk) to lag behind the
value reported by this attribute.

Returns the size in bytes of the video recorded since the last call to
either start_recording() or
split_recording(). For the reasons explained above,
this may differ from the size of the actual file/stream written so far.

Returns the presentation timestamp (PTS) of the frame. This represents
the point in time that the Pi received the first line of the frame from
the camera.

The timestamp is measured in microseconds (millionths of a second).
When the camera‚Äôs clock mode is 'reset' (the default), the
timestamp is relative to the start of the video recording. When the
camera‚Äôs clock_mode is 'raw', it is relative to
the last system reboot. See timestamp for more
information.

Warning

Currently, the camera occasionally returns ‚Äútime unknown‚ÄĚ values in
this field which picamera represents as None. If you are
querying this property you will need to check the value is not
None before using it. This happens for SPS header ‚Äúframes‚ÄĚ,
for example.

This class is a namedtuple() derivative used to store
the low and high limits of a range of framerates. It is recommended that
you access the information stored by this class by attribute rather than
position (for example: camera.framerate_range.low rather than
camera.framerate_range[0]).

The picamera library defines a few custom stream implementations useful for
implementing certain common use cases (like security cameras which only record
video upon some external trigger like a motion sensor).

PiCameraCircularIO provides an in-memory stream based on a ring buffer. It
is a specialization of CircularIO which associates video frame
meta-data with the recorded stream, accessible from the frames
property.

Warning

The class makes a couple of assumptions which will cause the frame
meta-data tracking to break if they are not adhered to:

the stream is only ever appended to - no writes ever start from
the middle of the stream

the stream is never truncated (from the right; being ring buffer
based, left truncation will occur automatically); the exception
to this is the clear() method.

The camera parameter specifies the PiCamera instance that will
be recording video to the stream. If specified, the size parameter
determines the maximum size of the stream in bytes. If size is not
specified (or None), then seconds must be specified instead. This
provides the maximum length of the stream in seconds, assuming a data rate
in bits-per-second given by the bitrate parameter (which defaults to
17000000, or 17Mbps, which is also the default bitrate used for video
recording by PiCamera). You cannot specify both size and
seconds.

The splitter_port parameter specifies the port of the built-in splitter
that the video encoder will be attached to. This defaults to 1 and most
users will have no need to specify anything different. If you do specify
something else, ensure it is equal to the splitter_port parameter of the
corresponding call to start_recording(). For example:

As the camera records video to the stream, the class captures the
meta-data associated with each frame (in the form of a
PiVideoFrame tuple), discarding meta-data for frames which are
no longer fully stored within the underlying ring buffer. You can use
the frame meta-data to locate, for example, the first keyframe present
in the stream in order to determine an appropriate range to extract.

This method truncates the stream to empty, and clears the associated
frame meta-data too, ensuring that subsequent writes operate correctly
(see the warning in the PiCameraCircularIO class
documentation).

By default, this method copies all complete frames from the circular
stream to the filename or file-like object given by output.

If size is specified then the copy will be limited to the whole
number of frames that fit within the specified number of bytes. If
seconds if specified, then the copy will be limited to that number of
seconds worth of frames. Only one of size or seconds can be
specified. If neither is specified, all frames are copied.

If first_frame is specified, it defines the frame type of the first
frame to be copied. By default this is
sps_header as this must usually be the first
frame in an H264 stream. If first_frame is None, not such limit
will be applied.

Warning

Note that if a frame of the specified type (e.g. SPS header) cannot
be found within the specified number of seconds or bytes then this
method will simply copy nothing (but no error will be raised).

CircularIO provides an in-memory stream similar to the io.BytesIO
class. However, unlike io.BytesIO its underlying storage is a
ring buffer with a fixed maximum size. Once the maximum size is reached,
writing effectively loops round to the beginning to the ring and starts
overwriting the oldest content.

The size parameter specifies the maximum size of the stream in bytes. The
read(), tell(), and seek() methods all operate
equivalently to those in io.BytesIO whilst write() only
differs in the wrapping behaviour described above. A read1() method
is also provided for efficient reading of the underlying ring buffer in
write-sized chunks (or less).

A re-entrant threading lock guards all operations, and is accessible for
external use via the lock attribute.

The performance of the class is geared toward faster writing than reading
on the assumption that writing will be the common operation and reading the
rare operation (a reasonable assumption for the camera use-case, but not
necessarily for more general usage).

Read up to n bytes from the stream and return them. As a convenience,
if n is unspecified or -1, readall() is called. Fewer than n
bytes may be returned if there are fewer than n bytes from the
current stream position to the end of the stream.

If 0 bytes are returned, and n was not 0, this indicates end of the
stream.

Read up to n bytes from the stream using only a single call to the
underlying object.

In the case of CircularIO this roughly corresponds to
returning the content from the current position up to the end of the
write that added that content to the stream (assuming no subsequent
writes overwrote the content). read1() is particularly useful
for efficient copying of the stream‚Äôs content.

Resize the stream to the given size in bytes (or the current position
if size is not specified). This resizing can extend or reduce the
current stream size. In case of extension, the contents of the new file
area will be NUL (\x00) bytes. The new stream size is returned.

The current stream position isn‚Äôt changed unless the resizing is
expanding the stream, in which case it may be set to the maximum stream
size if the expansion causes the ring buffer to loop around.

This is used internally by picamera for capturing directly to an existing
object which supports the buffer protocol (like a numpy array). Because the
underlying storage is fixed in size, the stream also has a fixed size and
will raise an IOError exception if an attempt is made to write
beyond the end of the buffer (though seek beyond the end is supported).

Read up to n bytes from the buffer and return them. As a convenience,
if n is unspecified or -1, readall() is called. Fewer than n
bytes may be returned if there are fewer than n bytes from the
current buffer position to the end of the buffer.

If 0 bytes are returned, and n was not 0, this indicates end of the
buffer.

Write the given bytes or bytearray object, b, to the underlying
buffer and return the number of bytes written. If the underlying
buffer isn‚Äôt large enough to contain all the bytes of b, as many
bytes as possible will be written before raising IOError.

Renderers are used by the camera to provide preview and overlay functionality
on the Pi‚Äôs display. Users will rarely need to construct instances of these
classes directly (start_preview() and
add_overlay() are generally used instead) but may find the
attribute references for them useful.

The parent parameter specifies the PiCamera instance that has
constructed this renderer. The layer parameter specifies the layer that
the renderer will inhabit. Higher numbered layers obscure lower numbered
layers (unless they are partially transparent). The initial opacity of the
renderer is specified by the alpha parameter (which defaults to 255,
meaning completely opaque). The fullscreen parameter which defaults to
True indicates whether the renderer should occupy the entire display.
Finally, the window parameter (which only has meaning when fullscreen
is False) is a four-tuple of (x,y,width,height) which gives the
screen coordinates that the renderer should occupy when it isn‚Äôt
full-screen.

When queried, the alpha property returns a value between 0 and
255 indicating the opacity of the renderer, where 0 is completely
transparent and 255 is completely opaque. The default value is 255. The
property can be set while recordings or previews are in progress.

Note

If the renderer is being fed RGBA data (as in partially transparent
overlays), the alpha property will be ignored.

The crop property specifies the rectangular area that the
renderer will read from the source as a 4-tuple of (x,y,width,height). The special value (0,0,0,0) (which is also the
default) means to read entire area of the source. The property can be
set while recordings or previews are active.

For example, if the camera‚Äôs resolution is currently configured as
1280x720, setting this attribute to (160,160,640,400) will
crop the preview to the center 640x400 pixels of the input. Note that
this property does not affect the size of the output rectangle,
which is controlled with fullscreen and window.

Note

This property only affects the renderer; it has no bearing on image
captures or recordings (unlike the zoom property
of the PiCamera class).

The fullscreen property is a bool which controls whether the
renderer takes up the entire display or not. When set to False, the
window property can be used to control the precise size of the
renderer display. The property can be set while recordings or previews
are active.

Retrieves or sets whether the renderer‚Äôs output is horizontally
flipped.

When queried, the vflip property returns a boolean indicating
whether or not the renderer‚Äôs output is horizontally flipped. The
property can be set while recordings or previews are in progress. The
default is False.

Note

This property only affects the renderer; it has no bearing on image
captures or recordings (unlike the hflip property
of the PiCamera class).

The layer property is an integer which controls the layer that
the renderer occupies. Higher valued layers obscure lower valued layers
(with 0 being the ‚Äúbottom‚ÄĚ layer). The default value is 2. The property
can be set while recordings or previews are in progress.

Retrieves or sets whether the renderer‚Äôs output is vertically flipped.

When queried, the vflip property returns a boolean indicating
whether or not the renderer‚Äôs output is vertically flipped. The
property can be set while recordings or previews are in progress. The
default is False.

Note

This property only affects the renderer; it has no bearing on image
captures or recordings (unlike the vflip property
of the PiCamera class).

When the fullscreen property is set to False, the
window property specifies the size and position of the renderer
on the display. The property is a 4-tuple consisting of (x,y,width,height). The property can be set while recordings or previews are
active.

The optional resolution parameter specifies the size of the source as a
(width,height) tuple. If this is omitted or None then the
resolution is assumed to be the same as the parent camera‚Äôs current
resolution. The optional format parameter specifies the
encoding of the source. This can be one of the unencoded formats:
'yuv', 'rgb', 'rgba', 'bgr', or 'bgra'. If omitted or
None, format will be guessed based on the size of source (assuming
3 bytes for RGB, and 4 bytes for RGBA).

The length of source must take into account that widths are rounded up to
the nearest multiple of 32, and heights to the nearest multiple of 16. For
example, if resolution is (1280,720), and format is 'rgb' then
source must be a buffer with length 1280 x 720 x 3 bytes, or 2,764,800
bytes (because 1280 is a multiple of 32, and 720 is a multiple of 16 no
extra rounding is required). However, if resolution is (97,57), and
format is 'rgb' then source must be a buffer with length 128 x 64 x
3 bytes, or 24,576 bytes (pixels beyond column 97 and row 57 in the source
will be ignored).

The layer, alpha, fullscreen, and window parameters are the same
as in PiRenderer.

The new source buffer must have the same size as the original buffer
used to create the overlay. There is currently no method for changing
the size of an existing overlay (remove and recreate the overlay if you
require this).

Note

If you repeatedly update an overlay renderer, you must make sure
that you do so at a rate equal to, or slower than, the camera‚Äôs
framerate. Going faster will rapidly starve the renderer‚Äôs pool of
buffers leading to a runtime error.

By default, the preview‚Äôs resolution matches the camera‚Äôs resolution.
However, particularly high resolutions (such as the maximum resolution
of the V2 camera module) can cause issues. In this case, you may wish
to set a lower resolution for the preview that the camera‚Äôs resolution.

When queried, the resolution property returns None if the
preview‚Äôs resolution is derived from the camera‚Äôs. In this case, changing
the camera‚Äôs resolution will also cause the preview‚Äôs resolution to
change. Otherwise, it returns the current preview resolution as a
tuple.

Note

The preview resolution cannot be greater than the camera‚Äôs
resolution (in either access). If you set a preview resolution,
then change the camera‚Äôs resolution below the preview‚Äôs resolution,
this property will silently revert to None, meaning the
preview‚Äôs resolution will follow the camera‚Äôs resolution.

When set, the property reconfigures the preview renderer with the new
resolution. As a special case, setting the property to None will
cause the preview to follow the camera‚Äôs resolution once more. The
property can be set while recordings are in progress. The default is
None.

Note

This property only affects the renderer; it has no bearing on image
captures or recordings (unlike the resolution
property of the PiCamera class).

The parent parameter specifies the PiCamera instance which
constructed this MMALNullSink. The source parameter
specifies the MMALPort which the null-sink should connect
to its input.

The null-sink can act as a drop-in replacement for PiRenderer in
most cases, but obviously doesn‚Äôt implement attributes like alpha,
layer, etc. as it simply dumps any incoming frames. This is also the
reason that this class doesn‚Äôt derive from PiRenderer like all
other classes in this module.

Encoders are typically used by the camera to compress captured images or video
frames for output to disk. However, picamera also has classes representing
‚Äúunencoded‚ÄĚ output (raw RGB, etc). Most users will have no direct need to use
these classes directly, but advanced users may find them useful as base classes
for Custom encoders.

Note

It is strongly recommended that you familiarize yourself with the
mmalobj layer before attempting to understand the encoder
classes as they deal with several concepts native to that layer.

The parent parameter specifies the PiCamera instance that has
constructed the encoder. The camera_port parameter provides the MMAL
camera port that the encoder should enable for capture (this will be the
still or video port of the camera component). The input_port parameter
specifies the MMAL port that the encoder should connect to its input.
Sometimes this will be the same as the camera port, but if other components
are present in the pipeline (e.g. a splitter), it may be different.

The format parameter specifies the format that the encoder should
produce in its output. This is specified as a string and will be one of
the following for image encoders:

'jpeg'

'png'

'gif'

'bmp'

'yuv'

'rgb'

'rgba'

'bgr'

'bgra'

And one of the following for video encoders:

'h264'

'mjpeg'

The resize parameter is either None (indicating no resizing
should take place), or a (width,height) tuple specifying the
resolution that the output of the encoder should be resized to.

Finally, the options parameter specifies additional keyword arguments
that can be used to configure the encoder (e.g. bitrate for videos, or
quality for images).

The MMALVideoPort that needs to be activated and
deactivated in order to start/stop capture. This is not necessarily the
port that the encoder component‚Äôs input port is connected to (for
example, in the case of video-port based captures, this will be the
camera video port behind the splitter).

The MMALVideoPort that produces the encoder‚Äôs output.
In the case no encoder component is created, this should be the
camera/component output port responsible for producing data. In other
words, this attribute must be set on initialization.

A mapping of key to (output,opened) tuples where output
is a file-like object, and opened is a bool indicating whether or
not we opened the output object (and thus whether we are responsible
for eventually closing it).

When the encoder is active, this method is periodically called in a
background thread. The port parameter specifies the MMALPort
providing the output (typically this is the encoder‚Äôs output port, but
in the case of unencoded captures may simply be a camera port), while
the buf parameter is an MMALBuffer which can be
used to obtain the data to write, along with meta-data about the
current frame.

This method must set event when the encoder has finished (and
should set exception if an exception occurred during encoding).

Developers wishing to write a custom encoder class may find it simpler
to override the _callback_write() method, rather than deal with
these complexities.

This method is called by _callback() to handle writing to an
object in outputs identified by key. The buf parameter is
an MMALBuffer which can be used to obtain the data.
The method is expected to return a boolean to indicate whether output
is complete (True) or whether more data is expected (False).

The default implementation simply writes the contents of the buffer to
the output identified by key, and returns True if the buffer
flags indicate end of stream. Image encoders will typically override
the return value to indicate True on end of frame (as they only
wish to output a single image). Video encoders will typically override
this method to determine where key-frames and SPS headers occur.

This method only constructs the encoder; it does not connect it to the
input port. The method sets the encoder attribute to the
constructed encoder component, and the output_port attribute to
the encoder‚Äôs output port (or the previously constructed resizer‚Äôs
output port if one has been requested). Descendent classes extend this
method to finalize encoder configuration.

Note

It should be noted that this method is called with the
initializer‚Äôs option keyword arguments. This base
implementation expects no additional arguments, but descendent
classes extend the parameter list to include options relevant to
them.

This is called when the initializer‚Äôs resize parameter is something
other than None. The width and height parameters are passed to
the constructed resizer. Note that this method only constructs the
resizer - it does not connect it to the encoder. The method sets the
resizer attribute to the constructed resizer component.

If output is a string, this method opens it as a filename and keeps
track of the fact that the encoder was the one to open it (which
implies that _close_output() should eventually close it).
Otherwise, if output has a write method it is assumed to be a
file-like object and it is used verbatim. If output is neither a
string, nor an object with a write method it is assumed to be a
writeable object supporting the buffer protocol (this is wrapped in
a BufferIO stream to simplify writing).

The opened output is added to the outputs dictionary with the
specified key.

This method is called by the camera prior to destroying the encoder (or
more precisely, letting it go out of scope to permit the garbage
collector to destroy it at some future time). The method destroys all
components that the various create methods constructed and resets their
attributes.

This method is called by the camera to start the encoder capturing
data from the camera to the specified output. The output parameter
is either a filename, or a file-like object (for image and video
encoders), or an iterable of filenames or file-like objects (for
multi-image encoders).

This method is called by the camera to terminate the execution of the
encoder. Typically, this is used with video to stop the recording, but
can potentially be called in the middle of image capture to terminate
the capture.

This method is called by the owning camera object to block execution
until the encoder has completed its task. If the timeout parameter
is None, the method will block indefinitely. Otherwise, the timeout
parameter specifies the (potentially fractional) number of seconds
to block for. If the encoder finishes successfully within the timeout,
the method returns True. Otherwise, it returns False.

This method is called by the camera to terminate the execution of the
encoder. Typically, this is used with video to stop the recording, but
can potentially be called in the middle of image capture to terminate
the capture.

This mixin class overrides the initializer of PiEncoder, along
with _create_resizer() and _create_encoder() to configure the
pipeline for unencoded output. Specifically, it disables the construction
of an encoder, and sets the output port to the input port passed to the
initializer, unless resizing is required (either for actual resizing, or
for format conversion) in which case the resizer‚Äôs output is used.

This method is called by _callback() to handle writing to an
object in outputs identified by key. The buf parameter is
an MMALBuffer which can be used to obtain the data.
The method is expected to return a boolean to indicate whether output
is complete (True) or whether more data is expected (False).

The default implementation simply writes the contents of the buffer to
the output identified by key, and returns True if the buffer
flags indicate end of stream. Image encoders will typically override
the return value to indicate True on end of frame (as they only
wish to output a single image). Video encoders will typically override
this method to determine where key-frames and SPS headers occur.

This class extends PiImageEncoder to handle an iterable of outputs
instead of a single output. The _callback_write() method
is extended to terminate capture when the iterable is exhausted, while
PiEncoder._open_output() is overridden to begin iteration and rely
on the new _next_output() method to advance output to the next item
in the iterable.

This method is called by _callback() to handle writing to an
object in outputs identified by key. The buf parameter is
an MMALBuffer which can be used to obtain the data.
The method is expected to return a boolean to indicate whether output
is complete (True) or whether more data is expected (False).

The default implementation simply writes the contents of the buffer to
the output identified by key, and returns True if the buffer
flags indicate end of stream. Image encoders will typically override
the return value to indicate True on end of frame (as they only
wish to output a single image). Video encoders will typically override
this method to determine where key-frames and SPS headers occur.

If output is a string, this method opens it as a filename and keeps
track of the fact that the encoder was the one to open it (which
implies that _close_output() should eventually close it).
Otherwise, if output has a write method it is assumed to be a
file-like object and it is used verbatim. If output is neither a
string, nor an object with a write method it is assumed to be a
writeable object supporting the buffer protocol (this is wrapped in
a BufferIO stream to simplify writing).

The opened output is added to the outputs dictionary with the
specified key.

This method is called by the camera to start the encoder capturing
data from the camera to the specified output. The output parameter
is either a filename, or a file-like object (for image and video
encoders), or an iterable of filenames or file-like objects (for
multi-image encoders).

This method is called by the camera to start the encoder capturing
data from the camera to the specified output. The output parameter
is either a filename, or a file-like object (for image and video
encoders), or an iterable of filenames or file-like objects (for
multi-image encoders).

All exceptions defined by picamera are listed in this section. All exception
classes utilize multiple inheritance in order to make testing for exception
types more intuitive. For example, PiCameraValueError derives from both
PiCameraError and ValueError. Hence it will be caught by blocks
intended to catch any error specific to the picamera library:

try:camera.brightness=int(some_user_value)exceptPiCameraError:print('Something went wrong with the camera')

This exception is intended for the common use-case of attempting to get
or send a buffer just when a component is shutting down (e.g. at script
teardown) and simplifies the trivial response (ignore the error and shut
down quietly). For example:

Checks the return status of an mmal call and raises an exception on
failure.

The status parameter is the result of an MMAL call. If status is
anything other than MMAL_SUCCESS, a PiCameraMMALError exception is
raised. The optional prefix parameter specifies a prefix message to place
at the start of the exception‚Äôs message to provide some context.

The picamera library includes a comprehensive Color class which
is capable of converting between numerous color representations and calculating
color differences. Various ancillary classes can be used to manipulate aspects
of a color.

The Color class is a tuple which represents a color as red, green, and
blue components.

The class has a flexible constructor which allows you to create an instance
from a variety of color systems including RGB, Y‚ÄôUV, Y‚ÄôIQ, HLS,
and HSV. There are also explicit constructors for each of these systems
to allow you to force the use of a system in your code. For example, an
instance of Color can be constructed in any of the following
ways:

If the constructor parameters do not conform to any of the variants in the
table above, a ValueError will be thrown.

Internally, the color is always represented as 3 float values
corresponding to the red, green, and blue components of the color. These
values take a value from 0.0 to 1.0 (least to full intensity). The class
provides several attributes which can be used to convert one color system
into another:

As Color derives from tuple, instances are immutable. While this
provides the advantage that they can be used as keys in a dict, it does
mean that colors themselves cannot be directly manipulated (e.g. by
reducing the red component).

However, several auxilliary classes in the module provide the ability to
perform simple transformations of colors via operators which produce a new
Color instance. For example:

From the last example above one can see that even attributes not directly
stored by the color (such as lightness) can be manipulated in this fashion.
In this case a Color instance is constructed from HLS (hue,
lightness, saturation) values with a lightness of 0.5. This is multiplied
by a Lightness instance with a value of 0.8 which constructs a new
Color with the same hue and saturation, but a lightness of 0.5 *
0.8 = 0.4.

If an instance is converted to a string (with str()) it will return a
string containing the 7-character HTML code for the color (e.g. ‚Äú#ff0000‚ÄĚ
for red). As can be seen in the examples above, a similar representation is
returned for repr().

Determines the difference between this color and other using the
specified method. The method is specified as a string, and the
following methods are valid:

‚Äėeuclid‚Äô - This is the default method. Calculate the Euclidian
distance. This is by far the fastest method, but also the least
accurate in terms of human perception.

‚Äėcie1976‚Äô - Use the CIE 1976 formula for calculating the
difference between two colors in CIE Lab space.

‚Äėcie1994g‚Äô - Use the CIE 1994 formula with the ‚Äúgraphic arts‚ÄĚ bias
for calculating the difference.

‚Äėcie1994t‚Äô - Use the CIE 1994 forumula with the ‚Äútextiles‚ÄĚ bias
for calculating the difference.

‚Äėcie2000‚Äô - Use the CIEDE 2000 formula for calculating the
difference.

Note that the Euclidian distance will be significantly different to the
other calculations; effectively this just measures the distance between
the two colors by treating them as coordinates in a three dimensional
Euclidian space. All other methods are means of calculating a Delta
E value in which 2.3 is considered a just-noticeable difference
(JND).

Warning

This implementation has yet to receive any significant testing
(constructor methods for CIELab need to be added before this can be
done).

Construct a Color from a 4 or 7 character CSS-like
representation (e.g. ‚Äú#f00‚ÄĚ or ‚Äú#ff0000‚ÄĚ for red), or from one of the
named colors (e.g. ‚Äúgreen‚ÄĚ or ‚Äúwheat‚ÄĚ) from the CSS standard. Any
other string format will result in a ValueError.

Construct a Color from three Y‚ÄôUV byte values between 0 and
255. The U and V values are biased by 128 to prevent negative values as
is typical in video applications. The Y value is biased by 16 for the
same purpose.

Represents the red component of a Color for use in
transformations. Instances of this class can be constructed directly with a
float value, or by querying the Color.red attribute. Addition,
subtraction, and multiplication are supported with Color
instances. For example:

Represents the green component of a Color for use in
transformations. Instances of this class can be constructed directly with
a float value, or by querying the Color.green attribute. Addition,
subtraction, and multiplication are supported with Color
instances. For example:

Represents the blue component of a Color for use in
transformations. Instances of this class can be constructed directly with
a float value, or by querying the Color.blue attribute. Addition,
subtraction, and multiplication are supported with Color
instances. For example:

Represents the hue of a Color for use in transformations.
Instances of this class can be constructed directly with a float value in
the range [0.0, 1.0) representing an angle around the HSL hue wheel. As
this is a circular mapping, 0.0 and 1.0 effectively mean the same thing,
i.e. out of range values will be normalized into the range [0.0, 1.0).

The class can also be constructed with the keyword arguments deg or
rad if you wish to specify the hue value in degrees or radians instead,
respectively. Instances can also be constructed by querying the
Color.hue attribute.

Addition, subtraction, and multiplication are supported with Color
instances. For example:

Note that whilst multiplication by a Hue doesn‚Äôt make much sense,
it is still supported. However, the circular nature of a hue value can lead
to suprising effects. In particular, since 1.0 is equivalent to 0.0 the
following may be observed:

Represents the saturation of a Color for use in transformations.
Instances of this class can be constructed directly with a float value, or
by querying the Color.saturation attribute. Addition, subtraction,
and multiplication are supported with Color instances. For
example:

Represents the lightness of a Color for use in transformations.
Instances of this class can be constructed directly with a float value, or
by querying the Color.lightness attribute. Addition, subtraction,
and multiplication are supported with Color instances. For
example:

The picamera library provides a set of classes designed to aid in construction
of n-dimensional numpy arrays from camera output. In order to avoid adding a
hard dependency on numpy to picamera, this module (picamera.array) is
not automatically imported by the main picamera package and must be explicitly
imported, e.g.:

After flush() is called, this attribute contains the
frame‚Äôs data as a multi-dimensional numpy array. This is typically
organized with the dimensions (rows,columns,plane). Hence, an
RGB image with dimensions x and y would produce an array with shape
(y,x,3).

Resize the stream to the given size in bytes (or the current position
if size is not specified). This resizing can extend or reduce the
current file size. The new file size is returned.

In prior versions of picamera, truncation also changed the position of
the stream (because prior versions of these stream classes were
non-seekable). This functionality is now deprecated; scripts should
use seek() and truncate() as one would with
regular BytesIO instances.

This custom output class can be used to easily obtain a 3-dimensional numpy
array, organized (rows, columns, colors), from an unencoded RGB capture.
The array is accessed via the array attribute. For
example:

If you are using the GPU resizer when capturing (with the resize
parameter of the various capture() methods), specify the
resized resolution as the optional size parameter when constructing the
array output:

This custom output class can be used to easily obtain a 3-dimensional numpy
array, organized (rows, columns, channel), from an unencoded YUV capture.
The array is accessed via the array attribute. For
example:

If you are using the GPU resizer when capturing (with the resize
parameter of the various capture() methods),
specify the resized resolution as the optional size parameter when
constructing the array output:

This custom output class is intended to be used with the
capture() method, with the bayer parameter set
to True, to include raw Bayer data in the JPEG output. The class
strips out the raw data, and constructs a numpy array from it. The
resulting data is accessed via the array attribute:

The output_dims parameter specifies whether the resulting array is
three-dimensional (the default, or when output_dims is 3), or
two-dimensional (when output_dims is 2). The three-dimensional data is
already separated into the three color planes, whilst the two-dimensional
variant is not (in which case you need to know the Bayer ordering to
accurately deal with the results).

Note

Bayer data is usually full resolution, so the resulting array usually
has the shape (1944, 2592, 3) with the V1 module, or (2464, 3280, 3)
with the V2 module (if two-dimensional output is requested the
3-layered color dimension is omitted). If the camera‚Äôs
sensor_mode has been forced to something
other than 0, then the output will be the native size for the requested
sensor mode.

This also implies that the optional size parameter (for specifying a
resizer resolution) is not available with this array class.

By default, de-mosaicing is not performed; if the resulting array is
viewed it will therefore appear dark and too green (due to the green bias
in the Bayer pattern). A trivial weighted-average demosaicing algorithm
is provided in the demosaic() method:

Viewing the result of the de-mosaiced data will look more normal but still
considerably worse quality than the regular camera output (as none of the
other usual post-processing steps like auto-exposure, white-balance,
vignette compensation, and smoothing have been performed).

Changed in version 1.13: This class now supports the V2 module properly, and handles flipped
images, and forced sensor modes correctly.

Perform a rudimentary de-mosaic of self.array, returning the
result as a new array. The result of the demosaic is always three
dimensional, with the last dimension being the color planes (see
output_dims parameter on the constructor).

Produces a 3-dimensional array of motion vectors from the H.264 encoder.

This custom output class is intended to be used with the motion_output
parameter of the start_recording() method. Once
recording has finished, the class generates a 3-dimensional numpy array
organized as (frames, rows, columns) where rows and columns are the
number of rows and columns of macro-blocks (16x16 pixel blocks) in the
original frames. There is always one extra column of macro-blocks present
in motion vector data.

The data-type of the array is an (x, y, sad)
structure where x and y are signed 1-byte values, and sad is an
unsigned 2-byte value representing the sum of absolute differences of
the block. For example:

This custom output class is intended to be used with the
start_recording() method when it is called with
format set to 'rgb' or 'bgr'. While recording is in progress, the
write() method converts incoming frame data into a
numpy array and calls the stub analyze() method
with the resulting array (this deliberately raises
NotImplementedError in this class; you must override it in your
descendent class).

Note

If your overridden analyze() method runs slower
than the required framerate (e.g. 33.333ms when framerate is 30fps)
then the camera‚Äôs effective framerate will be reduced. Furthermore,
this doesn‚Äôt take into account the overhead of picamera itself so in
practice your method needs to be a bit faster still.

The array passed to analyze() is organized as
(rows, columns, channel) where the channels 0, 1, and 2 are R, G, and B
respectively (or B, G, R if format is 'bgr').

This custom output class is intended to be used with the
start_recording() method when it is called with
format set to 'yuv'. While recording is in progress, the
write() method converts incoming frame data into a
numpy array and calls the stub analyze() method
with the resulting array (this deliberately raises
NotImplementedError in this class; you must override it in your
descendent class).

Note

If your overridden analyze() method runs slower
than the required framerate (e.g. 33.333ms when framerate is 30fps)
then the camera‚Äôs effective framerate will be reduced. Furthermore,
this doesn‚Äôt take into account the overhead of picamera itself so in
practice your method needs to be a bit faster still.

The array passed to analyze() is organized as
(rows, columns, channel) where the channel 0 is Y (luminance), while 1 and
2 are U and V (chrominance) respectively. The chrominance values normally
have quarter resolution of the luminance values but this class makes all
channels equal resolution for ease of use.

This custom output class is intended to be used with the motion_output
parameter of the start_recording() method. While
recording is in progress, the write method converts incoming motion data
into numpy arrays and calls the stub analyze()
method with the resulting array (which deliberately raises
NotImplementedError in this class).

Note

If your overridden analyze() method runs slower
than the required framerate (e.g. 33.333ms when framerate is 30fps)
then the camera‚Äôs effective framerate will be reduced. Furthermore,
this doesn‚Äôt take into account the overhead of picamera itself so in
practice your method needs to be a bit faster still.

The array passed to analyze() is organized as
(rows, columns) where rows and columns are the number of rows and
columns of macro-blocks (16x16 pixel blocks) in the original frames.
There is always one extra column of macro-blocks present in motion vector
data.

The data-type of the array is an (x, y, sad) structure where x and
y are signed 1-byte values, and sad is an unsigned 2-byte value
representing the sum of absolute differences of the block.

An example of a crude motion detector is given below:

importnumpyasnpimportpicameraimportpicamera.arrayclassDetectMotion(picamera.array.PiMotionAnalysis):defanalyze(self,a):a=np.sqrt(np.square(a['x'].astype(np.float))+np.square(a['y'].astype(np.float))).clip(0,255).astype(np.uint8)# If there're more than 10 vectors with a magnitude greater# than 60, then say we've detected motionif(a>60).sum()>10:print('Motion detected!')withpicamera.PiCamera()ascamera:withDetectMotion(camera)asoutput:camera.resolution=(640,480)camera.start_recording('/dev/null',format='h264',motion_output=output)camera.wait_recording(30)camera.stop_recording()

You can use the optional size parameter to specify the output resolution
of the GPU resizer, if you are using the resize parameter of
start_recording().

A derivative of MMALPythonComponent which eases
the construction of custom MMAL transforms by representing buffer data as
numpy arrays. The formats parameter specifies the accepted input
formats as a sequence of strings (default: ‚Äėrgb‚Äô, ‚Äėbgr‚Äô, ‚Äėrgba‚Äô, ‚Äėbgra‚Äô).

Override the transform() method to modify buffers sent to the
component, then place it in your MMAL pipeline as you would a normal
encoder.

This method will be called for every frame passing through the
transform. The source and target parameters represent buffers from
the input and output ports of the transform respectively. They will be
derivatives of MMALBuffer which return a
3-dimensional numpy array when used as context managers. For example:

deftransform(self,source,target):withsourceassource_array,targetastarget_array:# Copy the source array data to the targettarget_array[...]=source_array# Draw a box around the edgestarget_array[0,:,:]=0xfftarget_array[-1,:,:]=0xfftarget_array[:,0,:]=0xfftarget_array[:,-1,:]=0xffreturnFalse

The target buffer‚Äôs meta-data starts out as a copy of the source
buffer‚Äôs meta-data, but the target buffer‚Äôs data starts out
uninitialized.

This module provides an object-oriented interface to libmmal which is the
library underlying picamera, raspistill, and raspivid. It is provided
to ease the usage of libmmal to Python coders unfamiliar with C and also
works around some of the idiosyncrasies in libmmal.

Warning

This part of the API is still experimental and subject to change in future
versions. Backwards compatibility is not (yet) guaranteed.

A port (MMALControlPort and derivatives) is either a control port,
an input port or an output port (there are also clock ports but you generally
don‚Äôt need to deal with these as MMAL sets them up automatically):

Control ports are used to accept and receive commands, configuration
parameters, and error messages. All MMAL components have a control port,
but in picamera they‚Äôre only used for component configuration.

Input and output ports can be audio, video or sub-picture (subtitle) ports,
but picamera only deals with video ports.

Ports have a format which (in the case of video ports)
dictates the format of image/frame accepted or generated by the port (YUV,
RGB, JPEG, H.264, etc.)

Video ports have a framerate which specifies the
number of images expected to be received or sent per second.

Video ports also have a framesize which specifies
the resolution of images/frames accepted or generated by the port.

Finally, all ports (control, input and output) have
params which affect their operation.

An output port can have a MMALConnection to an input port.
Connections ensure the two ports use compatible formats, and handle
transferring data from output ports to input ports in an orderly fashion. A
port cannot have more than one connection from/to it.

Buffers belong to a port and can‚Äôt be passed arbitrarily between ports.

The size of a buffer is dictated by the format and frame-size of the port
that owns the buffer. The memory allocation of a buffer (readable from
size) cannot be altered once the port is enabled, but
the buffer can contain any amount of data up its allocation size. The
actual length of data in a buffer is stored in length.

Likewise, the number of buffers belonging to a port is fixed and cannot be
altered without disabling the port, reconfiguring it and re-enabling it.
The more buffers a port has, the less likely it is that the pipeline will
have to drop frames because a component has overrun, but the more GPU
memory is required.

Buffers also have flags which specify information about
the data they contain (e.g. start of frame, end of frame, key frame, etc.)

When a connection exists between two ports, the connection continually
requests a buffer from the output port, requests another buffer from the
input port, copies the output buffer‚Äôs data to the input buffer‚Äôs data,
then returns the buffers to their respective ports (this is a
simplification; various tricks are pulled under the covers to minimize the
amount of data copying that actually occurs, but as a mental model of
what‚Äôs going on it‚Äôs reasonable).

Components take buffers from their input port(s), process them, and write
the result into a buffer from the output port(s).

Now we‚Äôve got a mental model of what an MMAL pipeline consists of, let‚Äôs build
one. For the rest of the tour I strongly recommend using a Pi with a screen (so
you can see preview output) but controlling it via an SSH session (so the
preview doesn‚Äôt cover your command line). Follow along, typing the examples
into your remote Python session. And feel free to deviate from the examples if
you‚Äôre curious about things!

The fact the camera has three outputs should come as little surprise to those
who have read the Camera Hardware chapter (if you haven‚Äôt already, you
might want to skim it now). Let‚Äôs examine the first output port of the camera
and the input port of the renderer:

Now we‚Äôll try connecting the renderer‚Äôs input to the camera‚Äôs output. Don‚Äôt
worry about the fact that the port configurations are different. One of the
nice things about MMAL (and the mmalobj layer) is that connections try very
hard to auto-configure things so that they ‚Äújust work‚ÄĚ. Usually,
auto-configuration is based upon the output port being connected so it‚Äôs
important to get that configuration right, but you don‚Äôt generally need to
worry about the input port.

The renderer is what mmalobj terms a ‚Äúdownstream component‚ÄĚ. This is a
component with a single input that typically sits downstream from some feeder
component (like a camera). All such components have the
connect() method which can be used to connect the
sole input to a specified output:

Note that we‚Äôve been quite lazy in the snippet above by simply calling
connect() with the camera component. In this case, a
connection will be attempted between the first input port of the owner
(preview) and the first unconnected output of the parameter (camera).
However, this is not always what‚Äôs wanted so you can specify the exact ports
you wish to connect. In this case the example was equivalent to calling:

Note that the connection has implicitly reconfigured the camera‚Äôs output port
to use the OPAQUE (‚ÄúOPQV‚ÄĚ) format. This is a special format used internally by
the camera firmware which avoids passing complete frame data around, instead
passing pointers to frame data around (this explains the tiny buffer size of
128 bytes as very little data is actually being shuttled between the
components). Further, note that the connection has automatically copied the
port format, frame size and frame-rate to the preview‚Äôs input port.

At this point it is worth exploring the differences between the camera‚Äôs
three output ports:

Output 0 is the ‚Äúpreview‚ÄĚ output. On this port, the OPAQUE format contains a
pointer to a complete frame of data.

Output 1 is the ‚Äúvideo recording‚ÄĚ output. On this port, the OPAQUE format
contains a pointer to two complete frames of data. The dual-frame format
enables the H.264 video encoder to calculate motion estimation without the
encoder having to keep copies of prior frames itself (it can do this when
something other than OPAQUE format is used, but dual-image OPAQUE is much
more efficient).

Output 2 is the ‚Äústill image‚ÄĚ output. On this port, the OPAQUE format
contains a pointer to a strip of an image. The ‚Äústrips‚ÄĚ format is used by the
JPEG encoder (not to be confused with the MJPEG encoder) to deal with high
resolution images efficiently.

Generally, you don‚Äôt need to worry about these differences. The mmalobj
layer knows about them and negotiates the most efficient format it can for
connections. However, they‚Äôre worth bearing in mind if you‚Äôre aiming to get the
most out of the firmware or if you‚Äôre confused about why a particular format
has been selected for a connection.