Script to make HDRs with Linux

Este artículo también está disponible en Español: Un script para hacer HDR en Linux.

In my article HDR and Linux I explained my current work-flow to make HDRs using Linux. Still on that subject, in this article I show a script I wrote to make all that process automatic with a single call.

The source code for such script is:

#! /bin/bash

set -e

SELF=`basename $0`


echo "$SELF: `date`"

while [ "$1" != "" ]; do
 case "$1" in
   echo "$SELF: Parameters"
   echo "$SELF:  -d      -> Directory"
   echo "$SELF:  -a      -> Align images"
   echo "$SELF:  -e      -> Create enfuse"
   echo "$SELF:  -t      -> Create and tonemap HDR"



echo "$SELF: Options:"
echo "$SELF:  Directory  = $DIR"
echo "$SELF:  Output     = $HDR"
echo "$SELF:  Align      = $ALIGN"
echo "$SELF:  Enfuse     = $ENFUSE"
echo "$SELF:  Tonemap    = $TONEMAP"
echo "$SELF:  Files      = ${FILES[*]}"

if [ $COUNT -eq 0 ]; then
 echo "$SELF: No files found!!!"
 exit 1

echo "$SELF: Creating output directory:"
mkdir "$HDR"

echo "$SELF: Parsing EXIF information:"
dcraw2hdrgen ${FILES[*]} > "$HDR"/pfs_raw.hdrgen

echo "$SELF: Generating TIFFs"
ufraw-batch --wb=camera --gamma=0.45 --linearity=0.10 --exposure=0.0 --saturation=1.0 --out-type=tiff --out-depth=16 --overwrite --out-path="$HDR" ${FILES[*]}


if [ "$ALIGN" = "Y" -a $COUNT -gt 1 ]; then
 echo "$SELF: Aligning images"
 align_image_stack -a "$HDR"/AIS_ ${FILES[*]} > "$HDR"/align_image_stack.log
 rm -f ${FILES[*]}

if [ "$ENFUSE" = "Y" ]; then
 if [ $COUNT -gt 1 ]; then
  echo "$SELF: Generating enfuse:"
  enfuse -o "$HDR"/enfuse.tif ${FILES[*]} > "$HDR"/enfuse.log
  echo "$SELF: By-passing enfuse:"
  ln ${FILES[*]} "$HDR"/enfuse.tif

if [ "$TONEMAP" = "Y" ]; then
 echo "$SELF: Parsing hdrgen"
 > "$HDR"/pfs_tif.hdrgen
 cat "$HDR"/pfs_raw.hdrgen | while read LINE; do
  echo "${FILES[$i]} $LINE" | cut -d' ' -f1,3- >> "$HDR"/pfs_tif.hdrgen
  i=`expr $i + 1`

 echo "$SELF: Generating HDR:"
 pfsinhdrgen "$HDR"/pfs_tif.hdrgen | pfshdrcalibrate -b 16 -x | pfsout "$HDR"/pfs.hdr

 echo "$SELF: Tone-mapping HDR:"

 echo "$SELF:  Operator = mantiuk06"
 pfsin "$HDR"/pfs.hdr | pfstmo_mantiuk06 -e 1 -s 1 | pfsgamma -g 2.2 | pfsoutimgmagick "$HDR"/pfstmo_mantiuk06.tif

 echo "$SELF:  Operator = fattal02"
 pfsin "$HDR"/pfs.hdr | pfstmo_fattal02 -s 1 | pfsoutimgmagick "$HDR"/pfstmo_fattal02.tif

echo "$SELF: Cleanning:"
rm -f ${FILES[*]}

This script was made to be used with the RAW files generated by a Canon 400D camera, but I think it can be easily adapted to other cameras. Specifically, at "FILES=("$DIR"/*.[Cc][Rr]2)" we are selecting files with "CR2" extension, used by Canon (Nikon generates "NEF" files, by example); and the parameters "--gamma=0.45 --linearity=0.10" passed to "ufraw-batch" are specific of a 400D. I think that the rest should be generic.

First of all, we must download that code to our computer and save in into a file that we can execute. I suppose that the easiest way is to enter as the "root" superuser and create a file named "hdr.sh" inside the "/usr/local/bin/" directory. Then select and copy the code from this page, paste it into the file, and save it; finally, give execute permissions to everyone, with "chmod +x /usr/local/bin/hdr.sh" from the command line.

To use this script, we must first unload all the exposures from the same scene into an empty directory. Then execute the script with "hdr.sh -d _directory_ -a -e -t". We wait patiently for a while, and when the script ends there will be three new files inside our directory: "enfuse.tif", "pfstmo_mantiuk06.tif", and "pfstmo_fattal02.tif".

The "-a" parameter aligns the images; if the photos where made using a tripod, and we are completely sure that they are perfectly aligned, we can drop it and the script will be faster. With "-e" we indicate that an enfuse version must be generated, and we can drop it too; moreover, without "-t" the tone-mapped version will not be produced.


