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 dilated image dilationnp arraytrue false true np array0 1 0 arrayfalse false false dilationnp arrayfalse false true np array1 0 1 arrayfalse false false copy image to padded image iterate over image apply kernel read original image kernel to be applied 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 dilated image dilation np array true false true np array 0 1 0 array false false false dilation np array false false true np array 1 0 1 array false false false copy image to padded image iterate over image apply kernel read original image kernel to be applied 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 dilation(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 > 0)
    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 = dilation(gray_to_binary(rgb_to_gray(lena)), structuring_element)
    
    pil_img = Image.fromarray(output).convert("RGB")
    pil_img.save("result_dilation.png")