How to get all array edges?

前端 未结 5 1309
攒了一身酷
攒了一身酷 2021-01-05 08:17

I have a n x n array, and want to receive its outline values. For example,

[4,5,6,7]

[2,2,6,3]

5条回答
  •  萌比男神i
    2021-01-05 08:33

    Here's one vectorized approach to create a mask of such edge pixels/elements and then simply indexing into the array to get those -

    def border_elems(a, W): # Input array : a, Edgewidth : W
        n = a.shape[0]
        r = np.minimum(np.arange(n)[::-1], np.arange(n))
        return a[np.minimum(r[:,None],r)

    Again, this not exactly meant for performance, but more for cases when you might to vary the edge-width or just create such a mask of such edge elements. The mask would be : np.minimum(r[:,None],r) as created at the last step.

    Sample run -

    In [89]: a
    Out[89]: 
    array([[49, 49, 12, 90, 42],
           [91, 58, 92, 16, 78],
           [97, 19, 58, 84, 84],
           [86, 31, 80, 78, 69],
           [29, 95, 38, 51, 92]])
    
    In [90]: border_elems(a,1)
    Out[90]: array([49, 49, 12, 90, 42, 91, 78, 97, 84, 86, 69, 29, 95, 38, 51, 92])
    
    In [91]: border_elems(a,2) # Note this will select all but the center one : 58
    Out[91]: 
    array([49, 49, 12, 90, 42, 91, 58, 92, 16, 78, 97, 19, 84, 84, 86, 31, 80,
           78, 69, 29, 95, 38, 51, 92])
    

    For generic shape, we can extend like so -

    def border_elems_generic(a, W): # Input array : a, Edgewidth : W
        n1 = a.shape[0]
        r1 = np.minimum(np.arange(n1)[::-1], np.arange(n1))
        n2 = a.shape[1]
        r2 = np.minimum(np.arange(n2)[::-1], np.arange(n2))
        return a[np.minimum(r1[:,None],r2)

    2D convolution based solution for generic shape

    Here's another with 2D convolution that takes care of generic 2D shape -

    from scipy.signal import convolve2d
    
    k = np.ones((3,3),dtype=int) # kernel
    boundary_elements = a[convolve2d(np.ones(a.shape,dtype=int),k,'same')<9]
    

    Sample run -

    In [36]: a
    Out[36]: 
    array([[4, 3, 8, 3, 1],
           [1, 5, 6, 6, 7],
           [9, 5, 2, 5, 9],
           [2, 2, 8, 4, 7]])
    
    In [38]: k = np.ones((3,3),dtype=int)
    
    In [39]: a[convolve2d(np.ones(a.shape,dtype=int),k,'same')<9]
    Out[39]: array([4, 3, 8, 3, 1, 1, 7, 9, 9, 2, 2, 8, 4, 7])
    

提交回复
热议问题