6.14.5 EP06_05 🟠 Background Normalization by Division (Illumination Correction)
A form was photographed under non-uniform illumination, causing one side of the page to appear lighter than the other. Under these conditions, global thresholding by Otsu can produce unsatisfactory results, since a single threshold does not properly separate text and background across the entire image. The solution presented in the chapter consists of normalizing the background by dividing the original image by a heavily smoothed version of itself, which represents the low-frequency illumination.
In this exercise, the original image and the smoothed background (equivalent to the result of a cv2.GaussianBlur with high \(\sigma\)) are already provided. Your task is to implement the normalization step that produces the corrected image.
6.14.5.1 📋 Implementation Guidelines
- Dimensions: Read the integers \(L\) (rows) and \(C\) (columns).
- Original image: Read the \(L \times C\) integer values of the matrix
img(intensities between 0 and 255). - Estimated background: Read the \(L \times C\) integer values of the matrix
bg(intensities between 0 and 255, always strictly greater than zero). - Normalization: For each position \((i,j)\), compute \[ \text{value}(i,j)= \frac{\text{img}(i,j)}{\text{bg}(i,j)}\times255. \]
- Rounding: Round the result to the nearest integer (round half away from zero, using
np.floor(img + 0.5)). - Saturation: Clip the obtained value to the interval \([0,255]\).
- Output: Print the resulting matrix
img_norm.
6.14.5.2 📌 Computational Constraints
- Division by zero: the input guarantees \(\text{bg}(i,j)>0\) at all positions.
- Order of operations: first round, then apply saturation.
- Independent processing: each pixel must be normalized individually, without using information from neighboring pixels.
6.14.5.3 🧠 Theoretical Foundation
| Situation | Effect of normalization |
|---|---|
| \(\text{img}(i,j)=\text{bg}(i,j)\) | Result equal to \(255\), corresponding to the normalized background. |
| \(\text{img}(i,j)<\text{bg}(i,j)\) | Result less than \(255\), preserving darker regions, such as text. |
| \(\text{img}(i,j)>\text{bg}(i,j)\) | Result greater than \(255\), subsequently saturated. |
| Background with non-uniform illumination | The division reduces slow illumination variations, making the image more homogeneous. |
Dividing by the estimated background reduces the effects of non-uniform illumination and preserves the contrast between foreground and background, facilitating subsequent segmentation steps.
6.14.5.4 📦 Input and Output Specification (VPL)
Input:
- Line 1: Integer \(L\).
- Line 2: Integer \(C\).
- Next \(L\) lines: elements of the matrix
img. - Next \(L\) lines: elements of the matrix
bg.
Output:
- Matrix
img_norm, with \(L\) rows and \(C\) columns, containing integer values separated by spaces.
6.14.5.5 📌 Examples
| Input | Output | Observation |
|---|---|---|
| 2 2 60 120 180 40 100 100 200 80 |
153 255 230 128 |
Values greater than \(255\) must be saturated; \(180/200\times255=229.5\) results in \(230\) after rounding. |
| 1 3 30 60 90 60 60 60 |
128 255 255 | Only the first value remains below \(255\) after normalization. |
%%writefile EP06_05.py
# Python codeOverwriting EP06_05.py
TestSuite("EP06_05.py").run()✔️ EP06_05.cases already exists in casos/
📋 5 case(s) loaded from casos/EP06_05.cases
🔍 Testing Python: EP06_05.py
⚠️ EP06_05.py: Empty file (fewer than 3 lines). Tests skipped.