Over the past year the PyImageSearch blog has had a lot of popular blog posts. Using k-means clustering to find the dominant colors in an image was (and still is) hugely popular. One of my personal favorites, building a kick-ass mobile document scanner has been the most popular PyImageSearch article for months. And the first (big) tutorial I ever wrote, Hobbits and Histograms, an article on building a simple image search engine, still gets a lot of hits today.
But by far, the most popular post on the PyImageSearch blog is my tutorial on installing OpenCV and Python on your Raspberry Pi 2 and B+. It’s really, really awesome to see the love you and the PyImageSearch readers have for the Raspberry Pi community — and I plan to continue writing more articles about OpenCV + the Raspberry Pi in the future.
Anyway, after I published the Raspberry Pi + OpenCV installation tutorial, many of the comments asked that I continue on and discuss how to access the Raspberry Pi camera using Python and OpenCV.
In this tutorial we’ll be using picamera, which provides a pure Python interface to the camera module. And best of all, I’ll be showing you how to use picamera to capture images in OpenCV format.
Read on to find out how…
IMPORTANT: Be sure to follow one of my Raspberry Pi OpenCV installation guides prior to following the steps in this tutorial.
OpenCV and Python versions:
This example will run on Python 2.7/Python 3.4+ and OpenCV 2.4.X/OpenCV 3.0+.
Step 1: What do I need?
To get started, you’ll need a Raspberry Pi camera board module.
I got my 5MP Raspberry Pi camera board module from Amazon for under $30, with shipping. It’s hard to believe that the camera board module is almost as expensive as the Raspberry Pi itself — but it just goes to show how much hardware has progressed over the past 5 years. I also picked up a camera housing to keep the camera safe, because why not?
Assuming you already have your camera module, you’ll need to install it. Installation is very simple and instead of creating my own tutorial on installing the camera board, I’ll just refer you to the official Raspberry Pi camera installation guide:
Assuming your camera board and properly installed and setup, it should look something like this:
Step 2: Enable your camera module.
Now that you have your Raspberry Pi camera module installed, you need to enable it. Open up a terminal and execute the following command:
$ sudo raspi-config
This will bring up a screen that looks like this:
Use your arrow keys to scroll down to Option 5: Enable camera, hit your enter key to enable the camera, and then arrow down to the Finish button and hit enter again. Lastly, you’ll need to reboot your Raspberry Pi for the configuration to take affect.
Step 3: Test out the camera module.
Before we dive into the code, let’s run a quick sanity check to ensure that our Raspberry Pi camera is working properly.
Note: Trust me, you’ll want to run this sanity check before you start working with the code. It’s always good to ensure that your camera is working prior to diving into OpenCV code, otherwise you could easily waste time wondering when your code isn’t working correctly when it’s simply the camera module itself that is causing you problems.
Anyway, to run my sanity check I connected my Raspberry Pi to my TV and positioned it such that it was pointing at my couch:
And from there, I opened up a terminal and executed the following command:
$ raspistill -o output.jpg
This command activates your Raspberry Pi camera module, displays a preview of the image, and then after a few seconds, snaps a picture, and saves it to your current working directory as
Here’s an example of me taking a photo of my TV monitor (so I could document the process for this tutorial) as the Raspberry Pi snaps a photo of me:
And here’s what
output.jpg looks like:
Clearly my Raspberry Pi camera module is working correctly! Now we can move on to the some more exciting stuff.
Step 4: Installing picamera.
So at this point we know that our Raspberry Pi camera is working properly. But how do we interface with the Raspberry Pi camera module using Python?
The answer is the picamera module.
Remember from the previous tutorial how we utilized
virtualenvwrapper to cleanly install and segment our Python packages from the the system Python and packages?
Well, we’re going to do the same thing here.
picamera , be sure to activate our
cv virtual environment:
$ workon cv
Note: If you are installing the the
picamera module system wide, you can skip the previous commands. However, if you are following along from the previous tutorial, you’ll want to make sure you are in the
cv virtual environment before continuing to the next command.
And from there, we can install
picamera by utilizing pip:
$ pip install "picamera[array]"
IMPORTANT: Notice how I specified
picamera[array] and not just
Why is this so important?
While the standard
picamera module provides methods to interface with the camera, we need the (optional)
array sub-module so that we can utilize OpenCV. Remember, when using Python bindings, OpenCV represents images as NumPy arrays — and the
array sub-module allows us to obtain NumPy arrays from the Raspberry Pi camera module.
Assuming that your install finished without error, you now have the
picamera module (with NumPy array support) installed.
Step 5: Accessing a single image of your Raspberry Pi using Python and OpenCV.
Alright, now we can finally start writing some code!
Open up a new file, name it
test_image.py , and insert the following code:
# import the necessary packages from picamera.array import PiRGBArray from picamera import PiCamera import time import cv2 # initialize the camera and grab a reference to the raw camera capture camera = PiCamera() rawCapture = PiRGBArray(camera) # allow the camera to warmup time.sleep(0.1) # grab an image from the camera camera.capture(rawCapture, format="bgr") image = rawCapture.array # display the image on screen and wait for a keypress cv2.imshow("Image", image) cv2.waitKey(0)
We’ll start by importing our necessary packages on Lines 2-5.
From there, we initialize our PiCamera object on Line 8 and grab a reference to the raw capture component on Line 9. This
rawCapture object is especially useful since it (1) gives us direct access to the camera stream and (2) avoids the expensive compression to JPEG format, which we would then have to take and decode to OpenCV format anyway. I highly recommend that you use
PiRGBArray whenever you need to access the Raspberry Pi camera — the performance gains are well worth it.
From there, we sleep for a tenth of a second on Line 12 — this allows the camera sensor to warm up.
Finally, we grab the actual photo from the
rawCapture object on Line 15 where we take special care to ensure our image is in BGR format rather than RGB. OpenCV represents images as NumPy arrays in BGR order rather than RGB — this little nuisance is subtle, but very important to remember as it can lead to some confusing bugs in your code down the line.
Finally, we display our image to screen on Lines 19 and 20.
To execute this example, open up a terminal, navigate to your
test_image.py file, and issue the following command:
$ python test_image.py
If all goes as expected you should have an image displayed on your screen:
Note: I decided to add this section of the blog post after I had finished up the rest of the article, so I did not have my camera setup facing the couch (I was actually playing with some custom home surveillance software I was working on). Sorry for any confusion, but rest assured, everything will work as advertised provided you have followed the instructions in the article!
Step 6: Accessing the video stream of your Raspberry Pi using Python and OpenCV.
Alright, so we’ve learned how to grab a single image from the Raspberry Pi camera. But what about a video stream?
You might guess that we are going to use the
cv2.VideoCapture function here — but I actually recommend against this. Getting
cv2.VideoCapture to play nice with your Raspberry Pi is not a nice experience (you’ll need to install extra drivers) and something you should generally avoid.
And besides, why would we use the
cv2.VideoCapture function when we can easily access the raw video stream using the
Let’s go ahead and take a look on how we can access the video stream. Open up a new file, name it
test_video.py , and insert the following code:
# import the necessary packages from picamera.array import PiRGBArray from picamera import PiCamera import time import cv2 # initialize the camera and grab a reference to the raw camera capture camera = PiCamera() camera.resolution = (640, 480) camera.framerate = 32 rawCapture = PiRGBArray(camera, size=(640, 480)) # allow the camera to warmup time.sleep(0.1) # capture frames from the camera for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): # grab the raw NumPy array representing the image, then initialize the timestamp # and occupied/unoccupied text image = frame.array # show the frame cv2.imshow("Frame", image) key = cv2.waitKey(1) & 0xFF # clear the stream in preparation for the next frame rawCapture.truncate(0) # if the `q` key was pressed, break from the loop if key == ord("q"): break
This example starts off similarly to the previous one. We start off by importing our necessary packages on Lines 2-5.
And from there we construct our
camera object on Line 8 which allows us to interface with the Raspberry Pi camera. However, we also take the time to set the resolution of our camera (640 x 480 pixels) on Line 9 and the frame rate (i.e. frames per second, or simply FPS) on Line 10. We also initialize our
PiRGBArray object on Line 11, but we also take care to specify the same resolution as on Line 9.
Accessing the actual video stream is handled on Line 17 by making a call to the
capture_continuous method of our
This method returns a
frame from the video stream. The frame then has an
array property, which corresponds to the
frame in NumPy array format — all the hard work is done for us on Lines 17 and 20!
We then take the frame of the video and display on screen on Lines 23 and 24.
An important line to pay attention to is Line 27: You must clear the current frame before you move on to the next one!
If you fail to clear the frame, your Python script will throw an error — so be sure to pay close attention to this when implementing your own applications!
Finally, if the user presses the
q key, we break form the loop and exit the program.
To execute our script, just open a terminal (making sure you are in the
cv virtual environment, of course) and issue the following command:
$ python test_video.py
Below follows an example of me executing the above command:
As you can see, the Raspberry Pi camera’s video stream is being read by OpenCV and then displayed on screen! Furthermore, the Raspberry Pi camera shows no lag when accessing frames at 32 FPS. Granted, we are not doing any processing on the individual frames, but as I’ll show in future blog posts, the Pi 2 can easily keep up 24-32 FPS even when processing each frame.
What's next? I recommend PyImageSearch University.
53+ total classes • 57+ hours of on-demand code walkthrough videos • Last updated: Sept 2022
★★★★★ 4.84 (128 Ratings) • 15,800+ Students Enrolled
I strongly believe that if you had the right teacher you could master computer vision and deep learning.
Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?
That’s not the case.
All you need to master computer vision and deep learning is for someone to explain things to you in simple, intuitive terms. And that’s exactly what I do. My mission is to change education and how complex Artificial Intelligence topics are taught.
If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to successfully and confidently apply computer vision to your work, research, and projects. Join me in computer vision mastery.
Inside PyImageSearch University you'll find:
- ✓ 53+ courses on essential computer vision, deep learning, and OpenCV topics
- ✓ 53+ Certificates of Completion
- ✓ 57+ hours of on-demand video
- ✓ Brand new courses released regularly, ensuring you can keep up with state-of-the-art techniques
- ✓ Pre-configured Jupyter Notebooks in Google Colab
- ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
- ✓ Access to centralized code repos for all 450+ tutorials on PyImageSearch
- ✓ Easy one-click downloads for code, datasets, pre-trained models, etc.
- ✓ Access on mobile, laptop, desktop, etc.
This article extended our previous tutorial on installing OpenCV and Python on your Raspberry Pi 2 and B+ and covered how to access the Raspberry Pi camera module using Python and OpenCV.
We reviewed two methods to access the camera. The first method allowed us to access a single photo. And the second method allowed us to access the raw video stream from the Raspberry Pi camera module.
In reality, there are many ways to access the Raspberry Pi camera module, as the picamera documentation details. However, the methods detailed in this blog post are used because (1) they are easily compatible with OpenCV and (2) they are quite speedy. There are certainly more than one way to skin this cat, but if you intend on using OpenCV + Python, I would suggest using the code in this article as “boilerplate” for your own applications.
In future blog posts we’ll take these examples and use it to build computer vision systems to detect motion in videos and recognize faces in images.
Be sure to sign up for the PyImageSearch Newsletter to receive updates when new Raspberry Pi and computer vision posts go live, you definitely don’t want to miss them!
Download the Source Code and FREE 17-page Resource Guide
Enter your email address below to get a .zip of the code and a FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning. Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL!