I think it should be a very simple problem, but I cannot find a solution or an effective keyword for search.
I just have this image.
In case it helps anyone, I went with this tweak of @wordsforthewise's replacement for a PIL-based solution:
bw = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rows, cols = bw.shape
non_empty_columns = np.where(bw.max(axis=0) > 0)[0]
non_empty_rows = np.where(bw.max(axis=1) > 0)[0]
cropBox = (min(non_empty_rows) * (1 - padding),
min(max(non_empty_rows) * (1 + padding), rows),
min(non_empty_columns) * (1 - padding),
min(max(non_empty_columns) * (1 + padding), cols))
return img[cropBox[0]:cropBox[1]+1, cropBox[2]:cropBox[3]+1 , :]
(It's a tweak in that the original code expects to crop away a white background rather than a black one.)