As you've discovered, looping over individual pixels in Python is very slow. You need to organize your computation so that it uses a series of NumPy (or SciPy, or Scikit-Image, or OpenCV) operations on the whole image.
In this case, you could use numpy.argwhere
to find the bounding box of the non-black regions:
# Mask of non-black pixels (assuming image has a single channel).
mask = image > 0
# Coordinates of non-black pixels.
coords = np.argwhere(mask)
# Bounding box of non-black pixels.
x0, y0 = coords.min(axis=0)
x1, y1 = coords.max(axis=0) + 1 # slices are exclusive at the top
# Get the contents of the bounding box.
cropped = image[x0:x1, y0:y1]
(Note that this relies on there being some non-black pixels; if the whole image is black, then coords
will be empty and you'll have to find something else to do in that case.)