Home > Net >  Cropping excess padding from binary images keeping a constant margin
Cropping excess padding from binary images keeping a constant margin

Time:08-07

I'm trying to crop some binary images. The images have a black background and white silhouette. I want to crop all of my images, removing any excess background. I've tried doing this using the function below, however, the output images tend to also crop the edges of the silhouette, whilst I would like to keep these. I haven't been successful in finding a way to do this. Any ideas on how this could be done?

example images example images

def crop_image(img,tol):
    mask = img > tol
    return img[np.ix_(mask.any(1),mask.any(0))]

CodePudding user response:

You can get the coordinates from cv2.findNonZero() function, and cv2.boundingRect()

import matplotlib.pyplot as plt
import numpy as np
import cv2


def downloadImage(URL):
    """Downloads the image on the URL, and convers to cv2 RGB format"""
    from io import BytesIO
    from PIL import Image as PIL_Image
    import requests

    response = requests.get(URL)
    image = PIL_Image.open(BytesIO(response.content))
    return cv2.cvtColor(np.array(image), cv2.COLOR_BGR2RGB)


URL = "https://i.stack.imgur.com/WgnXW.jpg"

# Read image
img = downloadImage(URL)

# crop blank frame
initialImage = img[11:2330, 11:2208]

fig, ax = plt.subplots(1, 3)
ax[0].imshow(initialImage)
ax[0].set_title('Initial Image')

# crop the empty space
coords = cv2.findNonZero(cv2.cvtColor(initialImage, cv2.COLOR_BGR2GRAY))
x, y, w, h = cv2.boundingRect(coords)
cropedIMag = initialImage[y:y h, x:x w]

ax[1].imshow(cropedIMag)
ax[1].set_title('Cropped Image')

# Add an empty frame to the image
extraPixels = 100
paddedImag = np.pad(cropedIMag, ((extraPixels, extraPixels),(extraPixels, extraPixels),(0,0)), 'constant')

ax[2].imshow(paddedImag)
ax[2].set_title('Cropped \nand padded Image')

plt.show()

enter image description here

  • Related