astrolab.imaging module

This package contains a list of functions that can be used to load and reduce images. This includes images taken for astrophotography, grating spectroscopy, and stellar photometry.

astrolab.imaging.load_image(filename, gray_conv=[0.2126, 0.7152, 0.0722], bayer_colors=['R', 'G', 'B'], return_filtered_raw=True, print_log=False, cmap='Greys_r', stretch='log', log_a=1000)[source]

Load an image by filename and produce a 2D array.

Input images can either be FITS, RAW (NEF), or JPG images. If JPG images are provided, they are converted to grayscale first through a grayscale conversion vector that can be modified. RAW images are read using the rawpy package, and data for each of the individual colour filters is returned.

Note

The original implementation of reading RAW (NEF) image data was due to Ayush Gurule, an Ashoka undergraduate from the UG25 (2022-2026) batch.

Parameters

filename: str

The image file to read: a filename pointing to the location of the file.

gray_conv: [float, float, float], default: [0.2126, 0.7152, 0.0722]

R, G, and B weights to convert a JPEG or PNG from RGB to grayscale.

bayer_colors: list of chars, default: [“R”, “G”, “B”]

Colours to return, as defined in the Bayer pattern of a RAW image.

return_filtered_raw: bool, default: True

When extracting pixel-level information for individual colours in a Bayered sensor, the resulting arrow will contain multiple zeros for the rows and columns of pixels of a different colour from the one requested. By default, all these zeros are removed and the array is returned.

Note

Removing these pixels effectively “reduces” the size of the image by half in each dimension.

print_log: bool, default: False

Provides the option to print a log to debug your code. In this case, whether you want display the image you have loaded. For JPG or RAW images with multiple channels, a monochrome “average” over the channels is plotted.

cmap: str, default: “Greys_r”

A string containing the colormap title. Should be one of the colormaps used by matplotlib: https://matplotlib.org/stable/users/explain/colors/colormaps.html.

stretch: “log” or None, default: “log”

A string describing the type of stretching that can be applied to display image data. By default, a log stretch is applied. # TODO: Add more stretches.

log_a: float, default: 1000

The log index for stretch='log'.

Returns

data: array_like

An array containing the image data. If the input image is a RAW file, then this array will have one 2D array for each element of bayer_colors, which can be unpacked into as many variables. For all other input images, a single 2D array is returned.

Raises

ValueError

If the filetype is not FIT, FITS, JPG, JPEG, PNG, or NEF.

ValueError

If the input image is a RAW (NEF) file, and any element of bayer_colors is not present in the image’s Bayer pattern.

Usage

>>> this_data = load_image("some_image.JPG")
astrolab.imaging.display(image_array, cmap='Greys_r', stretch='log', log_a=1000, norm_array=None, min_percent=0.0, max_percent=100.0, title=None, xlim=None, ylim=None, fig=None, ax=None)[source]

Display 2D scalar data as an image.

Parameters

image_array: array_like

A 2D array which serves as the image data.

cmap: str, default: “Greys_r”

A string containing the colormap title. Should be one of the colormaps used by matplotlib: https://matplotlib.org/stable/users/explain/colors/colormaps.html.

stretch: {“linear”, “sqrt”, “power”, “log”, “asinh”}, default: “log”

A string describing the type of stretching that can be applied to display image data. By default, a log stretch is applied.

log_a: float, default: 1000

The log index for stretch='log'.

norm_array: array_like, default: None

A 2D array used to decide the normalisation of the simple_norm (from astropy.visualization) used to visualise the plot. By default, the image_array is used for this norm.

min_percentfloat, default: 0.0

The percentile value used to determine the pixel value of minimum cut level. This is a parameter for the astropy.visualization.simple_norm used to display the image.

max_percentfloat, default: 100.0

The percentile value used to determine the pixel value of maximum cut level. This is a parameter for the astropy.visualization.simple_norm used to display the image.

xlim, ylim: float, default: None

Set the x or y limits of the plot. First element is the lower limit, and the second is the upper limit.

fig: matplotlib figure object, default: None

Figure on which to plot the result. By default, a new figure is created.

ax: matplotlib axes object, default: None

Axes on which to plot the result. By default, a new axis is created.

Returns

matplotlib.image.AxesImage (A plot).

Raises

ValueError

If the stretch provided is not one of the allowed stretches.

Usage

>>> display(image_data, cmap="inferno", stretch='log', log_a=10, xlim=None, ylim=None, fig=None, ax=None)
astrolab.imaging.get_files(pathname, root_dir=None, print_log=False)[source]

