Recover Albedo from Normal
Recover surface albedo given known surface normal and light observation.
From the Lambertian equation: I=ฯโ (nโ l)
where:
- I is the observed intensity
- ฯ is the surface albedo (reflectance)
- n is the unit surface normal vector
- l is the unit light direction vector
We can solve for albedo: ฯ=nโ lIโ
This is only valid when nโ l>0 (the surface faces the light). For backlit surfaces where the dot product is zero or negative, albedo cannot be recovered from that observation.
In practice, we average albedo estimates from multiple light sources for robustness.
Example:
recover_albedo(0.4, [0, 0, 1], [0, 0, 1])
0.4
Normal parallel to light: dot(n, l) = 1.0
- albedo = 0.4 / 1.0 = 0.4
- When nยทl = 1, intensity equals albedo.
Constraints:
- intensity: observed intensity
- normal: surface normal [nx, ny, nz]
- light_dir: light direction [lx, ly, lz]
- Return albedo rounded to 4 decimal places, or 0 if dot product โค 0
Photometric stereo uses shading variation under known lights to recover both surface normals and albedo (intrinsic reflectance) of a surface. In the Lambertian model, each pixelโs intensity is modeled as the product of albedo and the cosine of the angle between the light direction and the surface normal. This separates geometry (normals) from material (albedo): the normal controls how much light a point receives; the albedo scales how much it reflects.
For a single light, the Lambertian equation is I=ฯ(nโ l) where I is the observed intensity, ฯ the scalar albedo, n a unit normal, and l a unit light direction. If n and l are known and the surface is front-lit (nโ \mathbf{l}>0), this becomes a simple scalar equation in ฯ. With multiple light sources, you get several independent measurements of the same ฯ, which allows you to reduce noise by averaging or doing a least-squares fit.
2. Algorithm / Approach
General pattern for recovering albedo from known normal(s) and intensities:
- Use the Lambertian model to express each observation as: Ikโ=ฯ(nโ lkโ)
- For each valid light (front-lit), solve for an estimate of ฯ: ฯkโ=nโ lkโIkโโ
- Combine multiple estimates {ฯkโ} into a single robust albedo, typically by:
- simple average, or
- weighted average (e.g., weights based on nโ \mathbf{l}kโ or confidence).
Backlit or grazing-angle observations (dot product โค0 or very small) are discarded since they provide unreliable or undefined albedo estimates.
3. Step-by-Step Strategy
Assume for each pixel you are given:
- observed intensities: I[k] for lights k = 0 โฆ K-1
- unit surface normal: n (3D vector)
- unit light directions: L[k] (3D vectors)
Per pixel:
- Initialize
- sum_rho = 0
- count = 0 (or sum_weight = 0 if using weighted averaging)
- Loop over lights
- Compute dot product: d = dot(n, L[k])
- If d <= 0:
- skip this light (backlit or edge-on).
- Else:
- Compute per-light albedo estimate: rho_k = I[k] / d
- Option A (simple average):
- sum_rho += rho_k
- count += 1
- Option B (weighted average, e.g. weight = d):
- w = d
- sum_rho += w * rho_k
- sum_weight += w
Continue the full explanation
You're reading the free preview. Unlock the complete walkthrough, the code editor, test runner and reference solution with Premium.
Editor locked
The code editor is locked for Pro problems. It is only available for free problems. Please upgrade to gain access to the code editor for all problems.