Being a city dweller, the night sky I usually see is just a black background with the occasional luminous dot. This is just a pathetic imitation of the way the sky is meant to look, but getting so see it the latter way takes some work.

What is important here is to choose your level. If you have a motor-mounted telescope, you will have a lot more flexibility in your subjects than if all you have is a standard DSLR. Since I only have a DSLR, I'm limiting myself to simple stuff in this essay.

1. Equipment

You don't need a telescope for simple astrophotography. A DSLR or any other camera capable of long exposures is sufficient. Although one can use the self-timer on the camera, I'd recommend a cable or IR remote. It is near impossible to not shift the camera ever so slightly when you have to touch it, and Nikon's IR ML-L3 remote[a], for those of us with compatible Nikon cameras, is only $20 or so. For Canon users there's the RC 6 remote[b] - I'm sure there are cheap and small remotes for just about every DSLR out there. A tripod is also a must, as is a memory card that can hold a couple hundred of RAW-format shots - you'll be taking a lot of them.

So much for the photographic equipment.

One requirement for astrophotography is that you must get away from light pollution. This means getting away from civilization, which means that this is a little like camping except you don't get to sleep when it gets dark. It also means some physical discomfort unless you clothe yourself appropriately. You'll be standing still a lot, so bring a bit warmer clothes and shoes than you think you need. I would also recommend getting a dynamo flashlight - getting away from light pollution means getting away from any light source; this tends to make navigation on foot a bit harder unless you bring your own illumination. The dynamo flashlight isn't dependent on you having charged it, and will not run out of charge when you need it the most.

2. Location

Having packed up everything your next mission is to get away from light with the intensity of an old-skool vampire.

3. Exposure Settings

When photographing the skies you can adopt one of two approaches, depending on the result you want:

  • With star trails: Make a single, long, exposure.

  • Without star trails: Make several, shorter, exposures and use a shift-and-add technique to overlay them on each other to get a single long exposure.

The first method is the simplest one. All you have to do is point your camera at something interesting, set the exposure time, and fire away. The second method is the one we will look into here. It involves splitting the single long exposure into several shorter exposures - short enough that the stars don't move appreciably during them - and then adding together the images produced in those. Since the stars will have moved relative to the camera over the course of these multiple exposures[1], we have to rotate and move the shots so the stars coincide.

But that's for the next step. Right now we have to acquire the images. These are the settings I use on a Nikon D40:

Focal LengthApertureShutterISOExposuresTotal TimeEV
10mmf/415s40020-405-10min-2.23 - -1.23
55mmf/45s40060-805-6.6min-2.23 - -2.64
200mmf/5.63s800100-1605-8min-0.26 - -0.94

Normally, I shoot in JPEG/Fine, but even if you, like me, shoot JPEG, switch your camera to RAW for this. Many parts of the image will be very faint, and the encoding noise will be on the same order of magnitude as the signal we're trying to capture.

The goal here is to use the longest exposure we can that doesn't produce star trails. The easiest way to figure out what that is, is to set your camera at the focal length you want to shoot, crank the ISO up all the way to the top, and then keep increasing the shutter time until the trails appear. At ISO 3200, you should have no problem seeing the trails of bright stars, if any.

Once you have your shutter speed, you need to calculate the total exposure time. I use anything from six to ten minutes, depending on the focal length. For shorter focal lengths, I use ten, for longer, six. The reason is the following: I don't move the camera between shots, so as I take my exposures, the region of interest moves across my field of view. Since I can only do image stacking in the region where all my shots overlap, that region shrinks as the number of shots go up. Furthermore, as the focal length increases, the rate of movement of the stars across my field of view goes up, so the region shrinks faster. A rule of thumb: Take more shots than you think you need. It is easy to throw shots away in the stacking phase of the workflow.

4. Aligning and Stacking

Now you should sit with a number of raw shots, totalling a couple hundred megabytes. The next step is to convert these to 16-bit linear TIFF files. For this, I use dcraw[c], for example:

dcraw -4 -T DSC_7252.NEF

This gives me a 16-bit TIFF file without any gamma or exposure correction.

I open the first of these files in Photoshop and crank up the brightness. Since every individual image is greatly underexposed, this makes the image look very noisy, but it is still possible to see the brightest stars in the photo:

Opening one exposure in Photoshop.
Opening one exposure in Photoshop.

Even when reduced to 240x159 the noise is obvious - but the brightest stars can be seen.

Note down the position in pixels for the three or four brightest stars in a text file. Try to get the stars as far apart as possible - ideally one in the center of each quadrant, but this is not a must. The contents of stars.txt for the above image was:

595 591
1493 164
274 978
2716 564

Then run the StarTrack utility[2] to produce control points for Hugin:

StarTrack shots/ stars.txt controlpoints.txt

The algorithm used is described in the StarTrack Algorithm[d] section. Once done, you can create a new panorama in Hugin[e] and add the TIFFs to it. Make sure that the files you add are added in alphabetical order. Do not attempt to align the images. Just add the images and save the panorama, then close Hugin. Open the .pto file you just saved in Notepad or any other text editor, and look for a section that looks like this:

# control points

#hugin_optimizeReferenceImage 0

Now open the file controlpoints.txt, which should look similar to this:

