Making a panoramic HDR image using Hugin
In order to be able to render scenes in Yafaray with a realistic background and just for sake of learning I decided to create a HDR (high dynamic range) image of the inside of my apartment. The fact that it’s HDR is important because it means it can capture the fact the the window is a lot brighter than the rest of the room and this means the HDR image can actually be used for lighting as well as a background, i.e. the lighting effect of the window is simulated when performing a render.
The first step is to take photos of the scene in all directions so they can be composed in to a panoramic image. The important thing is to have the centre of perspective of the camera in the same position for evey photo. This ensures there are no parallax effects between shots. The centre of perspective is actually the entrance pupil of the lens (http://doug.kerr.home.att.net/pumpkin/Pivot_Point.pdf). The ideal way to ensure this point stay in the correct place is to use a tripod and a panoramic head. These together allow you to take a picture in any direction while maintaining the centre of perspective in a fixed location.
However I decided to keep things simple and not use either of these tools, and instead used a circular table with a top I could pivot around its centre point. This however restricted me to taking pictures around the horizontal plane, nevermind, this is the most interesting area anyway.
Finding the centre of perspective
The simple way to do this it to position the camera in your panoramic head (on the table in my case) in roughly the right place then line up two items in front of the camera. For example, I used a chair infront of a door frame. Now rotate the camera on its pivot slightly to the right and look through the view finder again, if the closer object has moved to the left the camera’s centre of perspective is infront of its pivot point. You should move the camera back slightly. Or vice versa obviously. By repeating this you should be able to get the camera in a position where objects which are lined up in one shot stayed lined up no matter how you rotate the camera.
Taking the photos
When taking the photos ensure there is enough overlap between each pair of adjacent pictures to be able to smoothly join the pictures later. The important thing is not just the area of overlap but also the amount of features in the overlap. For example an overlap is no use if all it contains is bare featureless wall (I managed to fall in to this trap).
The other factor as we’re planning on using these pictures for rendering is exposure bracketing. You want to make sure that for every angle you take a picture at, you have a series of photos which covers the range of exposure necessary to capture details in the parts of the scene of all light intensities. For example, this is the series of photos I took for the part of the room where the window is:



Another thing to be wary of is not to take too long, as lighting conditions could have changed by the time you back round to where you started (this also happened to me). If just doing a horizontal plane panorama like I did, I would recommend starting at the place least likely to change by the time you back round to it.
Stitching the photos together with Hugin
Hugin, is an opensource tool for photo stiching. I’m not going to go in to massive detail on how to use this tools. But the gist is as follows:
1. Start a new Hugin project, add all the photos you took of the scene
2. For each set of exposure bracketed photos mark features in each photo which correspond to features in the others
3. For each pair of adjacent photos with overlapping sections, mark features in one photo that correspond to the other
4. Allow Hugin to match up the photos into a panoramic composition.
5. Preview the result to check it is ok
6. Use Hugin to generate a final EXR image
7. Use qtpfsgui to view and check the created EXR
If only it had actually been this simple for me. The feature matching process, is very easy, and Hugin’s interface is very easy to use for this task. The alignment solving also went relatively smoothly. The problems began with EXR output.
Viewing EXR files
EXR is the format specified by OpenEXR, it is capable of storing pixel values at much greater precision, over a greater range of intensities than LDR formats like jpeg and png. qtpfsgui is a tool for viewing and tone mapping HDR images. Its tone mapping features are very useful for converting an HDR image to an LDR one. However its also very useful simply for viewing EXR files as it has a tool for changing the exposure of the current LDR preview, this allows you to see both the bright and the dark parts of the image.
I did however find a bug in qtpfsgui 1.9.3 (the latest at time of writing), which meant I couldn’t save tone mapped images. However the fix was easy and I’ve attached the patch file below.
Hugin uses a tool called hugin_hdr_merge to merge together images taken at different exposure levels. The first problem I came across with this was a strange black blobby artefacts on the left had side of the window.

However after some investigation I came to the conclusion this was because I had started taking photos at the window, and my very last photo also overlapped with this left hand edge of the window. But by the time I took the last photo the sky had become significantly less cloudy which was presumably somehow confusing the EXR merger. I fixed this by cropping the last image to not include the window part of the scene. (There is a cropping tool in Hugin, it doesn’t actually affect the source image, it just determines which parts Hugin will use)
The second problem was that EXR merger seemed to introduce a lot of noise in certain places. In particular it seems to happen with exposure bracketed parts of the scene, in parts of the image which are very dark in less exposed photos. The worst place is on the sofa arm as can be seen here:

A similar problem was that noise sometimes appeared in high contrast areas, for example around the window frame.
These problems were quite frustrating, because I knew if they had occurred in an LDR image I could easily open them up in the gimp and touch up the noisy areas. However I didn’t have any tools for editting an HDR image. I tried for a while getting CinePaint to compile and run, but I ran in to too many problems getting this to work and decided to create a simpler solution, exrunfuse.
Exrunfuse
Exrunfuse (EXR unfuse), is at tool I created using the OpenEXR libraries to edit EXR files using normal LDR tools like the gimp. As command line arguments exrunfuse takes an exr file, and a range of EV values in to which to decompose the image, and a prefix to use for output files. It then writes a series of png files, each exposed at a different level. For each exposure level, 2 identical files are written, one which you may edit, and one which is kept for reference.
When editting a particular part of the image you should choose the png file which has the most appropriate exposure for that part of the image.
Once happy with the edits, Exrunfuse can be invoked again to recombine the editted png files back in to an exr. When it is invoked to re-fuse you should also pass in as an argument the original exr file. Then, for each png file it compares the editted version with its original reference version, and for each pixel it finds to have been editted it copies the editted pixel in to the new EXR file (taking into account the exposure settings and gamma), uneditted pixels are copied directly from the original exr file so no loss of precision occurs.
This is the exrunfuse source: exrunfuse-0.1.tar.gz
Memory issues
The ideal size for EXR background to be used in rendering is actually very big. If you assume you want to make a render using a virtual camera with a field of view of 45°, and you want the rendered image to have dimensions of 1024*768, then that works out as 22 pixels per degree. To have a crisp background you want at least one pixel of background per pixel of render so that means the background also has to have 22 pixels per degree as well. Which for a 360° by 180° background file works out as 7920*3960. So just to make it a nice round number I went for 10000*5000.
However when trying to do the full Hugin stitch, I got an error message from Hugin saying it was out of swap space. However after a bit of googling I discovered this doesn’t actually refer to virtual memory swap space, but to Hugins own swap files that it creates in the /tmp directory. My solution was to change the TMPDIR environment variable to point to a device where I had more space.
The ceiling and the floor
Up until now, theres been a huge black void representing the up and down directions in my panoramic images:

Ideally I would have taken pictures in these direction too (infact I did take some but without a tripod and panoramic head there was too much parallax error to smoothly merge the photos in). So instead I’m just going to bodge in a color (using my exrunfuse tool again) above and below to approximate the lighting:

Obviously this is fairly crude, but it should suffice as long as these parts of the image are not directly visible to the camera. The most significant part of the scene lighting-wise is the window so these approximations should go unnoticed. I couldn’t have just left them black though as this would have been too obvious in the lighting effects.
Results
So here are some images rendered using this HDR background. They’re all rendered using Yafaray with direct lighting.
This first image only shows a small part of the background, but demostrates the use of the background for lighting.

The HDR background is the only light source in this image, so in practice the window provides the bulk of the light, while more is provided by the walls in the background which are reflecting the light of the window. Notice how soft and realistic the shadows on the table look.
This next image is the same scene but with a depth of field, the aperture size used was 0.1.

Note that to get a good DOF effect more anti-alias samples are needed, but also bear in mind that as you increase the number of anti-alias samples you may decrease the number of IBL samples used and still get a similar quality result.
Finally in this image and movie I’ve tried to demonstrate how even though the window appears over-exposed in the scene generally, detail can still be seen when the light is reduced due to passing through dark glass or reflecting off a dark surface. This is the way a real camera would behave.

Ofcourse, if you actually want to be able to view the whole dynamic range of the scene, you can save the rendered scene as an EXR and use qtfpsgui to tone map it:


















































