Images (pyobs.images)

Some info about pyobs.images.Image.

The Image class is the fundamental data structure passed through the entire pyobs imaging pipeline. Every camera module produces an Image, every ImageProcessor consumes and returns one, and the VFS convenience methods (read_image(), write_image()) serialise and deserialise them transparently.

The Image class

An Image holds up to five arrays alongside a FITS header:

Attribute

Contents

data

2D float array of pixel values (or 3×H×W for colour images)

mask

Boolean/integer mask — non-zero pixels are excluded from processing

uncertainty

Per-pixel standard deviation array

catalog

astropy.table.Table of detected sources, populated by source detection processors

raw

Copy of the pixel data before calibration

Every property has a safe_ variant (e.g. safe_data) that returns None instead of raising an exception when the attribute is absent, which is useful in pipeline steps that handle both calibrated and uncalibrated images.

Creating images

from pyobs.images import Image

# from a FITS file on disk
image = Image.from_file("science_frame.fits")

# from raw bytes (e.g. received over the network)
image = Image.from_bytes(data)

# from an astropy CCDData object
image = Image.from_ccddata(ccd)

# from scratch
import numpy as np
image = Image(data=np.zeros((1024, 1024), dtype=np.float32))

Serialisation

Image serialises to a multi-extension FITS file. The primary HDU holds the science data; mask, uncertainty, source catalog, and raw data are stored in additional extensions named MASK, UNCERT, CAT, and RAW respectively. Round-tripping is lossless:

image.writeto("output.fits")
image2 = Image.from_file("output.fits")

# or to/from bytes in memory
raw_bytes = image.to_bytes()
image3 = Image.from_bytes(raw_bytes)

Meta information

The meta dict carries runtime data that is intentionally not written to FITS. It is keyed by class, which prevents accidental collisions between different pipeline stages:

from pyobs.images.meta import PixelOffsets, RaDecOffsets

# store
image.set_meta(PixelOffsets(dx=3.2, dy=-1.7))

# retrieve (raises ValueError if absent)
offsets = image.get_meta(PixelOffsets)

# retrieve safely
offsets = image.get_meta_safe(PixelOffsets)  # returns None if absent

The available meta classes are:

Image processors

ImageProcessor is the base class for all pipeline steps. A processor is an Object subclass that is callable — it receives an Image and returns a (possibly modified) Image:

from pyobs.images import Image
from pyobs.images.processor import ImageProcessor

class MyProcessor(ImageProcessor):
    async def __call__(self, image: Image) -> Image:
        image.data = image.data - image.data.mean()
        return image

Processors are composable — the Pipeline module chains them in sequence, passing each output as the next processor’s input. See Image processors for the full list of built-in processors.

API reference

class Image(data: ndarray[tuple[Any, ...], dtype[floating[Any]]] | None = None, header: Header | None = None, mask: ndarray[tuple[Any, ...], dtype[floating[Any]]] | None = None, uncertainty: ndarray[tuple[Any, ...], dtype[floating[Any]]] | None = None, catalog: Table | None = None, raw: ndarray[tuple[Any, ...], dtype[floating[Any]]] | None = None, meta: dict[Any, Any] | None = None, *args: Any, **kwargs: Any)

Bases: object

A container class for astronomical image data and associated metadata.

This class represents a two-dimensional astronomical image, typically loaded from or saved to a FITS file. It provides unified access to image data, mask, uncertainty, catalogs, raw calibration frames, and meta information. The Image class serves as the fundamental data structure within the pyobs imaging pipeline, enabling reading, writing, and conversion between FITS, astropy.CCDData, and in-memory representations.

The image may optionally contain:
  • data: 2D array of pixel values.

  • mask: Boolean or integer mask indicating invalid or excluded pixels.

  • uncertainty: Per-pixel uncertainty values.

  • catalog: Source catalog (as an astropy.table.Table).

  • raw: Reference to the unprocessed raw image data.

  • meta: Arbitrary metadata dictionary, typically used to store runtime or class-based contextual information (not preserved in FITS I/O).

The class supports deep/shallow copying, FITS serialization, arithmetic operations (e.g., division), and format conversions (e.g., to JPEG or astropy.CCDData). It is designed to be interoperable with the pyobs.images processing framework, and compatible with source detection and photometry tools such as SEP or Source Extractor.

Parameters:
  • data (numpy.ndarray[float], optional) – 2D array containing the image pixel data.

  • header (astropy.io.fits.Header, optional) – FITS header containing image metadata. If omitted, a new empty header is created.

  • mask (numpy.ndarray[float] or numpy.ndarray[bool], optional) – Image mask. Pixels marked True or non-zero are ignored during processing.

  • uncertainty (numpy.ndarray[float], optional) – Per-pixel uncertainty array.

  • catalog (astropy.table.Table, optional) – Source catalog table associated with the image.

  • raw (numpy.ndarray[float], optional) – Raw image data before calibration.

  • meta (dict, optional) – Dictionary of additional metadata. Not serialized in I/O operations.

  • *args, **kwargs (Any) – Additional positional or keyword arguments for subclass compatibility.

  • Behavior

  • ——–

  • - If `data` is provided, the FITS header keywords ``NAXIS1`` and ``NAXIS2`` are – automatically set to match the array shape.

  • - The `Image` can be created from FITS files (`from_file`), byte arrays – (from_bytes), or astropy.CCDData objects (from_ccddata).

  • - The `writeto()` method saves the image to a FITS file, including associated – mask, uncertainty, raw, and catalog extensions when present.

  • - The `to_bytes()` method serializes the image into an in-memory FITS byte stream.

  • - Metadata entries can be managed via `set_meta()`, `get_meta()`, andget_meta_safe() for safe retrieval of class-based meta objects.

  • - Supports lightweight arithmetic, such as division via `__truediv__`.

  • Input/Output

  • ————

  • - **Input**

    • FITS file or HDU list

    • In-memory bytes (FITS format)

    • astropy.CCDData object

  • - **Output**

    • Image instance

    • FITS file or bytes

    • astropy.CCDData object

    • JPEG bytes (grayscale representation)

