Skip to content

Commit fde966f

Browse files
committed
new post
1 parent 0978e00 commit fde966f

25 files changed

+125
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
---
2+
title: Naive even ilumination
3+
tags: [image processing]
4+
style: fill
5+
color: success
6+
description: A simple and efficient method to correct uneven ilumination in images
7+
---
8+
9+
TAGS: image processing
10+
11+
# Introduction
12+
13+
A way to improve uneven illumination in images → just as we can fit a line to a 1D signal, we can fit a plane to an image, as if it were a parallelepiped with a certain tilt. We convert this plane into a grayscale image, center it at 0±tol (with both negative and positive values), and add it to the grayscale channel of the unevenly illuminated image. This will make bright areas darker and dark areas brighter—or something like that. It’s like applying a proportional shadow correction to make the luminance channel more homogeneous.
14+
15+
In this post, we’ll design a simple and effective technique to enhance uneven illumination in images using plane fitting.
16+
17+
When we observe an image with uneven illumination, we often sense that something is wrong—it doesn’t look pleasing and makes it harder to perceive details. An intuitive and mathematical way to approach this problem is by fitting a plane to the image, similar to how a line is fit to a 1D signal.
18+
19+
# Theoretical Background
20+
21+
Imagine a grayscale image as a 3D surface, where each pixel has coordinates \((x, y)\) and an intensity \(z\). If we fit a plane to this surface using linear regression (least squares), we obtain a representation of the general intensity trend across the image.
22+
23+
This plane can be interpreted as capturing the global illumination or tonal bias of the image. By centering this plane around zero and scaling it appropriately, we can add it to the original image to enhance intensity differences: bright areas become darker and dark areas become brighter, thus improving the homogeneity of illumination.
24+
25+
# Algorithm
26+
27+
**1. Conversion to float**
28+
29+
Convert the grayscale image to `float32` to perform numerical operations:
30+
31+
```python
32+
I = img_gray.astype(np.float32)
33+
```
34+
35+
**2. Coordinate generation**
36+
37+
Generate pixel coordinates:
38+
39+
```python
40+
ys, xs = np.mgrid[0:h, 0:w]
41+
```
42+
43+
**3. Plane fitting via least squares**
44+
45+
We want to fit a plane:
46+
47+
$$
48+
z = ax + by + c
49+
$$
50+
51+
Construct the linear system:
52+
53+
$$
54+
A \cdot
55+
\begin{bmatrix}
56+
a \\
57+
b \\
58+
c
59+
\end{bmatrix}
60+
= I,
61+
$$
62+
63+
where $I$ is the vector of intensities and:
64+
65+
$$
66+
A = \begin{bmatrix} x_1 & y_1 & 1; \\ x_2 & y_2 & 1; \\ \cdots & \cdots & \cdots \end{bmatrix}
67+
$$
68+
69+
Solve using least squares:
70+
71+
```python
72+
coeffs, *_ = np.linalg.lstsq(A, b, rcond=None)
73+
```
74+
75+
**4. Plane centering and normalization**
76+
77+
Center and scale the resulting plane to have zero mean and unit standard deviation (to avoid imbalanced effects):
78+
79+
```python
80+
plane_centered = plane - np.mean(plane)
81+
plane_centered /= max(np.std(plane_centered), tol)
82+
```
83+
84+
---
85+
86+
**5. Enhancement Application**
87+
88+
Counteract uneven illumination by subtracting the (scaled) plane from the original image:
89+
90+
$$
91+
I_{\text{out}} = I + \alpha \cdot \text{Plano centrado} \cdot 127
92+
$$
93+
94+
Finally, clip values to valid range and convert back to `uint8`:
95+
96+
```python
97+
I_out = np.clip(I_out, 0, 255).astype(np.uint8)
98+
```
99+
100+
# 3D Visualization
101+
102+
This visualization helps to understand how the plane fits the image’s intensity surface and how its addition enhances illumination.
103+
104+
Testing with some synthetic images:
105+
106+
| Uneven | Heightmap and plane | Corrected |
107+
|--------|----------------------|-----------|
108+
| ![](../assets/blog_images/2025-04-22-naive-even-ilumination/1.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/3d_surface_1.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/perceptually_improved_1.png) |
109+
| ![](../assets/blog_images/2025-04-22-naive-even-ilumination/2.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/3d_surface_2.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/perceptually_improved_2.png) |
110+
| ![](../assets/blog_images/2025-04-22-naive-even-ilumination/3.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/3d_surface_3.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/perceptually_improved_3.png) |
111+
| ![](../assets/blog_images/2025-04-22-naive-even-ilumination/4.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/3d_surface_4.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/perceptually_improved_4.png) |
112+
113+
And with some real images:
114+
115+
| Uneven | Heightmap and plane | Corrected |
116+
|--------|----------------------|-----------|
117+
| ![](../assets/blog_images/2025-04-22-naive-even-ilumination/5.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/3d_surface_5.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/perceptually_improved_5.png) |
118+
| ![](../assets/blog_images/2025-04-22-naive-even-ilumination/6.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/3d_surface_6.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/perceptually_improved_6.png) |
119+
| ![](../assets/blog_images/2025-04-22-naive-even-ilumination/7.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/3d_surface_7.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/perceptually_improved_7.png) |
120+
| ![](../assets/blog_images/2025-04-22-naive-even-ilumination/8.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/3d_surface_8.png) | ![](../assets/blog_images/2025-04-22-naive-even-ilumination/perceptually_improved_8.png) |
121+
122+
# Conclusion
123+
124+
When vignetting is strong or the uneven distribution is very unimodal (e.g., in case 3), the method tends to perform worse than when the plane fit is clearly dominated by a directional tilt.
125+
36 KB
Loading
36.9 KB
Loading
55.6 KB
Loading
2.11 MB
Loading
2.2 MB
Loading
2.17 MB
Loading
2.15 MB
Loading
1.86 MB
Loading
1.72 MB
Loading

0 commit comments

Comments
 (0)