Skip to content

Instantly share code, notes, and snippets.

@chronick
Created January 2, 2019 16:00
Show Gist options
  • Save chronick/32c8757fc0361d5ae2be1e2a64288b88 to your computer and use it in GitHub Desktop.
Save chronick/32c8757fc0361d5ae2be1e2a64288b88 to your computer and use it in GitHub Desktop.
# make all pixels outside the polygon transparent
def get_cleaned_img(img, polygon):
# convert to numpy (for convenience)
imArray = np.asarray(img)
# create mask
maskIm = Image.new('L', (imArray.shape[1], imArray.shape[0]), 0)
ImageDraw.Draw(maskIm).polygon(polygon, outline=1, fill=1)
mask = np.array(maskIm)
# assemble new image (uint8: 0-255)
newImArray = np.empty(imArray.shape,dtype='uint8')
# colors (three first columns, RGB)
newImArray[:,:,:3] = imArray[:,:,:3]
# transparency (4th column)
newImArray[:,:,3] = mask*255
# back to Image from numpy
newIm = Image.fromarray(newImArray, "RGBA")
return newIm
def crop_picture(img, polygon):
img = np.asarray(img)
# vertices of the cropping polygon
xc = np.array([c[0] for c in polygon])
yc = np.array([c[1] for c in polygon])
xycrop = np.vstack((xc, yc)).T
# xy coordinates for each pixel in the image
nr, nc, channels = img.shape
ygrid, xgrid = np.mgrid[:nr, :nc]
xypix = np.vstack((xgrid.ravel(), ygrid.ravel())).T
# construct a Path from the vertices
pth = Path(xycrop, closed=False)
# test which pixels fall within the path
mask = pth.contains_points(xypix)
# reshape to the same size as the image
mask = mask.reshape((nr, nc))
mask = img * mask[:, :, None]
# create a masked array
masked = np.ma.masked_array(img, ~mask)
# if you want to get rid of the blank space above and below the cropped
# region, use the min and max x, y values of the cropping polygon:
xmin, xmax = int(xc.min()), int(np.ceil(xc.max()))
ymin, ymax = int(yc.min()), int(np.ceil(yc.max()))
trimmed = masked[ymin:ymax, xmin:xmax]
newIm = Image.fromarray(trimmed, "RGBA")
return newIm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment