Skip to main content

Crate mtb_align

Crate mtb_align 

Source
Expand description

Median threshold bitmap alignment for handheld HDR exposures.

Ward (2003). Thresholding each exposure at its own median gives a bitmap that survives any monotonic change of exposure, so frames can be registered before the camera response is solved. Integer translation only.

use mtb_align::{Gray, Options, Shift, shift};

let scene = |x: i64, y: i64| (((x / 16) * 61) ^ ((y / 16) * 37)) as u8;
let read = |dx: i64, dy: i64| {
    let samples = (0..256 * 256).map(|i| scene(i % 256 + dx, i / 256 + dy)).collect();
    Gray::from_vec(samples, 256, 256)
};
let options = Options { bits: 4, ..Options::default() };

assert_eq!(shift(&read(0, 0), &read(5, -3), &options), Ok(Shift::new(5, -3)));

align_stack does a whole bracket, common_crop the region left over.

Structs§

Bitmap
A one-bit-per-pixel image, least-significant bit first, each row padded to a word boundary so a shift never crosses a row. Ward flattens it instead.
Bitmaps
One exposure reduced to the two bitmaps the search compares. They travel together: the exclusion bitmap only means anything against its own threshold.
Gray
A single-channel 8-bit image: row-major samples carried with their dimensions.
Options
How the search is run.
Percentile
Which population split the threshold bitmap is cut at. Ward uses the median, falling back to the 17th or 83rd for exposures too dark or light for it.
Rect
A region of an image, in pixels from the top left.
Shift
How far the target image has to move to sit on top of the reference.

Enums§

Error
What can be wrong with a set of exposures.
Shrink
How a level of the pyramid is halved. Ward’s table calls ImageShrink2 a subsample; his text says “filtered down”. Both readings are available.

Functions§

align_stack
How far each exposure has to move to sit on images[reference], measured between adjacent exposures and accumulated: one percentile fits two neighbours well and the ends of a bracket badly.
common_crop
The region every exposure still covers once moved. What OpenCV’s cut trims to: outside it some frame contributes only padding.
compute_bitmaps
Reduces one exposure to its threshold and exclusion bitmaps.
disagreement
Ward’s BitmapTotal of (tb1 XOR shift(tb2)) AND eb1 AND shift(eb2), counted without materialising any of it. The exclusion terms mask the result of the XOR, never its operands — his footnote 4.
shift
How far target has to move to sit on top of reference.
shrink2
Halves a plane, dropping an odd final row or column.
threshold
The sample value the bitmaps are cut at. A u16 because it can land one past the range: an image of nothing but 255s gives 256, as it does in OpenCV.