Astrophotography and python

I’ve recently gotten out to take some wide-field astrophotography images for the first time in a long while. In processing the images (a series of 27 1-minute exposures for the most recent set), I’ve gotten to thinking again about how best to process my image data. There are a lot of tools available, but there seems to be a fairly large division between amateur and professional tools available. There are some very good amateur tools out there, including the free IRIS (which I use) and Deep Sky Stacker (DSS), and the commercial PixInsight and Nebulosity. They all have some drawbacks for me; my main home computer runs Linux, and the first two are Windows-only.  Although I am able to run IRIS under Wine, it is not ideal. DSS I haven’t gotten to work completely on my Linux machine, either in Wine or a VirtualBox Windows XP install. Nebulosity looks good and runs on Mac, but not Linux, and PixInsight is truly cross-platform, but expensive.

The other option is to explore professional tools for astronomical processing. The modern astronomical community largely uses Python nowadays, and tools include PyRAF and PyFITS for processing image data. Since I am a scientist by training (though not an astronomer), and now a full-time Python developer, this route is appealing to me. I’ve spent a little time investigating possibilities, and it seems that surprisingly few amateurs are using these Python tools. Most of the processing steps will be very similar. The first major difference I could see is in the sensor data. Professional sensors are generally monochrome CCDs, with color filters that may be applied. Amateur imaging (including mine) is usually done with a digital SLR which has a color CMOS sensor. The quality and resolution of these sensors is very good, but they have the color filter built into the sensor. Your 10 mexapixel camera is really taking 2.5 million red, 2.5 million blue, and 5 million green samples in a Bayer array.  That’s fine, and there are lots of tools for processing raw files from DSLRs, but they almost always do interpolation and scaling of the pixels while converting them, and to use the image as raw sensor data, you want to get it from the camera directly and process it before it is altered.

Calibrated sensor image

The only attempt to convert Canon raw (.CR2) files to FITS files for astronomy that I found was cr2fits, which uses dcraw to do the conversion.  That worked, but the FITS files were interpolated and scaled.  Luckily, dcraw has options to output the raw 12-bit sensor data, unscaled and uninterpolated, and I added that ability in a fork of cr2fits.  Now I am able to load the sensor values into numpy arrays and manipulate them in python.  I’ve converted them to floating point arrays and done a simple calibration with the “dark” images I took the same night.  A portion of a calibrated image is shown here, as raw grayscale values and as a colorized version showing the Bayer array.

Colorized sensor image


The next step will be to figure out how to do alignment and stacking. Some tools that may help include alipy (which uses PyRAF) and, which has downloadable software in addition to their blind astronomy solver on Flickr.

5 thoughts on “Astrophotography and python

  1. I’m exactly at the same point. For now I use PixInsight LE, but I miss a scripting system to stretch the histogram of an iterative, per example. So I will follow your blog with interest :-) .

  2. here is a crude and simple python script that just stacks. nothing else.

    from glob import *
    import re
    from PIL import Image, ImageChops

    def sorted_nicely( l ):
    “”” Sort the given iterable in the way that humans expect.”””
    convert = lambda text: int(text) if text.isdigit() else text
    alphanum_key = lambda key: [ convert(c) for c in re.split(‘([0-9]+)’, key) ]
    return sorted(l, key = alphanum_key)

    #### The Stacker #####
    def stack():
    files = glob(“orion/*.tif”) # import stack files
    s = set(files); files=[] # sort stack files
    for x in sorted_nicely(s):
    print(x); files.append(x)

    darkframes = glob(“darkframes/*”)
    df =[0]) # open dark frame
    a = files[0] # open first frame
    im1;im1 = ImageChops.subtract(im1,df) # subtract dark frame from first frame
    for n in range(len(files)-1):
    print n
    b = files[n+1]

    im2 = ImageChops.subtract(im2,df)# subtract darkframe from image

    newimage = ImageChops.add(im1,im2,2) # add first frame and second frame–this is the ‘stacking’
    im1 = newimage
    save= “orion.tif”

  3. Pingback: Nightscape image processing with IRIS « Chris Winstead

  4. Pingback: Aligning astronomical images with alipy | Kelsey's weblog

  5. Pingback: Reprocessed Milky Way image | Kelsey's weblog

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>