Get all filenames that match a given pattern and return a sorted list.

This is a simple wrapper around the glob.glob function. From glob.glob’s docstring: Return a list of paths matching a pathname pattern.

The pattern may contain simple shell-style wildcards a la fnmatch. However, unlike fnmatch, filenames starting with a dot are special cases that are not matched by ‘*’ and ‘?’ patterns.

If recursive is true, the pattern ‘**’ will match any files and zero or more directories and subdirectories.

Parameters

pathname: str

A string containing a path specification. Can be either absolute (like ~/data/ring*L.txt) or relative (like ../../spectrum_sirius*.fit), and can contain shell-style wildcards (* and ?).

root_dir: str or None, default: None

Path specifying the root directory for searching. If pathname is relative, the result will contain paths relative to root_dir.

print_log: bool, default: False

Provides the option to print a log to debug your code. In this case, it will print out the list of files loaded.

Returns

files: array_like

A 1D array containing the paths of all the files that match a specific pattern.

Usage

>>> filelist = get_files("./data/imaging/ring*L.fit")
astrolab.imaging.stack_files(filelist, stack_type='mean', gray_conv=[0.2126, 0.7152, 0.0722], bayer_colors=['R', 'G', 'B'], return_filtered_raw=True, print_log=False)[source]

Stack multiple image files together to produce a single output file. Input files can either be a list of FITS, NEF, or JPG images. If JPG images are used, they are converted to grayscale first using the gray_conv parameter. If a list of RAW images is provided, the stacked results for each of the individual colour filters is returned.

Parameters

filelist: array_like

List of strings containing the filenames of files that need to be added.

stack_type: {“mean”, “average”, “sum”}, default: “mean”

A string describing the type of stacking. “average” and “mean” both perform the same action.

bayer_colors: list of chars, default: [“R”, “G”, “B”]

Colours to return, as defined in the Bayer pattern of a RAW image.

return_filtered_raw: bool, default: True

Return only pixel-values of colours specified in bayer_colors from a RAW image, ignoring all other pixels.

print_log: bool, default: False

A boolean variable to decide whether you want to print a log of what you’ve done. In this case, a list of the files stacked.

Returns

stacked: array_like

An array containing the sum (or average) of every item in the file-list. If the input images are RAW files, this array will have one 2D array for each element of bayer_colors, which can be unpacked into as many variables. For all other input images, a single 2D array is returned.

Raises

ValueError

If stack_type is not one of the available types.

Usage

>>> stacked_image = stack_files(filelist, stack_type='mean')
astrolab.imaging.stack(array_of_images, shifts=None, stack_type='mean', print_log=False)[source]

Stack an array of multiple image arrays together to produce a single output array. Each image may be shifted by a pre-specified amount before stacking. Images shifts are taken from the shifts variable.

WARNING: Shifting an image may cause parts of the image array to be cut off.

Parameters

array_of_images: array_like

A 3-dimensional (N, Ly, Lx) array containing N image arrays of size (Ly, Lx) to stack.

shifts: array_like or None, default: None

An (N, 2) array containing N 2D vectors representing the shifts by which each image should be displaced before summing. If None is provided, no shifting is done.

stack_type: {“mean”, “average”, “sum”}, default: “mean”

A string describing the type of stacking. “average” and “mean” both perform the same action.

print_log: bool, default: False

A boolean variable to decide whether you want to print a log of what you’ve done.

Returns

stacked_array: array_like

A 2D array containing the sum (or average) of every item in the file-list.

Raises

ValueError

If stack_type is not one of the available types.

Warns

UserWarning

If the array_of_images is not of the specified dimensions.

UserWarning

If the lengths of the array_of_images and shifts don’t match.

Usage

>>> stacked_array = stack(filelist, stack_type='mean')
astrolab.imaging.flip(image_array, axis='x')[source]

Flip an image along the “x” or “y” axes.

Parameters

image_array: array_like

A 2D array which serves as the image data.

axis: str, default: “x”

Axis about which to flip image.

Returns

flipped_array: array_like

A 2D array. The flipped array.

Raises

ValueError

If axis is neither “x” nor “y”.

Usage

>>> flipped_array = flip(this_data)
astrolab.imaging.crop(image_array, left=None, right=None, top=None, bottom=None, origin=None, print_log=False, fig=None, ax=None)[source]

Crop an image between pre-specified pixels, with the option of choosing an origin around which to perform the cropping.

Parameters

image_array: array_like

A 2D array which serves as the image data.

left, right, top, bottom: int

