In particle microscopy and in OCR of worn license plates, thin or discontinuous traces need to be “thickened” for recognition to work. Morphological dilation does exactly that: it expands bright regions using a structuring element \(B\) — the same operation implemented in morph.py as mm::dil0(f, B), used when \(B\) is flat (without weights, only \(0\)/\(1\)). See Figure 4.32 for a simulation of this EP.
4.9.3.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.
Reflection: Construct \(B_{ref}\), the version of \(B\) reflected by \(180°\) (rows and columns reversed) — exactly as mm::dil0 does internally.
Neighborhood without padding: For each pixel \((y,x)\), traverse the positions \((by,bx)\) of \(B_{ref}\) centered at \((y,x)\), using the offset \[
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)\) — do not pad with zeros.
Mapping: Compute each output pixel as the maximum between \(f(y,x)\) and all valid \(f(v_y,v_x)\) whose corresponding position in \(B_{ref}\) is \(1\): \[
g(y,x) = \max\Big(f(y,x),\ \max_{\substack{(v_y,v_x)\ \text{valid}\\ B_{ref}(by,bx)=1}} f(v_y,v_x)\Big)
\]
Output: Display the matrix \(g\) with dimensions \(L \times C\).
4.9.3.2 📌 Computational Constraints
No padding: Never invent neighbors outside the image; use only those that actually exist.
Mandatory reflection:\(B\) must be reflected before being applied (this is what distinguishes mm::dil0 from a simple maximum search).
Edge robustness: If no valid position of \(B_{ref}=1\) falls within the domain for a given pixel, it maintains its original value.
4.9.3.3 🧠 Theoretical Foundation
Concept
Meaning
Visual Impact
Dilation
\(g \geq f\) always (extensive)
Bright regions grow, dark holes shrink
Larger \(B\)
Wider neighborhood
More aggressive growth
Reflection of \(B\)
\(B_{ref}(y,x) = B(-y,-x)\)
Ensures the formal Minkowski definition of dilation
4.9.3.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 the matrix \(B\).
Next \(L\) lines: integer elements of the matrix \(f\).
Output:
Matrix \(g\) in \(L\) rows and \(C\) columns, integer values separated by spaces.
4.9.3.5 📌 Examples
Input
Output
Remark
3
3
3
3
0 1 0
1 1 1
0 1 0
0 0 0
0 9 0
0 0 0
0 9 0
9 9 9
0 9 0
Symmetric cross \(B\): isolated point expands into a cross
1
4
1
3
1 1 1
10 200 5 80
200 200 200 80
Horizontal \(B\): each pixel “pulls” the maximum of row neighbors
🌱 Simulator EP04_03: Planar Dilation (mm.dil0)g = f ⊕ B
Toggle structuring element B (or select presets) and click cells of the original image f to light up or erase pixels.
Structuring Element B (Click to Toggle 0/1)
Original Image f (5×5)
Dilated g (f ⊕ B)
g(y,x) = max over valid neighbors of reflected B
Figure 4.32: Simulator EP04_03: Binary Dilation (g = f ⊕ B)
%%writefile EP04_03.cpp// your solution
Overwriting EP04_03.cpp
TestSuite("EP04_03.cpp").run()
✔️ EP04_03.cases already exists in casos/
📋 5 case(s) loaded from casos/EP04_03.cases
🔍 Testing C++: EP04_03.cpp
⚠️ EP04_03.cpp: Empty file (fewer than 3 lines). Tests skipped.