Controlling a camera in Linux - part 1


Here is a quick guide to controlling a camera from Linux. I first messed around with this in early 2011. Without (yet) a means to move/position the camera, I have found little use for it - but perhaps you may find it useful.

Obviously there are various applications, such as bracketing (possibly for HDR), and time lapse (intervalometer), which do not require movement of the camera (indeed it should he held steady), but many cameras have support for this - since I have upgraded my DSLR, these became less relevant for me.

Once you add the ability to swivel the camera, this adds additional applications such as programing/choreographing video, or taking long exposures of the night sky (automatically tracking with the rotation of the earth). These are obviously best done with a portable setup, ideally with the ability to control motors / path via a readily available UI, such as an Android phone. Using the gyro/accelerometer available in any modern smartphone, inclination of the camera can be managed this way, if you (and your camera!) are this way inclined :)

You could do all this with an 8-bit micro (see previous post), and a BT UART link - but if you want to load/process the images, this is where the processing power of the Parallella comes in.

I use gphoto2, a nifty command-line app built on libgphoto2. The list of supported cameras can be found here.

Note that I have no bothered with configuring udev rules to set permissions for non-root users. I might cover this in a later post. Install gphoto2:

linaro-nano:~> sudo apt-get install gphoto2
Connect the camera (using an OTG cable). If you type dmesg, you should see something like
usb 1-1: new high-speed USB device number 3 using zynq-ehci

And so you can search for the camera using

linaro-nano:~> **sudo gphoto2 --auto-detect**
Model Port
----------------------------------------------------------
Nikon DSC D60 (PTP mode) usb:001,003

As you can see, it has detected my Nikon D60 - my old project DSLR which is the victim of my various experiments. If I want further information about the camera, the following command has useful output.

linaro-nano:~> sudo gphoto2 --summary

Now, to show we are reading the current information from the camera:

linaro-nano:~> sudo gphoto2 --get-config=/main/capturesettings/focallength
Label: Focal Length
Type: RANGE
Current: 55
Bottom: 55
Top: 200
Step: 0.01
And now I twirl the zoom knob on the 55-200mm VR lens:
linaro-nano:~> sudo gphoto2 --get-config=/main/capturesettings/focallength
Label: Focal Length
Type: RANGE
Current: 105
Bottom: 55
Top: 200
Step: 0.01

And so we see the focal length has moved from 55mm to 105mm - thus we can read the current configuration of the camera.

In previous hacking, I used an 8-bit AVR with a usb host chip to dump the current aperture, focal length, and exposure settings to an LCD screen. Note that you can also control some of the settings.

You can obtain a list of the supported settings by running

linaro-nano:~> sudo gphoto2 --list-config

Say I then see the ISO setting, and want to see whether I can control this.

linaro-nano:~> sudo gphoto2 --list-config | grep iso
/main/imgsettings/iso
/main/imgsettings/isoauto
/main/imgsettings/autoiso
/main/capturesettings/isoautohilimit
linaro-nano:~> sudo gphoto2 --get-config=/main/imgsettings/iso
Label: ISO Speed
Type: RADIO
Current: 1600
Choice: 0 100
Choice: 1 200
Choice: 2 400
Choice: 3 800
Choice: 4 1600
Choice: 5 3200

So there are 6 settings I can use (the camera was already in autoiso mode - if it was not, likely this command would fail until you set the correct mode). I now wish to set it to 200.

linaro-nano:~> sudo gphoto2 --set-config=/main/imgsettings/iso=200
linaro-nano:~> sudo gphoto2 --get-config=/main/imgsettings/iso
Label: ISO Speed
Type: RADIO
Current: 200
Choice: 0 100
Choice: 1 200
Choice: 2 400
Choice: 3 800
Choice: 4 1600
Choice: 5 3200

And I can confirm via the camera display that it has indeed set the ISO to 200.

As for triggering a capture, I will demonstrate how to take a bracket of 3 images:

linaro-nano:~> sudo gphoto2 --set-config /main/capturesettings/exposurecompensation=12 --trigger-capture
linaro-nano:~> sudo gphoto2 --set-config /main/capturesettings/exposurecompensation=15 --trigger-capture
linaro-nano:~> sudo gphoto2 --set-config /main/capturesettings/exposurecompensation=18 --trigger-capture

This has taken a series of 3 exposures, storing them on my camera.

I'm now switching to ArchLinux since the gphoto2 2.5.3 which comes with Ewwbuntu does not seem to perform the --capture-image and --capture-image-and-download functions correctly.

With ubuntu, you can use the following workaround:

linaro-nano:~> sudo gphoto2 --list-files

and download all the photos using

linaro-nano:~> sudo gphoto2 --get-all-files
Downloading 'curve.ntc' from folder '/special'...                            
Saving file as curve.ntc Downloading 'DSC_2356.NEF' from folder '/store_00010001/DCIM/100NCD60'... Saving file as DSC_2356.NEF
....

But the way I generally do this, as shown using gphoto2 2.5.4 running on ArchLinux is:

[root@ParallellArch ~]# gphoto2 --trigger-capture
[root@ParallellArch ~]# gphoto2 --capture-image
New file is in location /capt0000.nef on the camera                          
[root@ParallellArch ~]# gphoto2 --capture-image-and-download New file is in location /capt0000.nef on the camera
Saving file as capt0000.nef Deleting file /capt0000.nef on the camera Deleting 'capt0000.nef' from folder '/'... [root@ParallellArch ~]# ls -l capt0000.nef; strings capt0000.nef | head -2 -rw-r--r-- 1 root root 7624570 Oct 1 20:48 capt0000.nef NIKON CORPORATION NIKON D60

Please see my followup post on the differences between these three commands (all of which cause the camera to take a photo).

Similarly, if I had hooked up my Nikon D7000, which has LiveView, I expect I would be able to capture a movie using --capture-movie. Since I have only had the D7000 for 2 years, I haven't yet explored the added functionality this may offer in terms of controlability, but I will do so in the coming months.

My old D60 does not appear to support setting the focus at all, while apparently even on newer Nikon and Cannon cameras this is quite limited.

This is a bit disappointing, however I expect for most applications of unattended photography, you will be using autofocus, or an unchanging manual focus (say infinity, for stellar photography).

Ultimately I intend to drive the zoom ring using a motor, so may also consider doing this for the focus ring. But this is fairly far into the future, and only really needed if I implement real-time target acquisition and can manually focus on the strength of this better than the camera can (a bit of a pipe dream).

Soon, I will be exploring the Python library for gphoto2, and will provide a separate post using this.


Back to Blog


comments powered by Disqus