Algorithms Module

The algorithms module contains image processing, detection, tracking, and analysis algorithms.

Module Structure

The algorithms module is organized into several submodules:

  • detectors - Object detection algorithms

  • trackers - Multi-object tracking algorithms

  • enhancement - Image enhancement algorithms

  • background_removal - Background subtraction methods

  • tracks - Track analysis and refinement

Detectors

detectors.threshold.SimpleThreshold

Detector that uses a fixed threshold to find blobs.

detectors.cfar.CFAR

Detector that uses local standard deviation-based thresholding to find blobs.

Detection algorithms identify objects of interest in imagery based on intensity, contrast, or other features.

Example:

from vista.algorithms.detectors.threshold import SimpleThreshold

detector = SimpleThreshold(threshold=10.0, min_area=5)
rows, columns = detector(image)

Trackers

trackers.simple_tracker.run_simple_tracker

Run simple nearest-neighbor tracker with adaptive parameters.

trackers.kalman_tracker.run_kalman_tracker

Run Kalman filter tracker on detections using a custom implementation.

trackers.network_flow_tracker.run_network_flow_tracker

Run network flow optimization tracker on detections.

trackers.tracklet_tracker.run_tracklet_tracker

Run tracklet-based hierarchical tracker on detections.

Tracking algorithms associate detections across frames to form object trajectories.

Example:

from vista.algorithms.trackers.kalman_tracker import run_kalman_tracker

config = {
    'tracker_name': 'My Tracker',
    'gating_distance': 10.0,
    'min_detections': 3,
    'process_noise': 1.0,
    'measurement_noise': 1.0,
    'delete_threshold': 100.0
}
tracks = run_kalman_tracker(detectors, config)

Background Removal

background_removal.temporal_median.TemporalMedian

Temporal median background removal algorithm.

background_removal.robust_pca.run_robust_pca

Apply Robust PCA background subtraction to a 3D array of images.

Background removal algorithms separate moving objects from static background.

Example:

from vista.algorithms.background_removal.temporal_median import TemporalMedian

temporal_median = TemporalMedian(imagery, background=5, offset=2)
frame_idx, foreground = temporal_median()

Enhancement

enhancement.coadd.Coaddition

Enhancement algorithm that sums imagery over a running window.

Enhancement algorithms improve image quality for better visualization and analysis.

Example:

from vista.algorithms.enhancement.coadd import Coaddition

coaddition = Coaddition(imagery, window_size=5)
frame_idx, enhanced = coaddition()

Track Analysis

tracks.interpolation.TrackInterpolation

Interpolates missing frames in a track trajectory.

tracks.savitzky_golay.SavitzkyGolayFilter

Applies Savitzky-Golay filter to smooth track trajectories.

tracks.extraction.TrackExtraction

Extract image chips and detect signal pixels around track points.

Track analysis algorithms refine and analyze track data.

Example:

from vista.algorithms.tracks.interpolation import TrackInterpolation
from vista.algorithms.tracks.savitzky_golay import SavitzkyGolayFilter

# Fill gaps in tracks
interpolator = TrackInterpolation(track, method='linear')
results = interpolator()
interpolated_track = results['interpolated_track']

# Smooth trajectories
smoother = SavitzkyGolayFilter(track, radius=2, polyorder=2)
results = smoother()
smoothed_track = results['smoothed_track']

Module Reference

Detectors

Simple threshold detector algorithm for finding bright blobs in imagery

class vista.algorithms.detectors.threshold.SimpleThreshold(threshold, min_area=1, max_area=1000, detection_mode='above')[source]

Bases: object

Detector that uses a fixed threshold to find blobs.

Uses regionprops to identify connected regions above or below threshold, or both, filtered by area, and returns weighted centroids as detections.

name = 'Simple Threshold'
__init__(threshold, min_area=1, max_area=1000, detection_mode='above')[source]

Initialize the Simple Threshold detector.

Parameters:
  • threshold (float) – Intensity threshold for detection.

  • min_area (int, optional) – Minimum detection area in pixels. Default is 1.

  • max_area (int, optional) – Maximum detection area in pixels. Default is 1000.

  • detection_mode ({'above', 'below', 'both'}, optional) –

    Detection mode controlling how threshold is applied:

    • ’above’: Detect pixels > threshold (default)

    • ’below’: Detect pixels < -threshold (negative values)

    • ’both’: Detect pixels where |pixel| > threshold (absolute value)

__call__(image)[source]

Process a single image and return detections.

Parameters:

image (ndarray) – 2D numpy array representing a single image frame to process.

