Search code examples
pythonnumpyscipycroptrim

Is there a SciPy method to autocrop an image, i. e. trim zeros from a 2d `numpy.ndarray`?


For 1d numpy.ndarray there is numpy.trim_zeros. Which method from numpy or scipy can I use to trim zeros for 2d arrays?

>>> import numpy as np
>>> a = np.array([[0, 0, 0, 0], [4, 1, 2, 0], [0, 3, 6, 0], [0, 0, 0, 0], [0, 0, 0, 0]])
>>> a
array([[0, 0, 0, 0],
       [4, 1, 2, 0],
       [0, 3, 6, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]])

The result I'd like to get:

array([[4, 1, 2],
       [0, 3, 6]])

Solution

  • I would search for position of leftmost, rightmost, topmost and bottommost nonzeros and then slice that array following way:

    import numpy as np
    a = np.array([[0, 0, 0, 0], [4, 1, 2, 0], [0, 3, 6, 0], [0, 0, 0, 0], [0, 0, 0, 0]])
    nzero = np.nonzero(a)
    top,bottom = np.min(nzero[0]),np.max(nzero[1])
    left,right = np.min(nzero[1]),np.max(nzero[1])
    out = a[top:bottom+1,left:right+1] # +1 as second argument is exclusive
    print(out)
    

    Output:

    [[4 1 2]
     [0 3 6]]
    

    Note that this method might be easily adopted also to 3D arrays by adding nearest and farthest, which would be respectively np.min and np.max of nzero[2]