Thursday, 23 August 2012

Canon 400D control, downloading, HDR and timelapse

Looked at controling the Canon 400D with the RPi over USB. gphoto2 seamed a good start, this was available through apt-get on the raspian distro I am using, information from Also looked a HDR and tone mapping, also managed to download pfstools through apt-get , information from Also looked at enfuse available through apt-get and information from

gphoto2 was basically working. However I wanted to take continuous time lapse photographs. It appeard to struggle after 7 frames for some reason. I'm unsure if the camera's resources were running out or the RPi's. I will need to investigate. I was taking dual JPED and RAW images. I manages to "fuse" three JPEG images of different exposures into a single TIFF image. I'm not sure if it was a HDR (16 bit float?) image but the exposure was excelent across the hole image. I need to solve the 7 frame timelapse issue and find a RAW file reader. The workflow I am looking for is somthing like.

gphoto2 => Canon RAW x3 (exposure bracketed)
Canon RAW => ?pfsindcraw? => HDR x3 (exposure bracketed)
HDR x3 (exposure bracketed) => enfuse => HDR x1 (Many 8 stops + dinamic range)
HDR => pfstm => JPEG (Tone mapped)

The idea is to use the RPi to do all this on the fly, hopfully as fast as the time lapse, so that the disk space requirments are very greatly reduced as the three RAW files are converted and deleted as more pictures are taken.

Part 2 So I had some success with bits of the system. I looked at the Photography Projects thread on the site. I found I had to get the small C file as discussed on a linux forum and compile usbreset executable. This built using cc usbreset.c -o usbreset followed by a chmod +x usbreset. I then wrote a bash script that called usbreset /dev/bus/usb/001/00x between calls to gphoto2. I stole the bash script from the Photography Projects thread that automatically worked out where the camera was attached. I found the camera kept moving around when the camerea was swiched on and off but the script could find it reliably.

The key to the discovery of the USB device is...
dev=`gphoto2 --auto-detect | grep usb | cut -b 36-42 | sed 's/,/\//'`
resetusb /dev/bus/usb/${dev}

I chose to call gphoto2 three times in the script to capture three images. I tried the single command line aproach shown in Photography Projects but I could not get it to work.
I used gphoto2 in --shell mode to discover the settings. Found for the canon 400D i needed to use
--set-config-index /main/capturesettings/exposurecompensation=0
--set-config-index /main/capturesettings/exposurecompensation=6
--set-config-index /main/capturesettings/exposurecompensation=12
Other combinations of command line options did not seam to give reliable results. The thread discusses a Nikon and the use of --set-config-value, I could not get this to work as expected for me.

I used the --filename xyz.jpg and --force-overwrite although I could not get it to work as I expected if the --filename appeared more than one. Therefore used seperate command lines for each photo aquired.

enfuse worked very well. With three small JPG images at three exposures they were combined into a single JPG with superior exposure. However I ran out of memory or TMP scratch space when I tried to produce a HDR image, eg floating point or 32 bit. Having reread the manual it looks like I may be able to set the scratch directory using TMPDIR enviroment variable and also set the cache size and buffer size. There is a table in the manual that is for systems with a lot more memory. I will try a setting in the same perportions scaled to RPi available memory. Note the available memeory will depend on how you have ivided up available memory between CPU and graphics. Raeding the manual it looks like enfuse does a weighted blens so it will reduce noise if given many pictures. enfuse did not do any tone mapping so the output was a suprior exposure but still natural. I played with the pfstools but I think because enfuse generated a LDR JPEG image the results were not very spectacular. The picture were quite ordinary. I need to retry this process and I think I can make improvments.

Raw images were too large to handle and I cause errors. I will stick with small JPG files for now. I may need to revisit RAW images. I think the lack of SD card space may be adding to the problems.

I will try the following workflow.
(gphoto => small jpg ) x 3
(x.jpg x 3) => enfuse => HDR_file.??? x 1 (Format not yet known)
HDR_file.??? => pfsin => pfstmo => frame.jpg.


  1. I have built (correctly??) pfscalibrate (this set isn't in pfstools) on the RPi and managed to do some true HDR tone mapped images. However I had to keep the JPGs to around 1500px wide or the whole thing gave errors and then crashed. Having seen how much RAM and diskswap this chain takes on my virtual Debian laptop it isn't surprising. Even if you use JPGs the chain expands these to the pfs stream and then the hdr images and these files are big.

    If you use enfuse you can't make HDR from that image. A lot quicker too!

  2. I must get back to this project one day. I am tempted to write a cheap HDR app for RPi that is very memory friendly, but I think I will end up spending a lot of time debugging it. I have an old Nikon Coolpix 950 that I intend to remove IR filter from. It has a serial port! HDR/IR/time-laps ?