Examples

Load an image from a FITS file and convert it to JPEG:

from pyobs.images import Image

image = Image.from_file("science_frame.fits")
jpeg_data = image.to_jpeg()

Create an image from CCDData and write it back to disk:

from astropy.nddata import CCDData

ccd = CCDData.read("flat_field.fits")
image = Image.from_ccddata(ccd)
image.writeto("flat_field_copy.fits")

Access image data safely:

if image.safe_data is not None:
    print(f"Mean value: {image.data.mean():.3f}")

Notes

  • Header keywords such as BUNIT and CD1_1 / CDELT1 are used to infer pixel units and scale (in arcsec/pixel).

  • The meta dictionary is not persisted in FITS I/O; it is intended for runtime information storage.

  • JPEG conversion (to_jpeg) automatically determines display scaling based on 5th–95th percentile clipping unless explicit limits are provided.

  • For color images (3×H×W arrays), to_grayscale() converts to a single channel using ITU-R BT.709 luminance coefficients by default.

See also

astropy.io.fits

For FITS file I/O.

astropy.nddata.CCDData

For conversion to/from standard CCD image structures.

pyobs.images.processors.detection.SepSourceDetection

For source extraction using SEP on Image objects.

Init a new image.

Parameters:
  • data – Numpy array containing data for image.

  • header – Header for the new image.

  • mask – Mask for the image.

  • uncertainty – Uncertainty image.

  • catalog – Catalog table.

  • raw – If image is calibrated, this should be the raw image.

  • meta – Dictionary with meta information (note: not preserved in I/O operations!).

copy() Image[source]

Returns a copy of this image.

format_filename(formatter: FilenameFormatter) str[source]

Format filename with given formatter.

classmethod from_bytes(data: bytes) Image[source]

Create Image from a bytes array containing a FITS file.

Parameters:

data – Bytes array to create image from.

Returns:

The new image.

classmethod from_ccddata(data: CCDData) Image[source]

Create image from astropy.CCDData.

Parameters:

data – CCDData to create image from.

Returns:

New image.

classmethod from_file(filename: str) Image[source]

Create image from FITS file.

Parameters:

filename – Name of file to load image from.

Returns:

New image.

get_meta(meta_class: Type[MetaClass]) MetaClass[source]

Returns meta information, assuming that it is stored under the class of the object.

Parameters:

meta_class – Class to return meta information for.

Returns:

Meta information of the given class.

get_meta_safe(meta_class: Type[MetaClass], default: MetaClass | None = None) MetaClass | None[source]

Calls get_meta in a safe way and returns default value in case of an exception.

has_meta(meta_class: Type[MetaClass]) bool[source]

Whether meta exists.

property pixel_scale: float | None

Returns pixel scale in arcsec/pixel.

set_meta(meta: Any) None[source]

Sets meta information, storing it under it class.

Note that it is possible to store, e.g., strings, but they would be stored as img.meta[str] and be overwritten with every new string, which is probably not what you want. Use the img.meta dict directly for this and set_meta/get_meta only for class-based data.

Parameters:

meta – Meta information to store.

to_bytes() bytes[source]

Write to a bytes array and return it.

to_ccddata() CCDData[source]

Convert Image to CCDData

to_grayscale(r: float = 0.2126, g: float = 0.7152, b: float = 0.0722, **kwargs: Any) Image[source]

Convert RGB image to grayscale.

Parameters:
  • r – Weight for red.

  • g – Weight for green.

  • b – Weight for blue.

to_jpeg(vmin: float | None = None, vmax: float | None = None) bytes[source]

Returns a JPEG image created from this image.

Returns:

The image.

property unit: str

Returns units of pixels in image.

write_catalog(f: Any, *args: Any, **kwargs: Any) None[source]

Write catalog to file object.

writeto(f: Any, *args: Any, **kwargs: Any) None[source]

Write image as FITS to given file object.

Parameters:

f – File object to write to.

class ImageProcessor(**kwargs: Any)[source]

Bases: Object

Init new image processor.

async reset() None[source]

Resets state of image processor

Meta classes

class PixelOffsets(dx: float = 0, dy: float = 0)[source]
class RaDecOffsets(dra: float = 0, ddec: float = 0)[source]
class AltAzOffsets(dalt: float = 0, daz: float = 0)[source]
class SkyOffsets(coord0: SkyCoord, coord1: SkyCoord)[source]
separation(frame: BaseCoordinateFrame = None) Angle[source]

Returns separatation between both coordinates, either in their own or a given frame.

Parameters:

frame – Coordinate frame to use, or None to use coordinates’ own frames.

Returns:

Angle between coordinates.

spherical_offsets(frame: BaseCoordinateFrame = None) Tuple[Angle, Angle][source]

Calculates spherical offset from first coordinate to second.

Parameters:

frame – Coordinate frame to use, or None to use coordinates’ own frames.

Returns:

Two angles for offset in lon and lat.

class OnSkyDistance(distance: Angle)[source]
class ExpTime(exptime: float)[source]