chicam 1.4.1

© 2005-2012 Horst Meyerdierks.

This programme is free software; you can redistribute it and/or modify it under the terms of the GNU General Public Licence as published by the Free Software Foundation; either version 2 of the Licence, or (at your option) any later version.

This programme is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licence for more details.

You should have received a copy of the GNU General Public Licence along with this programme; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

chicam is a small suite of command line utilities to process frames from webcams or digital SLRs. The central engine is the stack utility, which will read one or more frames and shift and stack them into a single average image. But you need a few other utilities to help stack do its job. Another aspect of chicam is the tone-mapping of high dynamic range data.

Using chicam applications

File formats

This is a grey graphics format that stores the brightness of each pixel as an 8-bit or as 16-bit integer, i.e. numbers from 0 to 255 or numbers from 0 to 65535. The files can be recognised by their name ending ".pgm". stack can take these frames as input. If it makes colour output, it will put the grey input values into each colour channel - red, green and blue.
This is the colour graphics format equivalent to the grey PGM. It stores the brighness in the red, green and blue channels each as 8-bit or as 16-bit integer. The files can be recognised by their name ending ".ppm". stack can take these frames as input. If it makes grey output, it will use only the green input and ignore the red and blue input.
This is a professional image storage format. Although it can store 8-bit integers, it more commonly stores 16-bit integers or 32-bit floating point numbers. FITS images are not in colour, colour images would usually be stored in three separate FITS files, one each for the red, green and blue channel. FITS files usually have names ending in ".fit" or ".fits". chicam does in general not recognise ".fit" files and considers ".fits" files to be grey images.
chicam introduces this format for grey images. The file names end with ".fits". The utilities in chicam interpret these files as single grey images. stack can create FITs output, and it can also take FITs input frames.
chicam introduces this format for colour images. The utilities in chicam interpret a given file name ending ".fitc" as a colour image that consists of three FITS files, the names of which end ".fitr", ".fitg" and ".fitb". stack can create FITc output, and it can also take FITc input frames.

Stacking frames

The stack utility will read one or more frames and shift and stack them into a single average image in FITs or FITc format. It can optionally subtract a FITs/FITc dark frame from each input frame and it can divide each input frame by a FITs/FITc flat field. What stack can't do is figure out the correct shifts between the frames.

This is where the idea of a registry file comes in. The registry is a text file that lists the frames and their shifts. We begin with, a registry that lists the frames with zero shifts, and we improve that by running the regist utility. It will go through the listed frames and determine the proper shift of each frame compared to the first. regist puts out a new registry with the same frames listed, but with their shifts determined. is a little helper utility that simply compiles the frame file names into a registry file. It assumes that all files in the working directory that have names ending ".pgm", ".ppm", ".fit", ".fits" or ".fitg" are frames to be used. For ".fitg" the assumption is also that it is one third of a FITc image, i.e. that there are corresponding ".fitr" and ".fitb" files to make them an RGB triplet. You can then use a text editor to remove files from the registry that you do not want to use.

Below is a typical sequence of commands to stack a bunch of frames that you have already collected into the working directory: > reg0
regist reg0 > reg1
stack reg1 output.fits

If you have only a single frame, but want to convert it from, say, PPM to FITc, you still have to create a registry for the one file: > reg0
stack reg0 output.fitc

Dark correction

The frames contain defects and a low level of signal known as bias and as dark current. You can capture these effects in dark frames: Take exposures of the same length as the "target frames", but with the lens cap on. When you reduce your data, use separate directories for the dark and target frames. If you take several dark frames, stack them into a master dark:

cd dark > reg0
stack reg0 dark.fits
cd ..

When it comes to stacking the target frames, you can use the dark thus:

cd target > reg0
regist reg0 > reg1
stack -d ../dark/dark.fits reg1 target.fits
cd ..

Flat correction

It can also be useful to apply a flat correction to your target frames. To take a flat field, point the camera with lens at an evenly bright surface and take a number of frames of it. Perhaps rotate the camera from frame to frame. Also take dark frames to correct the flat frames. In spite of the field rotation, you stack the flat frames without shifts:

