How the method works
For a mostly matte surface, the brightness measured under light k is approximately Ik = ρ · max(N · Lk, 0), where ρ is the lighting-independent albedo, N is the unknown surface normal, and Lk is the calibrated light vector. Four rotations give four such equations per pixel. The solver estimates the three components of ρN, normalizes that vector to get N, and keeps its length as ρ.
Three observations is the mathematical minimum. The fourth is what makes the result trustworthy: it gives the solver room to reject one highlight or one shadow per pixel and still remain determined.
Capture
Four scans at 0°, 90°, 180°, and 270° with identical exposure and colour settings, captured through WIA 2.0 or supplied as lossless files.
Register
De-rotate, refine rigidly, then correct elastic settling with optical flow run on a lighting-invariant proxy rather than the raw pixels.
Solve
Fit the lamp azimuth and elevation, then solve the Lambertian system per pixel with outlier rejection and residual-guided repair.
Export & verify
Write normals, albedo, height, and alpha, then re-render all four inputs so the residuals show exactly where the model does and does not hold.