2009/07/27: I have updated this script, to enhance the tonemapping step, using parameters that produce a better result; it can also produce HDRs from a single shot.

2009/09/21: Vincent Tassy has posted an enhancement to this script; his version automatically creates the GIMP file at the end of the process (that is a nice addition), and can also do HDRs from JPEG files (I always shot RAW, never JPEG). Go there and grab his version, it is better than mine: Linux script to generate HDR images from bracketed images.

2009/07/27: Thanks to the help of an anonymous reader, the outputs from the tone-mapping step are now TIFF files; I hope this will improve the quality of the final image.

2011/01/20: The script uses "pfshdrcalibrate -b 16 -x" during the generation of the HDR file; the results are now much better.


Adam Logan said...

Dude, I've been falling in love with Hugin. But a workflow like this sounds slick! Perhaps I'll try and duplicate this workflow in a virtual machine on my mac. Also which Linux distro do you use?

hvdwolf said...

All tools mentioned in the script are also available for OSX, either in binary form or as source suitable to compile on OSX which means that you don't need a virtual machine with Linux.

Seb also wrote another article (http://photoblog.edu-perez.com/2009/02/hdr-and-linux.html) where he mentions the use of rawtherapee as RAW editor. That tool is NOT neccessary for this script, but that tool is the only one not available on MacOSX (currently that is).

eduperez said...

@Adam Logam:

I used Fedora 9 when this article was written; but I have recently moved to Fedora 10 and keep the same workflow. However, I think there is nothing specific to any distribution in this script.

BTW, sorry for the late response.

brak3000 said...

Hi, I was trying to use this script, but kept getting an error at the following line:

echo "$SELF: Files = ${FILES[*]}"

the error is this:

$hdr.sh: 52: Bad ubstitution

I'm not very good with all the intricacies of shell scripting, and was wondering what I was doing wrong. Any help would be greatly appreciated. Thanks!

eduperez said...


That line should print the list of 'valid' files found inside the directory that you specified with the "-d" parameter; currently, this script looks for Canon RAW files (.CR2 extension) only, is that your case?

Perhaps there is an incompatibility with the interpreter; could you please change the first line to "#! /bin/bash" and try again? Thanks.

brak3000 said...

changing the shebang to bash worked perfectly. Thanks for your help!

eduperez said...


I'm glad to know it works now, thanks; I have just updated the script.

Tobias said...

Hi i cant find the dcraw2hdrgen command in the pfstools can you plz tell me where to download that program?


eduperez said...

dcraw2hdrgen is par of the PFSCalibration package, you can find it at http://pfstools.sourceforge.net/pfscalibration.html.
Hope this helps.

Tobias said...

ah ok ... first of all i had some stupid problems 2 find pfscalibration ... (I faild hard)

and several problems occupired while trying 2 install pfscalibration.


but now I tink it's working ...

Other question is it ok if i use your artice as an base 4 my own ... (in german language)
Ill link you :-)

eduperez said...

Yes, of course; and feel free to add a link to that article here, too.

Anonymous said...

Hi Guys,

Could you please tell me how to install pfs tools. I'm still receiving error saying - command dcraw2hdrgen not found.

Thanks in advance,

eduperez said...


dcraw2hdrgen is part of "pfscalibration", you can download from the PFS-Tools site, and then compile it. Some distributions include a "pfscalibration" package, have you checked yours?

Hope this helps.

Anonymous said...

Hi Edu,

Thanks for response.
I downloaded pfstools. What do you mean compile?
I executed configure script and I thought that is enough, but unfortunately that's not all (error persists).
How to check if my package contains pfscalibration?


Anonymous said...

Also, I downloaded only pfscalibration package and I wasn't able to resolve issue, which I mentioned about.

I would be grateful for any help. Can you describet step by step what needs to be done to fully configure pfstools and all other things necessary to run your script.


Anonymous said...

Ok, I was able to resolve this issue. Sorry for messing on your blog.

Thanks again.

Anonymous said...

$ sh hdrCreate.sh
hdrCreate.sh: czw, 7 cze 2012, 15:13:44 CEST
hdrCreate.sh: 43: hdrCreate.sh: Syntax error: "(" unexpected

eduperez said...


Try to launch it with "./hdrCreate.sh" (you may need to change the permissions with "chmod +x hdrCreate.sh").

Hope this helps.

Anonymous said...

I had some problems in Debian/Crunchbang (testing). ufraw produces ppm files instead on TIFF and Gimp gives error with option -b.

Minor updates in the script fixed this without problems. The pictures is still fantastic.

Thanks for the great script.

dhill said...

The rm -f ${FILES[*]} is kind of surprising.

dhill said...

And the Vincent Tassy's script was moved to:

Horea Christian said...

Hi there, I liked your script and updated it a bit. I also created a GitHub repo for it so it's easier to keep up-to-date (https://github.com/TheChymera/stackHDR). Additionally, I wrote an article about it on my blog (http://chymeric.eu/blog/2014/09/23/stack-bracketed-photos/) and also linked to you as the original author - I'd be very happy if you could link back to me!

Post a Comment