ninox [ options ] files or directoriesninox processes a sequence of image files or SER format videos, it can do many useful things including centering the object in each frame or re-sorting frames based on quality, histogram stretching and resizing 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.
Be warned that ninox is a work in progress - many of its features are experimental and probably do not work or are out of date and no longer used. In particular ninox has very limited support for colour images. If you have a colour camera then you'll probably find many cases where ninox will not work.
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.
By default, ninox will look for the ninox.ini control file in the current directory. You can override this and give another location with the -ini commandline option.
eg here is what the content of a random ninox.ini file might look like (but don't copy these settings, they're probably wrong for you):
[ninox] cut=480 qestimator qrenumber display overwrite resample=3 istretch mkdirs=yes
See above for the format of the INI file.
NOTE: The display option requires the presence of SDL2.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.
See -istretch. Here V is the fractional brightness point for stretching, in the range 0.0 - 1.0.
Values like 0.75 are recommended, i.e. -istretch=0.75.
Before writing out 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
Due to the quirky history of ninox, it will (by default) write it's output files into a numbered subdirectory. Look for directories named "1" or "2" etc to find it's output. It's bizarre, but once upon a time those were the filter positions in my wheel for filters like "red", "green" etc.
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
Resamples the image by a factor of N (or N/M).
e.g. 2 makes the images twice original size, 3/2 makes the image 1.5 times larger, and 1/2 makes the image half original size. The image as a whole becomes a factor of N/M larger in both dimensions.
NOTE: -width,-height,-cutx and -cuty always refer to the dimensions of the SOURCE image (i.e. before rescaling).
Synonyms: -rescale -resample -upsample
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.
For small targets that show no internal details (e.g. Uranus or Neptune) you can try the aperture algorithm which looks for light scattered outside the nominal area of the planetary disk as a way to rate the images. You need to provide the radius of the planetary disk in your data as the parameter, for example:
-qfunc=aperture:13would indicate that the planetary disk is radius 13 pixels (diameter 27 pixels) in your data. Light scattered outside this region indicates lower image quality. The given radius value should be accurate to within a couple of pixels for best results. The algorithm compares the light inside the given circular aperture to the light inside an aperture with twice the area, with the ratio as the quality estimate.
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/