A morfológia a képen lévő objektumok alakját módosító műveleteket foglalja magába. A kép mellett szükség van egy kernelre is, ami a gyakorlatban egy mátrix, általa a képen egyszerre nem csak az adott pixel, hanem környezete is vizsgálva van. A pixel környezetét a kernel által fedett terület jelenti. A kernel más elnevezése lehet a maszk vagy szűrő.
Célja az objektumok karcsúsítása. A kép minden képpontján a kernel alatti minimum érték lesz az új érték, tehát egy fehér pixel fekete színűre vált, ha környezetében legalább egy fekete pixel található. A fekete pixelek nyilvánvalóan feketék maradnak. Az objektum körül eltűnnek fehér pixelek, így az karcsúbbá válik.
Az objektumokat növeszti úgy, hogy minden képponton a kernel alatti legmagasabb érték lesz a vizsgált pixel értéke, azaz a fehér pixelek fehérek maradnak, a fekete színűek pedig fehérre változnak, ha a környezetükben van legalább egy fehér. Az objektumok körül új fehér képpontok keletkeznek, így azok növekednek.
Egy Erosion, majd egy azt követő Dilation elvégzése az Opening művelet. Eltávolítja a zajt objektumok körül, azaz a háttérről. A Closing egy Dilation és egy Erosion egymás után az objektumon belüli zaj eltávolítására, tehát a nem kívánt fekete pixeleket távolítja el a fehér területekről. A kettő együtt minden zajt eltávolít.
scikit-image telepítése: https://pypi.org/project/scikit-image
Fogaskerekek fénykép: Letöltés
Zajos fogaskerekek fénykép: Letöltés
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from skimage.morphology import erosion, dilation
# Open the image using PIL
image = Image.open("path-to-resources/gears.jpeg").convert("L")
# Convert image to a NumPy array
data = np.array(image, dtype=np.uint8)
# Apply thresholding
threshold = 128
data = np.where(data > threshold, 0, 1)
custom_footprint = np.array([[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1]], dtype=np.uint8)
# Set pixels to the minimum in their neighborhood
eroded_image = erosion(data, custom_footprint)
# Set pixels to the maximum in their neighborhood
dilated_image = dilation(data, custom_footprint)
# Display images
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
ax[0].imshow(eroded_image, cmap="gray")
ax[0].set_title("Eroded Image")
ax[0].axis("off")
ax[1].imshow(dilated_image, cmap="gray")
ax[1].set_title("Dilated Image")
ax[1].axis("off")
plt.show()
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from skimage.morphology import opening, closing
# Open the image using PIL
image = Image.open("path-to-resources/noisy-gears.jpeg").convert("L")
# Convert image to a NumPy array
data = np.array(image, dtype=np.uint8)
# Apply thresholding
threshold = 128
data = np.where(data > threshold, 0, 1)
custom_footprint = np.array([[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1]], dtype=np.uint8)
# Perform an erosion followed by a dilation
opened_image = opening(data, custom_footprint)
# Perform a dilation followed by an erosion
closed_image = closing(data, custom_footprint)
# Display images
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
ax[0].imshow(opened_image, cmap="gray")
ax[0].set_title("Opened Image")
ax[0].axis("off")
ax[1].imshow(closed_image, cmap="gray")
ax[1].set_title("Closed Image")
ax[1].axis("off")
plt.show()