Switch the structuring element B (or select the presets) and click the cells of the original image f to turn pixels on or off.
4.9.4 EP04_04 🪨 Binary Erosion by Flat Structuring Element (mm.ero0)
If dilation thickens, erosion thins. In cell counting systems, it is used to separate touching cells: by “eating away” the borders of each region, thin connections between objects disappear even before any counting is performed. In morph.py, this is the operation mm.ero0(f, B) — the exact dual of dilation, and the only one of the two that does not reflect the structuring element. See Figure 4.33 for a simulation of this exercise.
4.9.4.1 📋 Implementation Guidelines
- Image dimensions: Read the integers \(L\) (rows) and \(C\) (columns) from \(f\).
- Dimensions of \(B\): Read the integers \(L_B\) (rows) and \(C_B\) (columns) of the structuring element.
- Structuring element: Read the matrix \(B\) with values \(0\) or \(1\), row by row.
- Data: Read the matrix \(f\) (the original image), row by row.
- Neighborhood without padding (no reflection!): For each pixel \((y,x)\), traverse the positions \((by,bx)\) of \(B\) in the original order (without reflecting), using the same offset as in EP04_03: \[ v_y = y + by + o_y,\quad v_x = x + bx + o_x,\quad o_y=-\tfrac{L_B}{2}+0{,}5,\quad o_x=-\tfrac{C_B}{2}+0{,}5 \]
Discard every \((v_y,v_x)\) outside \([0,L)\times[0,C)\). 6. Mapping: Compute each output pixel as the minimum between \(f(y,x)\) and all valid \(f(v_y,v_x)\) whose corresponding position in \(B\) equals \(1\): \[ g(y,x) = \min\Big(f(y,x),\ \min_{\substack{(v_y,v_x)\ \text{valid}\\ B(by,bx)=1}} f(v_y,v_x)\Big) \] 7. Output: Display the matrix \(g\) with dimensions \(L \times C\).
4.9.4.2 📌 Computational Constraints
- No reflection: Unlike dilation, \(B\) is used exactly as read — reflecting it here would be a serious conceptual error.
- No padding: Neighbors outside the image are simply ignored, never treated as \(0\).
- Edge robustness: If no valid position of \(B=1\) falls within the domain, the pixel retains its original value.
4.9.4.3 🧠 Theoretical Background
| Concept | Meaning | Visual Impact |
|---|---|---|
| Erosion | \(g \leq f\) always (anti-extensive) | Bright regions shrink, point noise disappears |
| Duality | \(\text{ero}(f,B) = -\text{dil}(-f, B_{ref})\) | Erosion and dilation are mathematical “mirrors” |
| Larger \(B\) | More aggressive erosion | Thin objects disappear completely |
4.9.4.4 📦 Input and Output Specification (VPL)
Input:
- Line 1: Integer \(L\).
- Line 2: Integer \(C\).
- Line 3: Integer \(L_B\).
- Line 4: Integer \(C_B\).
- Next \(L_B\) lines: integer elements (\(0\) or \(1\)) of matrix \(B\).
- Next \(L\) lines: integer elements of matrix \(f\).
Output:
- Matrix \(g\) in \(L\) rows and \(C\) columns, integer values separated by spaces.
4.9.4.5 📌 Examples
| Input | Output | Observation |
|---|---|---|
| 3 3 3 3 0 1 0 1 1 1 0 1 0 9 9 9 9 0 9 9 9 9 |
9 0 9 0 0 0 9 0 9 |
The central “hole” (0) propagates in a cross pattern |
| 1 4 1 3 1 1 1 10 200 5 80 |
10 5 5 80 | Horizontal \(B\): each pixel “pulls” the minimum of its row neighbors |
%%writefile EP04_04.py
# Python codeOverwriting EP04_04.py
TestSuite("EP04_04.py").run()✔️ EP04_04.cases already exists in casos/
📋 5 case(s) loaded from casos/EP04_04.cases
🔍 Testing Python: EP04_04.py
⚠️ EP04_04.py: Empty file (fewer than 3 lines). Tests skipped.