# Cropping binary images based on pixel counts in python

I have a numpy binary masked image that looks like the following:

I want to automatically crop this image like the following:

Can I achieve this using some sort of image processing rather than building a bounding box regressor? The method should also work if the image is horizontally flipped.

I am currently using th below crop function to crop the image if any row or column have all 0 pixels:

def crop_image(img,tol=0):
# img is 2D image data
# tol  is tolerance


This crops out the upper black space from the image but does not work for the lower part for obvious reasons.

My attempt was to try to threshold the image based on pixel counts. Below is the code:

counts = np.sum(image==1,axis=0)
plt.plot(counts)


If we can threshold the image as below we might also consider the task partially successful as we would get something like the following:

Thanks alot. Any help will be highly appreciated.

One approach that is always available for binary images are morphological operations.

The critical piece of code is

# from skimage import morphology
# import numpy as np

# filter elements smaller than 1/6-th of the total width
selem = morphology.rectangle(1, img_binary.shape[1] // 6)
img_opened = morphology.opening(img_binary, selem=selem)

hist = np.sum(img_opened, axis=1)
non_zero = np.argwhere(hist > 0)
top_bound = int(np.round(np.min(non_zero) * (1 - 0.05))) # 5% tolerance
bottom_bound = int(np.round(np.max(non_zero) * (1 + 0.05))) # 5% tolerance


Here is the notebook I used to produce the image above: https://gist.github.com/FirefoxMetzger/5d0d5e207bf8182f61374ac9ad80f10f

• Hi FirefoxMetzger. Thanks for your answer. Unfortunately this does not work for me. I get this image when I try to visualize the img_opened. [![enter image description here][1]][1] [1]: i.stack.imgur.com/8PIt5.png . Addiitonally how do you choose the threshold 1/6th, is there a way to dynamically estimate this? Nov 23 '20 at 13:46
• @NolanCardozo Are you opening a binary image or a gray-scale image? Your result may stem from using a gray-scale morphological operation instead of a binary one. Regarding a dynamic threshold, you can choose the structuring element (selem) dynamically. I choose a fixed one, because - given your question - it seemed like the simplest solution. Nov 23 '20 at 19:48