ppmcentre has changed it's name
The original name of this tool ("ppmcentre") dates back many years to a time when I thought that it was going to be used as part of the PBMTools image processing set. However it has evolved much more functionality since then, and I've long since given up on that idea, so now it's a standalone tool for processing astronomical images.
After some thought (and a bit of research) I decided to rename it "ninox". However nothing else has changed -
the functionality is identical to the old ppmcentre.
ninox [ options ] files or directoriesninox processes a sequence of image files, it's primary objective is to find and centre the dominant object in each frame to make life easier for processing by Registax or other astronomy image-stacking programs.
With no file or directory arguments ninox will process all image files in the current directory that it understands. If you name a directory, then all image files in that directory will be processed.
Over the years ninox has evolved to add extra functionality as I needed it, so it now has many extra commandline options to do "other things" as well as it's main task of finding and centering objects.
Support file formats are:
You control it's behaviour by giving one or more switches with optional parameters on the command line, or by placing the commands in an INI file.
All switches given on the command line start with -
Any parameter not starting with - is assumed to be either an image file or the name of a directory containing image files. Switches and files are processed in the following order:
It is normal to provide all the switches first and then follow with the list of files or directories to be processed.
eg here is a sample ninox.ini:
[ninox] cut=480 qestimator qrenumber display overwrite gaincomp=C:/awesley/gaincomp/dr2-format7-50fps.fit resample=3 levels=3,255 istretch mkdirs=yes
See above for the format of the INI file.
NOTE: The display option requires the presence of SDL.DLL under Windows. A copy is included in this package.
NOTE: Not all colour formats and depths can be displayed. You will receive an error message if you use this option on an unsupported format.
NOTE: W MUST be an even number, and to be safe you should also make it a multiple of 4.
NOTE: When image rescaling is specified, W is interpreted as relative to the original image size (i.e. without rescaling).
Default: Width of input image (no cropping)
NOTE: H MUST be an even number, and to be safe you should also make it a multiple of 4.
NOTE: When image rescaling is specified, W is interpreted as relative to the original image size (i.e. without rescaling).
Default: Height of original image (no cropping).
This cutout size should be large enough to contain your object, but keeping it small speeds up other processing (rescaling, smoothing, gamma) as they apply only to the region inside the cutout.
This is normally what you would use rather than specifying each of the other 4 parameters individually, except when processing images that have different horizontal and vertical extents - ie Saturn.
Input-Histogram stretching: Immediately after reading monochrome images (.FIT files) they are histo-stretched so that the brightest part of the image is at the 90% brightness point.
Before writing output monochrome images (.FIT files) they are histo-stretched so that the brightest part of the image is value N (0..255, default 220).
Adjusts the images as they are loaded by setting the image pixel value MIN to black and the value MAX to white, stretching the histogram of the image appropriately.
MIN and MAX are always given in the range 0..255. The values will be scaled automatically for 16 bit images.
If your target image is very small you may want to decrease this value.
Default value 40
Without this switch ninox will write it's output into the same directory as its input, but this will fail unless you also specify -overwrite.
D can be either a relative directory, or an absolute directory. A relative directory is one that doesn't start with a directory separator (/ or \ depending on your O/S).
e.g. If you use -outdir=output (relative path) then ninox will create a directory named output under the directory holding the input images.
If you use -outdir=\out (MS Windows absolute path) or -outdir=/out (UNIX absolute path) then this is taken as a top-level directory name, and not relative to the input images.
In all cases ninox will create the output director(ies) as required, or die with a complaint if it doesn't have permission to do so.
NOTE: This behaviour is different to earlier versions of ninox which would by default overwrite their input. Now you have to specify -overwrite to get the old behaviour if you really want it :-)
1 = GBG
2 = RGR
3 = BGB
4 = GRG
By default when ninox creates a FIT output file it adds two special pixels (black & white) in the bottom left corner to stop histo-stretching by other programs. This switch turns this feature off.
A list of broken frames is stored in .ninox/brokenframes.txt
NOTE: -width,-height,-cutx and -cuty always refer to the dimensions of the SOURCE image (i.e. before rescaling).
NOTE: If the image is scaled up by more than a factor of 2 then an implicit smoothing operation is enabled (see next option). This is not supported on colour images, and so you can't resample colour images by more than a factor of 2 unless you disable the smoothing.
Synonyms: -rescale -resample -upsample
Smoothing is ON by default, and you should not turn it off unless you know what you are doing.
Smoothing is not applied to an image if the scaling factor is <= 2
Smoothing is not supported on colour images in this version.
Gamma adjustments are not supported on colour images.
For each pixel in the input image we calculate a difference value D:
D = (P-A)/A
P is the value of the pixel we are considering and A is the modified average of its 8 neighbors.
A is computed by taking the 8 neighbors and replacing the brightest pixel value with the darkest pixel value. This is done in recognition that most noise will artificially increase pixel values and inflate the average value. Dark pixel values are more likely to be reliable than bright values.
If D is greater than F then the pixel P is too bright, and we replace P with A.
If D is less than -F then the pixel is too dark, and we replace P with the value (P+A)/2.
This filter can be applied multiple times by giving the option more than once. e.g. '-inputfilter -inputfilter' applies the filter twice.
The default values for F is 0.2. If you want to change this then specify a replacement value with the first filter iteration.
NOTE: Filtering is not supported on colour images.
The quality for an image is calculated by generating a series of downsampled images and summing the computed quality of each of those smaller images. This allows the algorithm to reject noise.
The series of downsampled images is controlled by the two parameters min and max. They represent the smallest and largest divisor that will be used to generate the downsampled images. All integer divisor values between min and max are used.
The default values are min=3 and max=5, leading to three downsampled images (divisors 3,4,5). You can adjust min and max to accommodate images that are much larger or smaller than normal.
The quality of each downsampled image is calculated by the sum of squares of differences between adjacent horizontal and vertical pixels. This exaggerates the differences and locates sharp gradients in the image, usually a sign of good quality. Only pixels which have values greater than the background level are considered (see -threshhold);
Note: The algorithm used here is the same as the gradient algorithm used in Registax, however the implementation used here in ninox allows the algorithm to be examined by the user (via -qwrite) and fine-tuned using the min and max parameters.
You may find it useful to use the quality estimation function of ninox to "pre-sort" all your frames so you can then select only those that are good enough to load into registax for alignment and stacking.
With this switch enabled ninox will write all the downsampled images that are generated as part of the qestimator function. The images are written in the current directory as 8bpp monochrome PPM format, and are named sample_N.ppm with N being the sample level.
i.e. in the default case with min=3 and max=5, three images will be generated, sample_3.ppm, sample_4.ppm and sample_5.ppm.
These images are overwritten for each file that is processed, so if you are using this switch then it only makes sense to process one file.
After all files have been processed, ninox will sort the output files according to their computed quality from best -> worst and then renumber all the output files accordingly.
For this to work it a requirement that the output filenames contain a number as part of their name, e.g. 00234.bmp.
The renumbering algorithm locates the numeric portion (either the first or last numeric portion) and changes only that part of the filename, leaving the rest of the filename alone.
The renumbered part of the filename will start with the letter q followed by that files ranking in the quality list, highest quality will have rank 0.
e.g. An output file named C:\tmp\00234-red.fit may end up as C:\tmp\q00368-red.fit after renumbering.
The gaincomp option allows you to correct for nonlinear responses in the pixels in your camera. You will first have to create a "flat field" image by recording video of a uniformly lit target (make sure you remove the camera lens!), and then stack this video to generate a flat-field image that will show the non-uniform responses of your camera.
ninox will load the reference image and calculate the difference in brightness between each pixel in the reference image and the average intensity of the reference image. These differences are then converted into a scaling factor and stored internally to be applied to each pixel in the "real" frames as they are loaded.
ninox will perform a pixel filtering algorithm on the input frames as follows:
Each pixel in the input image is compared to the same location in the N (default 5) previous frames. If this pixel is either larger than the largest value or smaller than the smallest value in this history then it is replaced with a weighted average of itself and the average of the pixels in the history.
The idea behind this filter is that it can eliminate extreme pixel values by comparing each pixel to a history of that pixel in some preceding frames. This algorithm should be invoked only when the frames come from a session of good seeing where the image is not moving around, otherwise this will give incorrect results.
Note that the first N frames are not processed, they are passed through with no filtering.
ninox automatically locates and rotates the image of Jupiter that's found in the input image. Ninox assumes that there is no other information in the frame other than the planet, and also that the planet is oriented with its axis of rotation vertical (ie the planet rotates in the horizontal direction only).
A positive rotation value will rotate the planet from right-to-left, and a negative value will rotate the image from left-to-right.
Note: There is no attempt to correct for changes in illumination at the preceding or following limbs, so this will introduce artifacts at the left and right edges of the rotated image.
ninox divides the image into tiles that are N x N pixels in size (default N=5) and within each tile the brightest pixel is replaced by the average of its neighbors.
This acts as a "pop" filter and can help reduce the effects of noise by removing over bright pixels.
This switch turns on the image morphing filter. The value (1 or 2) selects the level of morphing, where Level 1 is align-only, ie the frame to be morphed is aligned as closely with the reference frame as possible without any distortions applied, and Level 2 is align + distort where each frame is first aligned and then distorted so that all the major features of the frame align perfectly with the reference frame.
You must select Level 1 or 2 with this option, there is no default. Level 2 is much better but also can take a lot longer to run.
If image morphing is enabled (via the -morphing option) then this option is required to provide the reference image. The reference image should be identical in size to the raw frames, ideally it should have been created by a preliminary run of the raw data through registax with moderate sharpening.
It is important that the reference image closely resemble the raw frames in terms of overall brightness as it will be used to compare with each of them. The reference image should also be smooth in appearance and free of processing artifacts that might mislead the morphing algorithm.
If image morphing is enabled (via the -morphing option) then this option sets the number of tiles that are created across the width of the image for Level 2 morphing. The tiles are square and the number of tiles required down the image is automatically calculated.
Level 2 image morphing works by breaking the source frame into tiles of size NxN pixels, and allowing each tile to "float" a few pixels away from its origin to find the best alignment with the reference image. Once all the tiles have found their best locations then the morphiong algorithm distorts the source frame so that these tiles move back to their starting locations, bringing the image features back with them.
If you have too few tiles across the image then the algorithm may not be able to find enough distortions to accurately correct the source image, and if there are too many tiles (ie each tile is too small) then there may not be enough detail inside each tile for a meaningful match to be found.
In practice you should try and keep the tiles between 32 and 64 pixels in size as a good estimate.
Example of image morphing with these three options:
ninox -outdir=morph -morphing=2 -morph-ref=../ref.fit -morph-across=15 srcdir/