Introduction
I'm currently working on an updated version of this PiCam sc which will be easier to install and gives you the possibility to receive updates and new features. You can find this project on GitHub: https://github.com/dofl/PiCam
This article will show you the best settings to use for your normal Raspberry Pi camera (not the NoIR) as a HD surveillance camera. In the end, you will have a crisp 720P image, with a pretty good quality at night and a webbrowser that shows the last 10 images.
Optionally, there is a tutorial on how to use an external storage like a NAS to copy images to. It uses an in-memory filesystem (TMPFS) as a buffer to store images while the slow Pi Wifi copies the images to the NAS.
Background
There are many good tutorials on how to implement the Raspberry Pi and the camera as a low-cost surveillance camera. I've used these articles as a base and I'll try to reference the sources as much as I still remember.
As everything is already described by others, I'm more interested in getting the best quality in image sharpness and settings at night when using the normal camera (not the NoIR) camera.
Getting Started
It's wise to read ahead a couple of lines before you dive in. I don't always use all code from another article.
It's a good idea to start where I did. He is also the one that made me use codeproject.com as I didn't want to setup another blog that would go down again in a couple of months because I want to use my Pi for another project. :-)
Raspberry Pi as low-cost HD surveillance camera by Christoph Buenger.
Things to do:
- Buy the hardware he describes
- Install Raspbian
- Setup networking
Things NOT to do (although experiment at will!):
- Install the motion detection software
- Read the rest of the article as it's based on other motion detection / image capture software
Why?
I never got the image sharpness and resolution that I now got and I think is because of Motion (the software package). I'd rather use the original software provided by the Raspberry Pi foundation as it uses less CPU, just as accurate with motion and creates very sharp pictures.
Casing
Offtopic: I also bought a dummy cam, but that was before I've seen 'PICE', a metal waterproof Raspberry Pi casing.
Installing picam.py
The people from MakeTechEasier also wrote an article about using the rPi as a surveillance camera.
They use a Python script that is written by community members that constantly takes small pictures (in memory), compares it with the previous one for changed pixels and when 'enough' changed pixels are found, it takes a high-res picture. Well written, lots of config and uses only the original Rpi provided software.
Install as followed:
sudo apt-get install python-imaging-tk
wget -c http://pastebin.com/raw.php?i=yH7JHz9w -O picam.py
chmod +x picam.py
The script will use a folder called 'picam' for storing all of the images. Create it before starting the script
mkdir ~/picam
Start picam.py at boot
The picam.py script needs to be started at boot. This is required later on when the Raspberry will reboot into night and day settings.
wget http://pastebin.com/raw.php?i=AfqbjQrb -O picam_init
The script needs to be moved to the init.d folder in order to boot:
sudo mv ~/picam_init /etc/init.d/picam
sudo chmod +x /etc/init.d/picam
Tell the system the picam 'service' has arrived:
sudo update-rc.d picam defaults
View the Latest Pictures Through a Website
After a while, the SD card will fill up, which is nice as an archive. But I also wanted to see the latest image through my browser. Therefore I installed the lightweight webserver Lighttpd and PHP.
sudo apt-get -y install lighttpd
sudo apt-get -y install php5-common php5-cgi php5
sudo lighty-enable-mod fastcgi-php
sudo service lighttpd force-reload
After this, you can view the demo website at the http://ip-address-of-your-raspberry-pi
Lighttpd is installed under /var/www/. The picam.py script writes its images under /home/pi/picam/.
I used a symboblic link to make the images of the picam available in the directory of the webserver:
sudo ln -s /home/pi/picam /var/www/picam
This creates a 'folder' (link) in /var/www/picam that refers to /home/pi/picam.
I borrowed and adapted a piece of PHP code that shows the latest 6 images from the picam/ folder.
sudo nano /var/www/index.php
Insert the following code:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
print '<meta http-equiv="refresh" content="15">';
$images = glob('picam/*.jpg', GLOB_BRACE);
$num_of_files = 10;
echo "Images: ". count($images). " | ";
$lastImage = new DateTime(date('Y-m-d h:i', filemtime(end($images))));
$firstImage = new DateTime(date('Y-m-d h:i', filemtime($images[0])));
$interval = $lastImage->diff($firstImage);
echo $interval->format('Timespan between first and last image: %a days, %h hours, %i minutes</br>');
krsort($images);
foreach($images as $image)
{
$num_of_files--;
if($num_of_files > -1)
echo "<b>".$image."</b> |
Created on ".date('D, d M y H:i:s', filemtime($image)) ."<br><img src="."'".$image."'"."><br><br>" ;
else
break;
}
?>
You now have a very simple website running that always shows the latest 6 images. It refreshes itself every 15 seconds.
Optional: webserver security
When you make the camera website public to the rest of the internet, I'll be wise to secure it. We'll do this by username/password protecting the root folder of the Lighttpd webserver:
Create a username/password file:
sudo nano /etc/lighttpd/.htpasswd
Insert your username:password combination in this file. Nothing more.
MyUsername:MyPassword
Next, add a few lines of code to the Lighttpd configuration file:
sudo nano /etc/lighttpd/lighttpd.conf
In 'server.modules =', add the line:
"mod_auth"
Place the following code (for example) after 'server.port = 80':
auth.backend = "plain"
auth.backend.plain.userfile = "/etc/lighttpd/.htpasswd"
auth.debug = 1
$HTTP["url"] == "/" {
auth.require = ( "" =>
(
"method" => "basic",
"realm" => "Authorization",
"require" => "valid-user"
) )
}
Save and restart Lighttpd by typing:
sudo service lighttpd restart
Optimal Settings for Night Photos
Normal surveillance cameras have some sort of infrared to lit up the environment at night in order to take a decent picture. As I also wanted good pictures by day, I decided to go with the normal camera and use longer exposure times for the camera. Fast moving objects will blur, but it's the best there is under low-light conditions.
First of all, install the camera in place. Wait for dark and run the excellent Python camera test script written by raspberrypi-spy.co.uk.
cd ~
mkdir test_camera
cd test_camera
wget http://www.raspberrypi-spy.co.uk/archive/python/pi_camera_options.py
Edit the pi_camera_options.py file:
nano pi_camera_options.py
Set it up so that it takes pictures under all different circumstances.
list_ex = ['off','auto','night','backlight','spotlight','fireworks']
list_awb = ['off','auto','sun','cloud','shade','tungsten','fluorescent','incandescent','flash','horizon']
After this, you can run it. It will take pictures under all kinds of different camera settings. It's up to you to compare them to see which picture gives you the best results for what you want to achieve. Remember the 'ex
' and 'awb
' setting that worked best for the next step.
sudo python pi_camera_options.py
CRON: Changing Between Day and Night Settings
I am switching between a day and night setting on my rPi. I want to scare away burglars with the blinking red light at night, but I don't want to freak out the neighbors with it by day. At the same time, I want pictures by night to use specific camera settings that worked best in the previous step as well as a longer exposure time. In order to do this, I created 2 scripts that are run by CRON at set times.
First, create the 2 scripts that CRON will run. One to rule by day, one by night.
sudo nano /opt/picam_night.sh
Insert the following code:
#! /bin/sh
sed -i 's/disable_camera_led=1/disable_camera_led=0/' /boot/config.txt
sed -i 's/cameraSettings = ""/cameraSettings = "-ex night -awb auto"/' /home/pi/picam.py
sed -i 's/-t 200/-t 500/' /home/pi/picam.py
sed -i 's/threshold = 30/threshold = 10/' /home/pi/picam.py
sed -i 's/sensitivity = 30/sensitivity = 20/' /home/pi/picam.py
/sbin/reboot
And the one by day:
sudo nano /opt/picam_day.sh
#! /bin/sh
sed -i 's/disable_camera_led=0/disable_camera_led=1/' /boot/config.txt
sed -i 's/cameraSettings = "-ex night -awb auto"/cameraSettings = ""/' /home/pi/picam.py
sed -i 's/-t 500/-t 200/' /home/pi/picam.py
sed -i 's/threshold = 10/threshold = 30/' /home/pi/picam.py
sed -i 's/sensitivity = 20/sensitivity = 30/' /home/pi/picam.py
/sbin/reboot
The SED command will find specific pieces of text inside a file and replace it with another piece of text. What the lines do:
- Change the LED of the camera in the rPi boot sequence. On by night, off by day.
- Set the specific nighttime camera setting (the '
ex
' and 'awb
' settings). - Change the exposure time of the camera for day and night. Longer by night, shorter by day.
- Set the threshold lower at night (more chance of shooting pictures at night).
- Set the sensitivity lower at night, also to get more pictures at night. Raise this if the Pi takes too much pictures at night, as it will be because of image noise.
The raspberry Pi will reboot after changing these settings. This is required for changing the blinking LED on the camera. It's set by boot options (/boot/config.txt).
In order to let it run by the CRON daemon:
sudo crontab -e
And add these two lines at the bottom:
00 23 * * * sh /opt/picam_night.sh
00 06 * * * sh /opt/picam_day.sh
This will run the 'night' script at 23.00 hours and the 'day' script at 06.00 hours.
That's it. I'll generate some pretty decent images and use specific settings at night.
Transferring Images to your NAS over WIFI with a Temporary RAM Buffer: TMPFS
I've fitted the Raspberry PI with a WIFI dongle from Edimax. Bought it on Ebay for a couple of euros. It's cheap but it also has a very limited in range and speed, especially when it's not in a direct line of site of the access point.
Therefore, I wanted my Raspberry PI images to be transferred to my NAS. It's on 24/7 and I'm afraid that the SD card in the Raspberry PI will die very soon if 1000 images of 300 KB (around 300 MB) are written to it, every day.
To make sure that copying images over a slow WIFI network does not interfere with the speed at which the picam can take images, I'll be using a temporary buffer to store images in the RAM memory with TMPFS.
By using TMPFS, the picam can keep shooting images as quickly as it can into the fast TMPFS file system, without having to wait on the slower WIFI network to finish copying the image to the NAS. The process of copying the images to the NAS will be taken care by a simple BASH script.
The approach:
- We'll setup the mount to the NAS share.
- Setup a TMPFS file system share of 10 MB as a buffer for images.
- Create a bash script that will copy all the photos from TMPFS buffer to the NAS, but:
Only if the image is created more than 5 seconds ago (to make sure it doesn't copy images that are being created by raspistill at the exact same moment. - Set the picam.py script to the right folder.
Step 1 and 2: Mount your NAS and create the TMPFS filesystem
Create the folders that will hold the mount to the NAS and the TMPFS file system.
sudo mkdir /mnt/Name_Of_Your_NAS_Share
sudo mkdir /mnt/picam_tmpfs
Mount the NAS share and TMPFS at boot. This can be done in the fstab file:
sudo nano /etc/fstab
Add the following two lines:
Line 1: This example below works for a Samba / CIFS / 'Windows' share that can login as guest.
//IP.ADDRESS.OF.SERVER/SHARENAME /mnt/Name_Of_Your_NAS_Share cifs guest 0 01
Line 2: This creates the 10MB tmpfs filesystem at the folder /mnt/picam_tmpfs folder that you just created.
tmpfs /mnt/picam_tmpfs tmpfs defaults,noatime,size=10M,mode=0777 0 0
The noatime
parameter skips settings the last accessed time for a file. This should give us a I/O performance boost, although I hardly doubt we will notice it on a file system in the RAM memory.
3. Create the BASH script that copies the images from TMPFS to the NAS
sudo nano /opt/tmpfsToNAS.sh
This script checks the TMPFS folder every two seconds (sleep 2) and moves (-exec mv) all files (-type f) that are created at least 5 seconds ago (-mmin +0.05). Insert the following code:
#! /bin/sh
while :
do
find /mnt/picam_tmpfs -type f -mmin +0.05 -exec mv "{}" /mnt/Name_Of_Your_NAS_Share/ \;
sleep 2
done
Let's make sure this script boots up when the Raspberry boots. This works the same as how picam.py boots at startup:
sudo nano /etc/init.d/tmpfsToNAS
Insert the following code. I 've set this up with the help of an article at stuffaboutcode.com.
#! /bin/sh
# /etc/init.d/tmpfsToNAS
### BEGIN INIT INFO
# Provides: Copies images from the picam tmpfs to a NAS
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Simple script to start a program at boot
# Description: Copies images from the picam tmpfs to a NAS
### END INIT INFO
# Carry out specific functions when asked to by the system
case "$1" in
start)
echo "Starting copy tmpfs to NAS"
sh /opt/tmpfsToNAS.sh 2>&1 &
;;
stop)
echo "Stopping copy tmpfs to serv"
tmpfsPID=`ps auxwww | grep tmpfsToNAS.sh | head -1 | awk '{print $2}'`
kill -9 $tmpfsPID
;;
*)
echo "Usage: /etc/init.d/tmpfsToNAS {start|stop}"
exit 1
;;
esac
exit 0
Make the script executable:
sudo chmod 755 /etc/init.d/tmpfsToNAS
Register the script to run at start-up:
sudo update-rc.d tmpfsToNAS defaults
And finally edit the picam.py script. Let it write to our new TMPFS location:
sudo nano ~/picam.py
Change the line:
filepath = "/mnt/picam_tmpfs"
I would say reboot your Pi and check if everything goes well. You should see images being created at the TMPFS folder, but quickly be copied to the NAS share.
History
- 21-04-2014: First release
- 21-04-2014: Added webserver security
- 08-05-2014: Added website statistics (image count and timespan) plus treshold and sensitivity change at night
- 11-05-2014: Added a TMPFS solution for copying files over WIFI to a NAS