Find a 3x3 sliding window over an image

前端 未结 3 1914
星月不相逢
星月不相逢 2020-12-09 13:56

I have an image.

I want to obtain a 3x3 window (neighbouring pixels) for every pixel in the image.

I have this Python code:

for x in range(2,         


        
3条回答
  •  感动是毒
    2020-12-09 14:09

    I think the following does what you are after. The loop is only over the 9 elements. I'm sure there is a way of vectorizing it, but it's probably not worth the effort.

    import numpy
    
    im = numpy.random.randint(0,50,(5,7))
    
    # idx_2d contains the indices of each position in the array
    idx_2d = numpy.mgrid[0:im.shape[0],0:im.shape[1]]
    
    # We break that into 2 sub arrays
    x_idx = idx_2d[1]
    y_idx = idx_2d[0]
    
    # The mask is used to ignore the edge values (or indeed any values).
    mask = numpy.ones(im.shape, dtype='bool')
    mask[0, :] = False
    mask[:, 0] = False
    mask[im.shape[0] - 1, :] = False
    mask[:, im.shape[1] - 1] = False
    
    # We create and fill an array that contains the lookup for every
    # possible 3x3 array.
    idx_array = numpy.zeros((im[mask].size, 3, 3), dtype='int64')
    
    # Compute the flattened indices for each position in the 3x3 grid
    for n in range(0, 3):
        for m in range(0, 3):
            # Compute the flattened indices for each position in the 
            # 3x3 grid
            idx = (x_idx + (n-1)) + (y_idx  + (m-1)) * im.shape[1]
    
            # mask it, and write it to the big array
            idx_array[:, m, n] = idx[mask]
    
    
    # sub_images contains every valid 3x3 sub image
    sub_images = im.ravel()[idx_array]
    
    # Finally, we can flatten and sort each sub array quickly
    sorted_sub_images = numpy.sort(sub_images.reshape((idx[mask].size, 9)))
    

提交回复
热议问题