Left, right, top, and bottom pixel values to crop the image if origin=None. If origin is provided, these are the pixels to the left, right, top, and bottom of the origin pixel within which the image is to be cropped.

origin: List [int, int] or None, default: None

Point about which to crop the image. By default, no point is provided, and left, right, top, and bottom correspond to absolute pixel values.

print_log: bool, default: False

Provides the option to print a log to debug your code. In this case, it will display the cropped array.

fig: matplotlib figure object, default: None

Figure on which to plot the result. By default, a new figure is created.

ax: matplotlib axes object, default: None

Axes on which to plot the result. By default, a new axis is created.

Returns

cropped_array: array_like

A 2D array. The cropped array.

Usage

>>> cropped_array = crop(this_data, left=0, right=1500)
>>> cropped_array = crop(this_data, left=100, right=100, top=100, bottom=100, origin=[1052,1002])
astrolab.imaging.shift(image_array, displacement, print_log=False)[source]

Translate an image by a displacement vector.

Parameters

image_array: array_like

A 2D array which serves as the image data.

displacement: List [float, float]

Vector of the (x,y) shift by which to translate the image.

print_log: bool, default: False

Provides the option to print a log to debug your code. In this case, it will display the shifted array.

Returns

shifted_array: array_like

A 2D array. The rotated array.

Usage

>>> shifted_array = shift(this_data, displacement=[10,200])
astrolab.imaging.rotate(image_array, angle, origin=None, expand=False, fill=False, print_log=False)[source]

Rotate an image by a fixed angle, with the option of choosing an origin about which to perform the rotation.

Parameters

image_array: array_like

A 2D array which serves as the image data.

angle: float

Angle by which to rotate the image.

origin: List [int, int] or None, default: None

Point about which to rotate the image. By default, no point is provided, and the image is rotated about its centre.

expand: bool, default: False

Expands the output image to make it large enough to hold the entire rotated image.

fill: bool, default: False

Fill area outside the rotated image. If True, this area is filled with the median value of the image.

print_log: bool, default: False

Provides the option to print a log to debug your code. In this case, it will display the rotated array.

Returns

rotated_array: array_like

A 2D array. The rotated array.

Usage

>>> rotated_array = rotate(this_data, angle=23.0)
>>> rotated_array = rotate(this_data, angle=23.0, origin=[1052,1002])
astrolab.imaging.find_star(image_array, star_pos=None, search=500, print_log=False, fig=None, ax=None)[source]

Find the pixel location of star in a 2D image array. A “star” is defined simply as the “brightest” pixel in the array.

If multiple bright pixels can be found, a rough location and search area can be defined to refine the search.

Parameters

image_array: array_like

A 2D array which serves as the image data.

star_pos: [int, int] or None, default: None

x and y pixel coordinates of the star’s rough location, to refine search for the brightest pixel. If None is provided, the brightest pixel is used.

search: float, default: 500

Search “radius” in pixels. The brightest pixel will be found in the range (star_pos[0] +/- search, star_pos[1]+/- search).

print_log: bool, default: False

Provides the option to print a log to debug your code. In this case, it will show the location of the detected star, and the provided search-box.

fig: matplotlib figure object, default: None

Figure on which to plot the result. By default, a new figure is created.

ax: matplotlib axes object, default: None

Axes on which to plot the result. By default, a new axis is created.

Returns

star: array_like

An array of 2 elements containing x and y pixel location of the “star”.

Usage

>>> this_star = find_star(this_data, star_pos=[1000,1500], search=500)
astrolab.imaging.display3D(image_array, cmap=None, stretch='log', log_a=1000, xlim=None, ylim=None, plot_view_angle=[25, 90], show_colorbar=True, smooth=False, smooth_n=4, fig=None, ax=None)[source]

EXPERIMENTAL: Display 2D scalar data as a 3D image.

Parameters

image_array: array_like

A 2D array which serves as the image data.

cmap: str, default: “Greys_r”

A string containing the colormap title. Should be one of the colormaps used by matplotlib: https://matplotlib.org/stable/users/explain/colors/colormaps.html.

stretch: “log” or None, default: “log”

A string describing the type of stretching that can be applied to display image data. By default, a log stretch is applied. # TODO: Add more stretches.

log_a: float, default: 1000

The log index for stretch='log'. # TODO: Implement log index stretching.

xlim, ylim: float, default: None

Set the x or y limits of the plot. First element is the lower limit, and the second is the upper limit.

plot_view_angle: [float, float], default: [25,90]

Angle of view of the 3D plot.

