return gray image from rgb image rgbtograynp array127 255 0 array187 6453 rgbtograynp array0 0 0 array0 rgbtograynp array2 4 1 array3 0598 rgbtograynp array26 255 14 5 147 20 1 200 0 array159 0524 90 0635 117 6989 return binary image from gray image graytobinarynp array127 255 0 arrayfalse true false graytobinarynp array0 arrayfalse graytobinarynp array26 2409 4 9315 1 4729 arrayfalse false false graytobinarynp array26 255 14 5 147 20 1 200 0 arrayfalse true false false true false false true false return eroded image erosionnp arraytrue true false np array0 1 0 arrayfalse false false erosionnp arraytrue false false np array1 1 0 arrayfalse false false copy image to padded image iterate over image apply kernel read original image kernel to be applied apply erosion operation to a binary image save the output image return gray image from rgb image rgb_to_gray np array 127 255 0 array 187 6453 rgb_to_gray np array 0 0 0 array 0 rgb_to_gray np array 2 4 1 array 3 0598 rgb_to_gray np array 26 255 14 5 147 20 1 200 0 array 159 0524 90 0635 117 6989 return binary image from gray image gray_to_binary np array 127 255 0 array false true false gray_to_binary np array 0 array false gray_to_binary np array 26 2409 4 9315 1 4729 array false false false gray_to_binary np array 26 255 14 5 147 20 1 200 0 array false true false false true false false true false return eroded image erosion np array true true false np array 0 1 0 array false false false erosion np array true false false np array 1 1 0 array false false false copy image to padded image iterate over image apply kernel read original image kernel to be applied apply erosion operation to a binary image save the output image
from pathlib import Path

import numpy as np
from PIL import Image


def rgb_to_gray(rgb: np.ndarray) -> np.ndarray:
    
    r, g, b = rgb[:, :, 0], rgb[:, :, 1], rgb[:, :, 2]
    return 0.2989 * r + 0.5870 * g + 0.1140 * b


def gray_to_binary(gray: np.ndarray) -> np.ndarray:
    
    return (gray > 127) & (gray <= 255)


def erosion(image: np.ndarray, kernel: np.ndarray) -> np.ndarray:
    
    output = np.zeros_like(image)
    image_padded = np.zeros(
        (image.shape[0] + kernel.shape[0] - 1, image.shape[1] + kernel.shape[1] - 1)
    )

    
    image_padded[kernel.shape[0] - 2 : -1 :, kernel.shape[1] - 2 : -1 :] = image

    
    for x in range(image.shape[1]):
        for y in range(image.shape[0]):
            summation = (
                kernel * image_padded[y : y + kernel.shape[0], x : x + kernel.shape[1]]
            ).sum()
            output[y, x] = int(summation == 5)
    return output


if __name__ == "__main__":
    
    lena_path = Path(__file__).resolve().parent / "image_data" / "lena.jpg"
    lena = np.array(Image.open(lena_path))

    
    structuring_element = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]])

    
    output = erosion(gray_to_binary(rgb_to_gray(lena)), structuring_element)

    
    pil_img = Image.fromarray(output).convert("RGB")
    pil_img.save("result_erosion.png")