cd flat > reg0
stack -d ../darkf/dark.fits reg0 flat.fits
cd ..

The master flat has recorded the vignette of the lens and the dust on the detector. Dividing your target frames by the flat can correct for these undesirable effects. If you also dark-correct your target frames, their stacking looks like this:

cd target > reg0
regist reg0 > reg1
stack -d ../darkt/dark.fits -f ../flat/flat.fits reg1 target.fits
cd ..

stack will read each frame listed in the registry, then subract the dark from it, then divide the result by the flat, and only then shift the result and add it to the stacked image.

Getting frames into PGM or PPM format

This is somthing chicam does not do. PGM and PPM are two variants of the libpbm format. If you run Linux the libpbm utilities to convert between its formats and virtually any other common image format should be readily available as part of your Linux distribution.

If your frames come from a digital camera and if you take raw images with it, then you can obtain the dcraw utility from Some Linux distributions (e.g. Debian) offer it as part of the distribution, making it very easy to install. If you use raw images, it is advisable to have dcraw convert it to 16-bit PPM rather than the common 8-bit PPM. Otherwise you lose a lot of the advantage of taking raw images in the first place. chicam will read 16-bit PPM without problem.

HDR processing

High dynamic range (HDR) data are images that have very subtle contrast at very low and at very high brightness. Such data are difficult to cast into an image format and to view on a computer screen. One either has to reduce the contrast so much that the sutble detail is lost, or one has to show full contrast at some intermediate brightness and allow the rest of the image to be black (underexposed) or white (overexposed).

The first problem you will have with an object for photography that has high dynamic range is to record the data. The JPG output from the camera won't do. Raw output from the camera helps. But in general you will take multiple raw images and vary the exposure time from one image to the next.

The first problem for this suite of utilities then is to combine the different exposures into a single data array. This problem is similar to stacking multiple frames into one image. Dark subtraction is even more important here than when stacking frames of equal exposure. In general this goes as follows:

cd target > reg0
regist reg0 > reg1
vi reg1
hdrfill -d ../dark/dark.fits reg1 lumi.fits
cd ..

The registry has to be edited before hdrfill can use it correctly: For each frame, change the third number from 1 to the exposure time of the frame. You can use any common unit, seconds, milliseconds, numbers 1 2 4 8 16, whatever. hdrfill will divide the data from each frame by its exposure before averaging the numbers from the frames. You also must re-order the frames into decreasing exposure.

There remains the problem of cleverly mapping the HDR data such that the human eye can see the fine detail while retaining some of the large scale brightness variations. The algorithm used is that of Michael Ashikhmin (2002), "A tone mapping algorithm for high contrast images", In: Paul Debevec, Simon Gibson, Eurographics Workshop on Rendering, p. 1-11, Given the HDR data (the luminance) from above, hdrtone performs the tone mapping, and gamma makes the final gamma correction for the computer screen.

hdrtone lumi.fits tone.fits
gamma tone.fits image.fits

All utilities

chicam covers a bit more ground than just stacking PPM frames into FITS images. Here are descriptions of all the utilities in an order that you might use them in your reduction routine.

Usage: > outreg creates a frame registry listing all frames in the working directory. Frames are detected as files with names ending with

PGM grey frames.
PPM colour frames.
FITS grey frames.
FITS grey frames.
FITc green channel frames. When these are found it is assumed that the red and blue channel also exist. In the registry this FITc colour frame is listed as ".fitc" instead of ".fitg", as regist and stack require.

The format of the registry is:

    0     0 1.000000e+00 crw_9443.ppm
    0     0 1.000000e+00 crw_9445.ppm

There is one line per frame and four fields in each line. The lines are in free format, meaning the fields do not have to be aligned vertically. The first two fields are integer numbers and record the shift in x and y resp. The third field is a floating point number and may be modified by quality to record the quality of the frame. The fourth field is the frame name. simply sets the shift of all frames to zero and the quality to 1.



  regist [-m] [-l lo hi] inreg

  regist    inreg > outreg
  regist -m inreg > outreg
  regist    -l lo hi inreg > outreg
  regist -m -l lo hi inreg > outreg

