Window matching
The simplest disparity map takes, for every pixel, the disparity with the lowest window cost along its row, as in the scanline matching cost demo. Every pixel decides alone. Where the window is ambiguous, on the flat panel, the stripes or next to depth edges, neighboring pixels pick unrelated disparities, and the map becomes noisy. A larger window helps there but rounds off the corners of objects and widens them at depth edges.
Scanline stereo as a shortest path
Instead of matching pixels one by one, match a whole row coherently. Put the pixels of the left row along one axis and those of the right row along the other. A path from the first to the last pixel of both rows describes one assignment for the whole row, and every step is one of three moves:
- match the next left pixel with the next right pixel, at the window cost of that disparity,
- left occlusion: skip a left pixel that is not visible in the right image, at the cost ,
- right occlusion: skip a right pixel that is not visible in the left image, also at .
A change of disparity needs occlusion steps, since the path must leave one diagonal and join another, so also acts as a penalty for depth jumps. The path keeps the order of the pixels: what is left of something in one image is left of it in the other. Dynamic programming finds the cheapest path in time proportional to the number of pixels times the number of disparities. Above, the path is drawn over the costs with and as axes: a match moves to the right, an occlusion up or down.
Stereo as energy minimization
The path minimizes an energy with two parts, which describe a good stereo correspondence:
- Match quality: each pixel should find a good match in the other image.
- Smoothness: neighboring pixels should usually have about the same disparity.
Every row is optimized on its own, so nothing ties a row to the rows above and below. Where the data is weak, as on the flat panel, neighboring rows choose different paths and the map shows horizontal streaks. Dynamic programming cannot optimize a full 2D grid of pixels; coherent 2D solutions need other energy minimization methods, such as graph cuts or belief propagation.
Try this
- Compare the window matching map with the true one: the box and the disk come out well, the flat panel is speckled, and the stripes are partly assigned to the wrong repetition.
- Raise the window radius to 8: the speckles disappear, but the corners of the box are rounded and the disk bulges into the background.
- Look at scanline stereo: rows are clean, but the flat panel shows horizontal streaks, each row with its own guess.
- Click a row through the flat panel (y ≈ 120) and look at the cost image: in the panel's columns every disparity is equally dark, and the path just continues straight.
- Click a row through the disk (y ≈ 46): the path jumps from the background diagonal to the disk's and back, with occlusion steps at both edges. The hatched pixels left of the disk are background that the right camera cannot see.
- Set κ to 0.001: occlusions are almost free, and the path skips everything that is not a perfect match. At 0.1, it prefers wrong matches over occlusions and smooths away small objects.
- Compare the energies: the true correspondences often have a higher energy than the path found. Then even a perfect optimizer cannot find them; the energy itself has to be improved.