Linear Fit

Match the brightness of channels (RGB) or of one image to another (mono) by scaling their medians to a common reference. A pure multiplicative gain — it equalises levels without clipping or distorting the linear data.

1. Using the tool

The dialog adapts to the active image: RGB images show a channel-target strategy; mono images show a reference-view picker. Results apply to the active view (OK runs it; a progress bar reports work).

ControlWhat it does
Target channel (RGB)Which channel's median the others are scaled to: Highest Median, Lowest Median, or an explicit Red / Green / Blue.
Reference view (mono)Another open image whose median the active mono image is scaled to. If the reference is RGB, a luminance proxy is used (see §2.3).
Out-of-range handlingClip to [0..1], Normalize to [0..1] if needed (default), or Leave values as-is — how to treat values pushed outside [0,1] by the scale.
Grip (bottom-left)Drag to the canvas to mint a Linear Fit shortcut with these settings, or drop on an image to apply headlessly.
Typical uses: equalise the R/G/B backgrounds of a colour image before neutralising it, or bring a mono channel (e.g. a narrowband or luminance frame) to the same level as a reference before combining them.

2. Technical details

The fit is a per-target multiplicative scale that matches medians. The median is used because it tracks the dominant background population and is insensitive to stars and hot pixels.

2.1 Why the median, and why a scale

Each channel/image is modelled as differing from the reference by a single gain factor (different filter throughput, exposure, or sensitivity). Matching a robust central value — the median — aligns the overall level without being skewed by the bright tail. The fit has no additive term: it is y = s·x with zero intercept. (Removing an additive floor is a separate operation — see Remove Pedestal.)

2.2 RGB mode

Per-channel medians m_c = median(x_c) are computed (nan-median), a reference channel is chosen by the strategy (argmax(m) for highest, argmin(m) for lowest, or a fixed R/G/B index), and every channel is scaled so its median equals the reference's:

s_c=\frac{m_{\mathrm{ref}}}{m_c}\,,\qquad \mathrm{out}_c=x_c\cdot s_c\qquad(m_c\ \mathrm{floored\ at}\ 10^{-12})

The reference channel is left unchanged (its scale is 1); the others are pulled to meet it, which equalises the channel backgrounds and removes a flat colour cast.

2.3 Mono → reference mode

A mono image is scaled so its median matches a reference image's median. If the reference is colour, its median is taken on a Rec.709 luminance proxy:

L=0.2126\,R+0.7152\,G+0.0722\,B
s=\frac{m_{\mathrm{ref}}}{m_{\mathrm{src}}}\,,\qquad \mathrm{out}=x\cdot s\qquad(m_{\mathrm{src}}\ \mathrm{floored\ at}\ 10^{-12})

2.4 Out-of-range handling

Because scaling can push values past 1.0 (or a negative input below 0), the result is post-processed by the chosen mode:

Clip to [0..1] out = clip(out, 0, 1) Normalize if needed if min(out) < 0 or max(out) > 1: out = (out - min) / (max - min) Leave as-is out unchanged

“Normalize if needed” (the default) only rescales when values actually left [0,1], so well-behaved data passes through untouched while over-range results are brought back without hard clipping.

2.5 Notes