Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ok-landscape
GitHub Repository: Ok-landscape/computational-pipeline
Path: blob/main/latex-templates/templates/image-processing/morphological.tex
51 views
unlisted
1
% Morphological Operations Template
2
% Topics: Erosion, dilation, opening, closing, morphological gradient, top-hat transform
3
% Style: Technical report with binary and grayscale image processing demonstrations
4
5
\documentclass[a4paper, 11pt]{article}
6
\usepackage[utf8]{inputenc}
7
\usepackage[T1]{fontenc}
8
\usepackage{amsmath, amssymb}
9
\usepackage{graphicx}
10
\usepackage{siunitx}
11
\usepackage{booktabs}
12
\usepackage{subcaption}
13
\usepackage[makestderr]{pythontex}
14
15
% Theorem environments
16
\newtheorem{definition}{Definition}[section]
17
\newtheorem{theorem}{Theorem}[section]
18
\newtheorem{example}{Example}[section]
19
\newtheorem{remark}{Remark}[section]
20
21
\title{Mathematical Morphology: Fundamental Operations and Applications}
22
\author{Image Processing Laboratory}
23
\date{\today}
24
25
\begin{document}
26
\maketitle
27
28
\begin{abstract}
29
This report presents a comprehensive analysis of mathematical morphology, focusing on fundamental
30
operations (erosion, dilation, opening, closing) and their applications in binary and grayscale
31
image processing. We examine the algebraic properties of morphological operators, demonstrate
32
their use in noise removal, edge detection, and feature extraction, and analyze the effects of
33
structuring element shape and size on operation outcomes. Computational examples illustrate
34
morphological gradient, top-hat transforms, and the hit-or-miss transform for pattern detection.
35
\end{abstract}
36
37
\section{Introduction}
38
39
Mathematical morphology provides a framework for analyzing geometric structure in images based
40
on set theory. Originally developed for binary images, morphological operations extend naturally
41
to grayscale images and find applications in image preprocessing, segmentation, feature
42
extraction, and texture analysis.
43
44
\begin{definition}[Structuring Element]
45
A structuring element $B$ is a small binary image used to probe the input image $A$. Common
46
shapes include:
47
\begin{itemize}
48
\item \textbf{Disk}: Approximates circular neighborhoods
49
\item \textbf{Square}: Captures horizontal and vertical connectivity
50
\item \textbf{Cross}: Emphasizes cardinal directions
51
\item \textbf{Line}: Oriented for directional analysis
52
\end{itemize}
53
\end{definition}
54
55
\section{Fundamental Operations}
56
57
\subsection{Erosion and Dilation}
58
59
\begin{definition}[Binary Erosion]
60
The erosion of binary image $A$ by structuring element $B$ is:
61
\begin{equation}
62
A \ominus B = \{z \mid B_z \subseteq A\}
63
\end{equation}
64
where $B_z$ is $B$ translated by vector $z$. Erosion shrinks objects and removes small features.
65
\end{definition}
66
67
\begin{definition}[Binary Dilation]
68
The dilation of binary image $A$ by structuring element $B$ is:
69
\begin{equation}
70
A \oplus B = \{z \mid (\hat{B})_z \cap A \neq \emptyset\}
71
\end{equation}
72
where $\hat{B}$ is the reflection of $B$. Dilation expands objects and fills small holes.
73
\end{definition}
74
75
\begin{theorem}[Duality Property]
76
Erosion and dilation are dual operations:
77
\begin{equation}
78
(A \ominus B)^c = A^c \oplus \hat{B}
79
\end{equation}
80
where $A^c$ denotes the complement and $\hat{B}$ the reflection of $B$.
81
\end{theorem}
82
83
\subsection{Opening and Closing}
84
85
\begin{definition}[Opening]
86
Opening is erosion followed by dilation:
87
\begin{equation}
88
A \circ B = (A \ominus B) \oplus B
89
\end{equation}
90
Opening removes small objects and smooths boundaries while preserving overall shape.
91
\end{definition}
92
93
\begin{definition}[Closing]
94
Closing is dilation followed by erosion:
95
\begin{equation}
96
A \bullet B = (A \oplus B) \ominus B
97
\end{equation}
98
Closing fills small holes and connects nearby objects while preserving overall shape.
99
\end{definition}
100
101
\begin{theorem}[Idempotence]
102
Opening and closing are idempotent:
103
\begin{equation}
104
(A \circ B) \circ B = A \circ B \quad \text{and} \quad (A \bullet B) \bullet B = A \bullet B
105
\end{equation}
106
\end{theorem}
107
108
\subsection{Compound Operations}
109
110
\begin{definition}[Morphological Gradient]
111
The morphological gradient emphasizes object boundaries:
112
\begin{equation}
113
\text{grad}(A) = (A \oplus B) - (A \ominus B)
114
\end{equation}
115
This operation highlights edges by computing the difference between dilated and eroded images.
116
\end{definition}
117
118
\begin{definition}[Top-Hat Transform]
119
The white top-hat extracts bright features smaller than the structuring element:
120
\begin{equation}
121
\text{WTH}(A) = A - (A \circ B)
122
\end{equation}
123
The black top-hat extracts dark features:
124
\begin{equation}
125
\text{BTH}(A) = (A \bullet B) - A
126
\end{equation}
127
\end{definition}
128
129
\section{Grayscale Morphology}
130
131
\begin{definition}[Grayscale Erosion]
132
For grayscale image $f(x,y)$ and flat structuring element $B$:
133
\begin{equation}
134
(f \ominus B)(x,y) = \min_{(s,t) \in B} \{f(x+s, y+t)\}
135
\end{equation}
136
\end{definition}
137
138
\begin{definition}[Grayscale Dilation]
139
For grayscale image $f(x,y)$ and flat structuring element $B$:
140
\begin{equation}
141
(f \oplus B)(x,y) = \max_{(s,t) \in B} \{f(x+s, y+t)\}
142
\end{equation}
143
\end{definition}
144
145
\section{Computational Analysis}
146
147
\begin{pycode}
148
import numpy as np
149
import matplotlib.pyplot as plt
150
from scipy.ndimage import binary_erosion, binary_dilation, binary_opening, binary_closing
151
from scipy.ndimage import grey_erosion, grey_dilation, grey_opening, grey_closing
152
from scipy.ndimage import morphological_gradient, white_tophat, black_tophat
153
from scipy.ndimage import distance_transform_edt, label
154
from skimage.morphology import disk, square, diamond, star
155
156
np.random.seed(42)
157
158
# Create synthetic binary image
159
binary_image = np.zeros((200, 200), dtype=bool)
160
# Large square object
161
binary_image[50:150, 50:150] = True
162
# Small square objects (noise)
163
binary_image[20:30, 20:30] = True
164
binary_image[170:180, 170:180] = True
165
# Small holes inside main object
166
binary_image[80:90, 80:90] = False
167
binary_image[110:120, 110:120] = False
168
# Elongated object
169
binary_image[30:40, 100:180] = True
170
171
# Structuring elements
172
disk_se_small = disk(3)
173
disk_se_medium = disk(7)
174
disk_se_large = disk(15)
175
square_se = np.ones((9, 9), dtype=bool)
176
cross_se = np.array([[0,0,1,0,0],
177
[0,0,1,0,0],
178
[1,1,1,1,1],
179
[0,0,1,0,0],
180
[0,0,1,0,0]], dtype=bool)
181
182
# Apply fundamental operations
183
eroded_image = binary_erosion(binary_image, disk_se_medium)
184
dilated_image = binary_dilation(binary_image, disk_se_medium)
185
opened_image = binary_opening(binary_image, disk_se_medium)
186
closed_image = binary_closing(binary_image, disk_se_medium)
187
188
# Morphological gradient (binary)
189
gradient_image = binary_dilation(binary_image, disk_se_small) ^ binary_erosion(binary_image, disk_se_small)
190
191
# Create noisy binary image
192
noisy_binary = binary_image.copy()
193
# Add salt noise
194
salt_noise = np.random.rand(200, 200) > 0.98
195
noisy_binary = noisy_binary | salt_noise
196
# Add pepper noise
197
pepper_noise = np.random.rand(200, 200) > 0.98
198
noisy_binary = noisy_binary & ~pepper_noise
199
200
# Denoise with opening followed by closing
201
denoised_step1 = binary_opening(noisy_binary, disk_se_small)
202
denoised_image = binary_closing(denoised_step1, disk_se_small)
203
204
# Create grayscale image with various features
205
x_gray = np.linspace(-5, 5, 200)
206
y_gray = np.linspace(-5, 5, 200)
207
X_gray, Y_gray = np.meshgrid(x_gray, y_gray)
208
grayscale_image = np.zeros((200, 200))
209
# Background gradient
210
grayscale_image = 50 + 20 * np.sin(X_gray/2) * np.cos(Y_gray/2)
211
# Add bright features
212
grayscale_image[60:80, 60:80] = 200
213
grayscale_image[120:140, 120:140] = 180
214
# Add small bright spots
215
for i in range(5):
216
x_spot = np.random.randint(20, 180)
217
y_spot = np.random.randint(20, 180)
218
grayscale_image[y_spot:y_spot+5, x_spot:x_spot+5] = 220
219
# Add dark features
220
grayscale_image[100:110, 50:60] = 20
221
# Normalize
222
grayscale_image = np.clip(grayscale_image, 0, 255).astype(np.uint8)
223
224
# Grayscale operations
225
gray_eroded = grey_erosion(grayscale_image, size=(11, 11))
226
gray_dilated = grey_dilation(grayscale_image, size=(11, 11))
227
gray_opened = grey_opening(grayscale_image, size=(11, 11))
228
gray_closed = grey_closing(grayscale_image, size=(11, 11))
229
gray_gradient = morphological_gradient(grayscale_image, size=(5, 5))
230
gray_tophat = white_tophat(grayscale_image, size=(15, 15))
231
gray_blackhat = black_tophat(grayscale_image, size=(15, 15))
232
233
# Hit-or-miss transform example
234
pattern_image = np.zeros((200, 200), dtype=bool)
235
# Create L-shaped patterns
236
for i in range(3):
237
x_offset = 40 + i * 60
238
y_offset = 40 + i * 50
239
pattern_image[y_offset:y_offset+30, x_offset:x_offset+10] = True
240
pattern_image[y_offset+20:y_offset+30, x_offset:x_offset+30] = True
241
242
# L-shaped structuring element
243
se_hit = np.array([[1, 0, 0],
244
[1, 0, 0],
245
[1, 1, 1]], dtype=bool)
246
se_miss = np.array([[0, 1, 1],
247
[0, 1, 1],
248
[0, 0, 0]], dtype=bool)
249
# Hit-or-miss
250
hit_image = binary_erosion(pattern_image, se_hit)
251
miss_image = binary_erosion(~pattern_image, se_miss)
252
hit_or_miss_result = hit_image & miss_image
253
254
# Size analysis with different SE sizes
255
sizes = [3, 7, 11, 15, 19]
256
erosion_sizes = []
257
dilation_sizes = []
258
259
for size in sizes:
260
se_disk = disk(size)
261
eroded = binary_erosion(binary_image, se_disk)
262
dilated = binary_dilation(binary_image, se_disk)
263
erosion_sizes.append(np.sum(eroded))
264
dilation_sizes.append(np.sum(dilated))
265
266
# Connected components analysis
267
labeled_array, num_features = label(opened_image)
268
component_sizes = []
269
for i in range(1, num_features + 1):
270
component_sizes.append(np.sum(labeled_array == i))
271
272
# Create comprehensive visualization
273
fig = plt.figure(figsize=(16, 14))
274
275
# Plot 1: Original binary image
276
ax1 = fig.add_subplot(4, 4, 1)
277
ax1.imshow(binary_image, cmap='gray')
278
ax1.set_title('Original Binary Image')
279
ax1.axis('off')
280
281
# Plot 2: Erosion
282
ax2 = fig.add_subplot(4, 4, 2)
283
ax2.imshow(eroded_image, cmap='gray')
284
ax2.set_title(f'Erosion (disk r={7})')
285
ax2.axis('off')
286
287
# Plot 3: Dilation
288
ax3 = fig.add_subplot(4, 4, 3)
289
ax3.imshow(dilated_image, cmap='gray')
290
ax3.set_title(f'Dilation (disk r={7})')
291
ax3.axis('off')
292
293
# Plot 4: Gradient
294
ax4 = fig.add_subplot(4, 4, 4)
295
ax4.imshow(gradient_image, cmap='gray')
296
ax4.set_title('Morphological Gradient')
297
ax4.axis('off')
298
299
# Plot 5: Opening
300
ax5 = fig.add_subplot(4, 4, 5)
301
ax5.imshow(opened_image, cmap='gray')
302
ax5.set_title(f'Opening (disk r={7})')
303
ax5.axis('off')
304
305
# Plot 6: Closing
306
ax6 = fig.add_subplot(4, 4, 6)
307
ax6.imshow(closed_image, cmap='gray')
308
ax6.set_title(f'Closing (disk r={7})')
309
ax6.axis('off')
310
311
# Plot 7: Noisy image
312
ax7 = fig.add_subplot(4, 4, 7)
313
ax7.imshow(noisy_binary, cmap='gray')
314
ax7.set_title('Noisy Binary Image')
315
ax7.axis('off')
316
317
# Plot 8: Denoised
318
ax8 = fig.add_subplot(4, 4, 8)
319
ax8.imshow(denoised_image, cmap='gray')
320
ax8.set_title('Denoised (Open + Close)')
321
ax8.axis('off')
322
323
# Plot 9: Grayscale original
324
ax9 = fig.add_subplot(4, 4, 9)
325
im9 = ax9.imshow(grayscale_image, cmap='viridis')
326
ax9.set_title('Grayscale Image')
327
ax9.axis('off')
328
plt.colorbar(im9, ax=ax9, fraction=0.046)
329
330
# Plot 10: Grayscale opening
331
ax10 = fig.add_subplot(4, 4, 10)
332
im10 = ax10.imshow(gray_opened, cmap='viridis')
333
ax10.set_title('Grayscale Opening')
334
ax10.axis('off')
335
plt.colorbar(im10, ax=ax10, fraction=0.046)
336
337
# Plot 11: Grayscale gradient
338
ax11 = fig.add_subplot(4, 4, 11)
339
im11 = ax11.imshow(gray_gradient, cmap='hot')
340
ax11.set_title('Grayscale Gradient')
341
ax11.axis('off')
342
plt.colorbar(im11, ax=ax11, fraction=0.046)
343
344
# Plot 12: Top-hat transform
345
ax12 = fig.add_subplot(4, 4, 12)
346
im12 = ax12.imshow(gray_tophat, cmap='hot')
347
ax12.set_title('White Top-Hat Transform')
348
ax12.axis('off')
349
plt.colorbar(im12, ax=ax12, fraction=0.046)
350
351
# Plot 13: Structuring element comparison
352
ax13 = fig.add_subplot(4, 4, 13)
353
ax13.plot(sizes, erosion_sizes, 'bo-', linewidth=2, markersize=8, label='Erosion')
354
ax13.plot(sizes, dilation_sizes, 'ro-', linewidth=2, markersize=8, label='Dilation')
355
ax13.axhline(y=np.sum(binary_image), color='gray', linestyle='--', label='Original')
356
ax13.set_xlabel('SE Radius (pixels)')
357
ax13.set_ylabel('Object Area (pixels)')
358
ax13.set_title('SE Size vs Object Area')
359
ax13.legend(fontsize=8)
360
ax13.grid(True, alpha=0.3)
361
362
# Plot 14: Hit-or-miss pattern detection
363
ax14 = fig.add_subplot(4, 4, 14)
364
ax14.imshow(pattern_image, cmap='gray', alpha=0.7)
365
# Overlay detected patterns in red
366
hit_or_miss_display = np.zeros((*pattern_image.shape, 3))
367
hit_or_miss_display[:,:,0] = pattern_image.astype(float) * 0.7
368
hit_or_miss_display[:,:,1] = pattern_image.astype(float) * 0.7
369
hit_or_miss_display[:,:,2] = pattern_image.astype(float) * 0.7
370
# Mark detections
371
for i in range(hit_or_miss_result.shape[0]):
372
for j in range(hit_or_miss_result.shape[1]):
373
if hit_or_miss_result[i, j]:
374
hit_or_miss_display[max(0,i-2):min(200,i+3), max(0,j-2):min(200,j+3), 0] = 1.0
375
ax14.imshow(hit_or_miss_display)
376
ax14.set_title('Hit-or-Miss Detection')
377
ax14.axis('off')
378
379
# Plot 15: Component size distribution
380
ax15 = fig.add_subplot(4, 4, 15)
381
if len(component_sizes) > 0:
382
ax15.bar(range(1, len(component_sizes)+1), component_sizes, color='steelblue', edgecolor='black')
383
ax15.set_xlabel('Component ID')
384
ax15.set_ylabel('Size (pixels)')
385
ax15.set_title('Connected Component Sizes')
386
ax15.grid(True, alpha=0.3, axis='y')
387
else:
388
ax15.text(0.5, 0.5, 'No components', ha='center', va='center')
389
ax15.axis('off')
390
391
# Plot 16: SE shape comparison
392
ax16 = fig.add_subplot(4, 4, 16)
393
opened_disk = binary_opening(binary_image, disk_se_medium)
394
opened_square = binary_opening(binary_image, square_se)
395
opened_cross = binary_opening(binary_image, cross_se)
396
difference_disk_square = np.sum(opened_disk != opened_square)
397
difference_disk_cross = np.sum(opened_disk != opened_cross)
398
difference_square_cross = np.sum(opened_square != opened_cross)
399
se_names = ['Disk vs\nSquare', 'Disk vs\nCross', 'Square vs\nCross']
400
differences = [difference_disk_square, difference_disk_cross, difference_square_cross]
401
bars = ax16.bar(range(len(se_names)), differences, color=['coral', 'skyblue', 'lightgreen'],
402
edgecolor='black')
403
ax16.set_ylabel('Pixel Differences')
404
ax16.set_title('SE Shape Sensitivity')
405
ax16.set_xticks(range(len(se_names)))
406
ax16.set_xticklabels(se_names, fontsize=8)
407
ax16.grid(True, alpha=0.3, axis='y')
408
409
plt.tight_layout()
410
plt.savefig('morphological_operations_analysis.pdf', dpi=150, bbox_inches='tight')
411
plt.close()
412
413
# Calculate statistics for reporting
414
original_area = np.sum(binary_image)
415
eroded_area = np.sum(eroded_image)
416
dilated_area = np.sum(dilated_image)
417
opened_area = np.sum(opened_image)
418
closed_area = np.sum(closed_image)
419
erosion_factor = eroded_area / original_area
420
dilation_factor = dilated_area / original_area
421
noise_pixels = np.sum(noisy_binary != binary_image)
422
recovered_pixels = np.sum(denoised_image == binary_image)
423
recovery_rate = recovered_pixels / binary_image.size * 100
424
\end{pycode}
425
426
\begin{figure}[htbp]
427
\centering
428
\includegraphics[width=\textwidth]{morphological_operations_analysis.pdf}
429
\caption{Comprehensive morphological operations analysis: (a) Original binary image with objects
430
of varying sizes and small noise features; (b) Erosion shrinks objects and removes small features;
431
(c) Dilation expands objects and fills small gaps; (d) Morphological gradient extracts object
432
boundaries; (e) Opening removes protrusions and small objects; (f) Closing fills holes and connects
433
nearby objects; (g) Binary image corrupted with salt-and-pepper noise; (h) Denoised result using
434
opening followed by closing; (i) Grayscale test image with bright and dark features on varying
435
background; (j) Grayscale opening removes bright features smaller than structuring element;
436
(k) Grayscale gradient highlights intensity transitions; (l) White top-hat transform isolates
437
small bright features; (m) Object area variation with structuring element size; (n) Hit-or-miss
438
transform detecting L-shaped patterns; (o) Connected component size distribution after opening;
439
(p) Sensitivity to structuring element shape.}
440
\label{fig:morphology}
441
\end{figure}
442
443
\section{Results}
444
445
\subsection{Binary Operations}
446
447
\begin{pycode}
448
print(r"\begin{table}[htbp]")
449
print(r"\centering")
450
print(r"\caption{Binary Morphological Operation Effects on Object Area}")
451
print(r"\begin{tabular}{lcc}")
452
print(r"\toprule")
453
print(r"Operation & Area (pixels) & Change (\%) \\")
454
print(r"\midrule")
455
print(f"Original & {original_area:.0f} & --- \\\\")
456
print(f"Erosion & {eroded_area:.0f} & {(erosion_factor-1)*100:.1f} \\\\")
457
print(f"Dilation & {dilated_area:.0f} & {(dilation_factor-1)*100:.1f} \\\\")
458
print(f"Opening & {opened_area:.0f} & {(opened_area/original_area-1)*100:.1f} \\\\")
459
print(f"Closing & {closed_area:.0f} & {(closed_area/original_area-1)*100:.1f} \\\\")
460
print(r"\bottomrule")
461
print(r"\end{tabular}")
462
print(r"\label{tab:binary_ops}")
463
print(r"\end{table}")
464
\end{pycode}
465
466
The erosion operation with a disk-shaped structuring element of radius 7 pixels reduced the
467
object area by \py{f"{(1-erosion_factor)*100:.1f}"}\%, effectively removing small features
468
and shrinking object boundaries. Conversely, dilation increased area by
469
\py{f"{(dilation_factor-1)*100:.1f}"}\%, expanding objects and filling small gaps.
470
471
\subsection{Noise Removal Performance}
472
473
\begin{pycode}
474
print(r"\begin{table}[htbp]")
475
print(r"\centering")
476
print(r"\caption{Denoising Performance Analysis}")
477
print(r"\begin{tabular}{lc}")
478
print(r"\toprule")
479
print(r"Metric & Value \\")
480
print(r"\midrule")
481
print(f"Noise pixels introduced & {noise_pixels:.0f} \\\\")
482
print(f"Pixels correctly recovered & {recovered_pixels:.0f} \\\\")
483
print(f"Total image pixels & {binary_image.size} \\\\")
484
print(f"Overall recovery rate & {recovery_rate:.2f}\\% \\\\")
485
print(r"\bottomrule")
486
print(r"\end{tabular}")
487
print(r"\label{tab:denoise}")
488
print(r"\end{table}")
489
\end{pycode}
490
491
The morphological filtering approach (opening followed by closing) successfully recovered
492
\py{f"{recovery_rate:.2f}"}\% of the original image structure, demonstrating the effectiveness
493
of morphological operations for salt-and-pepper noise removal in binary images.
494
495
\subsection{Grayscale Morphology}
496
497
\begin{pycode}
498
gray_gradient_mean = np.mean(gray_gradient)
499
gray_gradient_max = np.max(gray_gradient)
500
tophat_detected_features = np.sum(gray_tophat > 50)
501
502
print(r"\begin{table}[htbp]")
503
print(r"\centering")
504
print(r"\caption{Grayscale Morphological Operation Statistics}")
505
print(r"\begin{tabular}{lc}")
506
print(r"\toprule")
507
print(r"Metric & Value \\")
508
print(r"\midrule")
509
print(f"Mean gradient magnitude & {gray_gradient_mean:.2f} \\\\")
510
print(f"Maximum gradient & {gray_gradient_max:.0f} \\\\")
511
print(f"Top-hat detected pixels & {tophat_detected_features:.0f} \\\\")
512
print(f"Original intensity range & [{np.min(grayscale_image)}, {np.max(grayscale_image)}] \\\\")
513
print(f"Opened intensity range & [{np.min(gray_opened)}, {np.max(gray_opened)}] \\\\")
514
print(r"\bottomrule")
515
print(r"\end{tabular}")
516
print(r"\label{tab:grayscale}")
517
print(r"\end{table}")
518
\end{pycode}
519
520
\section{Discussion}
521
522
\begin{example}[Edge Detection via Morphological Gradient]
523
The morphological gradient $(f \oplus B) - (f \ominus B)$ provides a robust edge detector that:
524
\begin{itemize}
525
\item Emphasizes intensity transitions corresponding to object boundaries
526
\item Controls edge thickness through structuring element size
527
\item Remains less sensitive to noise than derivative-based methods
528
\item Produces closed contours around objects
529
\end{itemize}
530
\end{example}
531
532
\begin{remark}[Structuring Element Selection]
533
The choice of structuring element shape significantly affects operation results:
534
\begin{itemize}
535
\item \textbf{Disk}: Isotropic, no directional bias
536
\item \textbf{Square}: Emphasizes horizontal/vertical features
537
\item \textbf{Cross}: Produces connectivity-preserving operations
538
\item \textbf{Line}: Detects specific orientations
539
\end{itemize}
540
As demonstrated in Figure~\ref{fig:morphology}(p), different SE shapes produce measurable
541
differences in opening results, with disk and square elements differing by
542
\py{f"{difference_disk_square}"} pixels.
543
\end{remark}
544
545
\begin{example}[Top-Hat Transform for Small Feature Detection]
546
The white top-hat transform $f - (f \circ B)$ successfully isolated
547
\py{f"{tophat_detected_features}"} pixels corresponding to bright features smaller than the
548
structuring element. This operation is particularly valuable for:
549
\begin{itemize}
550
\item Detecting small defects on varying backgrounds
551
\item Enhancing low-contrast details
552
\item Preprocessing for segmentation
553
\item Eliminating uneven illumination effects
554
\end{itemize}
555
\end{example}
556
557
\subsection{Algebraic Properties}
558
559
\begin{theorem}[Increasing Property]
560
Both erosion and dilation are increasing operations:
561
\begin{equation}
562
A_1 \subseteq A_2 \Rightarrow (A_1 \ominus B) \subseteq (A_2 \ominus B) \text{ and }
563
(A_1 \oplus B) \subseteq (A_2 \oplus B)
564
\end{equation}
565
\end{theorem}
566
567
\begin{theorem}[Translation Invariance]
568
For translation vector $h$:
569
\begin{equation}
570
(A_h \ominus B) = (A \ominus B)_h \quad \text{and} \quad (A_h \oplus B) = (A \oplus B)_h
571
\end{equation}
572
\end{theorem}
573
574
\subsection{Application Domains}
575
576
Morphological operations find extensive use in:
577
578
\begin{itemize}
579
\item \textbf{Medical imaging}: Vessel segmentation, tumor boundary detection, cell counting
580
\item \textbf{Document analysis}: Character recognition, noise removal, skeletonization
581
\item \textbf{Industrial inspection}: Defect detection, quality control, measurement
582
\item \textbf{Remote sensing}: Road extraction, building detection, land cover classification
583
\item \textbf{Video processing}: Object tracking, foreground extraction, motion analysis
584
\end{itemize}
585
586
\section{Conclusions}
587
588
This analysis demonstrates fundamental morphological operations and their applications:
589
\begin{enumerate}
590
\item Binary erosion and dilation provide complementary operations for shrinking and expanding
591
objects, with area changes of \py{f"{(1-erosion_factor)*100:.1f}"}\% and
592
\py{f"{(dilation_factor-1)*100:.1f}"}\% respectively
593
\item Opening and closing effectively remove noise while preserving essential geometric structure,
594
achieving \py{f"{recovery_rate:.2f}"}\% recovery on salt-and-pepper corrupted images
595
\item Morphological gradient extracts object boundaries with controlled thickness and noise robustness
596
\item Top-hat transforms isolate small features against varying backgrounds, detecting
597
\py{f"{tophat_detected_features}"} feature pixels
598
\item Structuring element shape and size critically influence operation outcomes, requiring
599
careful selection based on application requirements
600
\item Hit-or-miss transform enables pattern detection for specific geometric configurations
601
\end{enumerate}
602
603
The algebraic properties of morphological operations (duality, idempotence, translation invariance)
604
provide theoretical foundations for developing complex image processing pipelines from fundamental
605
building blocks.
606
607
\section*{Further Reading}
608
609
\begin{itemize}
610
\item Soille, P. \textit{Morphological Image Analysis: Principles and Applications}, 2nd ed.
611
Springer, 2003.
612
\item Serra, J. \textit{Image Analysis and Mathematical Morphology}. Academic Press, 1982.
613
\item Gonzalez, R.C. and Woods, R.E. \textit{Digital Image Processing}, 4th ed. Pearson, 2018.
614
\item Haralick, R.M., Sternberg, S.R., and Zhuang, X. "Image analysis using mathematical morphology."
615
\textit{IEEE Trans. Pattern Anal. Mach. Intell.} 9(4): 532-550, 1987.
616
\item Vincent, L. "Morphological grayscale reconstruction in image analysis: applications and
617
efficient algorithms." \textit{IEEE Trans. Image Process.} 2(2): 176-201, 1993.
618
\item Meyer, F. and Beucher, S. "Morphological segmentation." \textit{J. Visual Commun. Image
619
Represent.} 1(1): 21-46, 1990.
620
\item Heijmans, H.J.A.M. \textit{Morphological Image Operators}. Academic Press, 1994.
621
\item Maragos, P. "Pattern spectrum and multiscale shape representation." \textit{IEEE Trans.
622
Pattern Anal. Mach. Intell.} 11(7): 701-716, 1989.
623
\item Najman, L. and Talbot, H. \textit{Mathematical Morphology: From Theory to Applications}.
624
Wiley, 2010.
625
\item Matheron, G. \textit{Random Sets and Integral Geometry}. Wiley, 1975.
626
\item Sternberg, S.R. "Grayscale morphology." \textit{Comput. Vision Graphics Image Process.}
627
35(3): 333-355, 1986.
628
\item Salembier, P. and Serra, J. "Flat zones filtering, connected operators, and filters by
629
reconstruction." \textit{IEEE Trans. Image Process.} 4(8): 1153-1160, 1995.
630
\item Roerdink, J.B.T.M. and Meijster, A. "The watershed transform: definitions, algorithms and
631
parallelization strategies." \textit{Fundam. Inform.} 41(1-2): 187-228, 2000.
632
\item Beucher, S. and Meyer, F. "The morphological approach to segmentation: the watershed
633
transformation." In \textit{Mathematical Morphology in Image Processing}, CRC Press, 1993.
634
\item Adams, R. and Bischof, L. "Seeded region growing." \textit{IEEE Trans. Pattern Anal.
635
Mach. Intell.} 16(6): 641-647, 1994.
636
\item Boomgaard, R. and Smeulders, A. "The morphological structure of images: the differential
637
equations of morphological scale-space." \textit{IEEE Trans. Pattern Anal. Mach. Intell.}
638
16(11): 1101-1113, 1994.
639
\item Jackway, P.T. and Deriche, M. "Scale-space properties of the multiscale morphological
640
dilation-erosion." \textit{IEEE Trans. Pattern Anal. Mach. Intell.} 18(1): 38-51, 1996.
641
\item Cheng, F. and Venetsanopoulos, A.N. "An adaptive morphological filter for image processing."
642
\textit{IEEE Trans. Image Process.} 1(4): 533-539, 1992.
643
\item Cuisenaire, O. and Macq, B. "Fast Euclidean distance transformation by propagation using
644
multiple neighborhoods." \textit{Comput. Vision Image Understand.} 76(2): 163-172, 1999.
645
\item Dougherty, E.R. and Lotufo, R.A. \textit{Hands-on Morphological Image Processing}.
646
SPIE Press, 2003.
647
\end{itemize}
648
649
\end{document}
650
651