Comparing a window at every shift
Given two images and with pixel positions , we look for the displacement for which is most similar to . For one window with pixels , each shift gives an error per pixel, , and an error metric combines them into one number. Plotted over all shifts, 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:
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:
Lp norms and robust kernels
Both are special cases of the Lp norm of the error vector, with and :
Values 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 to each error:
gives the Lp norm, but for 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 for errors much larger than , 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 and , 1 inside the region of interest and 0 elsewhere, restrict the sum to pixels that are valid in both images:
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 makes them comparable:
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, , and the SSD becomes
For every shift, and 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:
On its own it prefers bright regions of , whatever they look like. Normalized cross-correlation subtracts the means , of both windows and divides by their spread:
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 is tried. This is expensive, since each of the 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 from an initial guess.
Try this
- With the defaults, the SSD surface has a single dark minimum at the true shift (3, −2). Click other shifts and watch the errors grow.
- Click a flat region of : the surface is dark almost everywhere and the best shift is arbitrary. Click a straight edge: the minimum becomes a dark valley along the edge, since shifts along it change nothing.
- Choose the zone plate or text image: repeated patterns give several minima of nearly the same depth.
- Set the gain to 1.5 and the bias to 0.15. SSD, SAD and the robust costs grow at every shift and can pick a wrong one, CC runs to bright spots, while NCC and SSD with bias & gain keep the true shift. The fitted , match the settings until the brightest pixels clip at 1.
- Turn on the occluder: a block of large errors appears in the window. Compare SSD with SAD and Geman–McClure (): the histogram shows the outliers, and the robust kernels limit their weight. With masks, the occluded pixels do not count at all.
- Select a window near the border of the image, set and choose masks (WSRD): shifts that leave the image count fewer pixels and look better. Normalized (NWSRD) removes this bias.
- Set the true shift to (2.5, −2): the true minimum lies between pixels, and the full search can only report a neighbor.
- Choose the Lp norm and move between 0.5 and 2: below 1 the kernel rises steeply at 0 and flattens for large errors, like a robust kernel with a sharp tip; at 2 it is the SSD.