Crop black edges with OpenCV

I am not sure whether all your images are like this. But for this image, below is a simple python-opencv code to crop it.

first import libraries :

import cv2
import numpy as np

Read the image, convert it into grayscale, and make in binary image for threshold value of 1.

img = cv2.imread('sofwin.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
_,thresh = cv2.threshold(gray,1,255,cv2.THRESH_BINARY)

Now find contours in it. There will be only one object, so find bounding rectangle for it.

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
x,y,w,h = cv2.boundingRect(cnt)

Now crop the image, and save it into another file.

crop = img[y:y+h,x:x+w]
cv2.imwrite('sofwinres.png',crop)

Below is the result :

enter image description here


import numpy as np

def autocrop(image, threshold=0):
    """Crops any edges below or equal to threshold

    Crops blank image to 1x1.

    Returns cropped image.

    """
    if len(image.shape) == 3:
        flatImage = np.max(image, 2)
    else:
        flatImage = image
    assert len(flatImage.shape) == 2

    rows = np.where(np.max(flatImage, 0) > threshold)[0]
    if rows.size:
        cols = np.where(np.max(flatImage, 1) > threshold)[0]
        image = image[cols[0]: cols[-1] + 1, rows[0]: rows[-1] + 1]
    else:
        image = image[:1, :1]

    return image

I thought this answer is much more succinct:

def crop(image):
    y_nonzero, x_nonzero, _ = np.nonzero(image)
    return image[np.min(y_nonzero):np.max(y_nonzero), np.min(x_nonzero):np.max(x_nonzero)]