Path: blob/main/latex-templates/templates/image-processing/morphological.tex
51 views
unlisted
% Morphological Operations Template1% Topics: Erosion, dilation, opening, closing, morphological gradient, top-hat transform2% Style: Technical report with binary and grayscale image processing demonstrations34\documentclass[a4paper, 11pt]{article}5\usepackage[utf8]{inputenc}6\usepackage[T1]{fontenc}7\usepackage{amsmath, amssymb}8\usepackage{graphicx}9\usepackage{siunitx}10\usepackage{booktabs}11\usepackage{subcaption}12\usepackage[makestderr]{pythontex}1314% Theorem environments15\newtheorem{definition}{Definition}[section]16\newtheorem{theorem}{Theorem}[section]17\newtheorem{example}{Example}[section]18\newtheorem{remark}{Remark}[section]1920\title{Mathematical Morphology: Fundamental Operations and Applications}21\author{Image Processing Laboratory}22\date{\today}2324\begin{document}25\maketitle2627\begin{abstract}28This report presents a comprehensive analysis of mathematical morphology, focusing on fundamental29operations (erosion, dilation, opening, closing) and their applications in binary and grayscale30image processing. We examine the algebraic properties of morphological operators, demonstrate31their use in noise removal, edge detection, and feature extraction, and analyze the effects of32structuring element shape and size on operation outcomes. Computational examples illustrate33morphological gradient, top-hat transforms, and the hit-or-miss transform for pattern detection.34\end{abstract}3536\section{Introduction}3738Mathematical morphology provides a framework for analyzing geometric structure in images based39on set theory. Originally developed for binary images, morphological operations extend naturally40to grayscale images and find applications in image preprocessing, segmentation, feature41extraction, and texture analysis.4243\begin{definition}[Structuring Element]44A structuring element $B$ is a small binary image used to probe the input image $A$. Common45shapes include:46\begin{itemize}47\item \textbf{Disk}: Approximates circular neighborhoods48\item \textbf{Square}: Captures horizontal and vertical connectivity49\item \textbf{Cross}: Emphasizes cardinal directions50\item \textbf{Line}: Oriented for directional analysis51\end{itemize}52\end{definition}5354\section{Fundamental Operations}5556\subsection{Erosion and Dilation}5758\begin{definition}[Binary Erosion]59The erosion of binary image $A$ by structuring element $B$ is:60\begin{equation}61A \ominus B = \{z \mid B_z \subseteq A\}62\end{equation}63where $B_z$ is $B$ translated by vector $z$. Erosion shrinks objects and removes small features.64\end{definition}6566\begin{definition}[Binary Dilation]67The dilation of binary image $A$ by structuring element $B$ is:68\begin{equation}69A \oplus B = \{z \mid (\hat{B})_z \cap A \neq \emptyset\}70\end{equation}71where $\hat{B}$ is the reflection of $B$. Dilation expands objects and fills small holes.72\end{definition}7374\begin{theorem}[Duality Property]75Erosion and dilation are dual operations:76\begin{equation}77(A \ominus B)^c = A^c \oplus \hat{B}78\end{equation}79where $A^c$ denotes the complement and $\hat{B}$ the reflection of $B$.80\end{theorem}8182\subsection{Opening and Closing}8384\begin{definition}[Opening]85Opening is erosion followed by dilation:86\begin{equation}87A \circ B = (A \ominus B) \oplus B88\end{equation}89Opening removes small objects and smooths boundaries while preserving overall shape.90\end{definition}9192\begin{definition}[Closing]93Closing is dilation followed by erosion:94\begin{equation}95A \bullet B = (A \oplus B) \ominus B96\end{equation}97Closing fills small holes and connects nearby objects while preserving overall shape.98\end{definition}99100\begin{theorem}[Idempotence]101Opening and closing are idempotent:102\begin{equation}103(A \circ B) \circ B = A \circ B \quad \text{and} \quad (A \bullet B) \bullet B = A \bullet B104\end{equation}105\end{theorem}106107\subsection{Compound Operations}108109\begin{definition}[Morphological Gradient]110The morphological gradient emphasizes object boundaries:111\begin{equation}112\text{grad}(A) = (A \oplus B) - (A \ominus B)113\end{equation}114This operation highlights edges by computing the difference between dilated and eroded images.115\end{definition}116117\begin{definition}[Top-Hat Transform]118The white top-hat extracts bright features smaller than the structuring element:119\begin{equation}120\text{WTH}(A) = A - (A \circ B)121\end{equation}122The black top-hat extracts dark features:123\begin{equation}124\text{BTH}(A) = (A \bullet B) - A125\end{equation}126\end{definition}127128\section{Grayscale Morphology}129130\begin{definition}[Grayscale Erosion]131For grayscale image $f(x,y)$ and flat structuring element $B$:132\begin{equation}133(f \ominus B)(x,y) = \min_{(s,t) \in B} \{f(x+s, y+t)\}134\end{equation}135\end{definition}136137\begin{definition}[Grayscale Dilation]138For grayscale image $f(x,y)$ and flat structuring element $B$:139\begin{equation}140(f \oplus B)(x,y) = \max_{(s,t) \in B} \{f(x+s, y+t)\}141\end{equation}142\end{definition}143144\section{Computational Analysis}145146\begin{pycode}147import numpy as np148import matplotlib.pyplot as plt149from scipy.ndimage import binary_erosion, binary_dilation, binary_opening, binary_closing150from scipy.ndimage import grey_erosion, grey_dilation, grey_opening, grey_closing151from scipy.ndimage import morphological_gradient, white_tophat, black_tophat152from scipy.ndimage import distance_transform_edt, label153from skimage.morphology import disk, square, diamond, star154155np.random.seed(42)156157# Create synthetic binary image158binary_image = np.zeros((200, 200), dtype=bool)159# Large square object160binary_image[50:150, 50:150] = True161# Small square objects (noise)162binary_image[20:30, 20:30] = True163binary_image[170:180, 170:180] = True164# Small holes inside main object165binary_image[80:90, 80:90] = False166binary_image[110:120, 110:120] = False167# Elongated object168binary_image[30:40, 100:180] = True169170# Structuring elements171disk_se_small = disk(3)172disk_se_medium = disk(7)173disk_se_large = disk(15)174square_se = np.ones((9, 9), dtype=bool)175cross_se = np.array([[0,0,1,0,0],176[0,0,1,0,0],177[1,1,1,1,1],178[0,0,1,0,0],179[0,0,1,0,0]], dtype=bool)180181# Apply fundamental operations182eroded_image = binary_erosion(binary_image, disk_se_medium)183dilated_image = binary_dilation(binary_image, disk_se_medium)184opened_image = binary_opening(binary_image, disk_se_medium)185closed_image = binary_closing(binary_image, disk_se_medium)186187# Morphological gradient (binary)188gradient_image = binary_dilation(binary_image, disk_se_small) ^ binary_erosion(binary_image, disk_se_small)189190# Create noisy binary image191noisy_binary = binary_image.copy()192# Add salt noise193salt_noise = np.random.rand(200, 200) > 0.98194noisy_binary = noisy_binary | salt_noise195# Add pepper noise196pepper_noise = np.random.rand(200, 200) > 0.98197noisy_binary = noisy_binary & ~pepper_noise198199# Denoise with opening followed by closing200denoised_step1 = binary_opening(noisy_binary, disk_se_small)201denoised_image = binary_closing(denoised_step1, disk_se_small)202203# Create grayscale image with various features204x_gray = np.linspace(-5, 5, 200)205y_gray = np.linspace(-5, 5, 200)206X_gray, Y_gray = np.meshgrid(x_gray, y_gray)207grayscale_image = np.zeros((200, 200))208# Background gradient209grayscale_image = 50 + 20 * np.sin(X_gray/2) * np.cos(Y_gray/2)210# Add bright features211grayscale_image[60:80, 60:80] = 200212grayscale_image[120:140, 120:140] = 180213# Add small bright spots214for i in range(5):215x_spot = np.random.randint(20, 180)216y_spot = np.random.randint(20, 180)217grayscale_image[y_spot:y_spot+5, x_spot:x_spot+5] = 220218# Add dark features219grayscale_image[100:110, 50:60] = 20220# Normalize221grayscale_image = np.clip(grayscale_image, 0, 255).astype(np.uint8)222223# Grayscale operations224gray_eroded = grey_erosion(grayscale_image, size=(11, 11))225gray_dilated = grey_dilation(grayscale_image, size=(11, 11))226gray_opened = grey_opening(grayscale_image, size=(11, 11))227gray_closed = grey_closing(grayscale_image, size=(11, 11))228gray_gradient = morphological_gradient(grayscale_image, size=(5, 5))229gray_tophat = white_tophat(grayscale_image, size=(15, 15))230gray_blackhat = black_tophat(grayscale_image, size=(15, 15))231232# Hit-or-miss transform example233pattern_image = np.zeros((200, 200), dtype=bool)234# Create L-shaped patterns235for i in range(3):236x_offset = 40 + i * 60237y_offset = 40 + i * 50238pattern_image[y_offset:y_offset+30, x_offset:x_offset+10] = True239pattern_image[y_offset+20:y_offset+30, x_offset:x_offset+30] = True240241# L-shaped structuring element242se_hit = np.array([[1, 0, 0],243[1, 0, 0],244[1, 1, 1]], dtype=bool)245se_miss = np.array([[0, 1, 1],246[0, 1, 1],247[0, 0, 0]], dtype=bool)248# Hit-or-miss249hit_image = binary_erosion(pattern_image, se_hit)250miss_image = binary_erosion(~pattern_image, se_miss)251hit_or_miss_result = hit_image & miss_image252253# Size analysis with different SE sizes254sizes = [3, 7, 11, 15, 19]255erosion_sizes = []256dilation_sizes = []257258for size in sizes:259se_disk = disk(size)260eroded = binary_erosion(binary_image, se_disk)261dilated = binary_dilation(binary_image, se_disk)262erosion_sizes.append(np.sum(eroded))263dilation_sizes.append(np.sum(dilated))264265# Connected components analysis266labeled_array, num_features = label(opened_image)267component_sizes = []268for i in range(1, num_features + 1):269component_sizes.append(np.sum(labeled_array == i))270271# Create comprehensive visualization272fig = plt.figure(figsize=(16, 14))273274# Plot 1: Original binary image275ax1 = fig.add_subplot(4, 4, 1)276ax1.imshow(binary_image, cmap='gray')277ax1.set_title('Original Binary Image')278ax1.axis('off')279280# Plot 2: Erosion281ax2 = fig.add_subplot(4, 4, 2)282ax2.imshow(eroded_image, cmap='gray')283ax2.set_title(f'Erosion (disk r={7})')284ax2.axis('off')285286# Plot 3: Dilation287ax3 = fig.add_subplot(4, 4, 3)288ax3.imshow(dilated_image, cmap='gray')289ax3.set_title(f'Dilation (disk r={7})')290ax3.axis('off')291292# Plot 4: Gradient293ax4 = fig.add_subplot(4, 4, 4)294ax4.imshow(gradient_image, cmap='gray')295ax4.set_title('Morphological Gradient')296ax4.axis('off')297298# Plot 5: Opening299ax5 = fig.add_subplot(4, 4, 5)300ax5.imshow(opened_image, cmap='gray')301ax5.set_title(f'Opening (disk r={7})')302ax5.axis('off')303304# Plot 6: Closing305ax6 = fig.add_subplot(4, 4, 6)306ax6.imshow(closed_image, cmap='gray')307ax6.set_title(f'Closing (disk r={7})')308ax6.axis('off')309310# Plot 7: Noisy image311ax7 = fig.add_subplot(4, 4, 7)312ax7.imshow(noisy_binary, cmap='gray')313ax7.set_title('Noisy Binary Image')314ax7.axis('off')315316# Plot 8: Denoised317ax8 = fig.add_subplot(4, 4, 8)318ax8.imshow(denoised_image, cmap='gray')319ax8.set_title('Denoised (Open + Close)')320ax8.axis('off')321322# Plot 9: Grayscale original323ax9 = fig.add_subplot(4, 4, 9)324im9 = ax9.imshow(grayscale_image, cmap='viridis')325ax9.set_title('Grayscale Image')326ax9.axis('off')327plt.colorbar(im9, ax=ax9, fraction=0.046)328329# Plot 10: Grayscale opening330ax10 = fig.add_subplot(4, 4, 10)331im10 = ax10.imshow(gray_opened, cmap='viridis')332ax10.set_title('Grayscale Opening')333ax10.axis('off')334plt.colorbar(im10, ax=ax10, fraction=0.046)335336# Plot 11: Grayscale gradient337ax11 = fig.add_subplot(4, 4, 11)338im11 = ax11.imshow(gray_gradient, cmap='hot')339ax11.set_title('Grayscale Gradient')340ax11.axis('off')341plt.colorbar(im11, ax=ax11, fraction=0.046)342343# Plot 12: Top-hat transform344ax12 = fig.add_subplot(4, 4, 12)345im12 = ax12.imshow(gray_tophat, cmap='hot')346ax12.set_title('White Top-Hat Transform')347ax12.axis('off')348plt.colorbar(im12, ax=ax12, fraction=0.046)349350# Plot 13: Structuring element comparison351ax13 = fig.add_subplot(4, 4, 13)352ax13.plot(sizes, erosion_sizes, 'bo-', linewidth=2, markersize=8, label='Erosion')353ax13.plot(sizes, dilation_sizes, 'ro-', linewidth=2, markersize=8, label='Dilation')354ax13.axhline(y=np.sum(binary_image), color='gray', linestyle='--', label='Original')355ax13.set_xlabel('SE Radius (pixels)')356ax13.set_ylabel('Object Area (pixels)')357ax13.set_title('SE Size vs Object Area')358ax13.legend(fontsize=8)359ax13.grid(True, alpha=0.3)360361# Plot 14: Hit-or-miss pattern detection362ax14 = fig.add_subplot(4, 4, 14)363ax14.imshow(pattern_image, cmap='gray', alpha=0.7)364# Overlay detected patterns in red365hit_or_miss_display = np.zeros((*pattern_image.shape, 3))366hit_or_miss_display[:,:,0] = pattern_image.astype(float) * 0.7367hit_or_miss_display[:,:,1] = pattern_image.astype(float) * 0.7368hit_or_miss_display[:,:,2] = pattern_image.astype(float) * 0.7369# Mark detections370for i in range(hit_or_miss_result.shape[0]):371for j in range(hit_or_miss_result.shape[1]):372if hit_or_miss_result[i, j]:373hit_or_miss_display[max(0,i-2):min(200,i+3), max(0,j-2):min(200,j+3), 0] = 1.0374ax14.imshow(hit_or_miss_display)375ax14.set_title('Hit-or-Miss Detection')376ax14.axis('off')377378# Plot 15: Component size distribution379ax15 = fig.add_subplot(4, 4, 15)380if len(component_sizes) > 0:381ax15.bar(range(1, len(component_sizes)+1), component_sizes, color='steelblue', edgecolor='black')382ax15.set_xlabel('Component ID')383ax15.set_ylabel('Size (pixels)')384ax15.set_title('Connected Component Sizes')385ax15.grid(True, alpha=0.3, axis='y')386else:387ax15.text(0.5, 0.5, 'No components', ha='center', va='center')388ax15.axis('off')389390# Plot 16: SE shape comparison391ax16 = fig.add_subplot(4, 4, 16)392opened_disk = binary_opening(binary_image, disk_se_medium)393opened_square = binary_opening(binary_image, square_se)394opened_cross = binary_opening(binary_image, cross_se)395difference_disk_square = np.sum(opened_disk != opened_square)396difference_disk_cross = np.sum(opened_disk != opened_cross)397difference_square_cross = np.sum(opened_square != opened_cross)398se_names = ['Disk vs\nSquare', 'Disk vs\nCross', 'Square vs\nCross']399differences = [difference_disk_square, difference_disk_cross, difference_square_cross]400bars = ax16.bar(range(len(se_names)), differences, color=['coral', 'skyblue', 'lightgreen'],401edgecolor='black')402ax16.set_ylabel('Pixel Differences')403ax16.set_title('SE Shape Sensitivity')404ax16.set_xticks(range(len(se_names)))405ax16.set_xticklabels(se_names, fontsize=8)406ax16.grid(True, alpha=0.3, axis='y')407408plt.tight_layout()409plt.savefig('morphological_operations_analysis.pdf', dpi=150, bbox_inches='tight')410plt.close()411412# Calculate statistics for reporting413original_area = np.sum(binary_image)414eroded_area = np.sum(eroded_image)415dilated_area = np.sum(dilated_image)416opened_area = np.sum(opened_image)417closed_area = np.sum(closed_image)418erosion_factor = eroded_area / original_area419dilation_factor = dilated_area / original_area420noise_pixels = np.sum(noisy_binary != binary_image)421recovered_pixels = np.sum(denoised_image == binary_image)422recovery_rate = recovered_pixels / binary_image.size * 100423\end{pycode}424425\begin{figure}[htbp]426\centering427\includegraphics[width=\textwidth]{morphological_operations_analysis.pdf}428\caption{Comprehensive morphological operations analysis: (a) Original binary image with objects429of varying sizes and small noise features; (b) Erosion shrinks objects and removes small features;430(c) Dilation expands objects and fills small gaps; (d) Morphological gradient extracts object431boundaries; (e) Opening removes protrusions and small objects; (f) Closing fills holes and connects432nearby objects; (g) Binary image corrupted with salt-and-pepper noise; (h) Denoised result using433opening followed by closing; (i) Grayscale test image with bright and dark features on varying434background; (j) Grayscale opening removes bright features smaller than structuring element;435(k) Grayscale gradient highlights intensity transitions; (l) White top-hat transform isolates436small bright features; (m) Object area variation with structuring element size; (n) Hit-or-miss437transform detecting L-shaped patterns; (o) Connected component size distribution after opening;438(p) Sensitivity to structuring element shape.}439\label{fig:morphology}440\end{figure}441442\section{Results}443444\subsection{Binary Operations}445446\begin{pycode}447print(r"\begin{table}[htbp]")448print(r"\centering")449print(r"\caption{Binary Morphological Operation Effects on Object Area}")450print(r"\begin{tabular}{lcc}")451print(r"\toprule")452print(r"Operation & Area (pixels) & Change (\%) \\")453print(r"\midrule")454print(f"Original & {original_area:.0f} & --- \\\\")455print(f"Erosion & {eroded_area:.0f} & {(erosion_factor-1)*100:.1f} \\\\")456print(f"Dilation & {dilated_area:.0f} & {(dilation_factor-1)*100:.1f} \\\\")457print(f"Opening & {opened_area:.0f} & {(opened_area/original_area-1)*100:.1f} \\\\")458print(f"Closing & {closed_area:.0f} & {(closed_area/original_area-1)*100:.1f} \\\\")459print(r"\bottomrule")460print(r"\end{tabular}")461print(r"\label{tab:binary_ops}")462print(r"\end{table}")463\end{pycode}464465The erosion operation with a disk-shaped structuring element of radius 7 pixels reduced the466object area by \py{f"{(1-erosion_factor)*100:.1f}"}\%, effectively removing small features467and shrinking object boundaries. Conversely, dilation increased area by468\py{f"{(dilation_factor-1)*100:.1f}"}\%, expanding objects and filling small gaps.469470\subsection{Noise Removal Performance}471472\begin{pycode}473print(r"\begin{table}[htbp]")474print(r"\centering")475print(r"\caption{Denoising Performance Analysis}")476print(r"\begin{tabular}{lc}")477print(r"\toprule")478print(r"Metric & Value \\")479print(r"\midrule")480print(f"Noise pixels introduced & {noise_pixels:.0f} \\\\")481print(f"Pixels correctly recovered & {recovered_pixels:.0f} \\\\")482print(f"Total image pixels & {binary_image.size} \\\\")483print(f"Overall recovery rate & {recovery_rate:.2f}\\% \\\\")484print(r"\bottomrule")485print(r"\end{tabular}")486print(r"\label{tab:denoise}")487print(r"\end{table}")488\end{pycode}489490The morphological filtering approach (opening followed by closing) successfully recovered491\py{f"{recovery_rate:.2f}"}\% of the original image structure, demonstrating the effectiveness492of morphological operations for salt-and-pepper noise removal in binary images.493494\subsection{Grayscale Morphology}495496\begin{pycode}497gray_gradient_mean = np.mean(gray_gradient)498gray_gradient_max = np.max(gray_gradient)499tophat_detected_features = np.sum(gray_tophat > 50)500501print(r"\begin{table}[htbp]")502print(r"\centering")503print(r"\caption{Grayscale Morphological Operation Statistics}")504print(r"\begin{tabular}{lc}")505print(r"\toprule")506print(r"Metric & Value \\")507print(r"\midrule")508print(f"Mean gradient magnitude & {gray_gradient_mean:.2f} \\\\")509print(f"Maximum gradient & {gray_gradient_max:.0f} \\\\")510print(f"Top-hat detected pixels & {tophat_detected_features:.0f} \\\\")511print(f"Original intensity range & [{np.min(grayscale_image)}, {np.max(grayscale_image)}] \\\\")512print(f"Opened intensity range & [{np.min(gray_opened)}, {np.max(gray_opened)}] \\\\")513print(r"\bottomrule")514print(r"\end{tabular}")515print(r"\label{tab:grayscale}")516print(r"\end{table}")517\end{pycode}518519\section{Discussion}520521\begin{example}[Edge Detection via Morphological Gradient]522The morphological gradient $(f \oplus B) - (f \ominus B)$ provides a robust edge detector that:523\begin{itemize}524\item Emphasizes intensity transitions corresponding to object boundaries525\item Controls edge thickness through structuring element size526\item Remains less sensitive to noise than derivative-based methods527\item Produces closed contours around objects528\end{itemize}529\end{example}530531\begin{remark}[Structuring Element Selection]532The choice of structuring element shape significantly affects operation results:533\begin{itemize}534\item \textbf{Disk}: Isotropic, no directional bias535\item \textbf{Square}: Emphasizes horizontal/vertical features536\item \textbf{Cross}: Produces connectivity-preserving operations537\item \textbf{Line}: Detects specific orientations538\end{itemize}539As demonstrated in Figure~\ref{fig:morphology}(p), different SE shapes produce measurable540differences in opening results, with disk and square elements differing by541\py{f"{difference_disk_square}"} pixels.542\end{remark}543544\begin{example}[Top-Hat Transform for Small Feature Detection]545The white top-hat transform $f - (f \circ B)$ successfully isolated546\py{f"{tophat_detected_features}"} pixels corresponding to bright features smaller than the547structuring element. This operation is particularly valuable for:548\begin{itemize}549\item Detecting small defects on varying backgrounds550\item Enhancing low-contrast details551\item Preprocessing for segmentation552\item Eliminating uneven illumination effects553\end{itemize}554\end{example}555556\subsection{Algebraic Properties}557558\begin{theorem}[Increasing Property]559Both erosion and dilation are increasing operations:560\begin{equation}561A_1 \subseteq A_2 \Rightarrow (A_1 \ominus B) \subseteq (A_2 \ominus B) \text{ and }562(A_1 \oplus B) \subseteq (A_2 \oplus B)563\end{equation}564\end{theorem}565566\begin{theorem}[Translation Invariance]567For translation vector $h$:568\begin{equation}569(A_h \ominus B) = (A \ominus B)_h \quad \text{and} \quad (A_h \oplus B) = (A \oplus B)_h570\end{equation}571\end{theorem}572573\subsection{Application Domains}574575Morphological operations find extensive use in:576577\begin{itemize}578\item \textbf{Medical imaging}: Vessel segmentation, tumor boundary detection, cell counting579\item \textbf{Document analysis}: Character recognition, noise removal, skeletonization580\item \textbf{Industrial inspection}: Defect detection, quality control, measurement581\item \textbf{Remote sensing}: Road extraction, building detection, land cover classification582\item \textbf{Video processing}: Object tracking, foreground extraction, motion analysis583\end{itemize}584585\section{Conclusions}586587This analysis demonstrates fundamental morphological operations and their applications:588\begin{enumerate}589\item Binary erosion and dilation provide complementary operations for shrinking and expanding590objects, with area changes of \py{f"{(1-erosion_factor)*100:.1f}"}\% and591\py{f"{(dilation_factor-1)*100:.1f}"}\% respectively592\item Opening and closing effectively remove noise while preserving essential geometric structure,593achieving \py{f"{recovery_rate:.2f}"}\% recovery on salt-and-pepper corrupted images594\item Morphological gradient extracts object boundaries with controlled thickness and noise robustness595\item Top-hat transforms isolate small features against varying backgrounds, detecting596\py{f"{tophat_detected_features}"} feature pixels597\item Structuring element shape and size critically influence operation outcomes, requiring598careful selection based on application requirements599\item Hit-or-miss transform enables pattern detection for specific geometric configurations600\end{enumerate}601602The algebraic properties of morphological operations (duality, idempotence, translation invariance)603provide theoretical foundations for developing complex image processing pipelines from fundamental604building blocks.605606\section*{Further Reading}607608\begin{itemize}609\item Soille, P. \textit{Morphological Image Analysis: Principles and Applications}, 2nd ed.610Springer, 2003.611\item Serra, J. \textit{Image Analysis and Mathematical Morphology}. Academic Press, 1982.612\item Gonzalez, R.C. and Woods, R.E. \textit{Digital Image Processing}, 4th ed. Pearson, 2018.613\item Haralick, R.M., Sternberg, S.R., and Zhuang, X. "Image analysis using mathematical morphology."614\textit{IEEE Trans. Pattern Anal. Mach. Intell.} 9(4): 532-550, 1987.615\item Vincent, L. "Morphological grayscale reconstruction in image analysis: applications and616efficient algorithms." \textit{IEEE Trans. Image Process.} 2(2): 176-201, 1993.617\item Meyer, F. and Beucher, S. "Morphological segmentation." \textit{J. Visual Commun. Image618Represent.} 1(1): 21-46, 1990.619\item Heijmans, H.J.A.M. \textit{Morphological Image Operators}. Academic Press, 1994.620\item Maragos, P. "Pattern spectrum and multiscale shape representation." \textit{IEEE Trans.621Pattern Anal. Mach. Intell.} 11(7): 701-716, 1989.622\item Najman, L. and Talbot, H. \textit{Mathematical Morphology: From Theory to Applications}.623Wiley, 2010.624\item Matheron, G. \textit{Random Sets and Integral Geometry}. Wiley, 1975.625\item Sternberg, S.R. "Grayscale morphology." \textit{Comput. Vision Graphics Image Process.}62635(3): 333-355, 1986.627\item Salembier, P. and Serra, J. "Flat zones filtering, connected operators, and filters by628reconstruction." \textit{IEEE Trans. Image Process.} 4(8): 1153-1160, 1995.629\item Roerdink, J.B.T.M. and Meijster, A. "The watershed transform: definitions, algorithms and630parallelization strategies." \textit{Fundam. Inform.} 41(1-2): 187-228, 2000.631\item Beucher, S. and Meyer, F. "The morphological approach to segmentation: the watershed632transformation." In \textit{Mathematical Morphology in Image Processing}, CRC Press, 1993.633\item Adams, R. and Bischof, L. "Seeded region growing." \textit{IEEE Trans. Pattern Anal.634Mach. Intell.} 16(6): 641-647, 1994.635\item Boomgaard, R. and Smeulders, A. "The morphological structure of images: the differential636equations of morphological scale-space." \textit{IEEE Trans. Pattern Anal. Mach. Intell.}63716(11): 1101-1113, 1994.638\item Jackway, P.T. and Deriche, M. "Scale-space properties of the multiscale morphological639dilation-erosion." \textit{IEEE Trans. Pattern Anal. Mach. Intell.} 18(1): 38-51, 1996.640\item Cheng, F. and Venetsanopoulos, A.N. "An adaptive morphological filter for image processing."641\textit{IEEE Trans. Image Process.} 1(4): 533-539, 1992.642\item Cuisenaire, O. and Macq, B. "Fast Euclidean distance transformation by propagation using643multiple neighborhoods." \textit{Comput. Vision Image Understand.} 76(2): 163-172, 1999.644\item Dougherty, E.R. and Lotufo, R.A. \textit{Hands-on Morphological Image Processing}.645SPIE Press, 2003.646\end{itemize}647648\end{document}649650651