regist reads a frame registry and writes a new one. The output registry lists the same frames, but the shifts are re-calculated, based on the cross-correlation between the frame in hand and the first frame in the registry.

Without the "-m" flag the input shifts are taken as guess values and the cross-correlation is two-dimensional. With the "-m" option the input shifts are ignored, and the cross-correlation is done one-dimensionally separate for the x marginals and the y marginals. A marginal is when all columns or all rows are averaged into one. Determining the shifts by margnials is faster and requires less memory, but it is not as accurate. The idea is to register by margninals for a good first guess, then to register two-dimensionally.

The algorithm cannot deal with frames that are not at the same level of brightness all around their edges. This makes it difficult to handle frames that show part of the Sun or Moon with the limb running through the field of view. You can attempt to render the limb - and the area of sky background - harmless by declaring a brightness range within which the background falls. Say, if the sky background is between brightness values 10 and 50, then use

regist -l 10 50 inreg > outreg

regist will then attempt to neutralise the pixels in that brightness range. This may not always work.



  stack [-d{s|c}] [-f{s|c}] registry{s|c}

  stack registry output.fits
  stack registry output.fitc
  stack -d dark.fits registry output.fits
  stack -f flat.fitc registry output.fitc
  stack -d dark.fits -f flat.fits registry output.fits

stack reads the frames listed in the registry and aligns and averages them. The output can be grey FITs or colour FITc. If colour input is converted to grey output, then it simply copies the green channel and ignores the red and blue channels. If grey input is convereted to colour output then all three output channels are identical.

Note that with a registry of only one frame stack can be used to convert from PGM or PPM format to FITs or FITc format. Also note that a registry with all frame's shifts set zero - as provided by - can be used to stack a master dark or master flat, i.e. to simply average the frames without shifting them.

stack can optionally subtract a dark frame from each input frame and it can optionally divide each frame by a flat field. This is done with the "-d" and "-f" options, which are followed by the name of the dark and flat resp. Dark, flat and output must all be FITs or all FITc. Again, note that a registry of one frame can be used to dark- or flat-correct the frame and convert it to FITs or FITc.

If three or more frames are stacked, the linear regression of the frame shifts is calculated and written to standard output. This can be useful for drift stacks where the direction of the drift is celestial West. stack telling you the slope of the movement of the object tells you the orientation of the frame in celestial coordinates.



  mosaic registry{s|c}

mosaic reads the frames listed in the registry and aligns and averages them. The registry must be purely FITs or FITc and contain no PPM frames. The output can be FITs or FITc. If colour input is converted to grey output, then it simply copies the green channel and ignores the red and blue channels. If grey input is convereted to colour output then all three output channels are identical.

While this appears as a lesser variation of stack, the crucial difference is in the size of the output image. stack puts out only the overlap of all input frames, but mosaic puts out the rectangle that contains all input frames. The intention then is more that of assembling stacks into larger mosaics and not of stacking original frames into images of less noise.



  hdrfill [-d{s|c}] [-f{s|c}] [-l lo hi] registry{s|c}

  hdrfill registry output.fits
  hdrfill registry output.fitc
  hdrfill -d dark.fits registry output.fits
  hdrfill -f flat.fitc registry output.fitc
  hdrflll -d dark.fits -f flat.fits registry output.fits
  hdrfill -d dark.fits -l lo hi registry output.fitc

hdrfill reads the frames listed in the registry that have different exposure times and combines them into a single output image. If the optional lo/hi parameters are not given, they are set to 10000 and 50000, resp. Input data are ignored if they are above the higher number to avoid using saturated input pixels. Input data from all but the first frame are ignored if they are below the lower number to avoid transferring noise from shorter exposures into the output.

The hi/lo defaults may not be appropriate for your data. 50000 is a good saturation level for 16-bit data from which a few thousand has been subtracted as dark current or bias. If you find that some output pixels are not filled from any input frame, try reducing the lower limit to improve the chances of filling these pixels with valid data.

