numpy - Pixel neighbors in 2d array (image) using Python -
i have numpy array this:
x = np.array([[1,2,3],[4,5,6],[7,8,9]])
i need create function let's call "neighbors" following input parameter:
- x: numpy 2d array
- (i,j): index of element in 2d array
- d: neighborhood radius
as output want neighbors of cell i,j
given distance d
. if run
neighbors(im, i, j, d=1) = 1 , j = 1 (element value = 5)
i should indices of following values: [1,2,3,4,6,7,8,9]
. hope make clear. there library scipy deal this?
i've done working it's rough solution.
def pixel_neighbours(self, p): rows, cols = self.im.shape i, j = p[0], p[1] rmin = - 1 if - 1 >= 0 else 0 rmax = + 1 if + 1 < rows else cmin = j - 1 if j - 1 >= 0 else 0 cmax = j + 1 if j + 1 < cols else j neighbours = [] x in xrange(rmin, rmax + 1): y in xrange(cmin, cmax + 1): neighbours.append([x, y]) neighbours.remove([p[0], p[1]]) return neighbours
how can improve this?
edit: ah crap, answer writing im[i-d:i+d+1, j-d:j+d+1].flatten()
written in incomprehensible way :)
the old sliding window trick may here:
import numpy np numpy.lib.stride_tricks import as_strided def sliding_window(arr, window_size): """ construct sliding window view of array""" arr = np.asarray(arr) window_size = int(window_size) if arr.ndim != 2: raise valueerror("need 2-d input") if not (window_size > 0): raise valueerror("need positive window size") shape = (arr.shape[0] - window_size + 1, arr.shape[1] - window_size + 1, window_size, window_size) if shape[0] <= 0: shape = (1, shape[1], arr.shape[0], shape[3]) if shape[1] <= 0: shape = (shape[0], 1, shape[2], arr.shape[1]) strides = (arr.shape[1]*arr.itemsize, arr.itemsize, arr.shape[1]*arr.itemsize, arr.itemsize) return as_strided(arr, shape=shape, strides=strides) def cell_neighbors(arr, i, j, d): """return d-th neighbors of cell (i, j)""" w = sliding_window(arr, 2*d+1) ix = np.clip(i - d, 0, w.shape[0]-1) jx = np.clip(j - d, 0, w.shape[1]-1) i0 = max(0, - d - ix) j0 = max(0, j - d - jx) i1 = w.shape[2] - max(0, d - + ix) j1 = w.shape[3] - max(0, d - j + jx) return w[ix, jx][i0:i1,j0:j1].ravel() x = np.arange(8*8).reshape(8, 8) print x d in [1, 2]: p in [(0,0), (0,1), (6,6), (8,8)]: print "-- d=%d, %r" % (d, p) print cell_neighbors(x, p[0], p[1], d=d)
didn't timings here, it's possible version has reasonable performance.
for more info, search net phrases "rolling window numpy" or "sliding window numpy".
Comments
Post a Comment