Installing OpenCV on Raspberry Pi can be an intermediate challenge, but the rewards can be great! In this video, I show you how to install OpenCV step by step on a Raspberry Pi running the Raspbian operating system. This article is a companion article to the video of the same title on YouTube, which you can watch below.
I recommend you start with a fresh install of the latest version of Raspbian and on boot, update the system.
$ sudo apt update $ sudo apt upgrade
Install the package debian-goodies and see what large packages that aren’t useful to us are there by running:
$ dpigs -H
This should list packages sorted by their size. You can probably remove a lot of packages on a default Raspbian install and get away with it, but let’s just stick to the usual suspects. Let’s also install various packages that are dependencies to getting OpenCV compiled on the Raspberry Pi.
$ sudo apt purge wolfram-engine libreoffice* $ sudo apt clean $ sudo apt autoremove $ sudo apt install build-essential cmake pkg-config libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev libgtk2.0-dev libgtk-3-dev libcanberra-gtk* libatlas-base-dev gfortran python3-dev
If you face problems related to dependencies running the final command, replace “apt” with “aptitude”. That should take care of things better. If “apt” gets the job done, all the better. To make things a bit easier, we install a couple more packages:
$ sudo apt install tmux htop vim
Compiling a package like OpenCV not only requires a lot of available space on your SD card, it also requires quite a bit of RAM. Since the Raspberry Pi 3 comes with only 1GB of RAM, we’ll need to add swap space to the system so that virtual memory available to the system is larger than available RAM. The installation of Raspbian enables 100MB of swap by default, but we should change that to 1024 MB, which is 1GB. 1GB of RAM along with 1GB of swap space should be enough to get OpenCV compiled on the Raspberry Pi.
$ sudo vim /etc/dphys-swapfile
Change CONF_SWAPFILE to 1024
Now restart the swap service for the new swap size to take effect
$ sudo /etc/init.d/dphys-swapfile restart $ free -m total used free shared buff/cache available Mem: 875 87 355 12 432 721 Swap: 1023 0 1023
Let’s install PIP, the Python package installer / manager
$ wget https://bootstrap.pypa.io/get-pip.py $ sudo python3 get-pip.py
With pip in place, let’s use it to install virtualenvwrapper
$ sudo pip install virtualenv virtualenvwrapper
Add this to ~/.profile to make it easier to use virtualenvwrapper
# For VirtualEnv export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 export WORKON_HOME=$HOME/.virtualenvs source /usr/local/bin/virtualenvwrapper.sh
Source .profile changes into your current shell:
We will create a Python virtual environment named “cv” and install all our dependencies needed to build and use OpenCV into that virtual environment.
mkvirtualenv cv -p python3
You should now notice that your shell prompt has “(cv) ” prefixed to it. This is virtualenv’s way of telling you that your “cv” Python virtual environment is now active. Tip: You can use the “deactivate” command to, well, deactivate the virtual environment. This removes the prefix from your shell prompt.
(cv) shuveb@raspberrypi:~ $
Let’s now install Numpy, OpenCV, OpenCV-contrib and untar them both.
$ pip install numpy $ mkdir opencv $ cd opencv $ wget -O opencv.tar.gz https://github.com/opencv/opencv/archive/3.4.1.tar.gz $ wget -O opencv_contrib.tar.gz https://github.com/opencv/opencv_contrib/archive/3.4.1.tar.gz $ tar xvzf opencv.tar.gz $ tar xvzf opencv_contrib.tar.gz
Make a build directory and configure the build
$ cd opencv-3.4.1 $ mkdir build $ cd build $ cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D OPENCV_EXTRA_MODULES_PATH=~/opencv/opencv_contrib-3.4.1/modules \ -D ENABLE_NEON=ON \ -D ENABLE_VFPV3=ON \ -D BUILD_TESTS=OFF \ -D INSTALL_PYTHON_EXAMPLES=OFF \ -D BUILD_EXAMPLES=OFF ..
Once the build is configured, we can build it with make.
$ make -j4 #this will take several hours $ sudo make install $ sudo ldconfig
We need to rename the installed .so file so that we can import it into Python and go about our business
$ sudo mv /usr/local/lib/python3.5/site-packages/cv2.cpython-35m-arm-linux-gnueabihf.so /usr/local/lib/python3.5/site-packages/cv2.so $ ln -s /usr/local/lib/python3.5/site-packages/cv2.so ~/.virtualenvs/cv/lib/python3.5/site-packages/cv2.so
Let’s now ensure that we are indeed able to import OpenCV into Python
$ (cv) shuveb@raspberrypi:~ $ python Python 3.5.3 (default, Jan 19 2017, 14:11:04) [GCC 6.3.0 20170124] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> cv2.__version__ '3.4.1' >>>
While this means that we’ve installed OpenCV successfully on our Raspberry Pi, we could quickly check OpenCV with a simple script which detects human faces. You’ll need to ensure that your “cv” virtual environment is active while you run this script with the “python” command.
# import the necessary packages from picamera.array import PiRGBArray from picamera import PiCamera import imutils 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 #image = imutils.rotate(image, 180) #/usr/local/share/OpenCV/haarcascades/ face_cascade = cv2.CascadeClassifier('/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml') gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.1, 5) print("Found "+str(len(faces))+" face(s)") #Draw a rectangle around every found face for (x,y,w,h) in faces: cv2.rectangle(image,(x,y),(x+w,y+h),(255,255,0),2) # 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 is what I was able to see