Returns:

  • rows (ndarray) – Array of row coordinates (y-positions) for detection centroids.

  • columns (ndarray) – Array of column coordinates (x-positions) for detection centroids.

Raises:

ValueError – If detection_mode is not ‘above’, ‘below’, or ‘both’.

Notes

The detector: 1. Applies threshold based on detection_mode to create a binary mask 2. Labels connected components in the binary mask 3. Filters regions by area (min_area <= area <= max_area) 4. Computes weighted centroids for qualifying regions 5. Returns centroid coordinates as (rows, columns) tuple

Constant False Alarm Rate (CFAR) detector algorithm for finding bright blobs in imagery.

This module implements a CFAR (Constant False Alarm Rate) detector that uses local standard deviation-based thresholding to find signal blobs. The algorithm compares each pixel to the statistics of its local neighborhood (defined as an annular ring) to maintain a constant false alarm rate across images with varying backgrounds.

The implementation uses FFT-based convolution for efficient computation of local statistics across large images.

class vista.algorithms.detectors.cfar.CFAR(background_radius, ignore_radius, threshold_deviation, min_area=1, max_area=1000, annulus_shape='circular', detection_mode='above', search_radius=None)[source]

Bases: object

Detector that uses local standard deviation-based thresholding to find blobs.

Uses CFAR (Constant False Alarm Rate) approach where each pixel is compared to a multiple of the standard deviation in its neighborhood. The neighborhood is defined as an annular ring (background radius excluding ignore radius).

Can detect pixels above threshold, below threshold, or both (absolute deviation). Uses FFT-based convolution for efficient computation of local statistics.

Parameters:
  • background_radius (int) – Outer radius for neighborhood statistics calculation (pixels)

  • ignore_radius (int) – Inner radius to exclude from neighborhood (pixels)

  • threshold_deviation (float) – Number of standard deviations above/below mean for detection threshold

  • min_area (int, optional) – Minimum detection blob area in pixels, by default 1

  • max_area (int, optional) – Maximum detection blob area in pixels, by default 1000

  • annulus_shape (str, optional) – Shape of the annulus (‘circular’ or ‘square’), by default ‘circular’

  • detection_mode (str, optional) – Detection mode, by default ‘above’: - ‘above’: Detect pixels brighter than threshold (mean + threshold*std) - ‘below’: Detect pixels darker than threshold (mean - threshold*std) - ‘both’: Detect pixels deviating from mean in either direction

  • search_radius (int, optional) – When specified, only keep the blob whose weighted centroid is closest to the search_center (or image center) and within this radius. Used for chip-based detection where only blobs near the center are of interest. By default None (keep all blobs)

name

Algorithm name (“Constant False Alarm Rate”)

Type:

str

kernel

Pre-computed annular kernel for convolution

Type:

ndarray

n_pixels

Number of pixels in the annular neighborhood

Type:

int

__call__(image, search_center=None)[source]

Process single image and return detections as (rows, columns)

process_chip(chip, search_center=None)[source]

Process chip and return (signal_mask, noise_std) for track extraction

Notes

  • Detection threshold formula (above mode): pixel > mean + threshold_deviation * std

  • Detection threshold formula (below mode): pixel < mean - threshold_deviation * std

  • Detection threshold formula (both mode): |pixel - mean| > threshold_deviation * std

  • Detected pixels are grouped into connected blobs using 8-connectivity

  • Blobs are filtered by area (min_area <= area <= max_area)

  • Blob centroids are returned as sub-pixel coordinates

  • Kernel FFT is cached by image shape for efficiency

Examples

