This page describes a camera server
made with spare parts
and cheap components. The aim of the project is to build a Linux box
enclosed in an appropriate case so that it can be installed outdoor;
the PC controls a webcam and/or a digital photo camera. The system
can be accessed and controlled using a web interface.
This project is several years old, as can be seen by the fact that ancient Linux distributions are mentioned (e.g., Ubuntu 8.04), and the webcam server is a regular, bulky desktop PC instead of a, say, Raspberry PI that I would use today. I plan to bring the instructions up-to-date, but so far had no time to do so. Hopefully, the basic concepts should still be useful.
My server box is a cheap Intel PIII/450 machine with 128MB of RAM, running Linux Ubuntu 8.04. The machine has a very small disk (4.3GB Maxtor), which is enough given that we are not going to install a graphical user interface with applications and libraries. To cut power consumption, I removed the floppy disk and CD/DVD unit. I added a cheap 10/100 fast Ethernet PCI network card, and a video card which comes handy in case of troubles, although we are not going to hook a monitor to this machine.
Wireless connectivity is provided by a D-Link DWL-G122 USB wireless adapter, which is supported under Linux by the open source rt73 module. If you install Ubuntu 8.04, you don't need to do any further configuration, as the rt73 module is already in the kernel, and the DWL-G122 adapter will be automatically recognized as soon as it is plugged in. It is a pity that the DWL-G122 is no longer manufactured by D-Link.
I use a Logitech Quickcam E3500, which is a UVC-compliant device supported under Linux by the Linux UVC modules. The webcam is capable of a physical resolution of 640×480 pixels; it includes a microphone which is supported as well (it appears as an ALSA capture device). Again, Ubuntu 8.04 comes with the uvcvideo module already in the kernel, so this camera works out of the box without any further configuration.
The Quickcam E3500 provides a reasonable resolution (640×480) with a good quality considering its cost (I paid Eur 29.90 for it, now it could be even cheaper), but to get better still images you need a digital photo camera. I bough a used 4Mpx Canon PowerShot A80, which has the important feature of being remote controllable under Linux using gphoto2. You may check the gphoto2 documentation for the list of remote-controllable cameras.
You need to power the camera using an external power supply, as internal batteries will not last for long. Unfortunately, some digital cameras are quite picky about the voltage and current supplied by the external power adapter, so it might be the case that a "generic" power supply does not provide the appropriate current (and/or voltage) for operation. For the Canon PowerShot A80, the user manual says that it needs 4.3V @ 1.5A (Canon AC Adapter Kit ACK600). However, I managed to use a generic power adapter which supplies 4.5V @ 800mA—please note that in the PowerShot A80 power connector, the center pin is positive. This adapter is not enough to power the camera LCD display (which I don't need anyway, as the camera is being controlled by the PC), but is enough for shooting, even using the internal flash. If I try to use the LCD display, the camera complains about low battery and immediately shuts off. Pay attention when powering your camera with an external power supply: it worked for me, but use the above information at your own risk. I'm not responsible for any damage you might cause to your equipment.
Finally, given that the old motherboard I'm using only has two USB1.0 ports, I bought a D-Link DUB-A2 PCI board with 2 additional USB2.0 ports. Needless to say, this board is automatically recognized by Linux, and no special configuration is needed.
This is the list of components I used:
Here are some images of the assembly process. The case is a typical mid-tower, which is being put in horizontal position. The CD/DVD bay offer enough space to contain both the webcam and the Canon A80.
A rubber bands is used to secure the webcam and photo camera to a wooden plate.
These are the first tests of the assembled case, with the photo camera and webcam in their final position. The wooden plane which holds the cameras is secured to one side of the CD/DVD bay with a couple of screws.
The external case of the webcam server is made from an old wooden box. A small window has been cut to let the webcam and photo camera look outside; the window has been covered with Plexiglas, sealed with silicone on the border.
Two pairs of holes (two holes on the bottom, and two on the top of the opposite side) help circulating air from the outside. The holes have been covered with a very fine net to keep insects outside the box.
Finally, the box has been painted in white to reflect some light and hence avoid overheating the inside. The "roof" of the case is made by gluing a white plastic sheet on a wooden base.
To cover the front window I used a small piece of Plexiglas. This piece was cut from a larger Plexiglas sheet.
This is the final assembly. Note the three small pieces of wood which have been attached to the bottom of the case: these are needed to keep the internal PC case in place.
Here is the box with the PC inside. Note the small plastic ball with a green top: it contains hygroscopic material which is able to absorb moisture which might form inside the box. Also, note the big fan on the rear of the PC case: it is used to force circulation of air inside the box, thus avoiding moisture to form on the inside of the window.
I configured the wireless adapter with a static (private) IP
address. The adapter automatically connects to my access point using
WPA-PSK authentication. To enable WPA authentication, you need to
install the wpasupplicant
package:
Now, create the configuration file for wpa-supplicant
using the wpa_passphrase
command, like this:
$ wpa_passphrase my_network # reading passphrase from stdin my_password network={ ssid="my_network" #psk="my_password" psk=a4ea383f2d8e77c45ec859de70b9ea37b30d79153d049cbc88fe6bc86d2cba3d }
where my_network is the ESSID of your access point, and
my_password is your WPA passphrase. You need to paste the
output of the wpa_passphrase
command into the
/etc/wpa_supplicant.conf
file. At this point, suppose
that you want to automatically connect to the access point when the
system boots up. Furthermore, let us assume that the (static) IP
address of your webcam server will be 192.168.0.50, and the IP address
of the gateway is 192.168.0.71. You need to add something like the
following in your /etc/network/interfaces
configuration
file:
auto wlan0 iface wlan0 inet static address 192.168.0.50 netmask 255.255.255.0 gateway 192.168.0.71 wpa-driver wext wpa-conf /etc/wpa_supplicant.conf
Note that if you also have a wired interface connected to your
system (as I do), it is necessary to prevent it from being activated
on boot as well, otherwise you might be unable to route packets
correctly. If you have something like this in
/etc/network/interfaces
auto eth0 iface eth0 inet static address ... netmask ... gateway ...
you need to remove of comment the auto eth0
line, as follows:
# auto eth0 iface eth0 inet static address ... netmask ... gateway ...
We can assign a better name to the webcam server, for example
sacam-wlan.localdomain
. To use this name on other
machines, it is not necessary to install a full name server
somewhere. Client Linux boxes can be configured by simply adding the
following line to /etc/hosts
:
192.168.0.50 sacam-wlan sacam-wlan.localdomain
Check the Wireless HOWTO and Linux Networking HOWTO for more information.
If your webcam is an UVC device supported by the uvcvideo module
(check the list of UVC supported
devices), and your are using a recent kernel, the webcam should be
automatically recognized when you plug it into the system. Check the
output of dmesg
for something like this:
... [ 77.970315] Linux video capture interface: v2.00 [ 78.319026] uvcvideo: Found UVC 1.00 device <unnamed> (046d:09a4) [ 78.364309] usbcore: registered new interface driver uvcvideo [ 78.364347] USB Video Class driver (v0.1.0) ...
If the uvcvideo module is successfully loaded, you should find a
/dev/video0
device which corresponds to the webcam. To
check if everything is fine, you can try the following command:
The above comment grabs (and immediately drops) 10 frames from the
/dev/video0
device at a rate of 5 frames per second.
We now describe how to configure the webcam for streaming. In
order to enable streaming with the webcam, you can use ffmpeg and
ffserver. Install the ffmpeg
package (under Ubuntu,
you simply do sudo apt-get install ffmpeg), and create a
configuration file ~/ffserver.conf for
ffserver
. The configuration file defines three streams,
which are available from other machines as the following URIs:
Issue these commands to start the streams:
If you want to stream audio using the Quickcam E3500, you need to install the oss compatibility modules:
Furthermore, you need to add -f audio_device -i /dev/dsp
to the ffmpeg
command line; finally you need to tweak the
ffserver.conf configuration file to add audio capture (that
is, you need to remove the Noaudio
directives).
At this point, you can connect from another machine to view the video stream:
The following picture shows the MPlayer window at the receiving side (the picture on the left has been taken with the Canon PowerShot A80, the picture on the right is the live stream in ASF format captured by the Logitech Quickcam E3500):
relevant linkMJPEG-streamer is a software which allows you to stream live images in M-JPEG format from any UVC-compliant device. M-JPEG is basically a sequence of JPEG images, and most web browser are able to display a M-JPEG stream without the need of any plugin. Also, in my experience MJPEG-streamer is more robust than ffmpeg, so it is highly recommended.
You can use the webcam to capture single images. Note that at the time of writing, the uvcvideo module does not support still image capture from UVC devices. So, you cannot currently take advantage of higher resolutions which some devices allow for still image captures, but you must grab a single frame from the video stream. However, care must be taken, as many image capture programs initialize and close the video device before/after each capture. It is possible that the image is captured before the webcam has settled, resulting in black or very dark frames.
There are many ways in which you can reliably grab single frames
from a UVC video device. I suggest you to consider uvccapture. This
tool streams the live video from the webcam, and is able to save
selected frames as jpeg images. For example, suppose that we want to
grab one frame every 10 seconds, at 640×480 resolution, from the
/dev/video0
video device and save the frame into the
webcam.jpg
file in JPEG format with 95% quality. We can
use the following command on the webcam server
Make sure that no other program is accessing the webcam while you
run uvccapture, otherwise it will complain not being able to access
the video device. You can also grab a single frame from the
ffmpeg
stream using mplayer
. If you have
setup a video stream on the server machine according to the
instructions on the section above, you can use this command to grab a
single frame from it:
In conditions of low light, every CCD sensor produces noise. However, it is possible to improve the quality of the captured image by averaging multiple frames. You can use this command on the webcam server machine (make sure you are not streaming with ffmpeg, otherwise mplayer will be unable to access the video device):
This command grabs 10 frames (-frames 10) from the /dev/video0 device, and saves them as jpeg images which are named 00000001.jpg through 00000010.jpg.
You can also grab frames from the ffmpeg stream, as follows:
The frames can be combined and averaged using the following command (from the ImageMagick package):
I suggest to get a recent version of the gphoto2 and libgphoto2
packages from the gphoto2 home page. Compile and
install libgphoto2 first, and the gphoto2. To access the camera you
need to configure udev
to have the appropriate
permissions on the USB device: please see the
gphoto2 instructions on how to do that. Remember that the
selector on the top of the camera must be set to Auto
, and the
selector on the back of the camera must be set to
Play
, otherwise you will not be able to control the
camera.
To try the camera, first make sure that the camera mode to
Auto
using the top dial, then power on the camera. Now,
give the following command:
The --set-config capture=1
command is used to extract
the lens and enable shooting a picture. --set-config
capturetarget=0
lets the camera store the image on its internal
memory, rather than on the memory card. The actual picture is taken
with the --capture-image-and-download
switch, and the
final --set-config capture=0
is used to retract the
lens.
If you are using a different photo camera, you might be able to alter the settings used to capture a picture. To query the list of available controls, issue the following command:
To query a specific control, use the --get-config
control_name
parameter as follows:
Note that it might happen that the camera is capturing to the internal memory card, even if it reports that it is using the internal RAM. In such situation, capture times are longer and errors might occur when the camera internally switches folder. To make sure that you are indeed capturing the the internal RAM, do the following:
that is, set capture to memory card first, and then switch to capture to RAM. At this point the setting should be saved both on your computer and on the camera, so you do not need to issue this command again.
This is a complete capture command:
gphoto2 --set-config capture=1 # Enable capture \ --set-config capturetarget=0 # Capture to internal memory \ --set-config canonimgsize=2 # Capture at 1024x768 \ --set-config assistlight=0 # Disable the autofocus assist light \ -F 1680 -I 30 # Capture one image every 30s, 1680 images \ --capture-image-and-download # Capture and download \ --filename "%Y%m%d%H%M%S.jpg" # Files will be named YYYYMMDDhhmmss.jpg
More detailed information are in a separate page.
Work in progress...