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`][1] 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.) [1]: http://docs.scipy.org/doc/numpy/reference/generated/numpy.argwhere.html