The third number in the registry is interpreted as exposure time and used to scale each frame from raw image units (RIU) to RIU per second (or per time unit used). This works properly only if the frames are properly dark-corrected, either beforehand or as part of running hdrfill. The frames in the registry must be sorted by decreasing exposure time.

The output can be grey FITs or colour FITc. If colour input is converted to grey output, then it simply copies the green channel and ignores the red and blue channels. If grey input is convereted to colour output then all three output channels are identical.

hdrfill can optionally subtract a dark frame from each input frame and it can optionally divide each frame by a flat field. This is done with the "-d" and "-f" options, which are followed by the name of the dark and flat resp. Dark, flat and output must all be FITs or all FITc.




hdrtone performs tone mapping of the HDR input luminance and writes the tone-mapped output. The algorithm is that of Michael Ashikhmin (2002), "A tone mapping algorithm for high contrast images", In: Paul Debevec, Simon Gibson, Eurographics Workshop on Rendering, p. 1-11, The calculations involve Fourier transforms, so that the output image is in general somewhat reduced to make the calculations faster. The input and output size are reported by the utility.

The input data must be positive. The zero level is significant, meaning no light whatsoever from a particular part of the scene.

The output is a tone-mapped version of the input, but is not directly suitable for presentation on a computer screen or to the human eye. A standard gamma correction should be applied after hdrtone.



  unsmsk fwhm fract{s|c}{s|c}

Unsharp mask is an algorithm to sharpen an image. The way it does this is that it takes a copy of the input, blurs it with a Gauß function, and then subtracts a fraction of the blurred image from the original.

y = x - c (x * g)

There are two parameters to play with in this, one is the fraction c and determines how agressively we remove the broad features from the original and how much we therefore emphasise the small detail. The second parameter is the width of the Gauß function. The broader the blurring the larger a feature in the original has to be to be supressed.

The first parameter to unsmsk is the full width at half maximum (FWHM) in pixels of the Gauß function. The second parameter is the fraction of the blurred image that is removed from the original.

unsmsk shrinks the image in two steps. Since the convolution with the Gauß function is much more efficient after Fourier transformation, and because the Fourier transform is more efficient if the shape of the image can be factorised with only small prime numbers, the input is cropped to a size that can be expressed as product of only the numbers 2, 3 and 5, and by using 3 and 5 at most once. The second shrinkage occurs because the convolution would contaminate the edges of the output with input from the opposite edges. So all edges are moved in by 1.5 times the FWHM. unsmask report on standard output the sizes of the input and output and by how much the output bottom left corner lies inside the input image.



  colalign [-l lo hi] in.fitc out.fitc

  colalign in.fitc out.fitc
  colalign -l lo hi in.fitc out.fitc

colalign combines the functions of regist and stack for a special case. It takes the three colour channels of a FITc image and aligns them with each other. In high-magnification images the three colours are not aligned, because the Earth's atmosphere disperses the different colours slightly. So long as the object does not have very strong colour striping colalign can correct for that dispersion.

As with regist you can try to cope with the lunar or solar limb running through the field by ignoring a brightness range that includes the sky background. Use the "-l" option with the two brightness levels for this.

Input and output must be FITc, it makes no sense to use this utility on grey images.



  crop [-c] x1 y1 x2 y2{s|c}{s|c}

  crop left bottom right top{s|c}{s|c}
  crop -c midx midy sizex sizey{s|c}{s|c}

crop creates a smaller image from a larger one. Without the "-c" option you have to give four numbers that are the start x, start y, end x and end y pixels. The start pixel is the first one copied, the end pixel is the first one not copied.

If the "-c" option is used the four given numbers are the central x, central y, size in x and size in y. The first two numbers point into the input image to the centre of what gets copied to the output, and the last two numbers say how big the copied area is.