>>> from vista.algorithms.detectors.cfar import CFAR
>>> cfar = CFAR(background_radius=10, ignore_radius=3,
...             threshold_deviation=3.0, min_area=1, max_area=100)
>>> # Process single frame
>>> rows, columns = cfar(image)
>>> # Process chip with search radius
>>> signal_mask, noise_std = cfar.process_chip(chip, search_center=(chip_size//2, chip_size//2))
name = 'Constant False Alarm Rate'
__init__(background_radius, ignore_radius, threshold_deviation, min_area=1, max_area=1000, annulus_shape='circular', detection_mode='above', search_radius=None)[source]
__call__(image, search_center=None)[source]

Process a single image and return detection centroids.

Parameters:
  • image (ndarray) – 2D image array to process

  • search_center (tuple, optional) – (row, col) for search_radius filtering. If None and search_radius is set, uses image center. If search_radius is None, this parameter is ignored.

Returns:

  • rows (ndarray) – Array of detection centroid row coordinates

  • columns (ndarray) – Array of detection centroid column coordinates

process_chip(chip, search_center=None)[source]

Process a chip and return detailed signal information.

This method is designed for track extraction, where both the signal mask and noise statistics are needed.

Parameters:
  • chip (ndarray) – 2D image chip (may contain NaN values at edges)

  • search_center (tuple, optional) – (row, col) for search_radius filtering. If None and search_radius is set, uses chip center. If search_radius is None, this parameter is ignored.

Returns:

  • signal_mask (ndarray) – Boolean mask of signal pixels (same shape as chip)

  • noise_std (float) – Noise standard deviation at chip center

Notes

  • NaN values in the chip are replaced with 0 for processing and masked out

  • Uses search_radius to filter blobs (keeps closest by weighted centroid)

  • Returns full signal mask (all pixels in the blob), not just centroids

Trackers

Simple nearest-neighbor tracker with automatic parameter adaptation

class vista.algorithms.trackers.simple_tracker.SimpleTrack(detection_pos, frame, track_id, max_search_radius)[source]

Bases: object

Simple track using running average for position prediction.

This track class maintains a history of detected positions and predicts future positions using linear extrapolation based on recent velocity.

id

Unique identifier for this track.

Type:

int

positions

List of (x, y) position arrays for each detection/prediction.

Type:

list of ndarray

frames

Frame numbers corresponding to each position.

Type:

list of int

max_search_radius

Maximum distance to search for associated detections.

Type:

float

hits

Number of times this track was updated with a detection.

Type:

int

misses

Number of consecutive frames without a detection.

Type:

int

age

Total number of frames this track has existed.

Type:

int

__init__(detection_pos, frame, track_id, max_search_radius)[source]

Initialize a new track.

Parameters:
  • detection_pos (ndarray) – Initial (x, y) position of the detection.

  • frame (int) – Frame number where this track was initiated.

  • track_id (int) – Unique identifier for this track.

  • max_search_radius (float) – Maximum distance to search for associated detections.

predict_position()[source]

Predict next position using velocity estimate.

Returns:

Predicted (x, y) position for the next frame. If fewer than 2 positions exist, returns the last known position. Otherwise, uses linear extrapolation from the last 2-3 positions.

Return type:

ndarray

Notes

The prediction uses up to the last 3 positions to estimate velocity, providing more stable predictions than using only the last 2 positions.

distance_to(detection_pos)[source]

Compute Euclidean distance from detection to predicted position.

Parameters:

detection_pos (ndarray) – The (x, y) position of a detection to compare against.

Returns:

Euclidean distance between the detection and this track’s predicted position.

Return type:

float

update(detection_pos, frame)[source]

Update track with a new detection.

Parameters:
  • detection_pos (ndarray) – The (x, y) position of the new detection.

  • frame (int) – Frame number of the new detection.

Notes

This method appends the new position to the track history, increments the hit count, resets the consecutive miss count, and increments age.

mark_missed(frame)[source]

Mark a frame as missed and add predicted position.

Parameters:

frame (int) – Frame number that was missed (no detection associated).

Notes

When a track is not associated with any detection in a frame, this method adds the predicted position to maintain track continuity. It increments both the consecutive miss count and the track age.

quality_score()[source]

Compute track quality score (higher is better).

Returns:

Quality score between 0 and 1, representing track reliability. Calculated as detection rate multiplied by a recency penalty factor that heavily penalizes recent misses.

Return type:

float

Notes

The quality score combines two factors: - Detection rate: ratio of hits to total age - Recency penalty: exponential decay based on consecutive misses

This score helps identify high-quality tracks for retention and low-quality tracks for deletion.

vista.algorithms.trackers.simple_tracker.run_simple_tracker(detectors, config)[source]

Run simple nearest-neighbor tracker with adaptive parameters.

This tracker automatically adapts to the data and requires minimal configuration. It uses Hungarian algorithm for detection-to-track association and automatically computes search radius and maximum track age if not provided.

Parameters:
  • detectors (list of Detector) – List of Detector objects to use as input. Each detector should have frames, columns, and rows attributes containing detection data.

  • config (dict) –

    Dictionary containing tracker configuration with the following keys:

    • tracker_namestr, optional

      Name for the resulting tracker. Default is ‘Simple Tracker’.

    • max_search_radiusfloat, optional

      Maximum distance to search for associations. If not provided, automatically computed from detection nearest-neighbor statistics.

    • min_track_lengthint, optional

      Minimum number of detections for a valid track. Default is 5.

    • max_ageint, optional

      Maximum frames a track can go without detection before deletion. If not provided, automatically computed based on frame gaps.

Returns:

List of track data dictionaries, each containing:

  • ’frames’ndarray

    Array of frame numbers where track appears.

  • ’rows’ndarray

    Array of row (y) coordinates for each frame.

  • ’columns’ndarray

    Array of column (x) coordinates for each frame.

Return type:

list of dict

Notes

The tracker performs the following steps:

  1. Collects all detections organized by frame

  2. Auto-computes max_search_radius using 90th percentile of nearest-neighbor distances if not provided

  3. Auto-computes max_age based on average frame gaps if not provided

  4. Associates detections to tracks using Hungarian algorithm

  5. Creates new tracks from unassociated detections

  6. Marks missed detections for tracks without associations

  7. Deletes tracks that exceed max_age or have poor quality scores

  8. Returns tracks that meet minimum length requirement

Examples

>>> config = {
...     'tracker_name': 'My Tracker',
...     'min_track_length': 5,
...     'max_search_radius': 10.0
... }
>>> tracks = run_simple_tracker(detectors, config)
>>> print(f"Found {len(tracks)} tracks")

Multi-object tracker implementation for VISTA

class vista.algorithms.trackers.kalman_tracker.KalmanTrack(detection_pos, frame, process_noise, measurement_noise, track_id)[source]

Bases: object

Single track with constant velocity Kalman filter

__init__(detection_pos, frame, process_noise, measurement_noise, track_id)[source]

Initialize track with first detection.

State vector: [x, vx, y, vy] where x=column, y=row

predict(dt=1.0)[source]

Predict next state using constant velocity model

update(detection_pos, frame)[source]

Update state with new detection

mark_missed(frame)[source]

Mark that no detection was associated this frame

get_predicted_position()[source]

Get predicted position (x, y)

mahalanobis_distance(detection_pos)[source]

Compute Mahalanobis distance to detection

vista.algorithms.trackers.kalman_tracker.run_kalman_tracker(detectors, config)[source]

Run Kalman filter tracker on detections using a custom implementation.

Parameters:
  • detectors (list of Detector) – List of Detector objects to use as input

  • config (dict) –

    Dictionary containing tracker configuration:

    • tracker_name: Name for the resulting tracker

    • process_noise: Process noise for constant velocity model

    • measurement_noise: Measurement noise covariance

    • gating_distance: Mahalanobis distance threshold for gating

    • min_detections: Minimum detections required to initiate track

    • delete_threshold: Covariance trace threshold for track deletion

Returns:

List of track data dictionaries, each containing:

  • ’frames’: numpy array of frame numbers

  • ’rows’: numpy array of row coordinates

  • ’columns’: numpy array of column coordinates

Return type:

list of dict

Network flow optimization tracker for VISTA

vista.algorithms.trackers.network_flow_tracker.run_network_flow_tracker(detectors, config)[source]

Run network flow optimization tracker on detections.

This tracker formulates multi-object tracking as a minimum-cost flow problem on a graph where nodes are detections and edges represent possible associations. The algorithm finds the globally optimal set of tracks by solving for the minimum-cost flow from source to sink using Bellman-Ford successive shortest paths.

Key features:

  • Negative link costs incentivize longer tracks over many short tracks

  • Smoothness penalty encourages constant-velocity, straight-line paths

  • Global optimization finds better solutions than greedy local association

Parameters:
  • detectors (list of Detector) – List of Detector objects to use as input

  • config (dict) –

    Dictionary containing tracker configuration:

    • tracker_name: Name for the resulting tracker

    • max_gap: Maximum frame gap to search for associations (default: 5)

    • max_distance: Maximum spatial distance for associations (default: 50.0)

    • entrance_cost: Cost for starting a new track (default: 50.0)

    • exit_cost: Cost for ending a track (default: 50.0)

    • min_track_length: Minimum detections required for valid track (default: 3)

Returns:

List of track data dictionaries, each containing:

  • ’frames’: numpy array of frame numbers

  • ’rows’: numpy array of row coordinates

  • ’columns’: numpy array of column coordinates

Return type:

list of dict

vista.algorithms.trackers.network_flow_tracker.solve_min_cost_flow(detections, edges)[source]

Solve minimum-cost flow problem using successive shortest path with Bellman-Ford.

Key insight: Use NEGATIVE link costs to represent the benefit of linking detections. This makes longer tracks cheaper than many short tracks. For example: - Single detection track: entrance + exit = 100 + 100 = 200 - Two detection track: entrance + (-80) + exit = 100 - 80 + 100 = 120 (cheaper!) - Ten detection track: entrance + 9×(-80) + exit = 100 - 720 + 100 = -520 (much cheaper!)

Uses Bellman-Ford instead of Dijkstra because we have negative edge weights. No negative cycles exist because: 1. Used detections are removed (no loops back) 2. Time flows forward only (frame_i → frame_j where j > i) 3. Sink has no outgoing edges

Parameters:
  • detections (list) – List of detection dictionaries

  • edges (list) – List of edge dictionaries with ‘from’, ‘to’, ‘cost’

Returns:

list

Return type:

List of tracks, where each track is a list of detection dictionaries

vista.algorithms.trackers.network_flow_tracker.find_shortest_path(edges, used_detections)[source]

Find shortest path from source to sink using Bellman-Ford algorithm.

Bellman-Ford handles negative edge weights (unlike Dijkstra). This is necessary because link costs are negative to incentivize longer tracks.

Parameters:
  • edges (list) – List of edge dictionaries

  • used_detections (list) – Set of detection IDs already used in tracks

Returns:

list

Return type:

List of node IDs representing path from source to sink, or None if no path exists

Tracklet-based hierarchical tracker for high false alarm scenarios

This tracker uses a two-stage approach optimized for scenarios with: - High false alarm rate (100:1 or higher) - Smooth real target motion with consistent velocity

Stage 1: Form high-confidence tracklets using strict association criteria Stage 2: Link tracklets based on velocity extrapolation and smoothness

class vista.algorithms.trackers.tracklet_tracker.Tracklet(detection_pos, frame, tracklet_id)[source]

Bases: object

High-confidence track segment with velocity consistency

__init__(detection_pos, frame, tracklet_id)[source]
add_detection(detection_pos, frame)[source]

Add detection to tracklet and update velocity estimate

mark_missed(frame)[source]

Mark that no detection was associated this frame

detection_rate()[source]

Compute detection rate (hits / age)

predict_position(target_frame)[source]

Predict position at target frame using velocity

check_velocity_consistency(detection_pos, frame, max_velocity_change)[source]

Check if detection is consistent with tracklet velocity

distance_to(detection_pos, frame)[source]

Distance from predicted position to detection

extrapolate_forward(frames_ahead)[source]

Extrapolate tracklet forward in time

extrapolate_backward(frames_back)[source]

Extrapolate tracklet backward in time

get_start_velocity()[source]

Get velocity at tracklet start

get_end_velocity()[source]

Get velocity at tracklet end

vista.algorithms.trackers.tracklet_tracker.run_tracklet_tracker(detectors, config)[source]

Run tracklet-based hierarchical tracker on detections.

This tracker is optimized for high false alarm scenarios where real tracks move smoothly. It uses a two-stage approach:

Stage 1: Form high-confidence tracklets with strict association criteria

  • Small search radius for initial associations

  • Velocity consistency checking

  • “M out of N” approach: allows small detection gaps

Stage 2: Link tracklets using global optimization

  • Velocity extrapolation for gap filling

  • Smoothness scoring based on velocity/position consistency

  • Hungarian algorithm for optimal linking

Parameters:
  • detectors (list of Detector) – List of Detector objects to use as input

  • config (dict) –

    Dictionary containing tracker configuration:

    • tracker_name: Name for the resulting tracker

    • initial_search_radius: Max distance for tracklet formation (default: 10.0)

    • max_velocity_change: Max velocity change for tracklet formation (default: 5.0)

    • min_tracklet_length: Minimum detections for valid tracklet (default: 3)

    • max_consecutive_misses: Max consecutive missed detections in Stage 1 (default: 2)

    • min_detection_rate: Minimum detection rate (hits/age) for tracklets (default: 0.6)

    • max_linking_gap: Maximum frame gap to link tracklets (default: 10)

    • linking_search_radius: Max distance for tracklet linking (default: 30.0)

    • smoothness_weight: Weight for smoothness in linking cost (default: 1.0)

    • min_track_length: Minimum detections for final track (default: 5)

Returns:

List of track data dictionaries, each containing:

  • ’frames’: numpy array of frame numbers

  • ’rows’: numpy array of row coordinates

  • ’columns’: numpy array of column coordinates

Return type:

list of dict

Background Removal

class vista.algorithms.background_removal.temporal_median.TemporalMedian(imagery, name='Temporal Median', background=5, offset=2)[source]

Bases: object

Temporal median background removal algorithm.

Removes background by computing the median of surrounding frames, excluding a temporal offset around the current frame. This approach is effective for detecting moving objects against a relatively static background.

Parameters:
  • imagery (Imagery) – The multi-frame imagery dataset to process.

  • name (str, optional) – Name identifier for this algorithm instance. Default is “Temporal Median”.

  • background (int, optional) – Number of frames on each side (left and right) to use for computing the median background. Default is 5.

  • offset (int, optional) – Number of frames to skip on each side of the current frame before including frames in the background calculation. This prevents the current frame and immediately adjacent frames from influencing the background estimate. Default is 2.

_current_frame

Internal counter tracking the current frame being processed. Initialized to -1 and incremented on each call.

Type:

int

Notes

The algorithm computes a background estimate using frames in two windows: - Left window: [current - offset - background : current - offset] - Right window: [current + offset + 1 : current + offset + background + 1]

The median of all frames in these windows is subtracted from the current frame to produce the foreground image.

Examples

>>> from vista.imagery import Imagery
>>> imagery = Imagery.from_file('data.h5')
>>> temporal_median = TemporalMedian(imagery, background=5, offset=2)
>>> frame_idx, foreground = temporal_median()
imagery: Imagery
name: str = 'Temporal Median'
background: int = 5
offset: int = 2
__call__()[source]

Process the next frame and return the background-removed result.

Returns:

  • frame_idx (int) – Index of the processed frame.

  • foreground (NDArray) – The background-removed frame, computed as current_frame - median_background. Has the same shape as the input imagery frames.

Return type:

Tuple[int, ndarray[tuple[Any, …], dtype[_ScalarT]]]

Notes

This method maintains internal state (_current_frame) and should be called sequentially for each frame. Calling it multiple times will process successive frames in order.

__init__(imagery, name='Temporal Median', background=5, offset=2)

Robust PCA background subtraction for VISTA

This module implements Principal Component Pursuit (PCP) to decompose image sequences into low-rank (background) and sparse (foreground) components.

Reference: Candès, E. J., Li, X., Ma, Y., & Wright, J. (2011). Robust principal component analysis? Journal of the ACM (JACM), 58(3), 1-37.

vista.algorithms.background_removal.robust_pca.shrinkage_operator(X, tau)[source]

Soft-thresholding (shrinkage) operator for sparse component.

Parameters:
  • X (ndarray) – Input matrix

  • tau (float) – Threshold parameter

Returns:

Thresholded matrix

Return type:

ndarray

vista.algorithms.background_removal.robust_pca.singular_value_threshold(X, tau)[source]

Singular Value Thresholding (SVT) operator for low-rank component.

Parameters:
  • X (ndarray) – Input matrix

  • tau (float) – Threshold parameter

Returns:

Low-rank approximation of X

Return type:

ndarray

vista.algorithms.background_removal.robust_pca.robust_pca_inexact_alm(M, lambda_param=None, mu=None, tol=1e-07, max_iter=1000, callback=None)[source]

Robust PCA using Inexact Augmented Lagrange Multiplier method.

Decomposes M = L + S where: - L is low-rank (background) - S is sparse (foreground/moving objects)

Solves:

minimize ||L||_* + λ||S||_1 subject to L + S = M

Parameters:
  • M (ndarray) – Input matrix (each column is a vectorized image frame)

  • lambda_param (float, optional) – Sparsity parameter, by default 1/sqrt(max(m,n))

  • mu (float, optional) – Augmented Lagrangian parameter, by default auto

  • tol (float, optional) – Convergence tolerance, by default 1e-7

  • max_iter (int, optional) – Maximum iterations, by default 1000

  • callback (callable, optional) – Optional callback function called after each iteration. Called with (iteration, max_iter, rel_error). Should return False to cancel processing.

Returns:

  • L (ndarray) – Low-rank component (background)

  • S (ndarray) – Sparse component (foreground)

vista.algorithms.background_removal.robust_pca.run_robust_pca(images, lambda_param=None, tol=1e-07, max_iter=1000, callback=None)[source]

Apply Robust PCA background subtraction to a 3D array of images.

Parameters:
  • images (ndarray) – 3D numpy array (num_frames, height, width) containing image data

  • lambda_param (float, optional) – Sparsity parameter, by default auto = 1/sqrt(max(m,n))

  • tol (float, optional) – Convergence tolerance, by default 1e-7

  • max_iter (int, optional) – Maximum iterations, by default 1000

  • callback (callable, optional) – Optional callback function called after each iteration. Called with (iteration, max_iter, rel_error). Should return False to cancel processing.

Returns:

(background_images, foreground_images) where:

  • background_images: Low-rank background component (same shape as input)

  • foreground_images: Sparse foreground component (same shape as input)

Return type:

tuple of (ndarray, ndarray)

Enhancement

Coaddition algorithm for enhancing slowly moving objects by summing frames over a running window

class vista.algorithms.enhancement.coadd.Coaddition(imagery, window_size)[source]

Bases: object

Enhancement algorithm that sums imagery over a running window.

Useful for highlighting slowly moving objects by integrating signal over multiple frames. The algorithm maintains a running sum of frames within a sliding window.

name = 'Coaddition'
__init__(imagery, window_size)[source]

Initialize the Coaddition algorithm.

Parameters:
  • imagery (Imagery) – Imagery object to process

  • window_size (int) – Number of frames to sum in the running window

__call__()[source]

Process the next frame and return the coadded result.

Returns:

(frame_index, coadded_frame) where coadded_frame is the sum of frames within the window centered on the current frame.

Return type:

tuple

__len__()[source]

Return the number of frames to process

class vista.algorithms.enhancement.coadd.DecimatingCoaddition(imagery, window_size)[source]

Bases: object

Enhancement algorithm that sums imagery over non-overlapping windows.

Unlike the streaming Coaddition which produces an output for every input frame, this decimating version produces one output frame per window. This reduces the output frame count by a factor of window_size.

For example, with 10 input frames (0-9) and window_size=3: - Window 1: sum frames 0, 1, 2 → output at frame index 1 (center) - Window 2: sum frames 3, 4, 5 → output at frame index 4 (center) - Window 3: sum frames 6, 7, 8 → output at frame index 7 (center) - Remaining frame 9 is discarded (incomplete window)

name = 'Decimating Coaddition'
__init__(imagery, window_size)[source]

Initialize the Decimating Coaddition algorithm.

Parameters:
  • imagery (Imagery) – Imagery object to process

  • window_size (int) – Number of frames to sum in each non-overlapping window

__call__()[source]

Process the next window and return the coadded result.

Returns:

(output_frame_index, coadded_frame) where output_frame_index is the center frame of the window in the original imagery coordinates, and coadded_frame is the sum of all frames in the window.

Return type:

tuple

__len__()[source]

Return the number of output frames (complete windows)

get_output_frame_indices()[source]

Get the list of output frame indices in original imagery coordinates.

Returns:

List of frame indices that will have output values

Return type:

list[int]

Track Analysis

Track interpolation algorithm for filling missing frames in trajectories.

This module provides the TrackInterpolation class which fills gaps in track data by interpolating missing frames between existing track points.

class vista.algorithms.tracks.interpolation.TrackInterpolation(track, method='linear')[source]

Bases: object

Interpolates missing frames in a track trajectory.

Takes a Track object that may have gaps in frame coverage and returns a new Track with interpolated positions for all missing frames between the first and last tracked frames.

Parameters:
  • track (Track) – Input track that may have missing frames

  • method (str, optional) – Interpolation method for scipy.interp1d. Options include: - ‘linear’: Linear interpolation (default) - ‘nearest’: Nearest-neighbor interpolation - ‘zero’: Zero-order spline (piecewise constant) - ‘slinear’: First-order spline - ‘quadratic’: Second-order spline - ‘cubic’: Third-order spline By default ‘linear’

__call__()[source]

Execute the interpolation and return results

Examples

>>> interpolator = TrackInterpolation(track, method='linear')
>>> results = interpolator()
>>> interpolated_track = results['interpolated_track']
__init__(track, method='linear')[source]

Initialize the track interpolation algorithm.

Parameters:
  • track (Track) – Input track with potentially missing frames

  • method (str, optional) – Interpolation method for scipy.interp1d, by default ‘linear’

__call__()[source]

Execute interpolation on the track.

Returns:

Dictionary containing: - ‘interpolated_track’: Track object with all frames filled - ‘original_frames’: Array of frame numbers that existed in original track - ‘interpolated_frames’: Array of frame numbers that were interpolated - ‘n_interpolated’: Number of frames that were interpolated

Return type:

dict

Raises:

ValueError – If track has fewer than 2 points (cannot interpolate)

Savitzky-Golay filter for smoothing track trajectories.

This module provides the SavitzkyGolayFilter class which smooths track positions using a Savitzky-Golay filter, a polynomial smoothing filter that preserves higher moments of the signal better than a simple moving average.

class vista.algorithms.tracks.savitzky_golay.SavitzkyGolayFilter(track, radius=2, polyorder=2)[source]

Bases: object

Applies Savitzky-Golay filter to smooth track trajectories.

The Savitzky-Golay filter smooths data by fitting successive sub-sets of adjacent data points with a low-degree polynomial using least-squares. This preserves features of the distribution such as relative maxima, minima and width better than adjacent averaging.

Parameters:
  • track (Track) – Input track to smooth

  • radius (int, optional) – Radius of the smoothing window. The window length will be 2*radius + 1. Must be large enough to satisfy window_length > polyorder. By default 2

  • polyorder (int, optional) – Order of the polynomial used to fit the samples. Must be less than window_length (2*radius + 1). By default 2

__call__()[source]

Execute the filtering and return results

Examples

>>> filter = SavitzkyGolayFilter(track, radius=3, polyorder=2)
>>> results = filter()
>>> smoothed_track = results['smoothed_track']

Notes

  • The Savitzky-Golay filter requires at least window_length = 2*radius + 1 points

  • The polynomial order must be less than the window length

  • Edge effects: The filter uses ‘interp’ mode which interpolates at the boundaries

__init__(track, radius=2, polyorder=2)[source]

Initialize the Savitzky-Golay filter.

Parameters:
  • track (Track) – Input track to smooth

  • radius (int, optional) – Radius of the smoothing window, by default 2

  • polyorder (int, optional) – Order of the polynomial, by default 2

__call__()[source]

Execute Savitzky-Golay filtering on the track.

Returns:

Dictionary containing: - ‘smoothed_track’: Track object with smoothed positions - ‘original_rows’: Original row positions before smoothing - ‘original_columns’: Original column positions before smoothing - ‘smoothed_rows’: Smoothed row positions - ‘smoothed_columns’: Smoothed column positions

Return type:

dict

Raises:

ValueError – If window length is greater than number of track points, or if polyorder >= window_length, or if track has fewer than 3 points

Track extraction algorithm for extracting image chips and detecting signal pixels.

This module implements track extraction that crops image chips around each track point, detects signal pixels using CFAR-like thresholding, computes local noise statistics, and optionally refines track coordinates using weighted centroids.

class vista.algorithms.tracks.extraction.TrackExtraction(track, imagery, chip_radius, background_radius, ignore_radius, threshold_deviation, annulus_shape='circular', search_radius=None, update_centroids=False, max_centroid_shift=inf)[source]

Bases: object

Extract image chips and detect signal pixels around track points.

For each track point, this algorithm: 1. Extracts a square image chip of specified diameter 2. Detects signal pixels using CFAR-like thresholding 3. Computes local noise standard deviation from background annulus 4. Optionally updates track coordinates to weighted centroid of signal blob

Parameters:
  • track (Track) – Track object containing trajectory points

  • imagery (Imagery) – Imagery object to extract chips from

  • chip_radius (int) – Radius of square chips to extract (in pixels). Total chip diameter will be 2*radius + 1

  • background_radius (int) – Outer radius for background noise calculation (pixels)

  • ignore_radius (int) – Inner radius to exclude from background (guard region, pixels)

  • threshold_deviation (float) – Number of standard deviations above mean for signal detection

  • annulus_shape (str, optional) – Shape of the annulus (‘circular’ or ‘square’), by default ‘circular’

  • search_radius (int, optional) – When specified, only keep signal blobs that have at least one pixel within the central search region of this radius. By default None (keep all blobs)

  • update_centroids (bool, optional) – If True, update track coordinates to signal blob centroids, by default False

  • max_centroid_shift (float, optional) – Maximum allowed centroid shift in pixels. Points with larger shifts are not updated. By default np.inf (no limit)

name

Algorithm name (“Track Extraction”)

Type:

str

chip_diameter

Computed chip diameter (2 * chip_radius + 1)

Type:

int

__call__()[source]

Process all track points and return extraction results

Returns:

Dictionary with keys: - ‘chips’: NDArray with shape (n_points, diameter, diameter) - ‘signal_masks’: boolean NDArray with shape (n_points, diameter, diameter) - ‘noise_stds’: NDArray with shape (n_points,) - ‘updated_rows’: NDArray with shape (n_points,) - ‘updated_columns’: NDArray with shape (n_points,)

Return type:

dict

Notes

  • Chips near image edges are padded with np.nan values

  • Signal detection threshold: pixel > mean + threshold_deviation * std

  • Only the largest connected signal blob is used for centroid calculation

  • Centroid updates respect max_centroid_shift constraint

name = 'Track Extraction'
__init__(track, imagery, chip_radius, background_radius, ignore_radius, threshold_deviation, annulus_shape='circular', search_radius=None, update_centroids=False, max_centroid_shift=inf)[source]
__call__()[source]

Process all track points and extract chips with signal detection.

Returns:

Dictionary containing: - ‘chips’: Image chips array (n_points, diameter, diameter) - ‘signal_masks’: Signal pixel masks (n_points, diameter, diameter) - ‘noise_stds’: Noise standard deviations (n_points,) - ‘updated_rows’: Updated row coordinates (n_points,) - ‘updated_columns’: Updated column coordinates (n_points,)

Return type:

dict