webcm1First Step is to install OpenCV 3 on your Raspberry Pi. I also prefer Python 3, so will concentrate only on this version in this post. This post of Adrian Rosebrock gives very good guidance on how to install OpenCV 3.

At the time I wanted to install OpenCV I had to install the version 3.1.0 for which I am listing in the following just the steps I did and recommend the reader to have a look at Adrian’s post for more details.

Install Dependencies

sudo apt-get update
sudo apt-get upgrade
sudo rpi-update

sudo reboot

sudo apt-get install build-essential git cmake pkg-config
sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev

sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libxvidcore-dev libx264-dev

sudo apt-get install libgtk2.0-dev
sudo apt-get install libatlas-base-dev gfortran

sudo apt-get install python2.7-dev python3-dev

Grab the OpenCV source code

cd ~
wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.1.0.zip
unzip opencv.zip

wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/3.1.0.zip
unzip opencv_contrib.zip

I had some problems to get opencv_contrib installed. But after some tries it suddenly worked.
So try a few times and make sure you did not misspell something.

Setup Python

wget https://bootstrap.pypa.io/get-pip.py
sudo python get-pip.py

sudo pip install virtualenv virtualenvwrapper
sudo rm -rf ~/.cache/pip

Now open ~/.profile for example with

sudo nano ~/.profile

and add to the end of this file the following lines:

# virtualenv and virtualenvwrapper
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

Reload ~/.profile with

source ~/.profile

Create and start your Python virtual environment

mkvirtualenv cv -p python3
workon cv
pip install numpy

Compile and install OpenCV

workon cv

cd ~/opencv-3.1.0/
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
	-D CMAKE_INSTALL_PREFIX=/usr/local \
	-D INSTALL_C_EXAMPLES=OFF \
	-D INSTALL_PYTHON_EXAMPLES=ON \
	-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.1.0/modules \
	-D BUILD_EXAMPLES=ON ..

As Adrian is showing in his post make sure compiling OpenCV for Python 3 “.virtualenvs” in the highlighted paths as shown in below image. Then you know that your virtual environment is set up correctly. Again if there are issues at this point I recommend Adrian’s post for more details.
config

Now comes the part that takes the longest time (about 1.5 hours depending on the Raspberry Pi version you are using) – the actual compilation of OpenCV on your Pi:

make -j4

This worked flawlessly on the Raspberry Pi 2, but on the Pi 3 I got errors probably due to race condition issues. So I removed the build and installed it again using the one core approach (this might in some cases be necessary also for the Raspberry Pi 2):

make clean
make

Finally install OpenCV on your system:

sudo make install
sudo ldconfig

Finishing the install for Python 3

Check to see if OpenCV is installed with

ls /usr/local/lib/python3.4/site-packages/

where you should see cv2.cpyhon-34m.so.

Finally:

cd /usr/local/lib/python3.4/site-packages/
sudo mv cv2.cpython-34m.so cv2.so

cd ~/.virtualenvs/cv/lib/python3.4/site-packages/
ln -s /usr/local/lib/python3.4/site-packages/cv2.so cv2.so

Verifying your OpenCV 3 install

Starting Python you should see following:

workon cv
python3.4
>>> import cv2
>>> cv2.__version__
'3.1.0'

If this all worked you are all set for your Dropbox based home-surveillance system.
If you see errors, please consult Adrian’s post for troubleshooting.

Video Streaming with OpenCV

The OpenCV 3 system you just installed is a powerful image processing library that can be used for many purposes related to imaging.
As an introduction I want to present here a simple object-oriented (OO) Python script that allows capture and saving of videos. The OO setup simplifies the addition of more functions to process the video stream and also allows the easy addition of more cameras, by just adding more camera “instances”.
Save following code for example as “piCameraClass.py”:

import cv2
import time

class CameraInst():
        # Constructor...
        def __init__(self):
                fps        = 20.0               # Frames per second...
                resolution = (640, 480)         # Frame size/resolution...
                w = 640
                h = 480

                self.cap = cv2.VideoCapture(0)  # Capture Video...
                print("Camera warming up ...")
                time.sleep(1)

                # Define the codec and create VideoWriter object
                fourcc = cv2.VideoWriter_fourcc(*"H264")     # You also can use (*'XVID')
                self.out = cv2.VideoWriter('output.avi',fourcc, fps, (w, h))

        def captureVideo(self):
                # Capture
                self.ret, self.frame = self.cap.read()
                # Image manipulations come here...
                self.gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
                cv2.imshow('frame',self.gray)

        def saveVideo(self):
                # Write the frame
                self.out.write(self.frame)

        def __del__(self):
                self.cap.release()
                cv2.destroyAllWindows()
                print("Camera disabled and all output windows closed...")

def main():
        cam1 = CameraInst()

        while(True):
                # Display the resulting frames...
                cam1.captureVideo()    # Live stream of video on screen...
                cam1.saveVideo()       # Save video to file 'output.avi'...
                if cv2.waitKey(1) & 0xFF == ord('q'):
                        break

        cleanUp()

if __name__=='__main__':
        main()

In this Python code the camera functions are encapsulated in a class. This allows in the main program main() to easily start multiple camera instances if desired. It also makes the program easier oversee-able as the camera functions can be controlled by different member functions of this class. Here implemented is only one the following member functions:

  • __init__ and __del__ : The __init__ method is the “constructor” of this class which is called once at the instantiation of the class (in main() with cam1 = CameraInst() ). The constructor initializes a few class-internal parameters, activates the camera with the openCV method VideoCapture() and defines the output format to save the video to the file output.avi .
    The destructor __del__ releases the camera (which important to avoid crashing the camera controller) and closes all windows opened by this Python script using the openCV function destroyAllWindows() .
  • captureVideo() : This function captures singles frames with the read() method. The captured frame is transferred to a gray-level image using the openCV function cvtColor() with the argument COLOR_BGR2GRAY. Finally the image is displayed with the openCV function imshow() .
  • saveVideo : This function just saves the uses the write() method to save each captured image in the file output.avi.

main() is a function outside of the class CameraInst() . This is the function that instantiates the class using the name cam1 and uses this in an endless-loop to call the frma capture function of the class captureVideo() to capture frames and generate a video and also calls saveVideo() to save the video.

My favorite main-call in a Python function is using if __name__==”__main__” , which gives you the flexibility to use the code in this file (piCameraClass.py) ither directly as the main code or by using this code as a module that is called from another Python script.

Because OpenCV is installed in the virtual environment cv, following has to be done to run this script:

source ~/.profile
workon cv
python piCameraClass.py

The last command is the call to start the script. To stop the execution click on the video window and press “q”.

Summary

In this first part of this home surveillance series we are installing the basic tools to capture and to process images and video streams. OpenCV is a powerful tool-set to process images, which can be readily applied for home and any other surveillance.
In the following parts of this series I want to present an extended Python script that allows the detection of intruders. This script will allow the capture of videos and images of the scene at detection of motion. The videos and images can then be automatically uploaded to cloud-servers such as Dropbox to be view-able from anywhere in the world if you have access to the internet. Finally I will show you how to stream a life video to a website which you also can access from anywhere in the world.

As usual I am looking forward to hearing from you, your thoughts and comments. Please leave me your input or questions in below form and I will try to answer as soon as I can