degamma removes a standard gamma sacling from an image. In the context of FITS image, it is best to have image values E proportional to brightness. This is what dSLR raw images will provide, and a computer controlled webcam - with the γ (gamma) control on zero or minimum - will give similar results. But JPG or video from a digital camera or video camera will have been scaled with a power law, typically giving us values

S = E0.45

It can be useful or necessary to undo this transform. If that is the case, it is prudent to apply the inverse transform

S = E2.2

while the data are in floating-point FITS format. This is what degamma does. The transform is undefined for negative input values; this utility will make such output values zero.




gamma applies a standard gamma scaling to an image. A camera applies such a scaling to raw data E to make JPG data S.

S = E0.45

Hence, this can be an alternative to the logarithmic scaling in truec. It is really necessary after tone-mapping HDR data with hdrtone.

The transform is undefined for negative input values; this utility will make such output values zero.



  falsec in.fits black pink white | pnmtopng > out.png

falsec converts a grey image into an 8-bit graphic. The first parameter is the name of the input image. The remaining three parameters are

The input value that is converted to black in the output graphic. Input values below this are also black in the output.
The input value where the colour junps from white to pink. The input values between black and pink are grey values, which form a linear contrast stretch of the input.
The input value where the colour reaches white. Between pink and white the colour changes smoothly via blue, green, yellow, orange and red. Input values above the white value are also white in the output.

You can set pink equal to white to get grey output only. And you can set pink equal to black to get false colour output only. Finally, if you set black greater than black, then the pink value is ignored and you get a negative grey output graphic.

The output graphic is raw PGM or PPM and written to standard output. You must re-direct it to a file or into another command, such as a format converter.



  truec [-s red green blue]{s|c} zero white [noise] | pnmtopng > out.png
red, green, blue
These positive factors will be used to scale the red, green and blue channels separately. This scaling - if given - is applied before the scaling according to zero, white and noise.
The input zero level. If the noise parameter is not given this input value will be black in the output.
The input value that will be white in the output. If the noise parameter is not given the output is a linear contrast stretch from zero to white.
This parameter is optional. If given, it should be three times the rms noise. The zero value will not be exactly black and the contrast stretch will be logarithmic such that the noise should be just about visible in the output.

Given the zero level (z), the white value (M) and the noise value (n), the logarithmic scaling is calculated as

S = 255 * lg[2 + (E-z)/n] / lg[2 + (M-z)/n]

A black output pixel (S = 0) corresponds to an input value of E = z-n, a white output pixel (S = 255) corresponds to E = M. In practice it turns out often better to choose for z not the average background level itself but between 0.5 n and 0.75 n above the background level.

If the idea of a logarithmic - i.e. non-linear - stretch worries you, consider this. You are probably using raw data from a digital camera, which should be related linearly to the amount of light detected. The human eye would never see the image like that, it has a logarithmic response to light. The same digital camera, when generating the normal JPG images also performs a logarithmic stretch to emulate the human eye.

If, in trial and error, you find the noise too obvious, increase n. If you find the background too bright, increase z. If you find the bright stars overexposed, increase M.



  fourier{s|c} out.fits

fourier is just for playing around. It will calculate the Fourier transform - more precisely the power spectrum or auto-correlation - of the input image. For colour input it will take the green channel and ignore red and blue.



  quality [-l lo hi] inreg > outreg

quality reads the given registry and writes a new one to standard output. The quality of each frame is calculated and included in the new registry.

With the "-l" parameters frames with the solar or lunar limb running through them can be handled (probably). The two parameters are the low and high brightness of the background. Any brightness values between these levels are replaced with the mean brightness of the remaining area in the frame before the Fourier transform and auto-correlation is calculated.

The quality measure is the power spectrum integrated for frequencies above a certain threshold. Assuming that the best spatial resolution is 3 pix the threshold frequency corresponds to a spatial period of 6 pix. If we have a square array of size N going into the Fourier transform, the threshold is N/6 in Fourier space.

The quality measure does not work well. Use of this utility is not recommended.

Installing the binary distribution