c n0 N1 x593.905659 y591.710648 X595.675769 Y592.257280 t0
c n0 N1 x273.198038 y977.383521 X276.425569 Y976.578328 t0
c n0 N1 x1493.633163 y163.695619 X1493.891373 Y162.876887 t0
c n0 N1 x2716.367813 y564.233374 X2719.503754 Y563.361669 t0
c n1 N2 x595.675769 y592.257280 X598.673302 Y591.553973 t0

Copy and paste the entire contents of controlpoints.txt right below the line that says "# control points" in the .pto file, giving you this:

# control points
c n0 N1 x593.905659 y591.710648 X595.675769 Y592.257280 t0
c n0 N1 x273.198038 y977.383521 X276.425569 Y976.578328 t0
c n0 N1 x1493.633163 y163.695619 X1493.891373 Y162.876887 t0
c n0 N1 x2716.367813 y564.233374 X2719.503754 Y563.361669 t0
c n1 N2 x595.675769 y592.257280 X598.673302 Y591.553973 t0
c n28 N29 x355.688926 y959.326564 X357.931823 Y958.003702 t0
c n28 N29 x1542.872954 y144.555796 X1544.010897 Y144.243151 t0

#hugin_optimizeReferenceImage 0

Save and close the .pto file. Open the .pto file in Hugin again, and verify that the control points are correct. The easiest way is to go to the control point editor and select the two last images. If the control points are still near stars in those two, the rest are probably OK as well. If not, you may have to select other stars.

A pair of good control points
A pair of good control points

Optimize the panorama. You should have a maximum error of much less than a pixel. Done all that? Good! Now your images are aligned and ready to be remapped.

First, select the projection and size you want. I use "rectilinear" and then let hugin decide the field of view and image size. Select HDR remapped output, disable "cropped images", and stich.

Hugin output settings
Hugin output settings

Nona output settings
Nona output settings

Convert the remapped images to PPM format. I use ImageMagick with a command line like this (assuming that we chose remapped/ as output for the stiching:

convert remapped/*.tif remapped-ppm/image%d.ppm

Stack them by ading the corresponding pixel values in all files:

ImageStacking remapped-ppm/ image-stack.pfm

You now have an image stack in image-stack.pfm. The image is in a 32-bit floating-point format, so you need to open it with a tool capable of handling such files.

5. Editing

If you open the image stack output, you are probably very unimpressed with the result. That's ok. Astrophotography is a lot of art as well. The next part is to make that stacked image look good. Open the stack in Photoshop, and use the HDR tonemapping to get it down to 16 bit. I use "local adaptation" with a radius of 100 pixels and the default strength.

What comes next depends very much on your individual taste. Some operations that I find useful:

  • Background noise can be removed by cloning the image layer and then applying a median blur with a high radius (about 30 pixels), followed by a 60-pixel Gaussian blur. This removes all stars from the image without leaving any bright smudges (the median filter does away with it). One can then use the original image layer to create a layer mask that is more transparent the brighter the pixel is. That way, the blurred image can be overlaid on top of the darkest (and noisiest) parts of the image, while leaving the stars and other interesting details untouched.

  • The above method (median + Gaussian blur) can be used to get at the low-frequency imformation in the image[3], which helps to mask off areas where you got stray light from any unwanted source.

  • When you have fixed foreground objects, stack the un-transformed images as well. This gives you a fixed, non-blurred foreground, that you can incorporate into the final image.

6. Files

Due to the range of luminance values involved, and the precision required, I'm using the Portable Float-Map[f] format for intermediate results. It is a format where each sample is stored as a 32-bit float, which makes it very big, but also very accurate. From the 20 - 140 source images (totalling 100 - 600 MB), I keep the following:

  • The final image stack: 68 MB PFM.

  • The final, edited, image: 4 MB JPEG.

  • Exif data from the first RAW shot: 1 kB XMP.

The RAW images I throw away, unless there are special reasons for keeping them.

7. StarTrack Algorithm

The algorithm for tracking stars is quite simple:

  1. Sort the images from first to last.

  2. Set the positions of each star to the initial positions given by the user.

  3. For each image, for each star being tracked:

    1. Consider a square centered on the last known position of the star. The size of the square should be set so it is large enough to cover the movement of a star through two frames. That way, even if the star temporarily disappears in one frame, we'll catch it in the next.

    2. Use a weighted average to find the center of brightness in the square. That is, compute the average of all pixel coordinates in the square, weighted by the brightness of that pixel:

      int oldStarPosX = ...;
      int oldStarPosY = ...;
      double totalWeight = 0.0;
      double xSum = 0.0;
      double ySum = 0.0;
      for (int dx = -size; dx <= size; ++dx) {
          for (int dy = -size; dy <= size; ++dy) {
              double brightness = 
                  getBrightness (
                      oldStarPosX + dx, 
                      oldStarPosY + dy);
              totalWeight += brightness;
              xSum = dx * brightness;
              ySum = dy * brightness;
      // Compute the center of brightness
      // relative to oldStarPosX, oldStarPosY.
      double relPosX = xSum / totalWeight;
      double relPosY = ySum / totalWeight;
      // Update position
      double newStarPosX = oldStarPosX + relPosX;
      double newStarPosY = oldStarPosY + relPosY;
    3. This center of brightness is the new position of the star.

    4. Output the old and new positions of the star.

    5. Update the star's position. The new position will be the last known position.


2010-11-17, updated 2014-11-16