limitless
limitless

Reputation: 669

Sampling patches of points

Given an array of shape (N,2) I want to take a patch of size d x d for every point. for example if

d = 3
points = [[3, 2], [1, 2]]
patchs = array([[[[2, 1],[3, 1],[4, 1]],
                 [[2, 2],[3, 2],[4, 2]],
                 [[2, 3],[3, 3],[4, 3]]], [[[0, 1],[1, 1],[2, 1]],
                                           [[0, 2],[1, 2],[2, 2]],
                                           [[0, 3],[1, 3],[2, 3]]]])

I've managed to do it with one point only, but I can't find a smart way to avoid loops over N. this is what I did:

p = [3,2]
xs = p[0] + [-1,0,1]
ys = p[1] + [-1,0,1]
res = np.transpose([np.tile(xs, len(ys)), np.repeat(ys, len(xs))])

Upvotes: 1

Views: 56

Answers (1)

Divakar
Divakar

Reputation: 221534

Here's one vectorized approach leveraging broadcasting for assignments -

hd = d//2 # half patch size
r = np.arange(-hd,hd+1)

out = np.empty((len(points),d,d,2), dtype=points.dtype)
out[...,0] = points[:,0,None,None] + r
out[...,1] = points[:,1,None,None] + r[:,None]

Runtime test on one million points -

In [372]: points = np.random.randint(0,9,(1000000,2))

In [373]: %%timeit
     ...: hd = d//2 # half patch size
     ...: r = np.arange(-hd,hd+1)
     ...: 
     ...: out = np.empty((len(points),d,d,2), dtype=points.dtype)
     ...: out[...,0] = points[:,0,None,None] + r
     ...: out[...,1] = points[:,1,None,None] + r[:,None]
10 loops, best of 3: 69.9 ms per loop

Upvotes: 1

Related Questions