API
Public
Astroalign.align_frames — Method
align_frames(img_froms::AbstractVector{<:AbstractArray}, img_to; [warp_function], kwargs...)Align each image in img_froms to the single reference image img_to.
The photometry on img_to is computed once (during the alignment of the first frame) and reused for every subsequent frame, which is substantially cheaper than invoking the scalar align_frames method once per img_from.
Returns a vector of warped images, one per element of img_froms. Accepts the same keyword arguments as the scalar method.
Astroalign.align_frames — Method
align_frames(imgs::AbstractVector{<:AbstractArray}; kwargs...)Convenience method that takes the first image of imgs as the reference (img_to) and aligns the remaining length(imgs) - 1 images to it. Equivalent to align_frames(@view(imgs[2:end]), first(imgs); kwargs...).
Astroalign.align_frames — Method
function align_frames(img_from, img_to; [warp_function], kwargs...)Align img_from onto img_to.
Accepts an optional warp_function to specify the coordinate transformation (warping) function to use. The function maintains the call signature warp_function(img_from, inv(tfm), axes(img_to)), with the input image img_from, the transform to apply inv(tfm) and the axes() of the destination img_to. By default ImageTransformations.warp is used. Note that warp_function can potentially modify inputs provided via Julia's closure mechanism.
Additional keyword arguments are forwarded to find_transform.
Extended help
Alignment algorithm:
- Identify the
N_maxbrightest point-like sources inimg_fromandimg_to. - Calculate all triangular asterisms formed from these sources.
- Build a
2 × 3 × 2 × Narray of candidate triangle-level correspondences by matching each from-triangle to its nearest to-triangle in the invariant $ℳ$ space defined by Beroiz et al. (2020). Vertices are assigned via a canonical ordering that is invariant under rotation, so the positional correspondence between matched triangles is geometrically consistent. The axes are[coord, vertex, frame, match]wherecoord ∈ {x, y},vertex ∈ {1,2,3}, andframe ∈ {from, to}. - Run RANSAC (Fischler & Bolles, 1981) on the triangle matches to robustly identify the largest set of mutually consistent correspondences ("inliers"). Each hypothesis is a Kabsch fit to one randomly sampled triangle match (3 over-determined constraints), which prevents cross-triangle vertex mixing.
- Refine the transformation via the Kabsch / Umeyama least-squares algorithm applied to all vertex pairs from all inlier triangle matches.
- Finally, warp
img_fromto the coordinates ofimg_to.
Astroalign.apply_transform — Method
apply_transform(tfm, img_from, img_to; warp_function = warp)Apply transformation tfm to img_from, keeping axes consistent with img_to. tfm is typically supplied by find_transform, which is automatically computed internally by align_frames.
Astroalign.find_transform — Method
function find_transform(img_from, img_to;
[box_size],
[ap_radius],
[f],
[min_fwhm],
[nsigma],
[N_max],
[scale],
[ransac_threshold],
[final_iters],
[use_fitpos],
)Compute the transformation needed to align img_from onto img_to, assuming both images are related via a rigid (or similarity, when scale = true) transformation. Automatically called by align_frames.
If img_from or img_to is instead passed as a vector of (x, y) coordinates for the given sources, then the photometry step will be skipped for that image. This allows use of precomputed coordinate lists. A previously computed photometry Table (e.g. extracted from a prior find_transform result via params.phot_to) can also be passed in place of either image, which is useful when aligning a series of frames to a single reference image without recomputing its photometry on every call.
Parameters
box_size: The size of the grid cells (in pixels) used to extract candidate point sources to use for alignment. Defaults to (3, 3) pixels. See Photometry.jl > Source Detection Algorithms for more.ap_radius: The radius of the apertures (in pixel) to place around each point source. Defaults to 9 pixels. See Photometry.jl > Aperture Photometry for more.f: The function to compute within each aperture. Defaults tocom_psf, a fast non-iterative center-of-mass estimator that returns per-axis FWHMs. See the Source characterization section of the accompanying Pluto.jl notebook for more.min_fwhm: The minimum FWHM (in pixels) that an extracted point source must have to be considered as a control point. Defaults to 2 pixels. May be passed as a scalar or as an(fwhm_x, fwhm_y)tuple; the scalar form is compared againsthypot(fwhm...)of the per-axis FWHM returned bycom_psf. Set tonothingto use all identified sources as control points.nsigma: The number of standard deviations above the estimated background that a source must be to be considered as a control point. Defaults to 1. See Photometry.jl > Source Detection Algorithms for more.N_max: Maximal Number of (brightest) sources to consider for alignment (default is 10).scale: Iftrue, fit a similarity transformation (rotation + isotropic scale + translation) instead of a rigid transformation (rotation + translation only). Defaults tofalse.ransac_threshold: Pixel-distance threshold below which a correspondence is classified as an inlier by RANSAC. Defaults to3.0.final_iters: Number of iterative-refinement passes after RANSAC (default3). Each pass fits a new transform from the current inlier set and re-scores all correspondences to admit new inliers or drop old ones.use_fitpos: iftrue(default), the fit results are used in the position estimate for the triangles and thus the alignment.
Private
Astroalign._build_correspondences — Method
_build_correspondences(C_from, ℳ_from, phot_from, C_to, ℳ_to, phot_to)Build a 2 × 3 × 2 × N array of candidate triangle-level correspondences between the from and to frames. The C and ℳ are the combinations of three points and their invariants as returned by _triangle_invariants, which guarantees that both C_from and C_to are already in canonical vertex order (base vertices CCW, apex last).
The axes are [coord, vertex, frame, match]:
coord ∈ {1 = x, 2 = y}vertex ∈ {1, 2, 3}— canonical vertex index within the triangleframe ∈ {1 = from, 2 = to}match— index of the candidate triangle pair ($N$ total)
So out[:, v, 1, n] is the (x, y) position of vertex v in the from frame for match n, and out[:, v, 2, n] is the corresponding position in the to frame. Because both frames share the same canonical vertex ordering, corresponding vertices across frames are geometrically consistent and suitable for direct use in transform estimation.
Astroalign._canonical_vertex_order — Method
_canonical_vertex_order(i, j, l, d2_ji, d2_lj, d2_li, xs, ys)Re-order the three vertices of a triangle with x and y coordinates x = (xs[i], xs[j], xs[l]) and y = (ys[i], ys[j], ys[l]) into a canonical form so that:
- The apex (vertex opposite the longest edge) is last.
- The two base vertices are ordered counter-clockwise (positive cross product).
This canonical form is preserved under rotation and translation, so corresponding triangles in two images receive the same vertex permutation and produce geometrically consistent point correspondences.
Examples
Consider the triangle with vertices
(1) = (0,4)
|\
| \
4 | \ 5
| \
| \
(0,0) = (2)----(3) = (3,0)
3The longest edge is (1)-(3), so the apex is vertex (2). The initial canonical ordering is therefore (1,3,2).
However, this ordering is clockwise in image coordinates, so the base vertices are swapped to enforce counter-clockwise winding, yielding the final canonical ordering (3,1,2) for these vertices.
julia> using Astroalign: _canonical_vertex_order
julia> i, x_i, y_i = 1, 0.0, 4.0;
julia> j, x_j, y_j = 2, 0.0, 0.0;
julia> l, x_l, y_l = 3, 3.0, 0.0;
julia> d2_ji = (x_j - x_i)^2 + (y_j - y_i)^2
16.0
julia> d2_lj = (x_l - x_j)^2 + (y_l - y_j)^2
9.0
julia> d2_li = (x_l - x_i)^2 + (y_l - y_i)^2
25.0
julia> _canonical_vertex_order(i, j, l, d2_ji, d2_lj, d2_li, [x_i, x_j, x_l], [y_i, y_j, y_l])
(3, 1, 2)Notes
The squared edge lengths d2_ji, d2_lj, d2_li are accepted as arguments rather than recomputed, since they are already available at the call site in _triangle_invariants.
Astroalign._fit_minimal_rigid_triangle — Method
_fit_minimal_rigid_triangle(x)Fit a rigid 2-D transformation (rotation + translation) to the single triangle correspondence in the 2 × 3 × 2 × 1 RANSAC sample view x.
Axes are [coord, vertex, frame, 1] where frame = 1 is the from image and frame = 2 is the to image. The three vertex pairs are fitted in a least-squares sense via the Kabsch algorithm.
Returns a one-element Vector{AffineMap} (forward: from → to), or an empty vector when the from-vertices are collinear.
Astroalign._fit_minimal_similarity_triangle — Method
_fit_minimal_similarity_triangle(x)Fit a similarity 2-D transformation (rotation + isotropic scale + translation) to the single triangle correspondence in the 2 × 3 × 2 × 1 RANSAC sample view x. See _fit_minimal_rigid_triangle for the data layout and fitting procedure.
Astroalign._fit_triangle — Method
_fit_triangle(x, scale::Bool)Internal: fit a rigid or similarity transform to the single triangle match.
x is a 2×3×2×1 view from ransac: [coord, vertex, frame, 1]
frame = 1 => from image, frame = 2 => to image
Astroalign._get_sources — Method
_get_sources(img; box_size = nothing, nsigma = 1, N_max = 10)Extract candidate sources in img according to Photometry.Detection.extract_sources. By default, img is first sigma clipped and then background subtracted before the candidate sources are extracted. box_size is passed to BackgroundMeshes.estimate_background, and nsigma is passed to Photometry.Detection.extract_sources. See the Photometry.jl documentation for more.
TODO: Pass more options to clipping, background estimating, and extraction methods in Photometry.jl.
Astroalign._photometry — Method
_photometry(img; box_size, ap_radius, min_fwhm, nsigma, f, N_max, use_fitpos)Internal function used by align_frames. Calls to Photometry.Aperture.photometry with reasonable defaults.
See align_frames for keyword arguments.
Astroalign._ransac — Method
_ransac(correspondences; scale, ransac_threshold)
RANSAC on triangle matches to find the largest set of mutually consistent correspondences (inliers).Astroalign._refine_transform — Method
_refine_transform(tfm, inlier_idxs, correspondences; final_iters, scale, ransac_threshold)Finalize matches returned by Astroalign._ransac by iteratively refining the transform.
Astroalign._triangle_distfn — Method
_triangle_distfn(M_candidates, x, t)RANSAC verification function for triangle-level correspondences.
x is a 2 × 3 × 2 × N array with axes [coord, vertex, frame, match] where frame = 1 is the from image and frame = 2 is the to image.
A triangle match is classified as an inlier when all three of its vertex pairs satisfy ‖A·p_from + b − p_to‖ < t.
Returns (inliers, best_M) where inliers is a vector of match indices.
Astroalign._triangle_invariants — Method
_triangle_invariants(phot)Returns all combinations ($C$) of three candidate point sources from the table of sources phot returned by Photometry.Aperture.photometry, and the computed invariant $\mathscr M$ for each according to Eq. 3 from Beroiz, M., Cabral, J. B., & Sanchez, B. (2020).
Astroalign.com_psf — Method
com_psf(T::Type{<:AbstractFloat}, img_ap::AbstractMatrix, rel_thresh)Determine peak parameters via a fast, non-iterative center-of-mass approach. Return quantities are typed to promote_type(T, typeof(maximum(img_ap))). Peak parameters are returned as a NamedTuple with fields
psf_params: NamedTuple containing entriesx,y, andfwhm(a tuple of x and y FWHM).psf_model:"com"to indicate center-of-masspsf_data: the input image cutout (img_ap) for reference
Astroalign.com_psf — Method
com_psf(img_ap; rel_thresh::T=0.1f0) where T <: AbstractFloatForwards to com_psf(T, img_ap, rel_thresh) where T is inferred from the type of rel_thresh; accumulation promotes T with the image peak type.
Astroalign.to_subpixel — Method
to_subpixel(phot, aps)Creates a new photometry table that is identical to phot, but with the x and y centers replaced with their associated fitted values.
Requires the list of apertures aps that were used for the initial photometry to do the necessary conversion from aperture coordinates to image coordinates.