chicam comes with pre-built applications for three different platforms:

  1. Linux i386 (32 bit). This is actually built on the i386 platform of Debian 6.0 (squeeze).
  2. Linux amd64 (64 bit). This is actually built on the amd64 platform of Debian 6.0 (squeeze).
  3. Windows/Cygwin 32 bit. Cygwin is software that runs on the Microsoft Windows operating system and provides a Linux-like environment to build and run software.


Simply unpack the .tgz archive in your home directory. The archive will unpack into a sub-directory called "chicam-1.4.1". Rename that to "chicam". You can then run the chicam appliations with commands like

~/chicam/crop -c 320 240 100 100 image.fits cropped.fits

The applications were build on Debian 6.0 (squeeze) and use shareable object libraries for netpbm, fftw3 and cfitsio. Your Linux distribution may have suitable shareable libraries for this. For Debian 6.0 the relevant packages can be installed with

aptitude install libnetpbm10 libfftw3-3 libcfitsio3

If you can't get the binary-distributed applications to work, you may have to build them from source.


You cannot run the applications on a Windows system without installing a minimum subset of the Cygwin software first. Go to and click to "Install or update now". This will download a small Windows executable that will handle the download, installation and configuration for you. You can make a very detailed choice of which parts of Cygwin to install. You need the basic set, which is selected by default, and you also need shareable libraries for fftw3 and netpbm. You can find these in the Libs or Graphics category and the items are called

In this minimal installation Cygwin requires about 55 MByte of disc space. At the end of the Cygwin installation the Cygwin icon will be put on your desktop. This is your way to get a command-line shell, from which you can install and run the chicam applications.

In typical Linux style, the Cygwin bash shell tends to work in what it considers to be your home directory. To install chicam find the tar ball that you downloaded. If you placed it on your desktop this is known to Windows as "C:\Documents and Settings\user\Desktop" where "user" is your Windows user name. Cygwin will find that directory under the name "/cygdrive/c/Documents and Settings/user/Desktop". Without moving out of your Cygwin home directory:

tar -zxf \
  "/cygdrive/c/Documents and Settings/user/Desktop/chicam-1.4.1-cygwin.tgz"
mv chicam-1.4.1 chicam

This puts the chicam applications into a directory that you can always refer to as "~/chicam". For example, if you have a FITS image in what Windows calls "D:\My Data Area\image.fits" and you want to crop that image into a new file "D:\My Data Area\cropped.fits" there are two ways to do this. The first way is to give the full Cygwin paths for the files:

~/chicam/crop -c 320 240 100 100 "/cygdrive/d/My Data Area/image.fits" \
  "/cygdrive/d/My Data Area/cropped.fits"

But if you intend to do a lot of work with files in that directory it is more efficient to change to that directory and use short file names:

cd "/cygdrive/d/My Data Area"
~/chicam/crop -c 320 240 100 100 image.fits cropped.fits

Once you have changed directory with "cd" that is the directory where future commands will do their stuff. Here are a few other basic Linux commands that will be handy:

Building from the souce distribution

To build chicam from source you need a C compiler and three libraries with their C include files: libnetpbm10, libfftw3 and libcfitsio3. All Linux distributions and Cygwin provide the gcc compiler. The libraries and their include files may also be available from your Linux distribution or from Cygwin. For Debian 6.0 you can install the necessary libraries with

aptitude install libnetpbm10-dev libfftw3-dev libcfitsio3-dev

For Cygwin you need gcc4-core, make, libfftw3_3, libfftw3-devel, libnetpbm10, libnetpbm-devel. It does not provide cfitsio; you will have to build that yourself before building chicam. If you have to build fftw3 or cfitsio3 yourself, their source code is available at and resp.

To build chicam, go to a temporary directory and unpack the tar ball. Then change into the source code directory and run the make command. Then move the directory with the built applications somewhere save, such as a directory "cygwin" under your home directory:

cd /tmp
tar zxf chicam-1.4.1-source.tgz
cd chicam-1.4.1/src
mv ../bin ~/chicam

chicam 1.4.1

Using chicam applications

File formats
Stacking frames
HDR processing
All utilities

Installing the binary distribution


Building from the source distribution