I want to produce a Python algorithm which takes in a 'mask' RGB image comprised exclusively of black and white pixels. Basically, each mask is a black image with one or more white shapes on it (see below).
I want to transform this image by enlarging the white areas by a factor x:
So far I have only got it to work by drawing rectangles around the shapes using PIL:
def add_padding_to_mask(mask, padding):
# Create a copy of the original mask
padded_mask = mask.copy()
draw = ImageDraw.Draw(padded_mask)
# Iterate over the pixels in the original mask
for x in range(mask.width):
for y in range(mask.height):
# If the pixel is white, draw a white rectangle with the desired padding around it
if mask.getpixel((x, y)) == (255, 255, 255):
draw.rectangle((x-padding, y-padding, x+padding, y+padding), fill=(255, 255, 255))
return padded_mask
This is suboptimal since I want to retain the original white shapes (only make them larger). I can't figure out an efficient way to approach this problem. Any help greatly appreciated.
If you want to enlarge a white object on a black background, you can use "morphological dilation". There are many tools/methods:
The simplest is with ImageMagick on the command-line, e.g.:
magick XlAiE.png -morphology dilate disk:3.5 result.png
There are lots of examples here. I'm showing you with ImageMagick not because it is better or anything, but so you can quickly experiment with different structuring elements and sizes without needing to code any (slightly more complicated) Python. Increase the 3.5 in the command for more dilation, or decrease it for less.
If you want to use Python, see:
Here's an OpenCV version:
#!/usr/bin/env python3
import cv2
import numpy as np
# Load image
im = cv2.imread('XlAiE.png', cv2.IMREAD_GRAYSCALE)
# Dilate with an elliptical/circular structuring element
SE = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,9))
res = cv2.morphologyEx(im, cv2.MORPH_DILATE, SE)
cv2.imwrite('result.png', res)
Reduce the (9,9)
to, say (3,3)
for less dilation, or increase it to, say (20,20)
for more dilation.
If you just want to dilate vertically, use a tall thin structuring element:
SE = np.ones((20,1), np.uint8)
res = cv2.morphologyEx(im, cv2.MORPH_DILATE, SE)
If you just want to dilate horizontally, use a wide thin structuring element:
SE = np.ones((1,20), np.uint8)
res = cv2.morphologyEx(im, cv2.MORPH_DILATE, SE)