Matching cost surface

To estimate how a part of an image moved between two frames, compare a window of the first frame with shifted windows of the second and pick the shift that fits best. Which shift fits best depends on how the difference is measured. Pick a window, change the metric, and add noise, an occluder or a different exposure to see where each error metric succeeds and fails.

Frame I0I_0 click to select the window
Frame I1I_1 shift u\mathbf{u} best true u∗\mathbf{u}^* (×) click to select a shift
Error surface E(u)E(\mathbf{u}) black = best match, click to select a shift
Errors eie_i at the selected shift gray = 0 not counted
Kernels ρ(e)\rho(e) current metric e2e^2, ∣e∣|e|, ∣e∣p|e|^p, Geman–McClure histogram of eie_i

Comparing a window at every shift

Given two images I0(x)I_0(\mathbf{x}) and I1(x)I_1(\mathbf{x}) with pixel positions x=(x,y)\mathbf{x} = (x, y), we look for the displacement u=(u,v)\mathbf{u} = (u, v) for which I1(x+u)I_1(\mathbf{x} + \mathbf{u}) is most similar to I0(x)I_0(\mathbf{x}). For one window with pixels xi\mathbf{x}_i, each shift gives an error per pixel, ei=I1(xi+u)−I0(xi)e_i = I_1(\mathbf{x}_i + \mathbf{u}) - I_0(\mathbf{x}_i), and an error metric E(u)E(\mathbf{u}) combines them into one number. Plotted over all shifts, EE forms a surface whose minimum is the estimated motion. It is the same idea as the autocorrelation surface, where a window is compared with itself. For color images, the sum runs over the color channels or uses only the luminance, as here.

SSD and SAD

The simplest metric is the sum of squared differences, the squared L2 norm of the error vector:

ESSD(u)=∑i[I1(xi+u)−I0(xi)]2=∑iei2E_{SSD}(\mathbf{u}) = \sum_i \left[ I_1(\mathbf{x}_i + \mathbf{u}) - I_0(\mathbf{x}_i) \right]^2 = \sum_i e_i^2

Small errors count little and large errors a lot. That makes the SSD tolerant to low-amplitude noise and easy to minimize, since it is smooth. But it is not robust: a few large errors, e.g. from an occluded part of the window, dominate the sum. The sum of absolute differences, the L1 norm, weighs them less:

ESAD(u)=∑i∣ei∣E_{SAD}(\mathbf{u}) = \sum_i |e_i|

Lp norms and robust kernels

Both are special cases of the Lp norm of the error vector, with p=2p = 2 and p=1p = 1:

ELp(u)=(∑i∣ei∣p)1/pE_{L_p}(\mathbf{u}) = \Big( \sum_i |e_i|^p \Big)^{1/p}

Values p<1p < 1 also make sense for matching, even though the result is no longer a norm (it violates the triangle inequality). More generally, the sum of robust differences applies a kernel ρ\rho to each error:

ESRD(u)=∑iρ(ei),ρGM(x)=x21+x2/a2E_{SRD}(\mathbf{u}) = \sum_i \rho(e_i), \qquad \rho_{GM}(x) = \frac{x^2}{1 + x^2 / a^2}

ρ(x)=∣x∣p\rho(x) = |x|^p gives the Lp norm, but for p≤1p \le 1 it is not differentiable at 0, which is bad for optimization methods. The Geman–McClure kernel is quadratic for small errors like the SSD, but it levels off at a2a^2 for errors much larger than aa, so outliers can only contribute a bounded amount.

Outside the image and masked pixels

A shifted window can leave the image, and some pixels may be known to be invalid, e.g. because they are covered by another object. Masks w0w_0 and w1w_1, 1 inside the region of interest and 0 elsewhere, restrict the sum to pixels that are valid in both images:

EWSRD(u)=∑iw0(xi) w1(xi+u) ρ(ei)E_{WSRD}(\mathbf{u}) = \sum_i w_0(\mathbf{x}_i)\, w_1(\mathbf{x}_i + \mathbf{u})\, \rho(e_i)

Now different shifts sum over different numbers of pixels, and a shift that pushes most of the window out of the image has a small sum simply because little is left. Dividing by the counted area A(u)=∑iw0(xi) w1(xi+u)A(\mathbf{u}) = \sum_i w_0(\mathbf{x}_i)\, w_1(\mathbf{x}_i + \mathbf{u}) makes them comparable:

ENWSRD(u)=1A(u)∑iw0(xi) w1(xi+u) ρ(ei)E_{NWSRD}(\mathbf{u}) = \frac{1}{A(\mathbf{u})} \sum_i w_0(\mathbf{x}_i)\, w_1(\mathbf{x}_i + \mathbf{u})\, \rho(e_i)

Bias and gain

If the frames were taken with different exposure, aperture or even different cameras, their intensities are not directly comparable. A linear model maps one to the other, I0(x)→αI0(x)+βI_0(\mathbf{x}) \rightarrow \alpha I_0(\mathbf{x}) + \beta, and the SSD becomes

ESSD(u,α,β)=∑i[I1(xi+u)−(αI0(xi)+β)]2E_{SSD}(\mathbf{u}, \alpha, \beta) = \sum_i \left[ I_1(\mathbf{x}_i + \mathbf{u}) - (\alpha I_0(\mathbf{x}_i) + \beta) \right]^2

For every shift, α\alpha and β\beta are found by linear regression, and what remains is the error the model cannot explain.

Cross-correlation

Instead of an error, cross-correlation measures a similarity that is largest for the best shift:

ECC(u)=∑iI0(xi) I1(xi+u)E_{CC}(\mathbf{u}) = \sum_i I_0(\mathbf{x}_i)\, I_1(\mathbf{x}_i + \mathbf{u})

On its own it prefers bright regions of I1I_1, whatever they look like. Normalized cross-correlation subtracts the means Iˉ0\bar I_0, Iˉ1\bar I_1 of both windows and divides by their spread:

ENCC(u)=∑i[I0(xi)−Iˉ0][I1(xi+u)−Iˉ1]∑i[I0(xi)−Iˉ0]2∑i[I1(xi+u)−Iˉ1]2E_{NCC}(\mathbf{u}) = \frac{\sum_i [I_0(\mathbf{x}_i) - \bar I_0][I_1(\mathbf{x}_i + \mathbf{u}) - \bar I_1]}{\sqrt{\sum_i [I_0(\mathbf{x}_i) - \bar I_0]^2} \sqrt{\sum_i [I_1(\mathbf{x}_i + \mathbf{u}) - \bar I_1]^2}}

The normalization removes linear changes of brightness and contrast, so NCC works when the frames were taken with different exposure. The same score finds a template in template matching.

Full search

The surface above is a full search: every shift within a radius RR is tried. This is expensive, since each of the (2R+1)2(2R + 1)^2 shifts needs a sum over the whole window, and it only finds the best shift on the integer grid, not with subpixel accuracy. Gradient-based methods such as Lucas–Kanade avoid both problems by following the slope of EE from an initial guess.

Try this