show_colorbar: bool, default: True

Boolean option to show a colorbar on the 3D plot.

smooth: bool, default: False

Smooth every pixel by taking the sum of the pixel values of its neighbours.

smooth_n: int, default: 2

Number of neighbours to average over when smoothing.

fig: matplotlib figure object, default: None

Figure on which to plot the result. By default, a new figure is created.

ax: matplotlib axes object, default: None

Axes on which to plot the result. By default, a new axis is created.

Returns

matplotlib.image.AxesImage (A plot).

Raises

ValueError

If the stretch provided is not one of the allowed stretches.

Usage

>>> display3D(image_data, cmap="inferno", stretch='log', log_a=10, xlim=None, ylim=None, fig=None, ax=None)
astrolab.imaging.sort_astrophotos(base_dir, object_prefix, symlink=True, ext='fit', flat_prefix='flats', filter_suffixes=['L', 'R', 'G', 'B', 'Ha', 'SII', 'OIII'], light_suffix='', dark_suffix='D', flat_suffix='', bias_suffix='Bias', folders=['lights', 'darks', 'flats', 'biases'], print_log=False, log_level=0)[source]

Sort astrophotography images into appropriately named folders so that they can be used by Siril or other software.

This function can be used to sort images and calibration frames obtained from an automated astrophotography cameras. The files are sorted, based on their prefixes and suffixes, into appropriately named folders.

An object is specified using its filename’s prefix. The function then creates individual folders for each filter. Within each of these folders, separate folders for lights, darks, flats, and biases are created, within which the appropriate files are placed. Users have the option to link the files symbolically within these folders (strongly recommended, as it keeps the original file structure intact) or actually move them there, which would change the original file structure.

Important

Windows users will have to enable developer mode on their machines in order to use this function, since it relies on creating symbolic links between files. Developer mode can be activated (at least on Windows 11) by going to Settings -> System -> For developers and toggling the Developer mode option.

Danger

Setting symlink=False can move files around on your machine in ways that cannot easily be undone. Only use this option if you’re sure you know what you’re doing.

Parameters

base_dir: str

A string pointing to the path of the folder within which all the astrophotography images have been placed. This path can be either absolute or relative. Relative paths are converted to absolute paths.

object_prefix: str

Prefix used to filter out files for a single astronomical object. This is expected to be the first few characters of the filenames of the object’s images.

symlink: bool, default: True

Option to symbolically link the files rather than actually moving them to the appropriate folders. This is strongly recommended. If symlink=True, the external file structure is unchanged, only shortcuts are placed inside the newly created folders. If, on the other hand, symlink=False, a new flats folder is created in the base directory, and all flats are moved into it, inside appropriately named folders per filter. The darks and biases are moved into new directories within the object’s folder. These images are then symbolically linked to the appropriate folders for each filter. The lights are moved out from the external folder into the appropriate internal lights folder.

ext: str, default: “fit”

A string with the filename extension for the images. By default, it accepts FIT files.

flat_prefix:, str, default: “flats”

A string containing the prefix of the flat files. By default, these files are assumed to be named flats....

filter_suffixes: list of str, default: [“L”, “R”, “G”, “B”, “Ha”, “SII”, “OIII”]

A list of filter suffixes, assumed to be the end of the filename (before the extension).

light_suffix: str, default: “”

A string containing the suffix of the light files. By default, no suffix is assumed.

dark_suffix: str, default: “D”

A string containing the suffix for the darks. By default, “D” is used.

flat_suffix: str, default: “”

A string containing the suffix of the flat files. This can be used to differentiate between different flat frames taken on the same night, since this function filters out flats by looking for those filenames that follow the ...{flat_prefix}*{flat_suffix}... format. By default, no suffix is assumed.

bias_suffix: str, default: “Bias”

A string containing the suffix of the bias files. By default, “Bias” is used.

folders: list of str, default: [“lights”, “darks”, “flats”, “biases”]

A list of four strings containing the names of the different folders to be created. By default, these four folders are created for each of the filters.

print_log: bool, default: False

Provides the option to print a log to debug your code. In this case, it will print out which folders have been created.

log_level: int, default: 0

Provides the option to print out a more detailed log, indicating which files have been moved or symbolically linked. A higher level indicates a more detailed log.

Returns

NoneType

Warns

UserWarning

If files for any of the calibration frames of a filter are not present, but the lights for that filter are present.

Usage

>>> sort_astrophotos(base_dir="./my_ast1080_folder/session5/", object_prefix="DS_M13", flats_prefix="flats", flats_suffix="FR")