Capture an image - Raspberry Pi
In this part of the lesson, you will add a camera sensor to your Raspberry Pi, and read images from it.
Hardware
The Raspberry Pi needs a camera.
The camera you'll use is a Raspberry Pi Camera Module. This camera is designed to work with the Raspberry Pi and connects via a dedicated connector on the Pi.
💁 This camera uses the Camera Serial Interface, a protocol from the Mobile Industry Processor Interface Alliance, known as MIPI-CSI. This is a dedicated protocol for sending images
Connect the camera
The camera can be connected to the Raspberry Pi using a ribbon cable.
Task - connect the camera
-
Power off the Pi.
-
Connect the ribbon cable that comes with the camera to the camera. To do this, pull gently on the black plastic clip in the holder so that it comes out a little bit, then slide the cable into the socket, with the blue side facing away from the lens, the metal pin strips facing towards the lens. Once it is all the way in, push the black plastic clip back into place.
You can find an animation showing how to open the clip and insert the cable on the Raspberry Pi Getting Started with the Camera module documentation.
-
Remove the Grove Base Hat from the Pi.
-
Pass the ribbon cable through the camera slot in the Grove Base Hat. Make sure the blue side of the cable faces towards the analog ports labelled A0, A1 etc.
-
Inset the ribbon cable into the camera port on the Pi. Once again, pull the black plastic clip up, insert the cable, then push the clip back in. The blue side of the cable should face the USB and ethernet ports.
-
Refit the Grove Base Hat
Program the camera
The Raspberry Pi can now be programmed to use the camera using the PiCamera Python library.
Task - enable legacy camera mode
Unfortunately with the release of Raspberry Pi OS Bullseye, the camera software that came with the OS changed, meaning by default PiCamera no longer works. There is a replacement in the works, called PiCamera2, but this is not ready to be used yet.
For now, you can set your Pi into legacy camera mode to allow PiCamera to work. The camera socket is also disabled by default, but turning on the legacy camera software automatically enables the socket.
-
Power up the Pi and wait for it to boot
-
Launch VS Code, either directly on the Pi, or connect via the Remote SSH extension.
-
Run the following commands from your terminal:
sudo raspi-config nonint do_legacy 0
sudo rebootThis will toggle a setting to enable the legacy camera software, then reboot the Pi to make that setting take effect.
-
Wait for the Pi to reboot, then re-launch VS Code.
Task - program the camera
Program the device.
-
From the terminal, create a new folder in the
pi
users home directory calledfruit-quality-detector
. Create a file in this folder calledapp.py
. -
Open this folder in VS Code
-
To interact with the camera, you can use the PiCamera Python library. Install the Pip package for this with the following command:
pip3 install picamera
-
Add the following code to your
app.py
file:import io
import time
from picamera import PiCameraThis code imports some libraries needed, including the
PiCamera
library. -
Add the following code below this to initialize the camera:
camera = PiCamera()
camera.resolution = (640, 480)
camera.rotation = 0
time.sleep(2)This code creates a PiCamera object, sets the resolution to 640x480. Although higher resolutions are supported (up to 3280x2464), the image classifier works on much smaller images (227x227) so there is no need to capture and send larger images.
The
camera.rotation = 0
line sets the rotation of the image. The ribbon cable comes into the bottom of the camera, but if your camera was rotated to allow it to point easier at the item you want to classify, then you can change this line to the number of degrees of rotation.For example, if you suspend the ribbon cable over something so that it is at the top of the camera, then set the rotation to be 180:
camera.rotation = 180
The camera takes a few seconds to start up, hence the
time.sleep(2)
-
Add the following code below this to capture the image as binary data:
image = io.BytesIO()
camera.capture(image, 'jpeg')
image.seek(0)This codes creates a
BytesIO
object to store binary data. The image is read from the camera as a JPEG file and stored in this object. This object has a position indicator to know where it is in the data so that more data can be written to the end if needed, so theimage.seek(0)
line moves this position back to the start so that all the data can be read later. -
Below this, add the following to save the image to a file:
with open('image.jpg', 'wb') as image_file:
image_file.write(image.read())This code opens a file called
image.jpg
for writing, then reads all the data from theBytesIO
object and writes that to the file.💁 You can capture the image directly to a file instead of a
BytesIO
object by passing the file name to thecamera.capture
call. The reason for using theBytesIO
object is so that later in this lesson you can send the image to your image classifier. -
Point the camera at something and run this code.
-
An image will be captured and saved as
image.jpg
in the current folder. You will see this file in the VS Code explorer. Select the file to view the image. If it needs rotation, update thecamera.rotation = 0
line as necessary and take another picture.
💁 You can find this code in the code-camera/pi folder.
😀 Your camera program was a success!